From 1d5de0dcaac7a808e5d4aaa3a7f85f658d65e252 Mon Sep 17 00:00:00 2001 From: sherlock-admin Date: Tue, 24 Sep 2024 16:10:01 +0000 Subject: [PATCH] Fix Review --- .../.github/workflows/changelog.yml | 17 + andromeda-core/CHANGELOG.md | 59 + andromeda-core/Cargo.lock | 4254 +++- andromeda-core/Cargo.toml | 30 +- andromeda-core/README.md | 217 +- andromeda-core/build.sh | 28 +- andromeda-core/build_all.sh | 2 +- andromeda-core/build_schema.sh | 30 + andromeda-core/bump-version.sh | 64 + andromeda-core/ci-scripts/install_binaryen.sh | 6 + .../ci-scripts/localrelayer/Makefile | 24 - .../ci-scripts/localrelayer/README.md | 221 - .../localrelayer/config/hermes/config.toml | 101 - .../localrelayer/docker-compose.yml | 74 - andromeda-core/ci-scripts/localrelayer/go.mod | 335 - andromeda-core/ci-scripts/localrelayer/go.sum | 1855 -- .../ci-scripts/localrelayer/go.work | 15 - .../localrelayer/scripts/setup_chain.sh | 114 - .../localrelayer/scripts/setup_hermes.sh | 71 - .../app/andromeda-app-contract/Cargo.toml | 16 +- .../app/andromeda-app-contract/README.md | 6 + .../schema/andromeda-app-contract.json | 2025 -- .../schema/raw/execute.json | 797 - .../schema/raw/instantiate.json | 142 - .../schema/raw/query.json | 478 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_component_exists.json | 14 - .../schema/raw/response_to_config.json | 18 - .../schema/raw/response_to_get.json | 18 - .../schema/raw/response_to_get_address.json | 5 - .../response_to_get_addresses_with_names.json | 94 - .../raw/response_to_get_components.json | 88 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-app-contract/src/contract.rs | 195 +- .../app/andromeda-app-contract/src/execute.rs | 118 +- .../app/andromeda-app-contract/src/mock.rs | 46 +- .../app/andromeda-app-contract/src/reply.rs | 42 +- .../app/andromeda-app-contract/src/state.rs | 163 +- .../andromeda-app-contract/src/testing/mod.rs | 580 +- .../andromeda-boolean/.cargo/config | 4 + .../data-storage/andromeda-boolean/Cargo.toml | 40 + .../andromeda-boolean/examples/schema.rs | 10 + .../andromeda-boolean/src/contract.rs | 94 + .../andromeda-boolean/src/execute.rs | 184 + .../data-storage/andromeda-boolean/src/lib.rs | 9 + .../andromeda-boolean/src/mock.rs | 112 + .../andromeda-boolean/src/query.rs | 16 + .../andromeda-boolean/src/state.rs | 7 + .../andromeda-boolean/src/testing/mock.rs | 59 + .../andromeda-boolean/src/testing/mod.rs | 2 + .../andromeda-boolean/src/testing/tests.rs | 268 + .../andromeda-counter/.cargo/config | 4 + .../data-storage/andromeda-counter/Cargo.toml | 40 + .../andromeda-counter/examples/schema.rs | 10 + .../andromeda-counter/src/contract.rs | 301 + .../data-storage/andromeda-counter/src/lib.rs | 7 + .../andromeda-counter/src/mock.rs | 216 + .../andromeda-counter/src/state.rs | 10 + .../andromeda-counter/src/testing/mock.rs | 124 + .../andromeda-counter/src/testing/mod.rs | 2 + .../andromeda-counter/src/testing/tests.rs | 220 + .../andromeda-primitive/Cargo.toml | 12 +- .../andromeda-primitive/README.md | 21 + .../schema/andromeda-primitive.json | 1704 -- .../schema/raw/execute.json | 721 - .../schema/raw/instantiate.json | 34 - .../andromeda-primitive/schema/raw/query.json | 414 - .../schema/raw/response_to_all_keys.json | 8 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 168 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_get_value.json | 169 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../schema/raw/response_to_owner_keys.json | 8 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-primitive/src/contract.rs | 49 +- .../andromeda-primitive/src/execute.rs | 102 +- .../andromeda-primitive/src/mock.rs | 86 +- .../andromeda-primitive/src/query.rs | 11 +- .../andromeda-primitive/src/testing/mock.rs | 17 +- .../andromeda-primitive/src/testing/tests.rs | 252 +- .../andromeda-string-storage/.cargo/config | 4 + .../andromeda-string-storage/Cargo.toml | 40 + .../examples/schema.rs | 10 + .../andromeda-string-storage/src/contract.rs | 74 + .../andromeda-string-storage/src/execute.rs | 153 + .../andromeda-string-storage/src/lib.rs | 9 + .../andromeda-string-storage/src/mock.rs | 112 + .../andromeda-string-storage/src/query.rs | 31 + .../andromeda-string-storage/src/state.rs | 7 + .../src/testing/mock.rs | 68 + .../src/testing/mod.rs | 2 + .../src/testing/tests.rs | 305 + .../ecosystem/andromeda-vault/Cargo.toml | 39 +- .../ecosystem/andromeda-vault/README.md | 2 + .../schema/andromeda-vault.json | 1380 - .../andromeda-vault/schema/raw/execute.json | 747 - .../schema/raw/instantiate.json | 20 - .../andromeda-vault/schema/raw/query.json | 257 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../raw/response_to_strategy_address.json | 6 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_vault_balance.json | 6 - .../schema/raw/response_to_version.json | 14 - .../ecosystem/andromeda-vault/src/contract.rs | 94 +- .../src/testing/mock_querier.rs | 34 +- .../andromeda-vault/src/testing/mod.rs | 32 +- .../.cargo/config | 4 + .../andromeda-conditional-splitter/.gitignore | 2 + .../andromeda-conditional-splitter/Cargo.toml | 32 + .../andromeda-conditional-splitter/README.md | 6 + .../examples/schema.rs | 11 + .../src/contract.rs | 315 + .../andromeda-conditional-splitter/src/lib.rs | 8 + .../src/mock.rs | 67 + .../src/state.rs | 4 + .../src/testing/mock_querier.rs | 82 + .../src/testing/mod.rs | 2 + .../src/testing/tests.rs | 826 + .../andromeda-cross-chain-swap/Cargo.toml | 7 +- .../andromeda-cross-chain-swap/README.md | 0 .../schema/andromeda-cross-chain-swap.json | 1444 -- .../schema/raw/execute.json | 632 - .../schema/raw/instantiate.json | 99 - .../schema/raw/query.json | 207 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_get_splitter_config.json | 162 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../src/contract.rs | 60 +- .../andromeda-cross-chain-swap/src/mock.rs | 2 +- .../src/testing/mock_querier.rs | 8 +- .../Cargo.toml | 14 +- .../README.md | 5 + .../examples/schema.rs | 2 +- .../andromeda-rate-limiting-withdrawals.json | 1611 -- .../schema/raw/execute.json | 722 - .../schema/raw/instantiate.json | 99 - .../schema/raw/query.json | 245 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_get_splitter_config.json | 162 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../src/contract.rs | 288 +- .../src/testing/mock_querier.rs | 102 +- .../src/testing/tests.rs | 62 +- .../.cargo/config | 4 + .../andromeda-set-amount-splitter/.gitignore | 2 + .../andromeda-set-amount-splitter/Cargo.toml | 32 + .../examples/schema.rs | 11 + .../src/contract.rs | 325 + .../andromeda-set-amount-splitter/src/lib.rs | 8 + .../andromeda-set-amount-splitter/src/mock.rs | 60 + .../src/state.rs | 4 + .../src/testing/mock_querier.rs | 91 + .../src/testing/mod.rs | 2 + .../src/testing/tests.rs | 494 + .../finance/andromeda-splitter/Cargo.toml | 12 +- .../finance/andromeda-splitter/README.md | 5 + .../schema/andromeda-splitter.json | 1444 -- .../schema/raw/execute.json | 632 - .../schema/raw/instantiate.json | 99 - .../andromeda-splitter/schema/raw/query.json | 207 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_get_splitter_config.json | 162 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-splitter/src/contract.rs | 175 +- .../finance/andromeda-splitter/src/mock.rs | 15 +- .../finance/andromeda-splitter/src/state.rs | 2 - .../src/testing/mock_querier.rs | 103 +- .../andromeda-splitter/src/testing/tests.rs | 218 +- .../finance/andromeda-timelock/Cargo.toml | 10 +- .../finance/andromeda-timelock/README.md | 10 + .../schema/andromeda-timelock.json | 1768 -- .../schema/raw/execute.json | 682 - .../schema/raw/instantiate.json | 58 - .../andromeda-timelock/schema/raw/query.json | 255 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_get_locked_funds.json | 215 - ...nse_to_get_locked_funds_for_recipient.json | 214 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-timelock/src/contract.rs | 66 +- .../src/testing/mock_querier.rs | 104 +- .../andromeda-timelock/src/testing/tests.rs | 181 +- .../andromeda-validator-staking/Cargo.toml | 6 +- .../examples/schema.rs | 4 +- .../schema/andromeda-validator-staking.json | 40 - .../schema/raw/instantiate.json | 30 - .../src/contract.rs | 221 +- .../andromeda-validator-staking/src/lib.rs | 2 +- .../andromeda-validator-staking/src/mock.rs | 59 +- .../andromeda-validator-staking/src/state.rs | 4 +- .../src/testing/tests.rs | 18 +- .../andromeda-validator-staking/src/util.rs | 82 + .../finance/andromeda-vesting/Cargo.toml | 11 +- .../schema/andromeda-vesting.json | 1940 -- .../andromeda-vesting/schema/raw/execute.json | 813 - .../schema/raw/instantiate.json | 157 - .../andromeda-vesting/schema/raw/query.json | 263 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - .../schema/raw/response_to_batch.json | 121 - .../schema/raw/response_to_batches.json | 127 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_config.json | 115 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../finance/andromeda-vesting/src/contract.rs | 340 +- .../finance/andromeda-vesting/src/lib.rs | 2 + .../finance/andromeda-vesting/src/mock.rs | 73 + .../src/testing/mock_querier.rs | 103 +- .../andromeda-vesting/src/testing/tests.rs | 706 +- .../Cargo.toml | 8 +- ...romeda-weighted-distribution-splitter.json | 1622 -- .../schema/raw/execute.json | 694 - .../schema/raw/instantiate.json | 131 - .../schema/raw/query.json | 266 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_get_splitter_config.json | 162 - .../raw/response_to_get_user_weight.json | 25 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../src/contract.rs | 63 +- .../src/mock_querier.rs | 7 +- .../src/testing/tests.rs | 103 +- .../andromeda-cw20-exchange/Cargo.toml | 8 +- .../andromeda-cw20-exchange/README.md | 10 + .../examples/schema.rs | 13 +- .../schema/andromeda-cw20-exchange.json | 1504 -- .../schema/raw/execute.json | 627 - .../schema/raw/instantiate.json | 67 - .../schema/raw/query.json | 291 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_sale.json | 143 - .../schema/raw/response_to_sale_assets.json | 17 - .../schema/raw/response_to_token_address.json | 15 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-cw20-exchange/src/contract.rs | 126 +- .../src/testing/mock_querier.rs | 5 +- .../src/testing/tests.rs | 71 +- .../andromeda-cw20-staking/Cargo.toml | 13 +- .../andromeda-cw20-staking/README.md | 5 + .../schema/andromeda-cw20-staking.json | 1907 -- .../schema/raw/execute.json | 830 - .../schema/raw/instantiate.json | 185 - .../schema/raw/query.json | 325 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_config.json | 32 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_staker.json | 57 - .../schema/raw/response_to_stakers.json | 63 - .../schema/raw/response_to_state.json | 25 - .../schema/raw/response_to_timestamp.json | 7 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../src/allocated_rewards.rs | 86 +- .../andromeda-cw20-staking/src/contract.rs | 324 +- .../andromeda-cw20-staking/src/mock.rs | 41 +- .../src/testing/mock_querier.rs | 4 +- .../src/testing/tests.rs | 1027 +- .../fungible-tokens/andromeda-cw20/Cargo.toml | 13 +- .../fungible-tokens/andromeda-cw20/README.md | 5 + .../andromeda-cw20/schema/andromeda-cw20.json | 2351 -- .../andromeda-cw20/schema/raw/execute.json | 984 - .../schema/raw/instantiate.json | 242 - .../andromeda-cw20/schema/raw/query.json | 379 - .../schema/raw/response_to_all_accounts.json | 16 - .../raw/response_to_all_allowances.json | 101 - .../schema/raw/response_to_allowance.json | 82 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_download_logo.json | 25 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../raw/response_to_marketing_info.json | 74 - .../schema/raw/response_to_minter.json | 31 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_token_info.json | 34 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-cw20/src/contract.rs | 343 +- .../andromeda-cw20/src/mock.rs | 193 +- .../src/testing/mock_querier.rs | 94 +- .../andromeda-cw20/src/testing/tests.rs | 175 +- .../andromeda-lockdrop/Cargo.toml | 15 +- .../andromeda-lockdrop/README.md | 5 + .../schema/andromeda-lockdrop.json | 1630 -- .../schema/raw/execute.json | 729 - .../schema/raw/instantiate.json | 89 - .../andromeda-lockdrop/schema/raw/query.json | 305 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_config.json | 56 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_state.json | 30 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_user_info.json | 32 - .../schema/raw/response_to_version.json | 14 - ...esponse_to_withdrawal_percent_allowed.json | 6 - .../andromeda-lockdrop/src/contract.rs | 304 +- .../andromeda-lockdrop/src/lib.rs | 3 + .../andromeda-lockdrop/src/mock.rs | 56 + .../andromeda-lockdrop/src/state.rs | 12 +- .../src/testing/mock_querier.rs | 105 +- .../andromeda-lockdrop/src/testing/tests.rs | 538 +- .../andromeda-merkle-airdrop/Cargo.toml | 9 +- .../andromeda-merkle-airdrop/README.md | 5 + .../schema/andromeda-merkle-airdrop.json | 1538 -- .../schema/raw/execute.json | 618 - .../schema/raw/instantiate.json | 91 - .../schema/raw/query.json | 292 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_config.json | 49 - .../schema/raw/response_to_is_claimed.json | 14 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_latest_stage.json | 16 - .../schema/raw/response_to_merkle_root.json | 94 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_total_claimed.json | 20 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-merkle-airdrop/src/contract.rs | 213 +- .../andromeda-merkle-airdrop/src/state.rs | 8 +- .../src/testing/mock_querier.rs | 5 +- .../src/testing/tests.rs | 153 +- .../modules/andromeda-address-list/Cargo.toml | 14 +- .../modules/andromeda-address-list/README.md | 7 + .../schema/andromeda-address-list.json | 1549 -- .../schema/raw/execute.json | 675 - .../schema/raw/instantiate.json | 24 - .../schema/raw/query.json | 432 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_includes_address.json | 15 - .../schema/raw/response_to_is_inclusive.json | 14 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-address-list/src/contract.rs | 209 +- .../andromeda-address-list/src/mock.rs | 48 +- .../andromeda-address-list/src/state.rs | 34 +- .../src/testing/mock_querier.rs | 44 +- .../src/testing/tests.rs | 368 +- .../modules/andromeda-date-time/.cargo/config | 4 + .../modules/andromeda-date-time/Cargo.toml | 34 + .../andromeda-date-time/examples/schema.rs | 10 + .../andromeda-date-time/src/contract.rs | 126 + .../modules/andromeda-date-time/src/lib.rs | 6 + .../modules/andromeda-date-time/src/mock.rs | 58 + .../andromeda-date-time/src/testing/mock.rs | 39 + .../andromeda-date-time/src/testing/mod.rs | 2 + .../andromeda-date-time/src/testing/tests.rs | 82 + .../modules/andromeda-rates/Cargo.toml | 44 +- .../modules/andromeda-rates/README.md | 5 + .../schema/andromeda-rates.json | 1691 -- .../andromeda-rates/schema/raw/execute.json | 649 - .../schema/raw/instantiate.json | 165 - .../andromeda-rates/schema/raw/query.json | 372 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../schema/raw/response_to_payments.json | 155 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../modules/andromeda-rates/src/contract.rs | 199 +- .../modules/andromeda-rates/src/mock.rs | 16 +- .../modules/andromeda-rates/src/state.rs | 13 +- .../src/testing/mock_querier.rs | 85 +- .../andromeda-rates/src/testing/mod.rs | 1 + .../src/testing/test_handler.rs | 109 + .../andromeda-rates/src/testing/tests.rs | 240 +- .../modules/andromeda-shunting/Cargo.toml | 8 +- .../schema/andromeda-shunting.json | 1366 - .../schema/raw/execute.json | 540 - .../schema/raw/instantiate.json | 27 - .../andromeda-shunting/schema/raw/query.json | 435 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../raw/response_to_eval_with_params.json | 14 - .../schema/raw/response_to_evaluate.json | 14 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-shunting/src/contract.rs | 6 +- .../modules/andromeda-shunting/src/mock.rs | 5 +- .../andromeda-shunting/src/testing/tests.rs | 4 +- .../andromeda-auction/Cargo.toml | 17 +- .../andromeda-auction/README.md | 5 + .../schema/andromeda-auction.json | 2276 -- .../schema/cw721receive.json | 71 - .../andromeda-auction/schema/raw/execute.json | 780 - .../schema/raw/instantiate.json | 58 - .../andromeda-auction/schema/raw/query.json | 638 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_auction_ids.json | 23 - ...response_to_auction_infos_for_address.json | 31 - .../schema/raw/response_to_auction_state.json | 130 - .../schema/raw/response_to_balance.json | 39 - .../schema/raw/response_to_bids.json | 55 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_is_cancelled.json | 14 - .../schema/raw/response_to_is_claimed.json | 14 - .../schema/raw/response_to_is_closed.json | 14 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../raw/response_to_latest_auction_state.json | 130 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-auction/src/contract.rs | 736 +- .../andromeda-auction/src/mock.rs | 151 +- .../andromeda-auction/src/state.rs | 12 +- .../src/testing/mock_querier.rs | 140 +- .../andromeda-auction/src/testing/tests.rs | 1321 +- .../andromeda-crowdfund/Cargo.toml | 15 +- .../andromeda-crowdfund/README.md | 6 + .../schema/andromeda-crowdfund.json | 2033 -- .../schema/raw/execute.json | 852 - .../schema/raw/instantiate.json | 66 - .../andromeda-crowdfund/schema/raw/query.json | 473 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 181 - .../raw/response_to_available_tokens.json | 8 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_config.json | 30 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_is_token_available.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_state.json | 201 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-crowdfund/src/contract.rs | 1271 +- .../andromeda-crowdfund/src/mock.rs | 193 +- .../andromeda-crowdfund/src/state.rs | 521 +- .../src/testing/mock_querier.rs | 250 +- .../andromeda-crowdfund/src/testing/tests.rs | 3133 ++- .../andromeda-cw721/Cargo.toml | 13 +- .../andromeda-cw721/README.md | 5 + .../schema/andromeda-cw721.json | 4159 ---- .../andromeda-cw721/schema/raw/execute.json | 1577 -- .../schema/raw/instantiate.json | 77 - .../andromeda-cw721/schema/raw/query.json | 1330 - .../schema/raw/response_to_all_nft_info.json | 170 - .../schema/raw/response_to_all_operators.json | 100 - .../schema/raw/response_to_all_tokens.json | 18 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_approval.json | 97 - .../schema/raw/response_to_approvals.json | 100 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_contract_info.json | 18 - .../schema/raw/response_to_extension.json | 16 - .../schema/raw/response_to_get.json | 18 - .../schema/raw/response_to_is_archived.json | 14 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../schema/raw/response_to_minter.json | 15 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_nft_info.json | 42 - .../schema/raw/response_to_num_tokens.json | 16 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../schema/raw/response_to_owner_of.json | 106 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_tokens.json | 18 - .../raw/response_to_transfer_agreement.json | 56 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-cw721/src/contract.rs | 226 +- .../andromeda-cw721/src/mock.rs | 33 +- .../andromeda-cw721/src/state.rs | 3 - .../andromeda-cw721/src/testing/mod.rs | 260 +- .../andromeda-marketplace/Cargo.toml | 15 +- .../andromeda-marketplace/README.md | 10 + .../schema/andromeda-marketplace.json | 1820 -- .../schema/cw721receive.json | 54 - .../schema/raw/execute.json | 724 - .../schema/raw/instantiate.json | 58 - .../schema/raw/query.json | 507 - .../schema/raw/response_to_andr_hook.json | 6 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 39 - ...esponse_to_block_height_upon_creation.json | 16 - .../schema/raw/response_to_is_operator.json | 14 - .../raw/response_to_kernel_address.json | 20 - .../raw/response_to_latest_sale_state.json | 41 - .../schema/raw/response_to_module.json | 31 - .../schema/raw/response_to_module_ids.json | 8 - .../schema/raw/response_to_operators.json | 17 - .../raw/response_to_original_publisher.json | 14 - .../schema/raw/response_to_owner.json | 14 - .../raw/response_to_permissioned_actions.json | 8 - .../schema/raw/response_to_permissions.json | 165 - .../schema/raw/response_to_sale_ids.json | 23 - .../response_to_sale_infos_for_address.json | 37 - .../schema/raw/response_to_sale_state.json | 41 - .../schema/raw/response_to_type.json | 14 - .../schema/raw/response_to_version.json | 14 - .../andromeda-marketplace/src/contract.rs | 1032 +- .../andromeda-marketplace/src/mock.rs | 146 +- .../andromeda-marketplace/src/state.rs | 7 +- .../src/testing/mock_querier.rs | 141 +- .../src/testing/tests.rs | 607 +- .../contracts/os/andromeda-adodb/Cargo.toml | 8 +- .../contracts/os/andromeda-adodb/README.md | 6 +- .../schema/andromeda-adodb.json | 495 - .../andromeda-adodb/schema/raw/execute.json | 173 - .../schema/raw/instantiate.json | 20 - .../os/andromeda-adodb/schema/raw/query.json | 136 - .../raw/response_to_a_d_o_metadata.json | 30 - .../schema/raw/response_to_a_d_o_type.json | 8 - .../schema/raw/response_to_action_fee.json | 52 - .../response_to_action_fee_by_code_id.json | 52 - .../raw/response_to_all_a_d_o_types.json | 8 - .../schema/raw/response_to_andr_query.json | 7 - .../schema/raw/response_to_code_id.json | 7 - .../os/andromeda-adodb/src/contract.rs | 347 +- .../os/andromeda-adodb/src/execute.rs | 257 + .../contracts/os/andromeda-adodb/src/lib.rs | 3 + .../contracts/os/andromeda-adodb/src/mock.rs | 7 + .../contracts/os/andromeda-adodb/src/query.rs | 129 + .../contracts/os/andromeda-adodb/src/state.rs | 117 +- .../contracts/os/andromeda-adodb/src/tests.rs | 378 +- .../os/andromeda-economics/Cargo.toml | 9 +- .../os/andromeda-economics/README.md | 11 +- .../schema/andromeda-economics.json | 261 - .../schema/raw/execute.json | 173 - .../schema/raw/instantiate.json | 21 - .../andromeda-economics/schema/raw/query.json | 38 - .../schema/raw/response_to_a_d_o_type.json | 8 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_balance.json | 20 - .../schema/raw/response_to_code_id.json | 7 - .../os/andromeda-economics/src/contract.rs | 431 +- .../os/andromeda-economics/src/execute.rs | 326 + .../os/andromeda-economics/src/lib.rs | 2 + .../os/andromeda-economics/src/query.rs | 12 + .../src/tests/mock_querier.rs | 3 +- .../os/andromeda-economics/src/tests/mod.rs | 342 +- .../os/andromeda-ibc-registry/.cargo/config | 4 + .../os/andromeda-ibc-registry/Cargo.toml | 38 + .../andromeda-ibc-registry/examples/schema.rs | 10 + .../os/andromeda-ibc-registry/src/contract.rs | 194 + .../os/andromeda-ibc-registry/src/lib.rs | 7 + .../os/andromeda-ibc-registry/src/mock.rs | 27 + .../os/andromeda-ibc-registry/src/state.rs | 4 + .../andromeda-ibc-registry/src/testing/mod.rs | 1 + .../src/testing/tests.rs | 24 + .../contracts/os/andromeda-kernel/Cargo.toml | 10 +- .../contracts/os/andromeda-kernel/README.md | 11 +- .../schema/andromeda-kernel.json | 647 - .../andromeda-kernel/schema/raw/execute.json | 428 - .../schema/raw/instantiate.json | 20 - .../os/andromeda-kernel/schema/raw/query.json | 96 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_channel_info.json | 45 - .../schema/raw/response_to_key_address.json | 6 - .../schema/raw/response_to_recoveries.json | 29 - .../raw/response_to_verify_address.json | 14 - .../contracts/os/andromeda-kernel/src/ack.rs | 8 +- .../os/andromeda-kernel/src/contract.rs | 68 +- .../os/andromeda-kernel/src/execute.rs | 297 +- .../contracts/os/andromeda-kernel/src/ibc.rs | 31 +- .../os/andromeda-kernel/src/query.rs | 14 +- .../os/andromeda-kernel/src/reply.rs | 27 +- .../contracts/os/andromeda-kernel/src/sudo.rs | 4 +- .../os/andromeda-kernel/src/testing/mod.rs | 1 + .../src/testing/test_handler.rs | 229 + .../os/andromeda-kernel/src/testing/tests.rs | 268 +- .../contracts/os/andromeda-vfs/Cargo.toml | 10 +- .../contracts/os/andromeda-vfs/README.md | 7 +- .../andromeda-vfs/schema/andromeda-vfs.json | 424 - .../os/andromeda-vfs/schema/raw/execute.json | 192 - .../andromeda-vfs/schema/raw/instantiate.json | 21 - .../os/andromeda-vfs/schema/raw/query.json | 142 - .../schema/raw/response_to_andr_query.json | 181 - .../schema/raw/response_to_get_library.json | 5 - .../schema/raw/response_to_get_username.json | 5 - .../schema/raw/response_to_key_address.json | 6 - .../schema/raw/response_to_paths.json | 8 - .../schema/raw/response_to_resolve_path.json | 6 - .../raw/response_to_resolve_symlink.json | 6 - .../schema/raw/response_to_sub_dir.json | 30 - .../raw/response_to_verify_address.json | 5 - .../os/andromeda-vfs/src/contract.rs | 76 +- .../contracts/os/andromeda-vfs/src/execute.rs | 99 +- .../contracts/os/andromeda-vfs/src/query.rs | 18 +- .../contracts/os/andromeda-vfs/src/state.rs | 379 +- .../os/andromeda-vfs/src/testing/tests.rs | 250 +- andromeda-core/git-conventional-commits.yaml | 43 + andromeda-core/ibc-tests/.eslintrc.json | 34 - andromeda-core/ibc-tests/.gitignore | 111 - andromeda-core/ibc-tests/.prettierignore | 3 - andromeda-core/ibc-tests/Cargo.toml | 32 + andromeda-core/ibc-tests/README.md | 12 + andromeda-core/ibc-tests/package-lock.json | 20748 ---------------- andromeda-core/ibc-tests/package.json | 70 - .../ibc-tests/src/interface_macro.rs | 26 + andromeda-core/ibc-tests/src/lib.rs | 1 + andromeda-core/ibc-tests/src/main.rs | 204 + andromeda-core/ibc-tests/test/configs.ts | 154 - andromeda-core/ibc-tests/test/contract.ts | 71 - andromeda-core/ibc-tests/test/ibc.spec.ts | 1143 - andromeda-core/ibc-tests/test/logger.ts | 43 - andromeda-core/ibc-tests/test/os.ts | 96 - andromeda-core/ibc-tests/test/relayer.ts | 26 - andromeda-core/ibc-tests/test/utils.ts | 390 - .../ibc-tests/tests/validator_staking.rs | 210 + andromeda-core/ibc-tests/tsconfig.json | 24 - .../packages/andromeda-app/Cargo.toml | 11 +- .../packages/andromeda-app/src/app.rs | 226 +- .../andromeda-data-storage/Cargo.toml | 9 +- .../andromeda-data-storage/src/boolean.rs | 43 + .../andromeda-data-storage/src/counter.rs | 74 + .../andromeda-data-storage/src/lib.rs | 3 + .../andromeda-data-storage/src/primitive.rs | 234 +- .../src/string_storage.rs | 138 + .../packages/andromeda-ecosystem/Cargo.toml | 8 +- .../packages/andromeda-ecosystem/src/vault.rs | 13 +- .../packages/andromeda-finance/Cargo.toml | 9 +- .../src/conditional_splitter.rs | 317 + .../andromeda-finance/src/cross_chain_swap.rs | 4 - .../packages/andromeda-finance/src/lib.rs | 2 + .../src/rate_limiting_withdrawals.rs | 17 +- .../src/set_amount_splitter.rs | 250 + .../andromeda-finance/src/splitter.rs | 112 +- .../andromeda-finance/src/timelock.rs | 76 +- .../src/validator_staking.rs | 12 +- .../packages/andromeda-finance/src/vesting.rs | 35 +- .../src/weighted_splitter.rs | 9 +- .../andromeda-fungible-tokens/Cargo.toml | 7 +- .../andromeda-fungible-tokens/src/airdrop.rs | 19 +- .../andromeda-fungible-tokens/src/cw20.rs | 37 +- .../src/cw20_exchange.rs | 15 +- .../src/cw20_staking.rs | 55 +- .../andromeda-fungible-tokens/src/lockdrop.rs | 46 +- .../packages/andromeda-modules/Cargo.toml | 8 +- .../packages/andromeda-modules/README.md | 42 + .../andromeda-modules/src/address_list.rs | 48 +- .../andromeda-modules/src/date_time.rs | 66 + .../packages/andromeda-modules/src/lib.rs | 1 + .../packages/andromeda-modules/src/rates.rs | 199 +- .../andromeda-non-fungible-tokens/Cargo.toml | 8 +- .../src/auction.rs | 75 +- .../src/crowdfund.rs | 317 +- .../src/cw721.rs | 45 +- .../src/marketplace.rs | 43 +- .../packages/andromeda-testing-e2e/Cargo.toml | 50 + .../andromeda-testing-e2e/src/adodb.rs | 39 + .../andromeda-testing-e2e/src/economics.rs | 25 + .../andromeda-testing-e2e/src/faucet.rs | 18 + .../src/interface_macro.rs | 26 + .../andromeda-testing-e2e/src/kernel.rs | 31 + .../packages/andromeda-testing-e2e/src/lib.rs | 20 + .../andromeda-testing-e2e/src/mock.rs | 92 + .../packages/andromeda-testing-e2e/src/vfs.rs | 19 + .../packages/andromeda-testing/Cargo.toml | 24 +- .../packages/andromeda-testing/README.md | 61 +- .../packages/andromeda-testing/src/adodb.rs | 10 +- .../andromeda-testing/src/economics.rs | 12 +- .../andromeda-testing/src/economics_msg.rs | 17 + .../packages/andromeda-testing/src/faucet.rs | 30 + .../andromeda-testing/src/ibc_registry.rs | 86 + .../packages/andromeda-testing/src/kernel.rs | 13 +- .../packages/andromeda-testing/src/lib.rs | 37 +- .../packages/andromeda-testing/src/mock.rs | 195 +- .../andromeda-testing/src/mock_builder.rs | 62 + .../andromeda-testing/src/mock_contract.rs | 49 +- .../packages/andromeda-testing/src/vfs.rs | 14 +- andromeda-core/packages/std/Cargo.toml | 19 +- andromeda-core/packages/std/README.md | 29 + andromeda-core/packages/std/macros/Cargo.toml | 12 +- andromeda-core/packages/std/macros/src/lib.rs | 118 +- .../packages/std/src/ado_base/app_contract.rs | 7 + .../packages/std/src/ado_base/hooks.rs | 44 - .../packages/std/src/ado_base/mod.rs | 101 +- .../packages/std/src/ado_base/modules.rs | 9 +- .../packages/std/src/ado_base/operators.rs | 11 - .../packages/std/src/ado_base/ownership.rs | 20 + .../std/src/ado_base/permissioning.rs | 95 +- .../packages/std/src/ado_base/rates.rs | 252 + .../packages/std/src/ado_base/version.rs | 6 + .../packages/std/src/ado_contract/app.rs | 7 + .../packages/std/src/ado_contract/execute.rs | 335 +- .../std/src/ado_contract/instantiate.rs | 65 - .../packages/std/src/ado_contract/mod.rs | 11 +- .../std/src/ado_contract/modules/execute.rs | 80 - .../std/src/ado_contract/modules/mod.rs | 100 +- .../std/src/ado_contract/modules/query.rs | 74 - .../std/src/ado_contract/ownership.rs | 250 +- .../std/src/ado_contract/permissioning.rs | 618 +- .../packages/std/src/ado_contract/query.rs | 59 +- .../packages/std/src/ado_contract/rates.rs | 244 + .../packages/std/src/ado_contract/state.rs | 27 +- .../packages/std/src/ado_contract/withdraw.rs | 24 +- andromeda-core/packages/std/src/amp/README.md | 77 + .../packages/std/src/amp/addresses.rs | 114 +- .../packages/std/src/amp/messages.rs | 38 +- .../packages/std/src/amp/recipient.rs | 61 +- .../packages/std/src/common/actions.rs | 30 + .../packages/std/src/common/denom.rs | 113 + .../packages/std/src/common/expiration.rs | 100 +- .../packages/std/src/common/migration.rs | 35 + .../packages/std/src/common/milliseconds.rs | 173 + andromeda-core/packages/std/src/common/mod.rs | 208 +- .../packages/std/src/common/queries.rs | 14 - .../packages/std/src/common/rates.rs | 23 +- .../packages/std/src/common/reply.rs | 20 + .../packages/std/src/common/withdraw.rs | 33 +- andromeda-core/packages/std/src/error.rs | 120 +- andromeda-core/packages/std/src/lib.rs | 2 +- andromeda-core/packages/std/src/os/adodb.rs | 117 +- .../packages/std/src/os/aos_querier.rs | 43 +- .../packages/std/src/os/economics.rs | 19 +- .../packages/std/src/os/ibc_registry.rs | 115 + andromeda-core/packages/std/src/os/kernel.rs | 35 +- andromeda-core/packages/std/src/os/mod.rs | 1 + andromeda-core/packages/std/src/os/vfs.rs | 668 +- .../packages/std/src/testing/mock_querier.rs | 175 +- andromeda-core/tests-integration/Cargo.toml | 46 +- andromeda-core/tests-integration/tests/app.rs | 84 + .../tests-integration/tests/auction_app.rs | 1220 +- .../tests/conditional_splitter.rs | 176 + .../tests-integration/tests/crowdfund_app.rs | 1024 +- .../tests-integration/tests/cw20_app.rs | 148 + .../tests-integration/tests/cw20_staking.rs | 434 + .../tests-integration/tests/ibc_registry.rs | 112 + .../tests-integration/tests/kernel.rs | 70 +- .../tests-integration/tests/lockdrop.rs | 156 + .../tests/marketplace_app.rs | 1016 +- andromeda-core/tests-integration/tests/mod.rs | 14 +- .../tests-integration/tests/primitive.rs | 192 + .../tests-integration/tests/primtive.rs | 96 - .../tests/set-amount-splitter.rs | 85 + .../tests-integration/tests/shunting.rs | 50 +- .../tests-integration/tests/splitter.rs | 63 +- .../tests/validator_staking.rs | 407 +- .../tests-integration/tests_old/cw721.rs | 1 - .../tests_old/wrapped_cw721_app.rs | 1 - 925 files changed, 35901 insertions(+), 125145 deletions(-) create mode 100644 andromeda-core/.github/workflows/changelog.yml create mode 100644 andromeda-core/CHANGELOG.md create mode 100755 andromeda-core/bump-version.sh create mode 100644 andromeda-core/ci-scripts/install_binaryen.sh delete mode 100644 andromeda-core/ci-scripts/localrelayer/Makefile delete mode 100644 andromeda-core/ci-scripts/localrelayer/README.md delete mode 100644 andromeda-core/ci-scripts/localrelayer/config/hermes/config.toml delete mode 100644 andromeda-core/ci-scripts/localrelayer/docker-compose.yml delete mode 100644 andromeda-core/ci-scripts/localrelayer/go.mod delete mode 100644 andromeda-core/ci-scripts/localrelayer/go.sum delete mode 100644 andromeda-core/ci-scripts/localrelayer/go.work delete mode 100755 andromeda-core/ci-scripts/localrelayer/scripts/setup_chain.sh delete mode 100755 andromeda-core/ci-scripts/localrelayer/scripts/setup_hermes.sh create mode 100644 andromeda-core/contracts/app/andromeda-app-contract/README.md delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/andromeda-app-contract.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/query.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_component_exists.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_config.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_address.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_addresses_with_names.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_components.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/.cargo/config create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/Cargo.toml create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/examples/schema.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/contract.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/execute.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/lib.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/mock.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/query.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/state.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mock.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mod.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/tests.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/.cargo/config create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/Cargo.toml create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/examples/schema.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/src/contract.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/src/lib.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/src/mock.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/src/state.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mock.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mod.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-counter/src/testing/tests.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/README.md delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/andromeda-primitive.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/query.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_all_keys.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_get_value.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner_keys.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/.cargo/config create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/Cargo.toml create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/examples/schema.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/contract.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/execute.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/lib.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/mock.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/query.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/state.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mock.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mod.rs create mode 100644 andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/tests.rs create mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/README.md delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/andromeda-vault.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/query.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_strategy_address.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_vault_balance.json delete mode 100644 andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/.cargo/config create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/.gitignore create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/Cargo.toml create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/README.md create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/examples/schema.rs create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/src/contract.rs create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/src/lib.rs create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/src/mock.rs create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/src/state.rs create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mock_querier.rs create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mod.rs create mode 100644 andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs create mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/README.md delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/andromeda-cross-chain-swap.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_get_splitter_config.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/README.md delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/andromeda-rate-limiting-withdrawals.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_get_splitter_config.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/.cargo/config create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/.gitignore create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/Cargo.toml create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/examples/schema.rs create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/contract.rs create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/lib.rs create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/mock.rs create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/state.rs create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mock_querier.rs create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mod.rs create mode 100644 andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/tests.rs create mode 100644 andromeda-core/contracts/finance/andromeda-splitter/README.md delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/andromeda-splitter.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_get_splitter_config.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/finance/andromeda-timelock/README.md delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/andromeda-timelock.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds_for_recipient.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_version.json delete mode 100644 andromeda-core/contracts/finance/andromeda-validator-staking/schema/andromeda-validator-staking.json delete mode 100644 andromeda-core/contracts/finance/andromeda-validator-staking/schema/raw/instantiate.json create mode 100644 andromeda-core/contracts/finance/andromeda-validator-staking/src/util.rs delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/andromeda-vesting.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batch.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batches.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_config.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/finance/andromeda-vesting/src/mock.rs delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/andromeda-weighted-distribution-splitter.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_splitter_config.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_user_weight.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/README.md delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/andromeda-cw20-exchange.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale_assets.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_token_address.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/README.md delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/andromeda-cw20-staking.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_config.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_staker.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_stakers.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_state.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_timestamp.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/README.md delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/andromeda-cw20.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_accounts.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_allowances.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_allowance.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_download_logo.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_marketing_info.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_minter.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_token_info.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/README.md delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/andromeda-lockdrop.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_config.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_state.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_user_info.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_version.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_withdrawal_percent_allowed.json create mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/mock.rs create mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/README.md delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/andromeda-merkle-airdrop.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_config.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_claimed.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_latest_stage.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_merkle_root.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_total_claimed.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/modules/andromeda-address-list/README.md delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/andromeda-address-list.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/query.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_includes_address.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_inclusive.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/.cargo/config create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/Cargo.toml create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/examples/schema.rs create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/src/contract.rs create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/src/lib.rs create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/src/mock.rs create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/src/testing/mock.rs create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/src/testing/mod.rs create mode 100644 andromeda-core/contracts/modules/andromeda-date-time/src/testing/tests.rs create mode 100644 andromeda-core/contracts/modules/andromeda-rates/README.md delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/andromeda-rates.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/query.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_payments.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/modules/andromeda-rates/src/testing/test_handler.rs delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/andromeda-shunting.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/query.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_eval_with_params.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_evaluate.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/README.md delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/andromeda-auction.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/cw721receive.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_ids.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_infos_for_address.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_state.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_bids.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_cancelled.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_claimed.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_closed.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_latest_auction_state.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/README.md delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/andromeda-crowdfund.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_available_tokens.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_config.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_token_available.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_state.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/README.md delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/andromeda-cw721.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_nft_info.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_operators.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_tokens.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approval.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approvals.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_contract_info.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_extension.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_get.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_archived.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_minter.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_nft_info.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_num_tokens.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner_of.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_tokens.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_transfer_agreement.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_version.json create mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/README.md delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/andromeda-marketplace.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/cw721receive.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_hook.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_block_height_upon_creation.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_is_operator.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_kernel_address.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_latest_sale_state.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module_ids.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_operators.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_original_publisher.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_owner.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissioned_actions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissions.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_ids.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_infos_for_address.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_state.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_type.json delete mode 100644 andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_version.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/andromeda-adodb.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/query.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_metadata.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_type.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee_by_code_id.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_all_a_d_o_types.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_code_id.json create mode 100644 andromeda-core/contracts/os/andromeda-adodb/src/execute.rs create mode 100644 andromeda-core/contracts/os/andromeda-adodb/src/query.rs delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/andromeda-economics.json delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/raw/query.json delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_a_d_o_type.json delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_balance.json delete mode 100644 andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_code_id.json create mode 100644 andromeda-core/contracts/os/andromeda-economics/src/execute.rs create mode 100644 andromeda-core/contracts/os/andromeda-economics/src/query.rs create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/.cargo/config create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/Cargo.toml create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/examples/schema.rs create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/src/contract.rs create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/src/lib.rs create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/src/mock.rs create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/src/state.rs create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/mod.rs create mode 100644 andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/tests.rs delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/andromeda-kernel.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/query.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_channel_info.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_key_address.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_recoveries.json delete mode 100644 andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_verify_address.json create mode 100644 andromeda-core/contracts/os/andromeda-kernel/src/testing/test_handler.rs delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/andromeda-vfs.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/execute.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/instantiate.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/query.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_andr_query.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_library.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_username.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_key_address.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_paths.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_path.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_symlink.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_sub_dir.json delete mode 100644 andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_verify_address.json create mode 100644 andromeda-core/git-conventional-commits.yaml delete mode 100644 andromeda-core/ibc-tests/.eslintrc.json delete mode 100644 andromeda-core/ibc-tests/.gitignore delete mode 100644 andromeda-core/ibc-tests/.prettierignore create mode 100644 andromeda-core/ibc-tests/Cargo.toml create mode 100644 andromeda-core/ibc-tests/README.md delete mode 100644 andromeda-core/ibc-tests/package-lock.json delete mode 100644 andromeda-core/ibc-tests/package.json create mode 100644 andromeda-core/ibc-tests/src/interface_macro.rs create mode 100644 andromeda-core/ibc-tests/src/lib.rs create mode 100644 andromeda-core/ibc-tests/src/main.rs delete mode 100644 andromeda-core/ibc-tests/test/configs.ts delete mode 100644 andromeda-core/ibc-tests/test/contract.ts delete mode 100644 andromeda-core/ibc-tests/test/ibc.spec.ts delete mode 100644 andromeda-core/ibc-tests/test/logger.ts delete mode 100644 andromeda-core/ibc-tests/test/os.ts delete mode 100644 andromeda-core/ibc-tests/test/relayer.ts delete mode 100644 andromeda-core/ibc-tests/test/utils.ts create mode 100644 andromeda-core/ibc-tests/tests/validator_staking.rs delete mode 100644 andromeda-core/ibc-tests/tsconfig.json create mode 100644 andromeda-core/packages/andromeda-data-storage/src/boolean.rs create mode 100644 andromeda-core/packages/andromeda-data-storage/src/counter.rs create mode 100644 andromeda-core/packages/andromeda-data-storage/src/string_storage.rs create mode 100644 andromeda-core/packages/andromeda-finance/src/conditional_splitter.rs create mode 100644 andromeda-core/packages/andromeda-finance/src/set_amount_splitter.rs create mode 100644 andromeda-core/packages/andromeda-modules/src/date_time.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/Cargo.toml create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/adodb.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/economics.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/faucet.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/interface_macro.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/kernel.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/lib.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/mock.rs create mode 100644 andromeda-core/packages/andromeda-testing-e2e/src/vfs.rs create mode 100644 andromeda-core/packages/andromeda-testing/src/economics_msg.rs create mode 100644 andromeda-core/packages/andromeda-testing/src/faucet.rs create mode 100644 andromeda-core/packages/andromeda-testing/src/ibc_registry.rs create mode 100644 andromeda-core/packages/andromeda-testing/src/mock_builder.rs create mode 100644 andromeda-core/packages/std/README.md create mode 100644 andromeda-core/packages/std/src/ado_base/app_contract.rs delete mode 100644 andromeda-core/packages/std/src/ado_base/hooks.rs delete mode 100644 andromeda-core/packages/std/src/ado_base/operators.rs create mode 100644 andromeda-core/packages/std/src/ado_base/rates.rs delete mode 100644 andromeda-core/packages/std/src/ado_contract/instantiate.rs delete mode 100644 andromeda-core/packages/std/src/ado_contract/modules/execute.rs delete mode 100644 andromeda-core/packages/std/src/ado_contract/modules/query.rs create mode 100644 andromeda-core/packages/std/src/ado_contract/rates.rs create mode 100644 andromeda-core/packages/std/src/amp/README.md create mode 100644 andromeda-core/packages/std/src/common/actions.rs create mode 100644 andromeda-core/packages/std/src/common/denom.rs create mode 100644 andromeda-core/packages/std/src/common/migration.rs create mode 100644 andromeda-core/packages/std/src/common/milliseconds.rs delete mode 100644 andromeda-core/packages/std/src/common/queries.rs create mode 100644 andromeda-core/packages/std/src/common/reply.rs create mode 100644 andromeda-core/packages/std/src/os/ibc_registry.rs create mode 100644 andromeda-core/tests-integration/tests/app.rs create mode 100644 andromeda-core/tests-integration/tests/conditional_splitter.rs create mode 100644 andromeda-core/tests-integration/tests/cw20_app.rs create mode 100644 andromeda-core/tests-integration/tests/cw20_staking.rs create mode 100644 andromeda-core/tests-integration/tests/ibc_registry.rs create mode 100644 andromeda-core/tests-integration/tests/lockdrop.rs create mode 100644 andromeda-core/tests-integration/tests/primitive.rs delete mode 100644 andromeda-core/tests-integration/tests/primtive.rs create mode 100644 andromeda-core/tests-integration/tests/set-amount-splitter.rs diff --git a/andromeda-core/.github/workflows/changelog.yml b/andromeda-core/.github/workflows/changelog.yml new file mode 100644 index 0000000..8cf638e --- /dev/null +++ b/andromeda-core/.github/workflows/changelog.yml @@ -0,0 +1,17 @@ +name: "Documentation" +on: + pull_request: + # The specific activity types are listed here to include "labeled" and "unlabeled" + # (which are not included by default for the "pull_request" trigger). + # This is needed to allow skipping enforcement of the changelog in PRs with specific labels, + # as defined in the (optional) "skipLabels" property. + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] + branches: + - development + - main +jobs: + changelog: + if: "!contains(github.event.pull_request.labels.*.name, 'ci: skip-changelog')" + runs-on: ubuntu-latest + steps: + - uses: dangoslen/changelog-enforcer@v3 diff --git a/andromeda-core/CHANGELOG.md b/andromeda-core/CHANGELOG.md new file mode 100644 index 0000000..6cc334e --- /dev/null +++ b/andromeda-core/CHANGELOG.md @@ -0,0 +1,59 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +### Added + +- Added Validator Staking ADO [(#330)](https://github.com/andromedaprotocol/andromeda-core/pull/330) +- Added `Asset` enum [(#415)](https://github.com/andromedaprotocol/andromeda-core/pull/415) +- Added `ADOBaseVersion` query to all ADOs [(#416)](https://github.com/andromedaprotocol/andromeda-core/pull/416) +- Staking: Added ability to remove/replace reward token [(#418)](https://github.com/andromedaprotocol/andromeda-core/pull/418) +- Added Expiry Enum [(#419)](https://github.com/andromedaprotocol/andromeda-core/pull/419) +- Added Conditional Splitter [(#441)](https://github.com/andromedaprotocol/andromeda-core/pull/441) +- Validator Staking: Added the option to set an amount while unstaking [(#458)](https://github.com/andromedaprotocol/andromeda-core/pull/458) +- Set Amount Splitter [(#507)](https://github.com/andromedaprotocol/andromeda-core/pull/507) +- Added String Storage ADO [(#512)](https://github.com/andromedaprotocol/andromeda-core/pull/512) +- Boolean Storage ADO [(#513)](https://github.com/andromedaprotocol/andromeda-core/pull/513) +- Added Counter ADO [(#514)](https://github.com/andromedaprotocol/andromeda-core/pull/514) +- Added Date Time ADO [(#519)](https://github.com/andromedaprotocol/andromeda-core/pull/519) +- Added Authorized CW721 Addresses to Marketplace [(#542)](https://github.com/andromedaprotocol/andromeda-core/pull/542) +- Added IBC Registry ADO [(#566)](https://github.com/andromedaprotocol/andromeda-core/pull/566) + +### Changed + +- Merkle Root: stage expiration now uses `Milliseconds`[(#417)](https://github.com/andromedaprotocol/andromeda-core/pull/417) +- Module Redesign [(#452)](https://github.com/andromedaprotocol/andromeda-core/pull/452) +- Primitive Improvements [(#476)](https://github.com/andromedaprotocol/andromeda-core/pull/476) +- Crowdfund Restructure [(#478)](https://github.com/andromedaprotocol/andromeda-core/pull/478) +- Conditional Splitter Internal Audit [(#479)](https://github.com/andromedaprotocol/andromeda-core/pull/479) +- Merkle Root: Andromeda Asset is used now as a `asset_info`[(#480)](https://github.com/andromedaprotocol/andromeda-core/pull/480) +- Reference Address List contract for Permission [(#481)](https://github.com/andromedaprotocol/andromeda-core/pull/481) +- Crowdfund Internal Audit [(#485)](https://github.com/andromedaprotocol/andromeda-core/pull/485) +- Auction: Minimum Raise [(#486)](https://github.com/andromedaprotocol/andromeda-core/pull/486) +- Version Bump [(#488)](https://github.com/andromedaprotocol/andromeda-core/pull/488) +- Made Some CampaignConfig Fields Optional [(#541)](https://github.com/andromedaprotocol/andromeda-core/pull/541) +- Permissioning: Allow multiple actors to be set and removed at once [(#548)](https://github.com/andromedaprotocol/andromeda-core/pull/548) +- Make Action Names in CW721 Conform to Standard [(#545)](https://github.com/andromedaprotocol/andromeda-core/pull/545) +- Timelock ADO: Replace MillisecondsExpiration with Expiry [(#550)](https://github.com/andromedaprotocol/andromeda-core/pull/550) +- Removed staking from vesting contract [(#554)](https://github.com/andromedaprotocol/andromeda-core/pull/554) +- Address List: Support for multiple actors while adding and removing permissions [(#556)](https://github.com/andromedaprotocol/andromeda-core/pull/556) +- ADODB now supports pre-release tagging [(#560)](https://github.com/andromedaprotocol/andromeda-core/pull/560) +- Updated Validator Staking: Updated according to shrelock audit [(#565)](https://github.com/andromedaprotocol/andromeda-core/pull/565) + +### Fixed + +- Splitter: avoid zero send messages, owner updates lock any time [(#457)](https://github.com/andromedaprotocol/andromeda-core/pull/457) +- Splitter and Conditional Splitter: fix lock time calculation [(#547)](https://github.com/andromedaprotocol/andromeda-core/pull/547) +- AMPPkt verify origin fix [(#552)](https://github.com/andromedaprotocol/andromeda-core/pull/552) +- Fix permissioning limited use consumptions and blacklist bypass scenario [(#553)](https://github.com/andromedaprotocol/andromeda-core/pull/553) +- Fix precision issue with vestings claim batch method [(#555)](https://github.com/andromedaprotocol/andromeda-core/pull/555) +- Fix shunting ado to work with rust version 1.75.0 [(#565)](https://github.com/andromedaprotocol/andromeda-core/pull/565) + +### Removed + +- Schemas are no longer tracked [(#430)](https://github.com/andromedaprotocol/andromeda-core/pull/430) diff --git a/andromeda-core/Cargo.lock b/andromeda-core/Cargo.lock index d893667..241e2c6 100644 --- a/andromeda-core/Cargo.lock +++ b/andromeda-core/Cargo.lock @@ -2,20 +2,45 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "abstract-cw-multi-test" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c77f8d4bac08f74fbc4fce8943cb2d35e742682b6cae8cb65555d6cd3830feb" +dependencies = [ + "anyhow", + "bech32 0.11.0", + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20-ics20", + "derivative", + "hex", + "itertools 0.12.1", + "log", + "prost 0.12.6", + "schemars", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", +] + [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -28,9 +53,33 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "andromeda-address-list" -version = "0.2.1" +version = "2.0.3" dependencies = [ "andromeda-app", "andromeda-modules", @@ -41,13 +90,11 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", - "semver", ] [[package]] name = "andromeda-adodb" -version = "0.2.1" +version = "1.1.2" dependencies = [ "andromeda-std", "cosmwasm-schema", @@ -55,23 +102,23 @@ dependencies = [ "cw-asset", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.2", "semver", ] [[package]] name = "andromeda-app" -version = "0.1.0" +version = "1.0.0" dependencies = [ "andromeda-std", "cosmwasm-schema", "cosmwasm-std", + "cw-multi-test", "serde", ] [[package]] name = "andromeda-app-contract" -version = "0.2.1" +version = "1.1.2" dependencies = [ "andromeda-app", "andromeda-std", @@ -80,15 +127,12 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.2", "enum-repr", - "prost 0.9.0", - "semver", ] [[package]] name = "andromeda-auction" -version = "0.2.1" +version = "2.0.3" dependencies = [ "andromeda-app", "andromeda-non-fungible-tokens", @@ -99,15 +143,58 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", "cw721 0.18.0", - "semver", +] + +[[package]] +name = "andromeda-boolean" +version = "2.0.2" +dependencies = [ + "andromeda-data-storage", + "andromeda-std", + "andromeda-testing", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20", +] + +[[package]] +name = "andromeda-conditional-splitter" +version = "1.2.2" +dependencies = [ + "andromeda-app", + "andromeda-finance", + "andromeda-std", + "andromeda-testing", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", +] + +[[package]] +name = "andromeda-counter" +version = "1.0.2" +dependencies = [ + "andromeda-data-storage", + "andromeda-std", + "andromeda-testing", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20", ] [[package]] name = "andromeda-cross-chain-swap" -version = "0.2.0" +version = "1.1.2" dependencies = [ "andromeda-app", "andromeda-finance", @@ -117,7 +204,6 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "schemars", "semver", "serde", @@ -125,7 +211,7 @@ dependencies = [ [[package]] name = "andromeda-crowdfund" -version = "0.2.1" +version = "2.0.3" dependencies = [ "andromeda-app", "andromeda-non-fungible-tokens", @@ -136,32 +222,30 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", + "cw20", "cw721 0.18.0", - "semver", ] [[package]] name = "andromeda-cw20" -version = "0.2.1" +version = "2.0.4" dependencies = [ "andromeda-app", "andromeda-fungible-tokens", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", "cw20-base", - "semver", ] [[package]] name = "andromeda-cw20-exchange" -version = "0.2.2" +version = "2.0.2" dependencies = [ "andromeda-app", "andromeda-fungible-tokens", @@ -172,33 +256,30 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", - "semver", ] [[package]] name = "andromeda-cw20-staking" -version = "0.2.1" +version = "2.0.2" dependencies = [ "andromeda-app", "andromeda-fungible-tokens", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-asset", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", "cw20-base", - "semver", ] [[package]] name = "andromeda-cw721" -version = "0.2.1" +version = "2.0.4" dependencies = [ "andromeda-non-fungible-tokens", "andromeda-std", @@ -207,15 +288,13 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.2", "cw721 0.18.0", "cw721-base 0.18.0", - "semver", ] [[package]] name = "andromeda-data-storage" -version = "0.2.0" +version = "1.0.0" dependencies = [ "andromeda-std", "cosmwasm-schema", @@ -224,23 +303,37 @@ dependencies = [ "serde", ] +[[package]] +name = "andromeda-date-time" +version = "1.0.1" +dependencies = [ + "andromeda-app", + "andromeda-modules", + "andromeda-std", + "andromeda-testing", + "chrono 0.4.38", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", +] + [[package]] name = "andromeda-economics" -version = "0.2.0" +version = "1.1.1" dependencies = [ "andromeda-std", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.2", "cw20", - "semver", ] [[package]] name = "andromeda-ecosystem" -version = "0.1.0" +version = "1.0.0" dependencies = [ "andromeda-std", "cosmwasm-schema", @@ -254,7 +347,7 @@ dependencies = [ [[package]] name = "andromeda-finance" -version = "0.1.0" +version = "1.0.0" dependencies = [ "andromeda-std", "cosmwasm-schema", @@ -268,7 +361,7 @@ dependencies = [ [[package]] name = "andromeda-fungible-tokens" -version = "0.1.0" +version = "1.0.0" dependencies = [ "andromeda-std", "cosmwasm-schema", @@ -280,24 +373,35 @@ dependencies = [ "serde", ] +[[package]] +name = "andromeda-ibc-registry" +version = "1.0.0" +dependencies = [ + "andromeda-data-storage", + "andromeda-std", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20", +] + [[package]] name = "andromeda-kernel" -version = "0.2.15" +version = "1.1.1" dependencies = [ "andromeda-std", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "enum-repr", "hex", "itertools 0.10.5", "osmosis-std", "osmosis-std-derive 0.15.3", "prost 0.11.9", "schemars", - "semver", "serde", "serde-cw-value", "serde-json-wasm 1.0.1", @@ -306,25 +410,24 @@ dependencies = [ [[package]] name = "andromeda-lockdrop" -version = "0.2.1" +version = "2.0.2" dependencies = [ "andromeda-app", "andromeda-fungible-tokens", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-asset", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", - "semver", ] [[package]] name = "andromeda-macros" -version = "0.1.0" +version = "1.0.0" dependencies = [ "proc-macro2", "quote", @@ -333,7 +436,7 @@ dependencies = [ [[package]] name = "andromeda-marketplace" -version = "0.2.1" +version = "2.1.3" dependencies = [ "andromeda-app", "andromeda-non-fungible-tokens", @@ -344,35 +447,33 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", + "cw20", "cw721 0.18.0", - "semver", ] [[package]] name = "andromeda-merkle-airdrop" -version = "0.2.1" +version = "2.0.2" dependencies = [ "andromeda-app", "andromeda-fungible-tokens", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-asset", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", "hex", - "semver", "serde", "sha2 0.10.8", ] [[package]] name = "andromeda-modules" -version = "0.1.0" +version = "2.0.0" dependencies = [ "andromeda-std", "cosmwasm-schema", @@ -385,12 +486,13 @@ dependencies = [ [[package]] name = "andromeda-non-fungible-tokens" -version = "0.1.0" +version = "1.0.0" dependencies = [ "andromeda-std", "cosmwasm-schema", "cosmwasm-std", "cw-utils 1.0.3", + "cw20", "cw721 0.18.0", "cw721-base 0.18.0", "serde", @@ -398,57 +500,69 @@ dependencies = [ [[package]] name = "andromeda-primitive" -version = "0.2.0" +version = "2.0.3" dependencies = [ "andromeda-data-storage", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", - "semver", ] [[package]] name = "andromeda-rate-limiting-withdrawals" -version = "0.2.1" +version = "2.0.3" dependencies = [ "andromeda-app", "andromeda-finance", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", - "semver", ] [[package]] name = "andromeda-rates" -version = "0.2.1" +version = "2.0.3" dependencies = [ "andromeda-app", "andromeda-modules", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", "cw20", - "semver", +] + +[[package]] +name = "andromeda-set-amount-splitter" +version = "1.0.2" +dependencies = [ + "andromeda-app", + "andromeda-finance", + "andromeda-std", + "andromeda-testing", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", ] [[package]] name = "andromeda-shunting" -version = "0.1.0" +version = "0.2.3" dependencies = [ "andromeda-app", "andromeda-modules", @@ -467,7 +581,7 @@ dependencies = [ [[package]] name = "andromeda-splitter" -version = "0.2.3" +version = "2.1.2" dependencies = [ "andromeda-app", "andromeda-finance", @@ -478,24 +592,25 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", - "semver", ] [[package]] name = "andromeda-std" -version = "0.1.0" +version = "1.2.3" dependencies = [ "andromeda-macros", "cosmwasm-schema", "cosmwasm-std", "cw-asset", + "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", + "cw2 1.1.2", "cw20", "cw20-base", "cw721 0.18.0", "cw721-base 0.18.0", + "enum-repr", "hex", "lazy_static", "regex", @@ -507,9 +622,46 @@ dependencies = [ "thiserror", ] +[[package]] +name = "andromeda-string-storage" +version = "1.0.2" +dependencies = [ + "andromeda-data-storage", + "andromeda-std", + "andromeda-testing", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw20", +] + [[package]] name = "andromeda-testing" -version = "0.1.0" +version = "1.0.0" +dependencies = [ + "andromeda-adodb", + "andromeda-app", + "andromeda-economics", + "andromeda-ibc-registry", + "andromeda-kernel", + "andromeda-modules", + "andromeda-non-fungible-tokens", + "andromeda-std", + "andromeda-vfs", + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw20", + "cw721 0.18.0", + "serde", +] + +[[package]] +name = "andromeda-testing-e2e" +version = "1.0.0" dependencies = [ "andromeda-adodb", "andromeda-app", @@ -520,39 +672,43 @@ dependencies = [ "andromeda-std", "andromeda-vfs", "anyhow", + "cosmrs 0.18.0", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", + "cw-orch", + "cw-orch-daemon", "cw20", "cw721 0.18.0", - "prost 0.9.0", + "reqwest 0.12.7", + "secp256k1 0.29.1", "serde", + "tokio", ] [[package]] name = "andromeda-timelock" -version = "0.2.1" +version = "2.0.3" dependencies = [ "andromeda-app", "andromeda-finance", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", - "semver", ] [[package]] name = "andromeda-validator-staking" -version = "0.1.0" +version = "0.2.3" dependencies = [ "andromeda-finance", "andromeda-std", "andromeda-testing", - "chrono", + "chrono 0.3.0", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", @@ -564,7 +720,7 @@ dependencies = [ [[package]] name = "andromeda-vault" -version = "0.2.0" +version = "1.1.0" dependencies = [ "andromeda-ecosystem", "andromeda-std", @@ -573,44 +729,39 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", - "semver", ] [[package]] name = "andromeda-vesting" -version = "0.2.1" +version = "3.0.2" dependencies = [ "andromeda-app", "andromeda-finance", "andromeda-std", + "andromeda-testing", "cosmwasm-schema", "cosmwasm-std", "cw-asset", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", - "semver", ] [[package]] name = "andromeda-vfs" -version = "0.2.2" +version = "1.1.1" dependencies = [ "andromeda-std", "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", "cw-storage-plus 1.2.0", - "cw2 1.1.2", - "semver", "serde", ] [[package]] name = "andromeda-weighted-distribution-splitter" -version = "0.2.1" +version = "2.0.2" dependencies = [ "andromeda-app", "andromeda-finance", @@ -620,48 +771,136 @@ dependencies = [ "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "cw2 1.1.2", - "semver", ] [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.77", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 0.1.2", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] +[[package]] +name = "base16" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" + [[package]] name = "base16ct" version = "0.2.0" @@ -674,6 +913,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -686,6 +931,68 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + +[[package]] +name = "bip32" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa13fae8b6255872fd86f7faf4b41168661d7d78609f7bfe6771b85c6739a15b" +dependencies = [ + "bs58", + "hmac", + "k256", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "bitcoin" +version = "0.30.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462" +dependencies = [ + "bech32 0.9.1", + "bitcoin-private", + "bitcoin_hashes", + "hex_lit", + "secp256k1 0.27.0", +] + +[[package]] +name = "bitcoin-private" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" + +[[package]] +name = "bitcoin_hashes" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" +dependencies = [ + "bitcoin-private", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "block-buffer" version = "0.9.0" @@ -710,6 +1017,21 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56953345e39537a3e18bdaeba4cb0c58a78c1f61f361dc0fa7c5c7340ae87c5f" +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "sha2 0.10.8", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.5.0" @@ -718,15 +1040,21 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +dependencies = [ + "serde", +] [[package]] name = "cc" -version = "1.0.90" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -741,7 +1069,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "158b0bd7d75cbb6bf9c25967a48a2e9f77da95876b858eadfabaa99cd069de6e" dependencies = [ "num", - "time", + "time 0.1.45", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", ] [[package]] @@ -750,14 +1092,144 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cosmos-sdk-proto" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" +dependencies = [ + "prost 0.12.6", + "prost-types 0.12.6", + "tendermint-proto 0.34.1", + "tonic", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e23f6ab56d5f031cde05b8b82a5fefd3a1a223595c79e32317a97189e612bc" +dependencies = [ + "prost 0.12.6", + "prost-types 0.12.6", + "tendermint-proto 0.35.0", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2f63ab112b8c8e7b8a29c891adc48f43145beb21c0bfbf562957072c1e0beb" +dependencies = [ + "prost 0.13.2", + "prost-types 0.13.2", + "tendermint-proto 0.38.1", +] + +[[package]] +name = "cosmos-sdk-proto" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d0afc4daf81936e6ef5a2cf76f00c913ba5bc385d58ae1e09644e25d16b0381" +dependencies = [ + "prost 0.13.2", + "tendermint-proto 0.39.1", +] + +[[package]] +name = "cosmrs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.20.0", + "ecdsa", + "eyre", + "k256", + "rand_core 0.6.4", + "serde", + "serde_json", + "signature", + "subtle-encoding", + "tendermint 0.34.1", + "tendermint-rpc", + "thiserror", + "tokio", +] + +[[package]] +name = "cosmrs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f21bb63ec6a903510a3d01f44735dd4914724e5eccbe409e6da6833d17c7829" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.23.0", + "ecdsa", + "eyre", + "k256", + "rand_core 0.6.4", + "serde", + "serde_json", + "signature", + "subtle-encoding", + "tendermint 0.38.1", + "thiserror", +] + +[[package]] +name = "cosmrs" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af28a0ee4149da7cea0486fd7e3fbddea7dd81625279fdc521141ffb07fbd482" +dependencies = [ + "bip32", + "cosmos-sdk-proto 0.24.0", + "ecdsa", + "eyre", + "k256", + "rand_core 0.6.4", + "serde", + "serde_json", + "signature", + "subtle-encoding", + "tendermint 0.39.1", + "thiserror", +] + [[package]] name = "cosmwasm-crypto" -version = "1.5.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" +checksum = "0f862b355f7e47711e0acfe6af92cb3fd8fd5936b66a9eaa338b51edabd1e77d" dependencies = [ "digest 0.10.7", - "ecdsa", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -766,18 +1238,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.5.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" +checksum = "cd85de6467cd1073688c86b39833679ae6db18cf4771471edd9809f15f1679f1" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.5.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" +checksum = "5b4cd28147a66eba73720b47636a58097a979ad8c8bfdb4ed437ebcbfe362576" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -788,9 +1260,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.5.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5d803bea6bd9ed61bd1ee0b4a2eb09ee20dbb539cc6e0b8795614d20952ebb1" +checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" dependencies = [ "proc-macro2", "quote", @@ -799,12 +1271,12 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.5.3" +version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" +checksum = "2685c2182624b2e9e17f7596192de49a3f86b7a0c9a5f6b25c1df5e24592e836" dependencies = [ - "base64", - "bech32", + "base64 0.21.7", + "bech32 0.9.1", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -821,13 +1293,22 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-bigint" version = "0.5.5" @@ -863,6 +1344,46 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + [[package]] name = "cw-address-like" version = "1.0.4" @@ -874,9 +1395,9 @@ dependencies = [ [[package]] name = "cw-asset" -version = "3.1.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c999a12f8cd8736f6f86e9a4ede5905530cb23cfdef946b9da1c506ad1b70799" +checksum = "64e2cf17accdcafe71859a683b6ed3f18311634a769550aacf4829b50151b221" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -886,6 +1407,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw-controllers" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57de8d3761e46be863e3ac1eba8c8a976362a48c6abf240df1e26c3e421ee9e8" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "schemars", + "serde", + "thiserror", +] + [[package]] name = "cw-json" version = "0.1.0" @@ -900,18 +1436,18 @@ dependencies = [ [[package]] name = "cw-multi-test" -version = "0.20.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fff029689ae89127cf6d7655809a68d712f3edbdb9686c70b018ba438b26ca" +checksum = "91fc33b1d65c102d72f46548c64dca423c337e528d6747d0c595316aa65f887b" dependencies = [ "anyhow", - "bech32", + "bech32 0.11.0", "cosmwasm-std", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "derivative", - "itertools 0.12.1", - "prost 0.12.3", + "itertools 0.13.0", + "prost 0.12.6", "schemars", "serde", "sha2 0.10.8", @@ -919,18 +1455,161 @@ dependencies = [ ] [[package]] -name = "cw-ownable" -version = "0.5.1" +name = "cw-orch" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" +checksum = "0c81cb500eb2f9be31a0f90c7ce66572ee4a790ffbae1c6b42ff2e3f9faf3479" dependencies = [ - "cosmwasm-schema", + "anyhow", "cosmwasm-std", - "cw-address-like", - "cw-ownable-derive", - "cw-storage-plus 1.2.0", + "cw-orch-contract-derive", + "cw-orch-core", + "cw-orch-fns-derive", + "cw-orch-mock", + "cw-orch-traits", "cw-utils 1.0.3", - "thiserror", + "hex", + "log", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-orch-contract-derive" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc8ba75692fc7bd30e91c78fad2dc208a738e4e6ea26b232f9352c320e35543" +dependencies = [ + "convert_case", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "cw-orch-core" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9466093ad8bf067f9eebbe25835ada3ea155726ca557d9d1c7681538078ef24f" +dependencies = [ + "abstract-cw-multi-test", + "anyhow", + "cosmos-sdk-proto 0.21.1", + "cosmwasm-std", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "dirs", + "log", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "cw-orch-daemon" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "474651c5495b8644139a6978632ebe2e56f0e0fa3097b5e8b1bd7bd8128f8774" +dependencies = [ + "anyhow", + "async-recursion", + "base16", + "base64 0.22.1", + "bitcoin", + "chrono 0.4.38", + "cosmrs 0.15.0", + "cosmwasm-std", + "cw-orch-core", + "cw-orch-networks", + "cw-orch-traits", + "dirs", + "ed25519-dalek", + "eyre", + "file-lock", + "flate2", + "hex", + "hkd32", + "lazy_static", + "log", + "once_cell", + "prost 0.12.6", + "prost-types 0.12.6", + "rand_core 0.6.4", + "reqwest 0.11.27", + "ring", + "ripemd", + "schemars", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "tokio", + "tonic", + "uid", +] + +[[package]] +name = "cw-orch-fns-derive" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e21b23116a0702f540d7fa3f16e8276682d860b589fed56259220ad59d768e" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cw-orch-mock" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57beb30d841bde79df51c9402741ef926ca8ef7ecd3570aa180074f767ac04d3" +dependencies = [ + "abstract-cw-multi-test", + "cosmwasm-std", + "cw-orch-core", + "cw-utils 1.0.3", + "log", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "cw-orch-networks" +version = "0.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b0e1af56869ced61c25f509a0a40cddd028779d838441b70f4578a8d7c0253" +dependencies = [ + "cw-orch-core", + "serde", +] + +[[package]] +name = "cw-orch-traits" +version = "0.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e6b81dc282724c9c6334a499f4867e575458e69fe5b99034d4f962860f3357" +dependencies = [ + "cw-orch-core", + "prost 0.12.6", + "prost-types 0.12.6", +] + +[[package]] +name = "cw-ownable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093dfb4520c48b5848274dd88ea99e280a04bc08729603341c7fb0d758c74321" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-address-like", + "cw-ownable-derive", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "thiserror", ] [[package]] @@ -1054,6 +1733,25 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cw20-ics20" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76221201da08fed611c857ea3aa21c031a4a7dc771a8b1750559ca987335dc02" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "cw2 1.1.2", + "cw20", + "schemars", + "semver", + "serde", + "thiserror", +] + [[package]] name = "cw721" version = "0.16.0" @@ -1118,14 +1816,23 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1158,6 +1865,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dyn-clone" version = "1.0.17" @@ -1178,14 +1906,52 @@ dependencies = [ "spki", ] +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "serde", + "signature", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519", + "serde", + "sha2 0.10.8", + "subtle", + "zeroize", +] + [[package]] name = "ed25519-zebra" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ - "curve25519-dalek", - "hashbrown", + "curve25519-dalek 3.2.0", + "hashbrown 0.12.3", "hex", "rand_core 0.6.4", "serde", @@ -1195,9 +1961,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "elliptic-curve" @@ -1218,6 +1984,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + [[package]] name = "enum-repr" version = "0.2.6" @@ -1230,812 +2005,3119 @@ dependencies = [ ] [[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "generic-array" -version = "0.14.7" +name = "errno" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "typenum", - "version_check", - "zeroize", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "getrandom" -version = "0.2.12" +name = "eyre" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "indenter", + "once_cell", ] [[package]] -name = "gimli" -version = "0.28.1" +name = "fastrand" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] -name = "group" +name = "ff" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "ff", "rand_core 0.6.4", "subtle", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "fiat-crypto" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "file-lock" +version = "2.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "040b48f80a749da50292d0f47a1e2d5bf1d772f52836c07f64bfccc62ba6e664" dependencies = [ - "ahash", + "cc", + "libc", ] [[package]] -name = "heck" -version = "0.4.1" +name = "flate2" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +dependencies = [ + "crc32fast", + "miniz_oxide", +] [[package]] -name = "hex" -version = "0.4.3" +name = "flex-error" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "eyre", + "paste", +] [[package]] -name = "hmac" -version = "0.12.1" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "digest 0.10.7", + "foreign-types-shared", ] [[package]] -name = "itertools" -version = "0.10.5" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "either", + "percent-encoding", ] [[package]] -name = "itertools" -version = "0.11.0" +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "futures" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ - "either", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "itertools" -version = "0.12.1" +name = "futures-channel" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ - "either", + "futures-core", + "futures-sink", ] [[package]] -name = "itoa" -version = "1.0.10" +name = "futures-core" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] -name = "k256" -version = "0.13.1" +name = "futures-executor" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2 0.10.8", - "signature", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "futures-io" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] -name = "lexers" -version = "0.1.4" +name = "futures-macro" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82de9bb5d9e8ff5e13532a45583ea972e220b8a6efef755daad1f285333a8afa" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] [[package]] -name = "libc" -version = "0.2.153" +name = "futures-sink" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] -name = "libm" -version = "0.2.8" +name = "futures-task" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] -name = "memchr" -version = "2.7.1" +name = "futures-timer" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] -name = "miniz_oxide" -version = "0.7.2" +name = "futures-util" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ - "adler", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.5.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.5.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex_lit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" + +[[package]] +name = "hkd32" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e013a4f0b8772418eee1fc462e74017aba13c364a7b61bd3df1ddcbfe47b065" +dependencies = [ + "hmac", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "sha2 0.10.8", + "subtle-encoding", + "zeroize", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.30", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", + "rustls 0.23.13", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper 0.14.30", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.30", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.4.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ibc-tests" +version = "0.1.0" +dependencies = [ + "andromeda-app", + "andromeda-app-contract", + "andromeda-finance", + "andromeda-std", + "andromeda-testing-e2e", + "andromeda-validator-staking", + "cosmrs 0.19.0", + "cosmwasm-std", + "cw-orch", + "cw-orch-daemon", + "prost-types 0.13.2", + "serde", + "tokio", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "ipnet" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", + "signature", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lexers" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82de9bb5d9e8ff5e13532a45583ea972e220b8a6efef755daad1f285333a8afa" + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] name = "num" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +dependencies = [ + "num-integer", + "num-iter", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "osmosis-std" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50fb348fd7aefc37038ba8125e18b360af5bd44c6e007d2b10346777995857e3" +dependencies = [ + "cosmwasm-std", + "osmosis-std-derive 0.1.7", + "prost 0.11.9", + "prost-types 0.11.9", + "schemars", + "serde", +] + +[[package]] +name = "osmosis-std-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743ed6a9bb8d2c210a8c184a874244dbf56ebb2f6062c3848300b7ea9817ca50" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "osmosis-std-derive" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4d482a16be198ee04e0f94e10dd9b8d02332dcf33bc5ea4b255e7e25eedc5df" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "peg" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes", + "prost-derive 0.12.6", +] + +[[package]] +name = "prost" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" +dependencies = [ + "bytes", + "prost-derive 0.13.2", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +dependencies = [ + "anyhow", + "itertools 0.12.1", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "prost-derive" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" +dependencies = [ + "anyhow", + "itertools 0.13.0", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost 0.11.9", +] + +[[package]] +name = "prost-types" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +dependencies = [ + "prost 0.12.6", +] + +[[package]] +name = "prost-types" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" +dependencies = [ + "prost 0.13.2", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-rustls 0.24.2", + "hyper-tls 0.5.0", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-native-certs", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "reqwest" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-rustls 0.27.3", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.1.3", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "system-configuration 0.6.1", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rstest" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5316d2a1479eeef1ea21e7f9ddc67c191d497abc8fc3ba2467857abbb68330" +dependencies = [ + "futures", + "futures-timer", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04a9df72cc1f67020b0d63ad9bfe4a323e459ea7eb68e03bd9824db49f9a4c25" +dependencies = [ + "cfg-if", + "glob", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.77", + "unicode-ident", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.23.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.77", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "bitcoin_hashes", + "secp256k1-sys 0.8.1", +] + +[[package]] +name = "secp256k1" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" +dependencies = [ + "secp256k1-sys 0.10.1", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.209" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-cw-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.209" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "serde_json" +version = "1.0.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha256" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a975c1bc0941703000eaf232c4d8ce188d8d5408d6344b6b2c8c6262772828" +dependencies = [ + "hex", + "sha2 0.10.8", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simple-shunting" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb80ab4e2a505c887de71a93d97f71b38ff9f56c75dab1db4f175b235fca3e9a" +dependencies = [ + "lexers", + "libm", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "tendermint" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15ab8f0a25d0d2ad49ac615da054d6a76aa6603ff95f7d18bafdd34450a1a04b" +dependencies = [ + "bytes", + "digest 0.10.7", + "ed25519", + "ed25519-consensus", + "flex-error", + "futures", + "k256", + "num-traits", + "once_cell", + "prost 0.12.6", + "prost-types 0.12.6", + "ripemd", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "signature", + "subtle", + "subtle-encoding", + "tendermint-proto 0.34.1", + "time 0.3.36", + "zeroize", +] + +[[package]] +name = "tendermint" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d9d6ffeb83b1de47c307c6e0d2dff56c6256989299010ad03cd80a8491e97" +dependencies = [ + "bytes", + "digest 0.10.7", + "ed25519", + "ed25519-consensus", + "flex-error", + "futures", + "k256", + "num-traits", + "once_cell", + "prost 0.13.2", + "prost-types 0.13.2", + "ripemd", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "signature", + "subtle", + "subtle-encoding", + "tendermint-proto 0.38.1", + "time 0.3.36", + "zeroize", +] + +[[package]] +name = "tendermint" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3afea7809ffaaf1e5d9c3c9997cb3a834df7e94fbfab2fad2bc4577f1cde41" +dependencies = [ + "bytes", + "digest 0.10.7", + "ed25519", + "ed25519-consensus", + "flex-error", + "futures", + "k256", + "num-traits", + "once_cell", + "prost 0.13.2", + "ripemd", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "signature", + "subtle", + "subtle-encoding", + "tendermint-proto 0.39.1", + "time 0.3.36", + "zeroize", +] + +[[package]] +name = "tendermint-config" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1a02da769166e2052cd537b1a97c78017632c2d9e19266367b27e73910434fc" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint 0.34.1", + "toml 0.5.11", + "url", +] + +[[package]] +name = "tendermint-proto" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b797dd3d2beaaee91d2f065e7bdf239dc8d80bba4a183a288bc1279dd5a69a1e" +dependencies = [ + "bytes", + "flex-error", + "num-derive 0.3.3", + "num-traits", + "prost 0.12.6", + "prost-types 0.12.6", + "serde", + "serde_bytes", + "subtle-encoding", + "time 0.3.36", +] + +[[package]] +name = "tendermint-proto" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff525d5540a9fc535c38dc0d92a98da3ee36fcdfbda99cecb9f3cce5cd4d41d7" +dependencies = [ + "bytes", + "flex-error", + "num-derive 0.4.2", + "num-traits", + "prost 0.12.6", + "prost-types 0.12.6", + "serde", + "serde_bytes", + "subtle-encoding", + "time 0.3.36", +] + +[[package]] +name = "tendermint-proto" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed14abe3b0502a3afe21ca74ca5cdd6c7e8d326d982c26f98a394445eb31d6e" +dependencies = [ + "bytes", + "flex-error", + "prost 0.13.2", + "prost-types 0.13.2", + "serde", + "serde_bytes", + "subtle-encoding", + "time 0.3.36", +] + +[[package]] +name = "tendermint-proto" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3abf34ecf33125621519e9952688e7a59a98232d51538037ba21fbe526a802" +dependencies = [ + "bytes", + "flex-error", + "prost 0.13.2", + "serde", + "serde_bytes", + "subtle-encoding", + "time 0.3.36", +] + +[[package]] +name = "tendermint-rpc" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71afae8bb5f6b14ed48d4e1316a643b6c2c3cbad114f510be77b4ed20b7b3e42" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom", + "peg", + "pin-project", + "rand", + "reqwest 0.11.27", + "semver", + "serde", + "serde_bytes", + "serde_json", + "subtle", + "subtle-encoding", + "tendermint 0.34.1", + "tendermint-config", + "tendermint-proto 0.34.1", + "thiserror", + "time 0.3.36", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tests-integration" +version = "1.0.0" +dependencies = [ + "andromeda-address-list", + "andromeda-adodb", + "andromeda-app", + "andromeda-app-contract", + "andromeda-auction", + "andromeda-conditional-splitter", + "andromeda-crowdfund", + "andromeda-cw20", + "andromeda-cw20-staking", + "andromeda-cw721", + "andromeda-data-storage", + "andromeda-ecosystem", + "andromeda-finance", + "andromeda-fungible-tokens", + "andromeda-ibc-registry", + "andromeda-kernel", + "andromeda-lockdrop", + "andromeda-marketplace", + "andromeda-modules", + "andromeda-non-fungible-tokens", + "andromeda-primitive", + "andromeda-rates", + "andromeda-set-amount-splitter", + "andromeda-shunting", + "andromeda-splitter", + "andromeda-std", + "andromeda-testing", + "andromeda-validator-staking", + "andromeda-vault", + "andromeda-vesting", + "andromeda-vfs", + "cosmwasm-schema", + "cosmwasm-std", + "cw-asset", + "cw-multi-test", + "cw20", + "cw721 0.18.0", + "cw721-base 0.18.0", + "rstest", + "toml 0.7.8", +] + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "num-integer", - "num-iter", - "num-traits", + "thiserror-impl", ] [[package]] -name = "num-integer" -version = "0.1.46" +name = "thiserror-impl" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ - "num-traits", + "proc-macro2", + "quote", + "syn 2.0.77", ] [[package]] -name = "num-iter" -version = "0.1.44" +name = "time" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ - "autocfg", - "num-integer", - "num-traits", + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", ] [[package]] -name = "num-traits" +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ - "autocfg", + "num-conv", + "time-core", ] [[package]] -name = "object" -version = "0.32.2" +name = "tinyvec" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ - "memchr", + "tinyvec_macros", ] [[package]] -name = "once_cell" -version = "1.19.0" +name = "tinyvec_macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "opaque-debug" -version = "0.3.1" +name = "tokio" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] [[package]] -name = "osmosis-std" -version = "0.1.7" +name = "tokio-io-timeout" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50fb348fd7aefc37038ba8125e18b360af5bd44c6e007d2b10346777995857e3" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" dependencies = [ - "cosmwasm-std", - "osmosis-std-derive 0.1.7", - "prost 0.11.9", - "prost-types", - "schemars", - "serde", + "pin-project-lite", + "tokio", ] [[package]] -name = "osmosis-std-derive" -version = "0.1.7" +name = "tokio-macros" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743ed6a9bb8d2c210a8c184a874244dbf56ebb2f6062c3848300b7ea9817ca50" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ - "itertools 0.10.5", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] -name = "osmosis-std-derive" -version = "0.15.3" +name = "tokio-native-tls" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4d482a16be198ee04e0f94e10dd9b8d02332dcf33bc5ea4b255e7e25eedc5df" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", + "native-tls", + "tokio", ] [[package]] -name = "pin-project-lite" -version = "0.2.13" +name = "tokio-rustls" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] [[package]] -name = "pkcs8" -version = "0.10.2" +name = "tokio-rustls" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "der", - "spki", + "rustls 0.23.13", + "rustls-pki-types", + "tokio", ] [[package]] -name = "proc-macro2" -version = "1.0.79" +name = "tokio-stream" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ - "unicode-ident", + "futures-core", + "pin-project-lite", + "tokio", ] [[package]] -name = "prost" -version = "0.9.0" +name = "tokio-util" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", - "prost-derive 0.9.0", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] -name = "prost" -version = "0.11.9" +name = "toml" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "bytes", - "prost-derive 0.11.9", + "serde", ] [[package]] -name = "prost" -version = "0.12.3" +name = "toml" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ - "bytes", - "prost-derive 0.12.3", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", ] [[package]] -name = "prost-derive" -version = "0.9.0" +name = "toml_datetime" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", + "serde", ] [[package]] -name = "prost-derive" -version = "0.11.9" +name = "toml_edit" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", + "indexmap 2.5.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] -name = "prost-derive" -version = "0.12.3" +name = "tonic" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" dependencies = [ - "anyhow", - "itertools 0.11.0", - "proc-macro2", - "quote", - "syn 2.0.52", + "async-stream", + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.12.6", + "rustls 0.21.12", + "rustls-native-certs", + "rustls-pemfile 1.0.4", + "tokio", + "tokio-rustls 0.24.1", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "prost-types" -version = "0.11.9" +name = "tower" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ - "prost 0.11.9", + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "quote" -version = "1.0.35" +name = "tower-layer" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "proc-macro2", + "pin-project-lite", + "tracing-attributes", + "tracing-core", ] [[package]] -name = "rand_core" -version = "0.5.1" +name = "tracing-attributes" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] [[package]] -name = "rand_core" -version = "0.6.4" +name = "tracing-core" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ - "getrandom", + "once_cell", ] [[package]] -name = "regex" -version = "1.10.3" +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uid" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7041bb797d82c5728d3a4a40432809095d8acc59bdd9e67426a2529b3b80c9be" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ - "regex-automata", - "regex-syntax", + "tinyvec", ] [[package]] -name = "regex-automata" -version = "0.4.6" +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ - "regex-syntax", + "form_urlencoded", + "idna", + "percent-encoding", ] [[package]] -name = "regex-syntax" -version = "0.8.2" +name = "uuid" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" [[package]] -name = "rfc6979" -version = "0.4.0" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ - "hmac", - "subtle", + "same-file", + "winapi-util", ] [[package]] -name = "rustc-demangle" -version = "0.1.23" +name = "want" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] [[package]] -name = "rustversion" -version = "1.0.14" +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] -name = "ryu" -version = "1.0.17" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "schemars" -version = "0.8.16" +name = "wasm-bindgen" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", + "cfg-if", + "once_cell", + "wasm-bindgen-macro", ] [[package]] -name = "schemars_derive" -version = "0.8.16" +name = "wasm-bindgen-backend" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ + "bumpalo", + "log", + "once_cell", "proc-macro2", "quote", - "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.77", + "wasm-bindgen-shared", ] [[package]] -name = "sec1" -version = "0.7.3" +name = "wasm-bindgen-futures" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "semver" -version = "1.0.22" +name = "wasm-bindgen-macro" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] [[package]] -name = "serde" -version = "1.0.197" +name = "wasm-bindgen-macro-support" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ - "serde_derive", + "proc-macro2", + "quote", + "syn 2.0.77", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] -name = "serde-cw-value" -version = "0.7.0" +name = "wasm-bindgen-shared" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75d32da6b8ed758b7d850b6c3c08f1d7df51a4df3cb201296e63e34a78e99d4" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ - "serde", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "serde-json-wasm" -version = "0.5.2" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "serde", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "serde-json-wasm" -version = "1.0.1" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "serde", + "windows-sys 0.59.0", ] [[package]] -name = "serde_derive" -version = "1.0.197" +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", + "windows-targets 0.52.6", ] [[package]] -name = "serde_derive_internals" -version = "0.26.0" +name = "windows-registry" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", ] [[package]] -name = "serde_json" -version = "1.0.113" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "itoa", - "ryu", - "serde", + "windows-targets 0.52.6", ] [[package]] -name = "sha2" -version = "0.9.9" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "windows-result", + "windows-targets 0.52.6", ] [[package]] -name = "sha2" -version = "0.10.8" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", + "windows-targets 0.48.5", ] [[package]] -name = "sha256" -version = "1.5.0" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "async-trait", - "bytes", - "hex", - "sha2 0.10.8", - "tokio", + "windows-targets 0.52.6", ] [[package]] -name = "signature" -version = "2.2.0" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", + "windows-targets 0.52.6", ] [[package]] -name = "simple-shunting" -version = "0.1.2" +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb80ab4e2a505c887de71a93d97f71b38ff9f56c75dab1db4f175b235fca3e9a" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "lexers", - "libm", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] -name = "spki" -version = "0.7.3" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "base64ct", - "der", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "windows_aarch64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "strum_macros" -version = "0.24.3" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", -] +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "subtle" -version = "2.5.0" +name = "windows_aarch64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "syn" -version = "1.0.109" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "syn" -version = "2.0.52" +name = "windows_i686_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "tests-integration" -version = "0.1.0" -dependencies = [ - "andromeda-address-list", - "andromeda-adodb", - "andromeda-app", - "andromeda-app-contract", - "andromeda-auction", - "andromeda-crowdfund", - "andromeda-cw721", - "andromeda-data-storage", - "andromeda-ecosystem", - "andromeda-finance", - "andromeda-kernel", - "andromeda-marketplace", - "andromeda-modules", - "andromeda-non-fungible-tokens", - "andromeda-primitive", - "andromeda-rates", - "andromeda-shunting", - "andromeda-splitter", - "andromeda-std", - "andromeda-testing", - "andromeda-validator-staking", - "andromeda-vault", - "andromeda-vfs", - "cosmwasm-schema", - "cosmwasm-std", - "cw-multi-test", - "cw721 0.18.0", - "cw721-base 0.18.0", -] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "thiserror" -version = "1.0.58" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" -dependencies = [ - "thiserror-impl", -] +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "thiserror-impl" -version = "1.0.58" +name = "windows_i686_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "time" -version = "0.1.45" +name = "windows_i686_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "tokio" -version = "1.36.0" +name = "windows_x86_64_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" -dependencies = [ - "backtrace", - "bytes", - "pin-project-lite", -] +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "typenum" -version = "1.17.0" +name = "windows_x86_64_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "windows_x86_64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "version_check" -version = "0.9.4" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +name = "windows_x86_64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "winapi" -version = "0.3.9" +name = "winnow" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "memchr", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "winreg" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "zerocopy" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] diff --git a/andromeda-core/Cargo.toml b/andromeda-core/Cargo.toml index a867926..bb10198 100644 --- a/andromeda-core/Cargo.toml +++ b/andromeda-core/Cargo.toml @@ -12,7 +12,7 @@ members = [ "contracts/os/*", #Internal - "tests-integration", + "tests-integration", "ibc-tests", ] resolver = "2" @@ -28,18 +28,19 @@ panic = 'abort' strip = true [workspace.dependencies] -andromeda-std = { version = "0.1.0", path = "./packages/std" } -andromeda-macros = { path = "./packages/std/macros", version = "0.1.0" } -andromeda-non-fungible-tokens = { path = "./packages/andromeda-non-fungible-tokens" } -andromeda-fungible-tokens = { path = "./packages/andromeda-fungible-tokens" } -andromeda-finance = { path = "./packages/andromeda-finance" } -andromeda-data-storage = { path = "./packages/andromeda-data-storage" } -andromeda-modules = { path = "./packages/andromeda-modules" } -andromeda-app = { path = "./packages/andromeda-app" } -andromeda-ecosystem = { path = "./packages/andromeda-ecosystem" } -andromeda-testing = { path = "./packages/andromeda-testing" } +andromeda-std = { path = "./packages/std", default-features = false, version = "1.0.0" } +andromeda-macros = { path = "./packages/std/macros", default-features = false, version = "1.0.0" } +andromeda-non-fungible-tokens = { path = "./packages/andromeda-non-fungible-tokens", version = "1.0.0" } +andromeda-fungible-tokens = { path = "./packages/andromeda-fungible-tokens", version = "1.0.0" } +andromeda-finance = { path = "./packages/andromeda-finance", version = "1.0.0" } +andromeda-data-storage = { path = "./packages/andromeda-data-storage", version = "1.0.0" } +andromeda-modules = { path = "./packages/andromeda-modules", version = "2.0.0" } +andromeda-app = { path = "./packages/andromeda-app", version = "1.0.0" } +andromeda-ecosystem = { path = "./packages/andromeda-ecosystem", version = "1.0.0" } +andromeda-testing = { path = "./packages/andromeda-testing", version = "1.0.0" } +andromeda-testing-e2e = { path = "./packages/andromeda-testing-e2e", version = "1.0.0" } + -serde = { version = "1.0.127", default-features = false } strum_macros = "0.24.3" cosmwasm-std = "1.5.2" cw-utils = "1.0.3" @@ -49,8 +50,9 @@ cw20 = "1.1.2" cw20-base = "1.1.2" cw721 = "0.18.0" cw721-base = { version = "0.18.0", features = ["library"] } -cw-asset = "3.0.0" +cw-asset = "=3.0.0" cosmwasm-schema = "1.5.2" semver = "1.0.0" enum-repr = "0.2.6" -cw-multi-test = "0.20.0" +cw-multi-test = { version = "1.0.0", features = ["cosmwasm_1_2"] } +serde = { version = "1.0.127" } diff --git a/andromeda-core/README.md b/andromeda-core/README.md index bca9cd6..67b3d04 100644 --- a/andromeda-core/README.md +++ b/andromeda-core/README.md @@ -1,65 +1,127 @@

 

- -

- -A monorepository containing all the contracts and packages related to Andromeda Protocol. Full documentation for all the contracts can be found [here](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/introduction). - -## ADO Categories - -The contracts are classified based on their functionality. Currently we have 8 different contract categories. - -| Category| Description | -| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | -| [app](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/app)| Contracts used for building Andromeda apps. | -| [data-storage](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/data-storage/andromeda-primitive) | Contracts used to store any type of data (uint, string, bool ect...).| -| [ecosystem](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/ecosystem) | Contracts that are allow interaction with different ecosystem protocols.| -| [finance](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance) | Contracts used by fungible tokens to perform defi operations.| -| [fungible tokens](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens) | Contracts that integrate with fungible tokens (CW-20 tokens).| -| [non-fungible-tokens](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens) | Contacts that integrate with non-funible toknes (NFTs). Includes a standard CW721 contract with some custom features.| -| [modules](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/modules) |Andromeda modules that are attached to other ADOs to extend functionality.| - | [defunct](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/defunct) |Andromeda contracts that are no longer supported.| - - - -## ADOs - -| Contract | Category | Description | Documentation | -| ---------------------------|------------------------|-------------------------------------------|----------------------------------------------------- | -| [andromeda-app-contract](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/app/andromeda-app-contract)| app | Contract used to create Andromeda Apps. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/andromeda-apps/app)| -| [andromeda-factory](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/app/andromeda-factory)| app |Contract used to save the code Ids of all Andromeda ADOs. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/andromeda-apps/andromeda-factory)| -| [andromeda-primitive](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/data-storage/andromeda-primitive) | data-storage | Contract that stores any type of data that can be referenced by other ADOs. |[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/data-storage/primitive) | -| [andromeda-vault](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/ecosystem/andromeda-vault)|ecosystem| Contract that can receive and store funds. Acts as a central bank for projects. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/ecosystem/vault) | -| [andromeda-rate-limiting-withdrawals](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-rate-limiting-withdrawals) | finance | Contract that puts restrictions on the withdrawal of funds by users. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/rate-limiting-withdrawals)| -| [andromeda-splitter](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-splitter) | finance| Contract used to split any sent funds amongst defined addresses. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/andromeda-splitter)| -| [andromeda-timelock](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-timelock) | finance| Contract used to store funds until a condition has been satisfied before being released, similar to Escrow.|[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/timelock)| -| [andromeda-vesting](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-vesting) |finance | Contract used to custom vest tokens for a single recipient.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/vesting-ado)| -| [andromeda-weighted-distribution-splitter](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-weighted-distribution-splitter) | finance | Contract used to split any sent funds amongst defined addresses. Similar to the splitter but uses weights instead of percentages.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/weighted-splitter)| -| [andromeda-cw20](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/app/andromeda-factory) | fungible tokens |Contract to create standard cw-20 tokens. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/cw20-token) -| [andromeda-cw20-staking](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-cw20-staking) | fungible tokens | Contract that allows the staking of cw-20 tokens for rewards. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/cw20-staking)| -| [andromeda-lockdrop](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-lockdrop) | fungible tokens| Contract that allows users to deposit a netive token in exchange for the project's cw-20 token |[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/lockdrop)| -| [andromeda-merkle-airdrop](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-merkle-airdrop) | fungible tokens| Contract used to perform a merkle airdrop on cw20-tokens| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/merkle-airdrop)| -| [andromeda-auction](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-auction)|non-fungible-tokens| Contract that can receive an NFT and run an auction on it.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/auction)| -| [andromeda-crowdfund](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-crowdfund)|non-fungible-tokens| Contracts used to perform a crowdfund by selling NFTs.|[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/crowdfund)| -| [andromeda-cw721](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-cw721)| non-fungible-tokens| Contract used to create cw-721 standard NFTs. Has a custom message that allows selling the NFTs.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/andromeda-digital-object)| -| [andromeda-cw721-staking](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-cw721-staking)|non-fungible-tokens| Contract that allows custom staking of NFTs.|[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/cw721-staking)| -| [andromeda-gumball](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-gumball)|non-fungible-tokens| Contract that allows users to pay a price to get a random NFT.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/gumball)| -| [andromeda-nft-timelock](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-nft-timelock)|non-fungible-tokens| Contract that locks an NFT for a certain period of time.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/nft-timelock)| -| [andromeda-wrapped-cw721](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-wrapped-cw721)| non-fungible-tokens| Contract that wraps an NFT and mints an Andromeda NFT that can leverage our custom messages and modules instead. The token can be unwrapped.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/wrapped-cw721)| - -## Modules - -Modules are smart contracts that can be added to other ADOs on instantiation to extend their functionality. The communication between ADOs and our modules is achieved using our custom [Hooks](https://docs.andromedaprotocol.io/andromeda/andromeda-hooks/hooks). We currently have 4 modules: - -|Module| Description| Documentation| -|-------------------------------|---------------------------|-----------------------------| -| [address-list](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/modules/andromeda-address-list)| A module used to whitelist/blacklist a list of addresses to interact with the ADO.|[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/modules/address-list)| -| [rates](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/modules/andromeda-rates)| A module used to add rates (taxes/royalties) on fund transfers| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/modules/rates)| -| [cw721-bids](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-cw721-bids)|Module that can be attached to the cw721 ADO as another way to buy and sell NFTs.|[Gitbook](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/cw721-bids)| -| [receipts](https://docs.andromedaprotocol.io/andromeda/smart-contracts/modules/receipt-contract)| A module that can be attached to ADOs that saves the events of messages.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/modules/receipt-contract)| - -## Packages - + +

+ + AndromedaOS is a revolutionary software layer that provides a massively + abstracted environment and user experience for the next generation of + blockchain innovators to create, develop and get paid. + +# Introduction to AndromedaOS + +### Mission + +**Andromeda** **Protocol** is a rapid development framework and a next-generation user interface that brings an Easier, Better, and Faster capability to Web 3.0, and the blockchain industry. + + +#### What is a blockchain operating system? + +In short, a blockchain operating system provides an environment filled with ready to use tooling, common interfaces for applications and features familiar to modern computer users. As Andromeda is the first true operating system designed to run on distributed computing frameworks, the details are quite technical. + +AndromedaOS, or _aOS_ for short, is comprised of several interoperating systems that work together to bring clarity and ease of use to the user. It's important to understand the basic concepts and architecture of the system to develop. + +A quick description of each of the components that make up the aOS: + +* ​[Andromeda Digital Objects](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/introduction-to-ados) - the building blocks of the system +* [​Andromeda Apps](https://docs.andromedaprotocol.io/andromeda/andromeda-apps/introduction-to-apps) - advanced functionality built with ADOs +* ​[aOS Kernel](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/kernel) - the system for enforcing and coordinating the different systems +* ​[aOS File System](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/virtual-file-system) - common namespace for referencing ADOs, services, network, etc +* ​[aOS Economics](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/economics-engine) - developer and creator incentives + +It's important to note that each of these systems exist 100% on-chain. All logic, interactions, objects, economics, etc. are deployed on-chain. + +### Powered by the Cosmos Ecosystem + +The power and performance of the Rust/CosmWasm combo is what allowed this breakthrough in interoperability and complexity. + +#### Infinite Reach Through IBC + +Just like an operating system that can be seamlessly installed on any device, the AndromedaOS transcends limitations tied to the Andromeda chain. It is designed for universal compatibility and can be effortlessly deployed on any chain within the expansive Cosmos ecosystem. + +The operating system can be employed for local development on the chain, yet its true potential shines through Inter-Blockchain Communication (IBC). This capability allows the creation of Apps that extend seamlessly across multiple interconnected chains. + +Here is a visual representation of how this system is connected. + +

 

+

+ +

+ +As we can see, each of the Cosmos chains has AndromedaOS deployed . Since AndromedaOS can communicate using IBC, then users can build Applications that span accross many chains taking advantage of all the benefits that come along. + +For example, a user can build an NFT collection on Stargaze selling the NFTs using one of our ADOs and then using a splitter to send part of the funds to Terra to leverage some protocol and another part to Injective to leverage some functionality there. The user's imagination is the only limit to what can be built using the aOS. + +**Note**: IBC functionality is being slowly introduced into the system. Not all features mentioned above are currently available. + +### What is the benefit of using aOS + +* **For Projects:** + +Before **Andromeda**, projects would need to hire a full development teams in order to build their projects and custom smart contracts. Andromeda eliminates this need by providing a very large amount of custom smart contracts that upcoming projects can pick and chose from to achieve their desired utility. These projects can then use our **No-Code-Builder** to build their projects in a matter of minutes on any of the chains that Andromeda is deployed on. + +* **For Developers:** + +Developers can use our **Andromeda Logic Library** (ALL) which contains all our contracts to build from. Similar to how [**cw-plus**](https://github.com/CosmWasm/cw-plus) contracts are used as a base for production quality builds, the ALL will act as a base for all developers to create their own ADOs that use the superior interoperable system. + +As it stands, the ALL contains around 25 ADOs which is the tip of the iceberg. More and more ADOs are being added by the Andromeda team, and as we continue building, the ALL will eventually reach a state with thousands of ADOs where every use case imagined can be built using it. + +Furthermore, developers are incentivized for their contributions and the ADOs they create. This incentive system operates through our[ economic engine](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/economics-engine), enabling developers to set custom fees on their ADOs when it is published. Users utilizing these ADOs pay these fees, which are then returned to the developer responsible for their creation. + +* **For Chains:** + + AndromedaOS provides a whole suite of tooling that can be quickly installed on any chain in the Cosmos ecosystem. Installing the aOS would instantly give a chain and its users access to the following: + +1. A large number of production ready ADOs to be used. +2. The best no-code-builder in Cosmos and perhaps the entire blockchain industry. +3. IBC capable applications. +4. An incredible all in one CLI that is easy to use and manage. +5. Exposure to the chain, as users on any chain that implements the aOS will be able to to see where aOS is also deployed and might consider building applications on said chain. + +# Andromeda Core Repo + +A monorepository containing all the contracts and packages related to Andromeda Protocol. Full documentation for all the contracts can be found [here](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/introduction). + +## ADO Categories + +The contracts are classified based on their functionality. Currently we have 7 different contract categories. + +| Category| Description | +| ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| [app](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/app)| Contracts used for building Andromeda apps. | +| [ecosystem](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/ecosystem) | Contracts that are allow interaction with different ecosystem protocols.| +| [finance](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance) | Contracts used by fungible tokens to perform defi operations.| +| [fungible tokens](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens) | Contracts that integrate with fungible tokens (CW-20 tokens).| +| [non-fungible-tokens](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens) | Contacts that integrate with non-funible toknes (NFTs). Includes a standard CW721 contract with some custom features.| +| [os](https://github.com/andromedaprotocol/andromeda-core/tree/1.0.rc-1/contracts/os) | Contacts that make up the aOS architecture | + + +## Audited ADOs +The list of ADOs that have been audited and are available on our web-application. + +| Contract | Category | Description | Documentation | +| ---------------------------|------------------------|-------------------------------------------|----------------------------------------------------- | +| [andromeda-app-contract](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/app/andromeda-app-contract)| app | Contract used to create Andromeda Apps. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/andromeda-apps/app)| +| [andromeda-rate-limiting-withdrawals](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-rate-limiting-withdrawals) | finance | Contract that puts restrictions on the withdrawal of funds by users. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/rate-limiting-withdrawals)| +| [andromeda-splitter](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-splitter) | finance| Contract used to split any sent funds amongst defined addresses. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/andromeda-splitter)| +| [andromeda-timelock](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/finance/andromeda-timelock) | finance| Contract used to store funds until a condition has been satisfied before being released, similar to Escrow.|[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/finance/timelock)| +| [andromeda-cw20](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-cw20) | fungible tokens |Contract to create standard CW20 tokens. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/cw20-token) +| [andromeda-cw20-staking](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-cw20-staking) | fungible tokens | Contract that allows the staking of CW20 tokens for rewards. | [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/cw20-staking)| +| [andromeda-cw20-exchange](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-cw20-exchange) | fungible tokens | Contract that allows the exchanging native tokens for a specified CW20 | [Gitbook](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/cw20-exchange)| +| [andromeda-lockdrop](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-lockdrop) | fungible tokens| Contract that allows users to deposit a netive token in exchange for the project's cw-20 token |[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/lockdrop)| +| [andromeda-merkle-airdrop](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/fungible-tokens/andromeda-merkle-airdrop) | fungible tokens| Contract used to perform a merkle airdrop on cw20-tokens| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/fungible-tokens/merkle-airdrop)| +| [andromeda-auction](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-auction)|non-fungible-tokens| Contract that can receive an NFT and run an auction on it.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/auction)| +| [andromeda-marketplace](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-marketplace)|non-fungible-tokens| Contract that can receive an NFT and run an a sale on it.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/marketplace)| +| [andromeda-crowdfund](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-crowdfund)|non-fungible-tokens| Contracts used to perform a crowdfund by selling NFTs.|[Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/crowdfund)| +| [andromeda-cw721](https://github.com/andromedaprotocol/andromeda-core/tree/development/contracts/non-fungible-tokens/andromeda-cw721)| non-fungible-tokens| Contract used to create CW721 standard NFTs. Has a custom message that allows selling the NFTs.| [Gitbook](https://docs.andromedaprotocol.io/andromeda/smart-contracts/non-fungible-tokens/andromeda-digital-object)| +| [andromeda-adodb](https://github.com/andromedaprotocol/andromeda-core/tree/1.0.rc-1/contracts/os/andromeda-adodb)| os| The ADO database responsible for publishing new ADOs into the aOS| [Gitbook](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/andromeda-factory)| +| [andromeda-economics](https://github.com/andromedaprotocol/andromeda-core/tree/1.0.rc-1/contracts/os/andromeda-economics)| os | The contract responsible for handling ADO fees| [Gitbook](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/economics-engine)| +| [andromeda-kernel](https://github.com/andromedaprotocol/andromeda-core/tree/1.0.rc-1/contracts/os/andromeda-kernel)| os | The contract responsible for handling communication between ADOs| [Gitbook](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/kernel)| +| [andromeda-vfs](https://github.com/andromedaprotocol/andromeda-core/tree/1.0.rc-1/contracts/os/andromeda-vfs)| os| The contract responsible for managing the usernames and paths of ADOs and users in the aOs | [Gitbook](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/virtual-file-system)| + +**Note**: Other ADOs can be found in our repo, but they have not gone through the auditing process yet. + +## Packages + | Contract | Description | | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | [andromeda_protocol](https://github.com/andromedaprotocol/andromeda-core/tree/development/packages) | Package used to define message types and various utility methods used by Andromeda ADO Contracts.| @@ -67,12 +129,20 @@ Modules are smart contracts that can be added to other ADOs on instantiation to ### ADO Base The packages also includes the [ado_base](https://github.com/andromedaprotocol/andromeda-core/tree/development/packages/ado-base). Since all our ADOs are built using the same architecture, redundency was inevitable. So we decided to bundle up all the functions/messages/structures that are used by all ADOs into the ado_base which can be referenced by any new ADOs. - -## Development - -### Testing - -All tests can be run using: + +## Development + +### Andromeda Template and Crate + +A starting template for ADO development can be found [here](https://github.com/andromedaprotocol/andr-cw-template). +The andromeda-std crate can be found [here](https://crates.io/crates/andromeda-std). + +### Integration Tests +Check out our cw-multi-test based testing [library](https://github.com/andromedaprotocol/andromeda-core/tree/1.0.rc-1/packages/andromeda-testing) to setup custom ADO integration tests. + +### Testing + +All tests can be run using: `cargo test --workspace` @@ -133,9 +203,12 @@ rustup toolchain install nightly cargo clippy --all --all-targets -- -D warnings ``` ### Creating and Interacting with ADOs - -Andromeda is deployed on many of the Cosmos chains. Usually this will require you to set up an environment for each chain. Luckily, Andromeda has built the Andromeda CLI, an all in one tool to build, interact, and manage ADOs and wallets for any of the chains. The CLI documentation can be found [here](https://docs.andromedaprotocol.io/andromeda/andromeda-cli/introduction). - -## Licensing - -[Terms and Conditions](https://github.com/andromedaprotocol/andromeda-core/blob/development/LICENSE/LICENSE.md) + +Andromeda is deployed on many of the Cosmos chains. Usually this will require you to set up an environment for each chain. Luckily, Andromeda has built the Andromeda CLI, an all in one tool to build, interact, and manage ADOs and wallets for any of the chains. The CLI documentation can be found [here](https://docs.andromedaprotocol.io/andromeda/andromeda-cli/introduction). + +### Andromeda JS +[Andromeda.js](https://github.com/andromedaprotocol/andromeda.js) is a JavaScript SDK for writing applications that interact with ADOs on any of the blockchains that Andromeda is deployed on. More on the AndromedaJS can be found [here](https://docs.andromedaprotocol.io/andromeda.js/). + +## Licensing + +[Terms and Conditions](https://github.com/andromedaprotocol/andromeda-core/blob/development/LICENSE/LICENSE.md) diff --git a/andromeda-core/build.sh b/andromeda-core/build.sh index c746f63..14e51a6 100755 --- a/andromeda-core/build.sh +++ b/andromeda-core/build.sh @@ -5,18 +5,31 @@ # Builds "andromeda-contract" contract and "some-category" category # LOG all the contracts compiled with there compressed file size -local FILE_LOG="" +FILE_LOG="" -build_contract () { +get_version_filename (){ local CONTRACT=$1 - echo "Building contract $CONTRACT..." - cargo wasm -p $CONTRACT -q - # Get the version of the contract processed local BUILD_VERSION=$(cargo pkgid $CONTRACT | cut -d# -f2 | cut -d: -f2) local BUILD_TARGET=${CONTRACT//-/_} + + echo "$BUILD_TARGET@$BUILD_VERSION"; +} + +build_contract () { + local CONTRACT_PATH=$1; + + local CONTRACT=`basename $CONTRACT_PATH`; + echo "Building contract $CONTRACT..." + if ! cargo wasm -p $CONTRACT -q; then + exit 1 + fi + + local BUILD_TARGET=${CONTRACT//-/_} + local VERSION_FILENAME=$(get_version_filename $CONTRACT); + local IN_FILE="./target/wasm32-unknown-unknown/release/$BUILD_TARGET.wasm" - local OUT_FILE="./artifacts/$BUILD_TARGET@$BUILD_VERSION.wasm" + local OUT_FILE="./artifacts/$VERSION_FILENAME.wasm" wasm-opt -Os $IN_FILE -o $OUT_FILE # NOT SO IMPORTANT STEPS @@ -32,7 +45,7 @@ build_category () { if [[ "$(basename $directory)" = "$1" ]]; then echo "Building all contracts in category $(basename $directory)..." for contract in $directory/*/; do - build_contract $(basename $contract) + build_contract $contract; done break fi @@ -73,6 +86,7 @@ rm -rf ./target rm -rf ./artifacts mkdir artifacts +set -e for target in "$@"; do if [[ "$target" = "all" ]]; then build_all diff --git a/andromeda-core/build_all.sh b/andromeda-core/build_all.sh index 1789632..250475d 100755 --- a/andromeda-core/build_all.sh +++ b/andromeda-core/build_all.sh @@ -2,4 +2,4 @@ docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/workspace-optimizer:0.13.0 \ No newline at end of file + cosmwasm/optimizer:0.15.1 \ No newline at end of file diff --git a/andromeda-core/build_schema.sh b/andromeda-core/build_schema.sh index d5250d2..2168d6f 100755 --- a/andromeda-core/build_schema.sh +++ b/andromeda-core/build_schema.sh @@ -3,8 +3,38 @@ set -e set -o pipefail +get_version_filename (){ + local CONTRACT=$1 + # Get the version of the contract processed + local BUILD_VERSION=$(cargo pkgid $CONTRACT | cut -d# -f2 | cut -d: -f2) + local BUILD_TARGET=${CONTRACT//-/_} + + echo "$BUILD_TARGET@$BUILD_VERSION"; +} + +copy_schema () { + local CONTRACT_PATH=$1; + local CONTRACT=$(basename $CONTRACT_PATH); + echo "$CONTRACT" + local VERSION_FILENAME=$(get_version_filename $CONTRACT); + rm -rf ./artifacts/$VERSION_FILENAME + mkdir ./artifacts/$VERSION_FILENAME + # Loop through all the schema for this contract + for schema in $CONTRACT_PATH/schema/*.json; do + local SCHEMA_NAME=$(basename $schema); + cp "$schema" "./artifacts/$VERSION_FILENAME/$SCHEMA_NAME" + + done + +} + +if [ ! -d "./artifacts" ]; then + mkdir artifacts; +fi; + for directory in contracts/*/; do for contract in $directory/*/; do ( cd $contract && cargo schema ) + copy_schema $contract done done \ No newline at end of file diff --git a/andromeda-core/bump-version.sh b/andromeda-core/bump-version.sh new file mode 100755 index 0000000..36d1bec --- /dev/null +++ b/andromeda-core/bump-version.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Check if directory and version bump type are provided +if [ $# -ne 2 ]; then + echo "Usage: $0 " + echo "version_bump should be one of: patch, minor, major" + exit 1 +fi + +DIRECTORY=$1 +VERSION_BUMP=$2 + +# Function to bump the version in a Cargo.toml file +bump_version() { + FILE=$1 + VERSION_BUMP=$2 + + # Extract the current version + VERSION=$(grep '^version =' "$FILE" | sed -E 's/version = "(.*)"/\1/') + + if [[ ! $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "No valid version found in $FILE" + return 1 + fi + + IFS='.' read -r -a VERSION_PARTS <<< "$VERSION" + + MAJOR=${VERSION_PARTS[0]} + MINOR=${VERSION_PARTS[1]} + PATCH=${VERSION_PARTS[2]} + + # Bump the version based on the input + case $VERSION_BUMP in + major) + MAJOR=$((MAJOR + 1)) + MINOR=0 + PATCH=0 + ;; + minor) + MINOR=$((MINOR + 1)) + PATCH=0 + ;; + patch) + PATCH=$((PATCH + 1)) + ;; + *) + echo "Invalid version bump type. Use 'patch', 'minor', or 'major'." + return 1 + ;; + esac + + NEW_VERSION="$MAJOR.$MINOR.$PATCH" + + # Update the version in the Cargo.toml file + sed -i.bak "s/version = \"$VERSION\"/version = \"$NEW_VERSION\"/" "$FILE" + rm "$FILE.bak" + + echo "Updated $FILE to version $NEW_VERSION" +} + +export -f bump_version + +# Find all Cargo.toml files and bump their versions +find "$DIRECTORY" -name "Cargo.toml" -exec bash -c 'bump_version "$0" "$1"' {} "$VERSION_BUMP" \; diff --git a/andromeda-core/ci-scripts/install_binaryen.sh b/andromeda-core/ci-scripts/install_binaryen.sh new file mode 100644 index 0000000..0c579a0 --- /dev/null +++ b/andromeda-core/ci-scripts/install_binaryen.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +wget https://github.com/WebAssembly/binaryen/releases/download/version_117/binaryen-version_117-x86_64-linux.tar.gz +tar -xf binaryen-version_117-x86_64-linux.tar.gz +mv binaryen-version_117/bin/wasm-opt /usr/local/bin +rm -rf binaryen-version_117* diff --git a/andromeda-core/ci-scripts/localrelayer/Makefile b/andromeda-core/ci-scripts/localrelayer/Makefile deleted file mode 100644 index e2af7cc..0000000 --- a/andromeda-core/ci-scripts/localrelayer/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -init: clean build - -build: - @DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f docker-compose.yml build - -start: - @docker-compose -f docker-compose.yml up - -startd: - @docker-compose -f docker-compose.yml up -d - -stop: - @docker-compose -f docker-compose.yml down -t 3 - - -restart: stop - @docker-compose -f docker-compose.yml up --force-recreate - -restartd: stop - @docker-compose -f docker-compose.yml up --force-recreate -d - -clean: - @rm -rfI ./template/.osmosisd-local-a - @rm -rfI ./template/.osmosisd-local-b diff --git a/andromeda-core/ci-scripts/localrelayer/README.md b/andromeda-core/ci-scripts/localrelayer/README.md deleted file mode 100644 index c6403b2..0000000 --- a/andromeda-core/ci-scripts/localrelayer/README.md +++ /dev/null @@ -1,221 +0,0 @@ -# Localrelayer - -Localrelayer is a local testing environment composed of two localOsmosis instances connected by a relayer. - -![Architecture](./assets/architecture.png) - -## Endpoints - -| Chain ID | Component | Endpoint | -| ---------------- | ---------- | ------------------------ | -| `localosmosis-a` | `RPC` | | -| `localosmosis-a` | `REST/LCD` | | -| `localosmosis-a` | `gRPC` | | -| `localosmosis-a` | `faucet` | | -| `localosmosis-b` | `RPC` | | -| `localosmosis-b` | `REST/LCD` | | -| `localosmosis-b` | `gRPC` | | -| `localosmosis-b` | `faucet` | | -| `-` | `hermes` | | - -## Accounts - -By default the following mnemonics are used: - -| Chain ID | Account | Mnemonic | -| ---------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `localosmosis-a` | `validator-a` | _family album bird seek tilt color pill danger message abuse manual tent almost ridge boost blast high comic core quantum spoon coconut oyster remove_ | -| `localosmosis-a` | `faucet` | _increase bread alpha rigid glide amused approve oblige print asset idea enact lawn proof unfold jeans rabbit audit return chuckle valve rather cactus great_ | -| `localosmosis-a` | `relayer` | _black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken_ | -| `localosmosis-b` | `validator-b` | _family album bird seek tilt color pill danger message abuse manual tent almost ridge boost blast high comic core quantum spoon coconut oyster remove_ | -| `localosmosis-b` | `faucet` | _increase bread alpha rigid glide amused approve oblige print asset idea enact lawn proof unfold jeans rabbit audit return chuckle valve rather cactus great_ | -| `localosmosis-b` | `relayer` | _black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken_ | - -## Deploy - -Build a local docker image with current changes - -```bash -make build -``` - -Start the testing environment: - -```bash -make start -``` - -The command will: - -1. create a local docker network: - -```bash - ⠿ Network localrelayer_localosmosis Created -``` - -2. run the following containers: - -```bash - ⠿ Container localrelayer-localosmosis-b-1 Created - ⠿ Container localrelayer-localosmosis-a-1 Created - ⠿ Container localrelayer-faucet-a-1 Created - ⠿ Container localrelayer-faucet-b-1 Created - ⠿ Container localrelayer-hermes-1 Created -``` - -> If you don't want the logs, you can start in detached mode with the following command: -> -> `make startd` - -Check that everything is running: - -```bash -docker ps -``` - -Expected output: - -```bash -❯ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -318c89d3015f informalsystems/hermes:1.1.0 "/home/hermes/setup.…" About a minute ago Up 2 seconds 0.0.0.0:3000->3000/tcp localrelayer-hermes-1 -ff7abb62fdb3 confio/faucet:0.28.11 "/app/packages/fauce…" About a minute ago Up 2 seconds 0.0.0.0:38000->8000/tcp localrelayer-faucet-b-1 -7e7ca3ff8a67 confio/faucet:0.28.11 "/app/packages/fauce…" About a minute ago Up 2 seconds 0.0.0.0:8000->8000/tcp localrelayer-faucet-a-1 -d90ec29c7a6f local:osmosis "/osmosis/setup.sh" About a minute ago Up 3 seconds 26656/tcp, 0.0.0.0:31317->1317/tcp, 0.0.0.0:39090->9090/tcp, 0.0.0.0:36657->26657/tcp localrelayer-localosmosis-b-1 -e36cead49a07 local:osmosis "/osmosis/setup.sh" About a minute ago Up 3 seconds 0.0.0.0:1317->1317/tcp, 0.0.0.0:9090->9090/tcp, 0.0.0.0:26657->26657/tcp, 26656/tcp localrelayer-localosmosis-a-1 -``` - -## Usage - -### Interact with chain - -Check `localosmosis-a` status: - -```bash -curl -s http://localhost:26657/status -``` - -Check `localosmosis-b` status: - -```bash -curl -s http://localhost:36657/status -``` - -### Faucet - -The faucet used is `confio/faucet:0.28.11`. The source code and additional documentation are available [here](https://github.com/cosmos/cosmjs/tree/main/packages/faucet). - -Create a new account: - -```bash -❯ osmosisd keys add my-account --keyring-backend test - -- name: my-account - type: local - address: osmo1e5zmvznxr0zuulsstna0rd3959sw858e5ctw2j - pubkey: '{"@type":"/cosmos.crypto.secp256k1.PubKey","key":"AougdpyGftv+BMBXzQWFVJx9ASz/QRoBDM0nRI/xq90Y"}' - mnemonic: "" -``` - -Request founds: - -```bash -FAUCET_ENDPOINT=http://localhost:8080 - -# Use the following endpoint for localosmosis-b: -# FAUCET_ENDPOINT=http://localhost:38080 - -curl --header "Content-Type: application/json" \ - --request POST \ - --data '{"denom":"uosmo","address":"osmo1e5zmvznxr0zuulsstna0rd3959sw858e5ctw2j"}' \ - http://localhost:8000/credit -``` - -Check balance: - -```bash -LCD_ENDPOINT=\localhost:1317 - -# Use the following endpoint for localosmosis-b: -# LCD_ENDPOINT=localhost:31317 - -curl -s http://$LCD_ENDPOINT/cosmos/bank/v1beta1/balances/osmo1e5zmvznxr0zuulsstna0rd3959sw858e5ctw2j -``` - -### Hermes - -You can test that hermes is working by sending a test IBC transaction. - -Make sure `hermes` is running: - -```bash -❯ docker ps | grep hermes -``` - -Expected output: - -```bash -318c89d3015f informalsystems/hermes:1.1.0 "/home/hermes/setup.…" 23 minutes ago Up 22 minutes 0.0.0.0:3000->3000/tcp -``` - -Exec inside the container: - -```bash -docker exec -ti localrelayer-hermes-1 sh -``` - -Send a transaction: - -```bash -hermes tx ft-transfer --timeout-seconds 1000 \ - --dst-chain localosmosis-a \ - --src-chain localosmosis-b \ - --src-port transfer \ - --src-channel channel-0 \ - --amount 100 \ - --denom uosmo -``` - -Expected output: - -```bash -2022-12-01T11:41:22.351909Z INFO ThreadId(01) using default configuration from '/root/.hermes/config.toml' -SUCCESS [ - IbcEventWithHeight { - event: SendPacket( - SendPacket { - packet: Packet { - sequence: Sequence( - 1, - ), - source_port: PortId( - "transfer", - ), - source_channel: ChannelId( - "channel-0", - ), - destination_port: PortId( - "transfer", - ), - destination_channel: ChannelId( - "channel-0", - ), - data: [123, 34, 97, 109, 111, 117, 110, 116, 34, 58, 34, 49, 48, 48, 34, 44, 34, 100, 101, 110, 111, 109, 34, 58, 34, 117, 111, 115, 109, 111, 34, 44, 34, 114, 101, 99, 101, 105, 118, 101, 114, 34, 58, 34, 111, 115, 109, 111, 49, 113, 118, 100, 101, 117, 52, 120, 51, 52, 114, 97, 112, 112, 51, 119, 99, 56, 102, 121, 109, 53, 103, 52, 119, 117, 51, 52, 51, 109, 115, 119, 120, 50, 101, 120, 107, 117, 103, 34, 44, 34, 115, 101, 110, 100, 101, 114, 34, 58, 34, 111, 115, 109, 111, 49, 113, 118, 100, 101, 117, 52, 120, 51, 52, 114, 97, 112, 112, 51, 119, 99, 56, 102, 121, 109, 53, 103, 52, 119, 117, 51, 52, 51, 109, 115, 119, 120, 50, 101, 120, 107, 117, 103, 34, 125], - timeout_height: Never, - timeout_timestamp: Timestamp { - time: Some( - Time( - 2022-12-01 11:57:59.365129852, - ), - ), - }, - }, - }, - ), - height: Height { - revision: 0, - height: 1607, - }, - }, -] -``` diff --git a/andromeda-core/ci-scripts/localrelayer/config/hermes/config.toml b/andromeda-core/ci-scripts/localrelayer/config/hermes/config.toml deleted file mode 100644 index 70e5378..0000000 --- a/andromeda-core/ci-scripts/localrelayer/config/hermes/config.toml +++ /dev/null @@ -1,101 +0,0 @@ -[global] -log_level = 'info' - -[mode.clients] -enabled = true -refresh = true -misbehaviour = true - -[mode.connections] -enabled = true - -[mode.channels] -enabled = true - -[mode.packets] -enabled = true -clear_interval = 120 -clear_on_start = false -tx_confirmation = true - -[rest] -enabled = true -host = '0.0.0.0' -port = 3000 - -[telemetry] -enabled = true -host = '0.0.0.0' -port = 3001 - -[[chains]] -id = 'localosmosis-b' -type = 'CosmosSdk' -rpc_addr = 'http://localosmosis-b:26657' -grpc_addr = 'http://localosmosis-b:9090' -websocket_addr = 'ws://localosmosis-b:26657/websocket' -rpc_timeout = '10s' -account_prefix = 'osmo' -key_name = 'localosmosis-b' -key_store_type = 'Test' -store_prefix = 'ibc' -default_gas = 1000000 -max_gas = 40000000 -gas_multiplier = 1.1 -max_msg_num = 30 -max_tx_size = 2097152 -clock_drift = '5s' -max_block_time = '30s' -memo_prefix = '' -sequential_batch_tx = true - -[chains.trust_threshold] -numerator = '1' -denominator = '3' - -[chains.gas_price] -price = 0.1 -denom = 'uosmo' - -[chains.packet_filter] -policy = 'allow' -list = [['transfer', 'channel-*']] - -[chains.address_type] -derivation = 'cosmos' - -[[chains]] -id = 'localosmosis-a' -type = 'CosmosSdk' -rpc_addr = 'http://localosmosis-a:26657' -grpc_addr = 'http://localosmosis-a:9090' -websocket_addr = 'ws://localosmosis-a:26657/websocket' -rpc_timeout = '10s' -account_prefix = 'osmo' -key_name = 'localosmosis-a' -key_store_type = 'Test' -store_prefix = 'ibc' -default_gas = 1000000 -max_gas = 4000000 -gas_multiplier = 1.1 -max_msg_num = 30 -max_tx_size = 2097152 -clock_drift = '5s' -max_block_time = '30s' -memo_prefix = '' -sequential_batch_tx = true - -[chains.trust_threshold] -numerator = '1' -denominator = '3' - -[chains.gas_price] -price = 0.1 -denom = 'uosmo' - -[chains.packet_filter] -policy = 'allow' -list = [['transfer', 'channel-*']] - -[chains.address_type] -derivation = 'cosmos' diff --git a/andromeda-core/ci-scripts/localrelayer/docker-compose.yml b/andromeda-core/ci-scripts/localrelayer/docker-compose.yml deleted file mode 100644 index c55a6c9..0000000 --- a/andromeda-core/ci-scripts/localrelayer/docker-compose.yml +++ /dev/null @@ -1,74 +0,0 @@ -version: "3" - -services: - localosmosis-a: - build: - context: https://github.com/osmosis-labs/osmosis.git#main - args: - RUNNER_IMAGE: alpine:3.17 - GO_VERSION: "1.20" - volumes: - - ./scripts/setup_chain.sh:/osmosis/setup.sh - - ./template/.osmosisd-local-a/:/osmosis/.osmosisd/ - entrypoint: - - /osmosis/setup.sh - environment: - - CHAIN_ID=localosmosis-a - - VALIDATOR_MONIKER=validator-a - - VALIDATOR_MNEMONIC=family album bird seek tilt color pill danger message abuse manual tent almost ridge boost blast high comic core quantum spoon coconut oyster remove - - FAUCET_MNEMONIC=notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius - - RELAYER_MNEMONIC=black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken - ports: - - 26657:26657 - - 1317:1317 - - 9090:9090 - networks: - - localosmosis - - localosmosis-b: - build: - context: https://github.com/osmosis-labs/osmosis.git#main - args: - RUNNER_IMAGE: alpine:3.17 - GO_VERSION: "1.20" - volumes: - - ./scripts/setup_chain.sh:/osmosis/setup.sh - - ./template/.osmosisd-local-b:/osmosis/.osmosisd - entrypoint: - - /osmosis/setup.sh - environment: - - CHAIN_ID=localosmosis-b - - VALIDATOR_MONIKER=validator-b - - VALIDATOR_MNEMONIC=family album bird seek tilt color pill danger message abuse manual tent almost ridge boost blast high comic core quantum spoon coconut oyster remove - - FAUCET_MNEMONIC=notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius - - RELAYER_MNEMONIC=black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken - ports: - # Can't use the same ports - - 36657:26657 - - 31317:1317 - - 39090:9090 - networks: - - localosmosis - hermes: - image: informalsystems/hermes:1.1.0 - user: root:root - volumes: - - ./scripts/setup_hermes.sh:/home/hermes/setup.sh - - ./config/hermes/config.toml:/root/.hermes/config.toml - entrypoint: - - /home/hermes/setup.sh - environment: - - CHAIN_A_ID=localosmosis-a - - CHAIN_A_MNEMONIC=black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken - - CHAIN_B_ID=localosmosis-b - - CHAIN_B_MNEMONIC=black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken - ports: - - 3000:3000 - depends_on: - - localosmosis-a - - localosmosis-b - networks: - - localosmosis - -networks: - localosmosis: diff --git a/andromeda-core/ci-scripts/localrelayer/go.mod b/andromeda-core/ci-scripts/localrelayer/go.mod deleted file mode 100644 index b7a9f01..0000000 --- a/andromeda-core/ci-scripts/localrelayer/go.mod +++ /dev/null @@ -1,335 +0,0 @@ -module github.com/osmosis-labs/osmosis/v16 - -go 1.20 - -require ( - cosmossdk.io/errors v1.0.0-beta.7 - github.com/CosmWasm/wasmd v0.31.0 - github.com/cosmos/cosmos-proto v1.0.0-beta.2 - github.com/cosmos/cosmos-sdk v0.47.3 - github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/ibc-apps/modules/async-icq/v4 v4.0.0-20230524151648-c02fa46c2860 - github.com/cosmos/ibc-go/v4 v4.3.1 - github.com/gogo/protobuf v1.3.3 - github.com/golang/mock v1.6.0 - github.com/golang/protobuf v1.5.3 - github.com/golangci/golangci-lint v1.52.2 - github.com/gorilla/mux v1.8.0 - github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/iancoleman/orderedmap v0.2.0 - github.com/mattn/go-sqlite3 v1.14.17 - github.com/ory/dockertest/v3 v3.10.0 - github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 - github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230516205127-c213fddde069 - github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230608190634-3395abe098ce - github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 - github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230602130523-f9a94d8bbd10 - github.com/pkg/errors v0.9.1 - github.com/rakyll/statik v0.1.7 - github.com/spf13/cast v1.5.1 - github.com/spf13/cobra v1.7.0 - github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.16.0 - github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5 - github.com/stretchr/testify v1.8.4 - github.com/tendermint/tendermint v0.37.0-rc1 - github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b - github.com/tidwall/btree v1.6.0 - github.com/tidwall/gjson v1.14.4 - go.uber.org/multierr v1.11.0 - golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 - google.golang.org/grpc v1.55.0 - gopkg.in/yaml.v2 v2.4.0 - mvdan.cc/gofumpt v0.5.0 -) - -require ( - 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect - github.com/Abirdcfly/dupword v0.0.11 // indirect - github.com/Djarvur/go-err113 v0.1.0 // indirect - github.com/alingse/asasalint v0.0.11 // indirect - github.com/benbjohnson/clock v1.3.0 // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/cosmos/gogoproto v1.4.6 // indirect - github.com/cosmos/iavl v0.19.5 // indirect - github.com/creachadair/taskgroup v0.3.2 // indirect - github.com/curioswitch/go-reassign v0.2.0 // indirect - github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/felixge/httpsnoop v1.0.2 // indirect - github.com/go-playground/locales v0.14.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect - github.com/gogo/gateway v1.1.0 // indirect - github.com/google/btree v1.1.2 // indirect - github.com/junk1tm/musttag v0.5.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.4 // indirect - github.com/maratori/testableexamples v1.0.0 // indirect - github.com/nunnatsa/ginkgolinter v0.9.0 // indirect - github.com/regen-network/cosmos-proto v0.3.1 // indirect - github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.23.0 // indirect - github.com/sivchari/nosnakecase v1.7.0 // indirect - github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect - github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect - github.com/timonwong/loggercheck v0.9.4 // indirect - github.com/zimmski/go-mutesting v0.0.0-20210610104036-6d9217011a00 // indirect - github.com/zondax/ledger-go v0.14.1 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/goleak v1.1.12 // indirect - go.uber.org/zap v1.24.0 // indirect -) - -require ( - 4d63.com/gochecknoglobals v0.2.1 // indirect - filippo.io/edwards25519 v1.0.0-rc.1 // indirect - github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/99designs/keyring v1.2.1 // indirect - github.com/Antonboom/errname v0.1.9 // indirect - github.com/Antonboom/nilnil v0.1.3 // indirect - github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/BurntSushi/toml v1.2.1 // indirect - github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect - github.com/CosmWasm/wasmvm v1.2.1 - github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect - github.com/Masterminds/semver v1.5.0 // indirect - github.com/Microsoft/go-winio v0.6.0 // indirect - github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect - github.com/OpenPeeDeeP/depguard v1.1.1 // indirect - github.com/Workiva/go-datastructures v1.0.53 // indirect - github.com/alexkohler/prealloc v1.0.0 // indirect - github.com/armon/go-metrics v0.4.1 // indirect - github.com/ashanbrown/forbidigo v1.5.1 // indirect - github.com/ashanbrown/makezero v1.1.1 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect - github.com/bkielbasa/cyclop v1.2.0 // indirect - github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v3 v3.4.0 // indirect - github.com/breml/bidichk v0.2.4 // indirect - github.com/breml/errchkjson v0.3.1 // indirect - github.com/btcsuite/btcd v0.22.3 // indirect - github.com/butuzov/ireturn v0.1.1 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/charithe/durationcheck v0.0.10 // indirect - github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect - github.com/confio/ics23/go v0.9.0 // indirect - github.com/containerd/continuity v0.3.0 // indirect - github.com/cosmos/btcutil v1.0.5 - github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/ledger-cosmos-go v0.12.2 // indirect - github.com/daixiang0/gci v0.10.1 // indirect - github.com/danieljoos/wincred v1.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/denis-tingaikin/go-header v0.4.3 // indirect - github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v3 v3.2103.2 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect - github.com/docker/cli v20.10.17+incompatible // indirect - github.com/docker/docker v20.10.24+incompatible // indirect - github.com/docker/go-connections v0.4.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect - github.com/esimonov/ifshort v1.0.4 // indirect - github.com/ettle/strcase v0.1.1 // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/fatih/structtag v1.2.0 // indirect - github.com/firefart/nonamedreturns v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/go-critic/go-critic v0.7.0 // indirect - github.com/go-kit/kit v0.12.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/go-toolsmith/astcast v1.1.0 // indirect - github.com/go-toolsmith/astcopy v1.1.0 // indirect - github.com/go-toolsmith/astequal v1.1.0 // indirect - github.com/go-toolsmith/astfmt v1.1.0 // indirect - github.com/go-toolsmith/astp v1.1.0 // indirect - github.com/go-toolsmith/strparse v1.1.0 // indirect - github.com/go-toolsmith/typep v1.1.0 // indirect - github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect - github.com/gobwas/glob v0.2.3 // indirect - github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gofrs/flock v0.8.1 // indirect - github.com/golang/glog v1.0.0 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect - github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect - github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect - github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect - github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect - github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect - github.com/golangci/misspell v0.4.0 // indirect - github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect - github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect - github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/google/gofuzz v1.2.0 // indirect - github.com/google/orderedcode v0.0.1 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect - github.com/gorilla/handlers v1.5.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/gostaticanalysis/analysisutil v0.7.1 // indirect - github.com/gostaticanalysis/comment v1.4.2 // indirect - github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect - github.com/gostaticanalysis/nilerr v0.1.1 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect - github.com/gtank/merlin v0.1.1 // indirect - github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect - github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/imdario/mergo v0.3.13 // indirect - github.com/improbable-eng/grpc-web v0.15.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jessevdk/go-flags v1.4.0 // indirect - github.com/jgautheron/goconst v1.5.1 // indirect - github.com/jingyugao/rowserrcheck v1.1.1 // indirect - github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect - github.com/jmhodges/levigo v1.0.0 // indirect - github.com/joho/godotenv v1.5.1 - github.com/julz/importas v0.1.0 // indirect - github.com/kisielk/errcheck v1.6.3 // indirect - github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.15.11 // indirect - github.com/kulti/thelper v0.6.3 // indirect - github.com/kunwardeep/paralleltest v1.0.6 // indirect - github.com/kyoh86/exportloopref v0.1.11 // indirect - github.com/ldez/gomoddirectives v0.2.3 // indirect - github.com/ldez/tagliatelle v0.4.0 // indirect - github.com/leonklingele/grouper v1.1.1 // indirect - github.com/lib/pq v1.10.7 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/lufeee/execinquery v1.2.1 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/maratori/testpackage v1.1.1 // indirect - github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.10 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.3.1 // indirect - github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect - github.com/minio/highwayhash v1.0.2 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect - github.com/moricho/tparallel v0.3.1 // indirect - github.com/mtibben/percent v0.2.1 // indirect - github.com/nakabonne/nestif v0.3.1 // indirect - github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.9.5 // indirect - github.com/nishanths/predeclared v0.2.2 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc2 // indirect - github.com/opencontainers/runc v1.1.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect - github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.4.0 // indirect - github.com/prometheus/client_golang v1.15.1 - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/quasilyte/go-ruleguard v0.3.19 // indirect - github.com/quasilyte/gogrep v0.5.0 // indirect - github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect - github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect - github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/rs/cors v1.8.2 // indirect - github.com/rs/zerolog v1.27.0 // indirect - github.com/ryancurrah/gomodguard v1.3.0 // indirect - github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect - github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect - github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/securego/gosec/v2 v2.15.0 // indirect - github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/sivchari/containedctx v1.0.2 // indirect - github.com/sivchari/tenv v1.7.1 // indirect - github.com/sonatard/noctx v0.0.2 // indirect - github.com/sourcegraph/go-diff v0.7.0 // indirect - github.com/spf13/afero v1.9.5 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect - github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect - github.com/stretchr/objx v0.5.0 // indirect - github.com/subosito/gotenv v1.4.2 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tdakkota/asciicheck v0.2.0 // indirect - github.com/tendermint/btcd v0.1.1 // indirect - github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect - github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tetafro/godot v1.4.11 // indirect - github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect - github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect - github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect - github.com/ultraware/funlen v0.0.3 // indirect - github.com/ultraware/whitespace v0.0.5 // indirect - github.com/uudashr/gocognit v1.0.6 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/yagipy/maintidx v1.0.0 // indirect - github.com/yeya24/promlinter v0.2.0 // indirect - github.com/zimmski/go-tool v0.0.0-20150119110811-2dfdc9ac8439 // indirect - github.com/zimmski/osutil v0.0.0-20190128123334-0d0b3ca231ac // indirect - github.com/zondax/hid v0.9.1 // indirect - gitlab.com/bosi/decorder v0.2.3 // indirect - go.etcd.io/bbolt v1.3.6 // indirect - go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/tools v0.8.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 - honnef.co/go/tools v0.4.3 // indirect - mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect - mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect - mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect - nhooyr.io/websocket v1.8.7 // indirect -) - -replace ( - // osmosis-patched wasmd. - github.com/CosmWasm/wasmd => github.com/osmosis-labs/wasmd v0.31.0-osmo-v16 - // Security patch for wasmvm. See https://github.com/CosmWasm/advisories/blob/main/CWAs/CWA-2023-002.md - github.com/CosmWasm/wasmvm => github.com/CosmWasm/wasmvm v1.2.3 - // dragonberry - github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - // Our cosmos-sdk branch is: https://github.com/osmosis-labs/cosmos-sdk, current branch: v16.x. Direct commit link: https://github.com/osmosis-labs/cosmos-sdk/commit/93d9d4851b92bcbc1ede8c031ca1559b35ecc708 - github.com/cosmos/cosmos-sdk => github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230603004404-93d9d4851b92 - - // N.B. v0.19.5 contains a breaking change to the IAVL API - github.com/cosmos/iavl v0.19.5 => github.com/cosmos/iavl v0.19.4 - // use cosmos-compatible protobufs - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - - // Informal Tendermint fork - github.com/tendermint/tendermint => github.com/informalsystems/tendermint v0.34.24 - // use grpc compatible with cosmos protobufs - google.golang.org/grpc => google.golang.org/grpc v1.33.2 -) diff --git a/andromeda-core/ci-scripts/localrelayer/go.sum b/andromeda-core/ci-scripts/localrelayer/go.sum deleted file mode 100644 index d8f5b47..0000000 --- a/andromeda-core/ci-scripts/localrelayer/go.sum +++ /dev/null @@ -1,1855 +0,0 @@ -4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= -4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= -4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= -4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -cosmossdk.io/errors v1.0.0-beta.7 h1:gypHW76pTQGVnHKo6QBkb4yFOJjC+sUGRc5Al3Odj1w= -cosmossdk.io/errors v1.0.0-beta.7/go.mod h1:mz6FQMJRku4bY7aqS/Gwfcmr/ue91roMEKAmDUDpBfE= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= -filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= -git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= -github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= -github.com/99designs/keyring v1.2.1/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= -github.com/Abirdcfly/dupword v0.0.11 h1:z6v8rMETchZXUIuHxYNmlUAuKuB21PeaSymTed16wgU= -github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA= -github.com/Antonboom/errname v0.1.9 h1:BZDX4r3l4TBZxZ2o2LNrlGxSHran4d1u4veZdoORTT4= -github.com/Antonboom/errname v0.1.9/go.mod h1:nLTcJzevREuAsgTbG85UsuiWpMpAqbKD1HNZ29OzE58= -github.com/Antonboom/nilnil v0.1.3 h1:6RTbx3d2mcEu3Zwq9TowQpQMVpP75zugwOtqY1RTtcE= -github.com/Antonboom/nilnil v0.1.3/go.mod h1:iOov/7gRcXkeEU+EMGpBu2ORih3iyVEiWjeste1SJm8= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= -github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4= -github.com/CosmWasm/wasmvm v1.2.3 h1:OKYlobwmVGbl0eSn0mXoAAjE5hIuXnQCLPjbNd91sVY= -github.com/CosmWasm/wasmvm v1.2.3/go.mod h1:vW/E3h8j9xBQs9bCoijDuawKo9kCtxOaS8N8J7KFtkc= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Djarvur/go-err113 v0.1.0 h1:uCRZZOdMQ0TZPHYTdYpoC0bLYJKPEHPUJ8MeAa51lNU= -github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= -github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= -github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= -github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA= -github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= -github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= -github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= -github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= -github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= -github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/ashanbrown/forbidigo v1.5.1 h1:WXhzLjOlnuDYPYQo/eFlcFMi8X/kLfvWLYu6CSoebis= -github.com/ashanbrown/forbidigo v1.5.1/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= -github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= -github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= -github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= -github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= -github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= -github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= -github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= -github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= -github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= -github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= -github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU= -github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= -github.com/breml/bidichk v0.2.4 h1:i3yedFWWQ7YzjdZJHnPo9d/xURinSq3OM+gyM43K4/8= -github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s= -github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjoxQ= -github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= -github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= -github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd v0.22.3 h1:kYNaWFvOw6xvqP0vR20RP1Zq1DVMBxEO8QN5d1/EfNg= -github.com/btcsuite/btcd v0.22.3/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= -github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= -github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= -github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= -github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= -github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= -github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 h1:W9o46d2kbNL06lq7UNDPV0zYLzkrde/bjIqO02eoll0= -github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= -github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= -github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= -github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/bavard v0.1.8-0.20210915155054-088da2f7f54a/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= -github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= -github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.2 h1:X3OKvWgK9Gsejo0F1qs5l8Qn6xJV/AzgIWR2wZ8Nua8= -github.com/cosmos/cosmos-proto v1.0.0-beta.2/go.mod h1:+XRCLJ14pr5HFEHIUcn51IKXD1Fy3rkEQqt4WqmN4V0= -github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 h1:iKclrn3YEOwk4jQHT2ulgzuXyxmzmPczUalMwW4XH9k= -github.com/cosmos/cosmos-sdk/ics23/go v0.8.0/go.mod h1:2a4dBq88TUoqoWAU5eu0lGvpFP3wWDPgdHPargtyw30= -github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= -github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= -github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= -github.com/cosmos/gogoproto v1.4.6 h1:Ee7z15dWJaGlgM2rWrK8N2IX7PQcuccu8oG68jp5RL4= -github.com/cosmos/gogoproto v1.4.6/go.mod h1:VS/ASYmPgv6zkPKLjR9EB91lwbLHOzaGCirmKKhncfI= -github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= -github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.4 h1:t82sN+Y0WeqxDLJRSpNd8YFX5URIrT+p8n6oJbJ2Dok= -github.com/cosmos/iavl v0.19.4/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-apps/modules/async-icq/v4 v4.0.0-20230524151648-c02fa46c2860 h1:25/KpA4WJqdFjKFsa3VEL0ctWRovkEsqIn2phCAi9v0= -github.com/cosmos/ibc-apps/modules/async-icq/v4 v4.0.0-20230524151648-c02fa46c2860/go.mod h1:X/dLZ6QxTImzno7qvD6huLhh6ZZBcRt2URn4YCLcXFY= -github.com/cosmos/ibc-go/v4 v4.3.1 h1:xbg0CaCdxK3lvgGvSaI91ROOLd7s30UqEcexH6Ba4Ys= -github.com/cosmos/ibc-go/v4 v4.3.1/go.mod h1:89E+K9CxpkS/etLEcG026jPM/RSnVMcfesvRYp/0aKI= -github.com/cosmos/interchain-accounts v0.2.6 h1:TV2M2g1/Rb9MCNw1YePdBKE0rcEczNj1RGHT+2iRYas= -github.com/cosmos/ledger-cosmos-go v0.12.2 h1:/XYaBlE2BJxtvpkHiBm97gFGSGmYGKunKyF3nNqAXZA= -github.com/cosmos/ledger-cosmos-go v0.12.2/go.mod h1:ZcqYgnfNJ6lAXe4HPtWgarNEY+B74i+2/8MhZw4ziiI= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= -github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= -github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= -github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/daixiang0/gci v0.10.1 h1:eheNA3ljF6SxnPD/vE4lCBusVHmV3Rs3dkKvFrJ7MR0= -github.com/daixiang0/gci v0.10.1/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI= -github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= -github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= -github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= -github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= -github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= -github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= -github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= -github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= -github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= -github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= -github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE= -github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac h1:opbrjaN/L8gg6Xh5D04Tem+8xVcz6ajZlGCs49mQgyg= -github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= -github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= -github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= -github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= -github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= -github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= -github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= -github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-critic/go-critic v0.7.0 h1:tqbKzB8pqi0NsRZ+1pyU4aweAF7A7QN0Pi4Q02+rYnQ= -github.com/go-critic/go-critic v0.7.0/go.mod h1:moYzd7GdVXE2C2hYTwd7h0CPcqlUeclsyBRwMa38v64= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= -github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= -github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= -github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= -github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= -github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= -github.com/go-toolsmith/astequal v1.1.0 h1:kHKm1AWqClYn15R0K1KKE4RG614D46n+nqUQ06E1dTw= -github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= -github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= -github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= -github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= -github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= -github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= -github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= -github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= -github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= -github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= -github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= -github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= -github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= -github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= -github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= -github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo= -github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= -github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= -github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.52.2 h1:FrPElUUI5rrHXg1mQ7KxI1MXPAw5lBVskiz7U7a8a1A= -github.com/golangci/golangci-lint v1.52.2/go.mod h1:S5fhC5sHM5kE22/HcATKd1XLWQxX+y7mHj8B5H91Q/0= -github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.4.0 h1:KtVB/hTK4bbL/S6bs64rYyk8adjmh1BygbBiaAiX+a0= -github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= -github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U= -github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= -github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= -github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= -github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= -github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= -github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= -github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= -github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= -github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= -github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= -github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= -github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= -github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= -github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= -github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= -github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= -github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= -github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= -github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= -github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= -github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= -github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/informalsystems/tendermint v0.34.24 h1:2beNEg5tp+U5oj/Md+0xDBsMHGbdue31T3OrstS6xS0= -github.com/informalsystems/tendermint v0.34.24/go.mod h1:rXVrl4OYzmIa1I91av3iLv2HS0fGSiucyW9J4aMTpKI= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= -github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= -github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= -github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= -github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= -github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= -github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/junk1tm/musttag v0.5.0 h1:bV1DTdi38Hi4pG4OVWa7Kap0hi0o7EczuK6wQt9zPOM= -github.com/junk1tm/musttag v0.5.0/go.mod h1:PcR7BA+oREQYvHwgjIDmw3exJeds5JzRcvEJTfjrA0M= -github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8= -github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= -github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= -github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= -github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= -github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= -github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= -github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.4.0 h1:sylp7d9kh6AdXN2DpVGHBRb5guTVAgOxqNGhbqc4b1c= -github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= -github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= -github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= -github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= -github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= -github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= -github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= -github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= -github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= -github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= -github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= -github.com/mattn/goveralls v0.0.3/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= -github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/revive v1.3.1 h1:OlQkcH40IB2cGuprTPcjB0iIUddgVZgGmDX3IAMR8D4= -github.com/mgechev/revive v1.3.1/go.mod h1:YlD6TTWl2B8A103R9KWJSPVI9DrEf+oqr15q21Ld+5I= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= -github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= -github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= -github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= -github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= -github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= -github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= -github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= -github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.9.5 h1:TzssWan6orBiLYVqewCG8faud9qlFntJE30ACpzmGME= -github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= -github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= -github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.9.0 h1:Sm0zX5QfjJzkeCjEp+t6d3Ha0jwvoDjleP9XCsrEzOA= -github.com/nunnatsa/ginkgolinter v0.9.0/go.mod h1:FHaMLURXP7qImeH6bvxWJUpyH+2tuqe5j4rW1gxJRmI= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI= -github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= -github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= -github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= -github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= -github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg= -github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230603004404-93d9d4851b92 h1:BedgZf5yT5jYTrYsUJc7JF+4PXw2P/W0uuXHdG7MNho= -github.com/osmosis-labs/cosmos-sdk v0.45.1-0.20230603004404-93d9d4851b92/go.mod h1:9KGhMg+7ZWgZ50Wa/x8w/jN19O0TSqYLlqUj+2wwxLU= -github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 h1:YlmchqTmlwdWSmrRmXKR+PcU96ntOd8u10vTaTZdcNY= -github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI= -github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230516205127-c213fddde069 h1:ZgDrTJ2GCH4CJGbV6rudw4O9rPMAuwWoLVZnG6cUr+A= -github.com/osmosis-labs/osmosis/osmomath v0.0.3-dev.0.20230516205127-c213fddde069/go.mod h1:a7lhiXRpn8QJ21OhFpaEnUNErTSIafaYpp02q6uI/Dk= -github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230608190634-3395abe098ce h1:RulJTKTrptrWjWb84wyNGTxoVnXcwIzEAl6cK0bBImc= -github.com/osmosis-labs/osmosis/osmoutils v0.0.0-20230608190634-3395abe098ce/go.mod h1:FqFOfj9+e5S1I7hR3baGUHrqje3g32EOHAXoOf7R00M= -github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304 h1:RIrWLzIiZN5Xd2JOfSOtGZaf6V3qEQYg6EaDTAkMnCo= -github.com/osmosis-labs/osmosis/x/epochs v0.0.0-20230328024000-175ec88e4304/go.mod h1:yPWoJTj5RKrXKUChAicp+G/4Ni/uVEpp27mi/FF/L9c= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230602130523-f9a94d8bbd10 h1:XrES5AHZMZ/Y78boW35PTignkhN9h8VvJ1sP8EJDIu8= -github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.0-20230602130523-f9a94d8bbd10/go.mod h1:Ln6CKcXg/CJLSBE6Fd96/MIKPyA4iHuQTKSbl9q7vYo= -github.com/osmosis-labs/wasmd v0.31.0-osmo-v16 h1:X747cZYdnqc/+RV48iPVeGprpVb/fUWSaKGsZUWrdbg= -github.com/osmosis-labs/wasmd v0.31.0-osmo-v16/go.mod h1:Rf8zW/GgBQyFRRB4s62VQHWA6sTlMFSjoDQQpoq64iI= -github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= -github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= -github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= -github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.4.0 h1:b+sQ5HibPIAjEZwtuwU8Wz/u0dMZ7YL+bk+9yWyHVJk= -github.com/polyfloyd/go-errorlint v1.4.0/go.mod h1:qJCkPeBn+0EXkdKTrUCcuFStM2xrDKfxI3MGLXPexUs= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quasilyte/go-ruleguard v0.3.19 h1:tfMnabXle/HzOb5Xe9CUZYWXKfkS1KwRmZyPmD9nVcc= -github.com/quasilyte/go-ruleguard v0.3.19/go.mod h1:lHSn69Scl48I7Gt9cX3VrbsZYvYiBYszZOZW4A+oTEw= -github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= -github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= -github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= -github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= -github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= -github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= -github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= -github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= -github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= -github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= -github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= -github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= -github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw= -github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= -github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= -github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= -github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= -github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= -github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= -github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1jbEOPrEhDzGYq0= -github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/securego/gosec/v2 v2.15.0 h1:v4Ym7FF58/jlykYmmhZ7mTm7FQvN/setNm++0fgIAtw= -github.com/securego/gosec/v2 v2.15.0/go.mod h1:VOjTrZOkUtSDt2QLSJmQBMWnvwiQPEjg0l+5juIqGk8= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= -github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= -github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= -github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= -github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= -github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= -github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= -github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= -github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= -github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= -github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5 h1:KKUqeGhVBK38+1LwThC8IeIcsJZ6COX5kvhiJroFqCM= -github.com/strangelove-ventures/packet-forward-middleware/v4 v4.0.5/go.mod h1:4zAtg449/JISRmf+sbmqolqSLP+QJBh+EtWkWtt/AKE= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= -github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= -github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= -github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= -github.com/tendermint/btcd v0.1.1 h1:0VcxPfflS2zZ3RiOAHkBiFUcPvbtRj5O7zHmcJWHV7s= -github.com/tendermint/btcd v0.1.1/go.mod h1:DC6/m53jtQzr/NFmMNEu0rxf18/ktVoVtMrnDD5pN+U= -github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RMWx1aInLzndwxKalgi5rTqgfXxOxbEI= -github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= -github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= -github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b h1:Y3ZPG6gdDCAV2sdGkD759ji/09GzaNu1X3qKTmZIbTo= -github.com/tendermint/tm-db v0.6.8-0.20220506192307-f628bb5dc95b/go.mod h1:ADqbS9NOSnBRK9R2RtYC61CdsHmVMD/yXAzcMuPexbU= -github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= -github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= -github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= -github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= -github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= -github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/tidwall/btree v1.6.0 h1:LDZfKfQIBHGHWSwckhXI0RPSXzlo+KYdjK7FWSqOzzg= -github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= -github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= -github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= -github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e h1:MV6KaVu/hzByHP0UvJ4HcMGE/8a6A4Rggc/0wx2AvJo= -github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= -github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= -github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomarrell/wrapcheck/v2 v2.8.1 h1:HxSqDSN0sAt0yJYsrcYVoEeyM4aI9yAm3KQpIXDJRhQ= -github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= -github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= -github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= -github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= -github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= -github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= -github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= -github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= -github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= -github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= -github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= -github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zimmski/go-mutesting v0.0.0-20210610104036-6d9217011a00 h1:KNiPkpQpqXvq40f8hh/1T7QasLJT/1MuBoOYA2vlxJk= -github.com/zimmski/go-mutesting v0.0.0-20210610104036-6d9217011a00/go.mod h1:RJt5SMnyha63GbdwCKJiX9djvvEC4KsfXJSZ5oTmSPw= -github.com/zimmski/go-tool v0.0.0-20150119110811-2dfdc9ac8439 h1:yHqsjUkj0HWbKPw/6ZqC0/eMklaRpqubA199vaRLzzE= -github.com/zimmski/go-tool v0.0.0-20150119110811-2dfdc9ac8439/go.mod h1:G4FVqCRvfz74AEB1crDNdQuvMfOoKtk7DlePsnV2yGs= -github.com/zimmski/osutil v0.0.0-20190128123334-0d0b3ca231ac h1:uiFRlKzyIzHeLOthe0ethUkSGW7POlqxU3Tc21R8QpQ= -github.com/zimmski/osutil v0.0.0-20190128123334-0d0b3ca231ac/go.mod h1:wJ9WGevuM/rw8aB2pQPFMUgXZWeaouI0ueFamR0DUPE= -github.com/zondax/hid v0.9.1 h1:gQe66rtmyZ8VeGFcOpbuH3r7erYtNEAezCAYu8LdkJo= -github.com/zondax/hid v0.9.1/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.1 h1:Pip65OOl4iJ84WTpA4BKChvOufMhhbxED3BaihoZN4c= -github.com/zondax/ledger-go v0.14.1/go.mod h1:fZ3Dqg6qcdXWSOJFKMG8GCTnD7slO/RL2feOQv8K320= -gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= -gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 h1:BEABXpNXLEz0WxtA+6CQIz2xkg80e+1zrhWyMcq8VzE= -golang.org/x/exp v0.0.0-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 h1:J74nGeMgeFnYQJN59eFwh06jX/V8g0lB7LWpjSLxtgU= -golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191018212557-ed542cd5b28a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= -golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= -golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= -honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= -mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= -mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w= -mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/andromeda-core/ci-scripts/localrelayer/go.work b/andromeda-core/ci-scripts/localrelayer/go.work deleted file mode 100644 index df8f616..0000000 --- a/andromeda-core/ci-scripts/localrelayer/go.work +++ /dev/null @@ -1,15 +0,0 @@ -go 1.20 - -use ./osmomath - -use ./osmoutils - -use ./x/ibc-hooks - -use ./tests/cl-go-client - -use ./tests/cl-genesis-positions - -use . - -use ./x/epochs diff --git a/andromeda-core/ci-scripts/localrelayer/scripts/setup_chain.sh b/andromeda-core/ci-scripts/localrelayer/scripts/setup_chain.sh deleted file mode 100755 index 2930071..0000000 --- a/andromeda-core/ci-scripts/localrelayer/scripts/setup_chain.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/sh -set -eo pipefail - -DEFAULT_CHAIN_ID="localosmosis" -DEFAULT_VALIDATOR_MONIKER="validator" -DEFAULT_VALIDATOR_MNEMONIC="bottom loan skill merry east cradle onion journey palm apology verb edit desert impose absurd oil bubble sweet glove shallow size build burst effort" -DEFAULT_FAUCET_MNEMONIC="increase bread alpha rigid glide amused approve oblige print asset idea enact lawn proof unfold jeans rabbit audit return chuckle valve rather cactus great" -DEFAULT_RELAYER_MNEMONIC="black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken" - -# Override default values with environment variables -CHAIN_ID=${CHAIN_ID:-$DEFAULT_CHAIN_ID} -VALIDATOR_MONIKER=${VALIDATOR_MONIKER:-$DEFAULT_VALIDATOR_MONIKER} -VALIDATOR_MNEMONIC=${VALIDATOR_MNEMONIC:-$DEFAULT_VALIDATOR_MNEMONIC} -FAUCET_MNEMONIC=${FAUCET_MNEMONIC:-$DEFAULT_FAUCET_MNEMONIC} -RELAYER_MNEMONIC=${RELAYER_MNEMONIC:-$DEFAULT_RELAYER_MNEMONIC} - -OSMOSIS_HOME=$HOME/.osmosisd -CONFIG_FOLDER=$OSMOSIS_HOME/config - -install_prerequisites () { - apk add dasel -} - -edit_genesis () { - - GENESIS=$CONFIG_FOLDER/genesis.json - - # Update staking module - dasel put string -f $GENESIS '.app_state.staking.params.bond_denom' 'uosmo' - dasel put string -f $GENESIS '.app_state.staking.params.unbonding_time' '240s' - - # Update crisis module - dasel put string -f $GENESIS '.app_state.crisis.constant_fee.denom' 'uosmo' - - # Udpate gov module - dasel put string -f $GENESIS '.app_state.gov.voting_params.voting_period' '60s' - dasel put string -f $GENESIS '.app_state.gov.deposit_params.min_deposit.[0].denom' 'uosmo' - - # Update epochs module - dasel put string -f $GENESIS '.app_state.epochs.epochs.[1].duration' "60s" - - # Update poolincentives module - dasel put string -f $GENESIS '.app_state.poolincentives.lockable_durations.[0]' "120s" - dasel put string -f $GENESIS '.app_state.poolincentives.lockable_durations.[1]' "180s" - dasel put string -f $GENESIS '.app_state.poolincentives.lockable_durations.[2]' "240s" - dasel put string -f $GENESIS '.app_state.poolincentives.params.minted_denom' "uosmo" - - # Update incentives module - dasel put string -f $GENESIS '.app_state.incentives.lockable_durations.[0]' "1s" - dasel put string -f $GENESIS '.app_state.incentives.lockable_durations.[1]' "120s" - dasel put string -f $GENESIS '.app_state.incentives.lockable_durations.[2]' "180s" - dasel put string -f $GENESIS '.app_state.incentives.lockable_durations.[3]' "240s" - dasel put string -f $GENESIS '.app_state.incentives.params.distr_epoch_identifier' "day" - - # Update mint module - dasel put string -f $GENESIS '.app_state.mint.params.mint_denom' "uosmo" - dasel put string -f $GENESIS '.app_state.mint.params.epoch_identifier' "day" - - # Update gamm module - dasel put string -f $GENESIS '.app_state.gamm.params.pool_creation_fee.[0].denom' "uosmo" - - # Update txfee basedenom - dasel put string -f $GENESIS '.app_state.txfees.basedenom' "uosmo" - - # Update wasm permission (Nobody or Everybody) - dasel put string -f $GENESIS '.app_state.wasm.params.code_upload_access.permission' "Everybody" -} - -add_genesis_accounts () { - - # Validator - echo "⚖️ Add validator account" - echo $VALIDATOR_MNEMONIC | osmosisd keys add $VALIDATOR_MONIKER --recover --keyring-backend=test --home $OSMOSIS_HOME - VALIDATOR_ACCOUNT=$(osmosisd keys show -a $VALIDATOR_MONIKER --keyring-backend test --home $OSMOSIS_HOME) - osmosisd add-genesis-account $VALIDATOR_ACCOUNT 100000000000uosmo,100000000000uion,100000000000stake --home $OSMOSIS_HOME - - # Faucet - echo "🚰 Add faucet account" - echo $FAUCET_MNEMONIC | osmosisd keys add faucet --recover --keyring-backend=test --home $OSMOSIS_HOME - FAUCET_ACCOUNT=$(osmosisd keys show -a faucet --keyring-backend test --home $OSMOSIS_HOME) - osmosisd add-genesis-account $FAUCET_ACCOUNT 100000000000uosmo,100000000000uion,100000000000stake --home $OSMOSIS_HOME - - # Relayer - echo "🔗 Add relayer account" - echo $RELAYER_MNEMONIC | osmosisd keys add relayer --recover --keyring-backend=test --home $OSMOSIS_HOME - RELAYER_ACCOUNT=$(osmosisd keys show -a relayer --keyring-backend test --home $OSMOSIS_HOME) - osmosisd add-genesis-account $RELAYER_ACCOUNT 1000000000uosmo,1000000000uion,1000000000stake --home $OSMOSIS_HOME - - osmosisd gentx $VALIDATOR_MONIKER 500000000uosmo --keyring-backend=test --chain-id=$CHAIN_ID --home $OSMOSIS_HOME - osmosisd collect-gentxs --home $OSMOSIS_HOME -} - -edit_config () { - # Remove seeds - dasel put string -f $CONFIG_FOLDER/config.toml '.p2p.seeds' '' - - # Expose the rpc - dasel put string -f $CONFIG_FOLDER/config.toml '.rpc.laddr' "tcp://0.0.0.0:26657" - - dasel put string -f $CONFIG_FOLDER/config.toml '.consensus.timeout_commit' "1000ms" -} - -if [[ ! -d $CONFIG_FOLDER ]] -then - install_prerequisites - echo "🧪 Creating Osmosis home for $VALIDATOR_MONIKER" - echo $VALIDATOR_MNEMONIC | osmosisd init -o --chain-id=$CHAIN_ID --home $OSMOSIS_HOME --recover $VALIDATOR_MONIKER - edit_genesis - add_genesis_accounts - edit_config -fi - -echo "🏁 Starting $CHAIN_ID..." -osmosisd start --home $OSMOSIS_HOME diff --git a/andromeda-core/ci-scripts/localrelayer/scripts/setup_hermes.sh b/andromeda-core/ci-scripts/localrelayer/scripts/setup_hermes.sh deleted file mode 100755 index 5bd17b2..0000000 --- a/andromeda-core/ci-scripts/localrelayer/scripts/setup_hermes.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -set -e - -DEFAULT_CHAIN_A_ID="localosmosis-a" -DEFAULT_CHAIN_A_MNEMONIC="black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken" -DEFAULT_CHAIN_B_ID="localosmosis-b" -DEFAULT_CHAIN_B_MNEMONIC="black frequent sponsor nice claim rally hunt suit parent size stumble expire forest avocado mistake agree trend witness lounge shiver image smoke stool chicken" - -CHAIN_A_MNEMONIC=${CHAIN_A_MNEMONIC:-$DEFAULT_CHAIN_A_MNEMONIC} -CHAIN_A_ID=${CHAIN_A_ID:-$DEFAULT_CHAIN_A_ID} -CHAIN_B_MNEMONIC=${CHAIN_B_MNEMONIC:-$DEFAULT_CHAIN_B_MNEMONIC} -CHAIN_B_ID=${CHAIN_B_ID:-$DEFAULT_CHAIN_B_ID} - -install_prerequisites(){ - echo "🧰 Install prerequisites" - apt update - apt -y install curl -} - -add_keys(){ - - echo "🔑 Adding key for $CHAIN_A_ID" - mkdir -p /home/hermes/mnemonics/ - echo $CHAIN_A_MNEMONIC > /home/hermes/mnemonics/$CHAIN_A_ID - - hermes keys add \ - --chain $CHAIN_A_ID \ - --mnemonic-file /home/hermes/mnemonics/$CHAIN_A_ID \ - --key-name $CHAIN_A_ID \ - --overwrite - - echo "🔑 Adding key for $CHAIN_B_ID" - echo $CHAIN_B_MNEMONIC > /home/hermes/mnemonics/$CHAIN_B_ID - - hermes keys add \ - --chain $CHAIN_B_ID \ - --mnemonic-file /home/hermes/mnemonics/$CHAIN_B_ID \ - --key-name $CHAIN_B_ID \ - --overwrite -} - -create_channel(){ - echo "🥱 Waiting for $CHAIN_A_ID to start" - COUNTER=0 - until $(curl --output /dev/null --silent --head --fail http://$CHAIN_A_ID:26657/status); do - printf '.' - sleep 2 - done - - echo "🥱 Waiting for $CHAIN_B_ID to start" - COUNTER=0 - until $(curl --output /dev/null --silent --head --fail http://$CHAIN_B_ID:26657/status); do - printf '.' - sleep 5 - done - - echo "📺 Creating channel $CHAIN_A_ID <> $CHAIN_B_ID" - hermes create channel \ - --a-chain $CHAIN_A_ID \ - --b-chain $CHAIN_B_ID \ - --a-port transfer \ - --b-port transfer \ - --new-client-connection --yes -} - -install_prerequisites -add_keys -create_channel - -echo "✉️ Start Hermes" -hermes start diff --git a/andromeda-core/contracts/app/andromeda-app-contract/Cargo.toml b/andromeda-core/contracts/app/andromeda-app-contract/Cargo.toml index fc6916b..892376d 100644 --- a/andromeda-core/contracts/app/andromeda-app-contract/Cargo.toml +++ b/andromeda-core/contracts/app/andromeda-app-contract/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-app-contract" -version = "0.2.1" +version = "1.1.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -13,18 +13,14 @@ crate-type = ["cdylib", "rlib"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } -andromeda-app = { path = "../../../packages/andromeda-app" } -andromeda-std = { workspace = true, features = ["instantiate"] } +andromeda-app = { workspace = true } +andromeda-std = { workspace = true } enum-repr = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } -andromeda-testing = { workspace = true } +andromeda-testing = { workspace = true, optional = true } -[dev-dependencies] -prost = "0.9" [features] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] diff --git a/andromeda-core/contracts/app/andromeda-app-contract/README.md b/andromeda-core/contracts/app/andromeda-app-contract/README.md new file mode 100644 index 0000000..0e3d80f --- /dev/null +++ b/andromeda-core/contracts/app/andromeda-app-contract/README.md @@ -0,0 +1,6 @@ +# Overview + +The App ADO is a smart contract that is used to bundle up ADOs that will be interacting with each other into what we call an "App". It also offers a naming system that allows the contracts to reference each other by their assigned names rather than contract addresses. +An ADO in the App is called an AppComponent. Every App would be composed of many of these components (up to 50). Each component is assigned a name which can be used by other components to reference each other. The App ADO allows us to instantiate all of these components in one go. + +[App Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/app) diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/andromeda-app-contract.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/andromeda-app-contract.json deleted file mode 100644 index 71ed5b9..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/andromeda-app-contract.json +++ /dev/null @@ -1,2025 +0,0 @@ -{ - "contract_name": "andromeda-app-contract", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "app_components", - "kernel_address", - "name" - ], - "properties": { - "app_components": { - "type": "array", - "items": { - "$ref": "#/definitions/AppComponent" - } - }, - "chain_info": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/ChainInfo" - } - }, - "kernel_address": { - "type": "string" - }, - "name": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AppComponent": { - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "ChainInfo": { - "type": "object", - "required": [ - "chain_name", - "owner" - ], - "properties": { - "chain_name": { - "type": "string" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "add_app_component" - ], - "properties": { - "add_app_component": { - "type": "object", - "required": [ - "component" - ], - "properties": { - "component": { - "$ref": "#/definitions/AppComponent" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "claim_ownership" - ], - "properties": { - "claim_ownership": { - "type": "object", - "properties": { - "name": { - "type": [ - "string", - "null" - ] - }, - "new_owner": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "proxy_message" - ], - "properties": { - "proxy_message": { - "type": "object", - "required": [ - "msg", - "name" - ], - "properties": { - "msg": { - "$ref": "#/definitions/Binary" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_address" - ], - "properties": { - "update_address": { - "type": "object", - "required": [ - "addr", - "name" - ], - "properties": { - "addr": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "assign_app_to_components" - ], - "properties": { - "assign_app_to_components": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AppComponent": { - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "get_address" - ], - "properties": { - "get_address": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_components" - ], - "properties": { - "get_components": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "component_exists" - ], - "properties": { - "component_exists": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_addresses_with_names" - ], - "properties": { - "get_addresses_with_names": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "component_exists": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ComponentExistsResponse", - "type": "object", - "required": [ - "component_exists" - ], - "properties": { - "component_exists": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConfigResponse", - "type": "object", - "required": [ - "name", - "owner" - ], - "properties": { - "name": { - "type": "string" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "get_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "String", - "type": "string" - }, - "get_addresses_with_names": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_AppComponent", - "type": "array", - "items": { - "$ref": "#/definitions/AppComponent" - }, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AppComponent": { - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - } - }, - "get_components": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AppComponent", - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/execute.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/execute.json deleted file mode 100644 index 2e6283f..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/execute.json +++ /dev/null @@ -1,797 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "add_app_component" - ], - "properties": { - "add_app_component": { - "type": "object", - "required": [ - "component" - ], - "properties": { - "component": { - "$ref": "#/definitions/AppComponent" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "claim_ownership" - ], - "properties": { - "claim_ownership": { - "type": "object", - "properties": { - "name": { - "type": [ - "string", - "null" - ] - }, - "new_owner": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "proxy_message" - ], - "properties": { - "proxy_message": { - "type": "object", - "required": [ - "msg", - "name" - ], - "properties": { - "msg": { - "$ref": "#/definitions/Binary" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_address" - ], - "properties": { - "update_address": { - "type": "object", - "required": [ - "addr", - "name" - ], - "properties": { - "addr": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "assign_app_to_components" - ], - "properties": { - "assign_app_to_components": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AppComponent": { - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/instantiate.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/instantiate.json deleted file mode 100644 index 8934f07..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/instantiate.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "app_components", - "kernel_address", - "name" - ], - "properties": { - "app_components": { - "type": "array", - "items": { - "$ref": "#/definitions/AppComponent" - } - }, - "chain_info": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/ChainInfo" - } - }, - "kernel_address": { - "type": "string" - }, - "name": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AppComponent": { - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "ChainInfo": { - "type": "object", - "required": [ - "chain_name", - "owner" - ], - "properties": { - "chain_name": { - "type": "string" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/query.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/query.json deleted file mode 100644 index 933c265..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/query.json +++ /dev/null @@ -1,478 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "get_address" - ], - "properties": { - "get_address": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_components" - ], - "properties": { - "get_components": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "component_exists" - ], - "properties": { - "component_exists": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_addresses_with_names" - ], - "properties": { - "get_addresses_with_names": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_balance.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_component_exists.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_component_exists.json deleted file mode 100644 index 43114e4..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_component_exists.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ComponentExistsResponse", - "type": "object", - "required": [ - "component_exists" - ], - "properties": { - "component_exists": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_config.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_config.json deleted file mode 100644 index caa7462..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_config.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConfigResponse", - "type": "object", - "required": [ - "name", - "owner" - ], - "properties": { - "name": { - "type": "string" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get.json deleted file mode 100644 index a2e5afd..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_Binary", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_address.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_address.json deleted file mode 100644 index f689ace..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_address.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "String", - "type": "string" -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_addresses_with_names.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_addresses_with_names.json deleted file mode 100644 index b727b5e..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_addresses_with_names.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_AppComponent", - "type": "array", - "items": { - "$ref": "#/definitions/AppComponent" - }, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AppComponent": { - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_components.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_components.json deleted file mode 100644 index b44f6e4..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_get_components.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AppComponent", - "type": "object", - "required": [ - "ado_type", - "component_type", - "name" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "component_type": { - "$ref": "#/definitions/ComponentType" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "ComponentType": { - "oneOf": [ - { - "type": "object", - "required": [ - "new" - ], - "properties": { - "new": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "symlink" - ], - "properties": { - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cross_chain" - ], - "properties": { - "cross_chain": { - "$ref": "#/definitions/CrossChainComponent" - } - }, - "additionalProperties": false - } - ] - }, - "CrossChainComponent": { - "type": "object", - "required": [ - "chain", - "instantiate_msg" - ], - "properties": { - "chain": { - "type": "string" - }, - "instantiate_msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_operators.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_owner.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissions.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_type.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_version.json b/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/app/andromeda-app-contract/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/src/contract.rs b/andromeda-core/contracts/app/andromeda-app-contract/src/contract.rs index 626f783..49f3ef6 100644 --- a/andromeda-core/contracts/app/andromeda-app-contract/src/contract.rs +++ b/andromeda-core/contracts/app/andromeda-app-contract/src/contract.rs @@ -1,28 +1,23 @@ -use crate::reply::{on_component_instantiation, ReplyId}; -use crate::state::{create_cross_chain_message, get_chain_info, APP_NAME}; -use andromeda_app::app::{ - AppComponent, ComponentType, CrossChainComponent, ExecuteMsg, InstantiateMsg, MigrateMsg, - QueryMsg, -}; +use crate::reply::on_component_instantiation; +use crate::state::{add_app_component, create_cross_chain_message, ADO_ADDRESSES, APP_NAME}; +use andromeda_app::app::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::ado_contract::ADOContract; use andromeda_std::amp::AndrAddr; use andromeda_std::common::context::ExecuteContext; +use andromeda_std::common::reply::ReplyId; use andromeda_std::os::vfs::{convert_component_name, ExecuteMsg as VFSExecuteMsg}; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, - common::encode_binary, - error::{from_semver, ContractError}, + ado_base::InstantiateMsg as BaseInstantiateMsg, ado_base::MigrateMsg, common::encode_binary, + error::ContractError, }; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure, to_json_binary, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Reply, - Response, StdError, SubMsg, WasmMsg, + ensure, wasm_execute, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, + SubMsg, }; -use cw2::{get_contract_version, set_contract_version}; use crate::{execute, query}; -use semver::Version; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-app-contract"; @@ -35,7 +30,6 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; APP_NAME.save(deps.storage, &msg.name)?; ensure!( @@ -49,94 +43,105 @@ pub fn instantiate( deps.storage, env.clone(), deps.api, + &deps.querier, info.clone(), BaseInstantiateMsg { - ado_type: "app-contract".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address.clone(), owner: msg.owner.clone(), }, )? - .add_attribute("owner", &msg.owner.clone().unwrap_or(sender.clone())) .add_attribute("andr_app", msg.name.clone()); - let mut msgs: Vec = vec![]; - let app_name = msg.name; + let vfs_address = ADOContract::default().get_vfs_address(deps.storage, &deps.querier)?; + let adodb_addr = ADOContract::default().get_adodb_address(deps.storage, &deps.querier)?; + + let mut vfs_msgs: Vec = vec![]; + for component in msg.app_components.clone() { + ensure!( + !ADO_ADDRESSES.has(deps.storage, &component.name), + ContractError::NameAlreadyTaken {} + ); component.verify(&deps.as_ref()).unwrap(); - match component.component_type { - ComponentType::CrossChain(CrossChainComponent { chain, .. }) => { - let chain_info = get_chain_info(chain.clone(), msg.chain_info.clone()); - ensure!( - chain_info.is_some(), - ContractError::InvalidComponent { - name: component.name.clone() - } - ); - let owner_addr = chain_info.unwrap().owner; - let name = component.name; - let new_component = AppComponent { - name: name.clone(), - ado_type: component.ado_type, - component_type: ComponentType::Symlink(AndrAddr::from_string(format!( - "ibc://{chain}/home/{owner_addr}/{app_name}/{name}" - ))), - }; - let comp_resp = execute::handle_add_app_component( - &deps.querier, - deps.storage, - &sender, - new_component, - )?; - msgs.extend(comp_resp.messages); - } - _ => { - let comp_resp = execute::handle_add_app_component( - &deps.querier, - deps.storage, - &sender, - component, - )?; - msgs.extend(comp_resp.messages); - } + + // Generate addresses and store expected address in state + let new_addr = component.get_new_addr( + deps.api, + &adodb_addr, + &deps.querier, + env.contract.address.clone(), + )?; + ADO_ADDRESSES.save( + deps.storage, + &component.name, + &new_addr.clone().unwrap_or(Addr::unchecked("")), + )?; + + // Register components with VFS + // Sub message is optional as component may be hidden (Starts with a '.') + let register_submsg = component.generate_vfs_registration( + new_addr.clone(), + &env.contract.address, + &msg.name, + msg.chain_info.clone(), + &adodb_addr, + &vfs_address, + )?; + + if let Some(register_submsg) = register_submsg { + vfs_msgs.push(register_submsg); + } + + let event = component.generate_event(new_addr); + resp = resp.add_event(event); + } + + let mut inst_msgs = vec![]; + + // This is done in a separate loop to ensure ordering, VFS registration first then instantiation after + for component in msg.app_components.clone() { + // Generate an ID for the component to help with tracking + let idx = add_app_component(deps.storage, &component)?; + + // Generate an instantiation message if required + let inst_msg = component.generate_instantiation_message( + &deps.querier, + &adodb_addr, + &env.contract.address, + &sender, + idx, + )?; + + if let Some(inst_msg) = inst_msg { + inst_msgs.push(inst_msg) } } - let vfs_address = ADOContract::default().get_vfs_address(deps.storage, &deps.querier)?; - let add_path_msg = VFSExecuteMsg::AddParentPath { - name: convert_component_name(app_name.clone()), + // Register app under parent + let app_name = msg.name; + let add_path_msg = VFSExecuteMsg::AddChild { + name: convert_component_name(&app_name), parent_address: AndrAddr::from_string(sender), }; - let cosmos_msg: CosmosMsg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: vfs_address.to_string(), - msg: to_json_binary(&add_path_msg)?, - funds: vec![], - }); - + let cosmos_msg = wasm_execute(vfs_address.to_string(), &add_path_msg, vec![])?; let register_msg = SubMsg::reply_on_error(cosmos_msg, ReplyId::RegisterPath.repr()); - let assign_app_msg = ExecuteMsg::AssignAppToComponents {}; - let assign_app_msg = SubMsg::reply_on_error( - CosmosMsg::Wasm::(WasmMsg::Execute { - contract_addr: env.contract.address.to_string(), - msg: to_json_binary(&assign_app_msg)?, - funds: vec![], - }), - ReplyId::AssignApp.repr(), - ); + resp = resp .add_submessage(register_msg) - .add_submessages(msgs) - .add_submessage(assign_app_msg); + .add_submessages(vfs_msgs) + .add_submessages(inst_msgs); if let Some(chain_info) = msg.chain_info { - for chain in chain_info { + for chain in chain_info.clone() { let sub_msg = create_cross_chain_message( &deps, app_name.clone(), msg.owner.clone().unwrap_or(info.sender.to_string()), msg.app_components.clone(), chain, + chain_info.clone(), )?; resp = resp.add_submessage(sub_msg); } @@ -178,12 +183,9 @@ pub fn execute( pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AddAppComponent { component } => execute::handle_add_app_component( - &ctx.deps.querier, - ctx.deps.storage, - ctx.info.sender.as_str(), - component, - ), + ExecuteMsg::AddAppComponent { component } => { + execute::handle_add_app_component(ctx, component) + } ExecuteMsg::ClaimOwnership { name, new_owner } => { execute::claim_ownership(ctx, name, new_owner) } @@ -196,36 +198,7 @@ pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/andromeda-core/contracts/app/andromeda-app-contract/src/execute.rs b/andromeda-core/contracts/app/andromeda-app-contract/src/execute.rs index 055aa30..02eb315 100644 --- a/andromeda-core/contracts/app/andromeda-app-contract/src/execute.rs +++ b/andromeda-core/contracts/app/andromeda-app-contract/src/execute.rs @@ -1,76 +1,109 @@ use crate::state::{ add_app_component, generate_assign_app_message, generate_ownership_message, - load_component_addresses, ADO_ADDRESSES, + load_component_addresses, ADO_ADDRESSES, APP_NAME, }; use andromeda_app::app::{AppComponent, ComponentType}; -use andromeda_std::common::context::ExecuteContext; +use andromeda_std::common::{context::ExecuteContext, reply::ReplyId}; use andromeda_std::error::ContractError; use andromeda_std::os::aos_querier::AOSQuerier; use andromeda_std::os::vfs::ExecuteMsg as VFSExecuteMsg; use andromeda_std::{ado_contract::ADOContract, amp::AndrAddr}; -use crate::reply::ReplyId; use cosmwasm_std::{ ensure, to_json_binary, Addr, Binary, CosmosMsg, QuerierWrapper, ReplyOn, Response, Storage, SubMsg, WasmMsg, }; pub fn handle_add_app_component( - querier: &QuerierWrapper, - storage: &mut dyn Storage, - sender: &str, + ctx: ExecuteContext, component: AppComponent, ) -> Result { + let querier = &ctx.deps.querier; + let env = ctx.env; + let sender = ctx.info.sender.as_str(); + + let maybe_app_component = ADO_ADDRESSES.may_load(ctx.deps.storage, &component.name)?; + ensure!( + maybe_app_component.is_none(), + ContractError::InvalidComponent { + name: "Component name already taken".to_string() + } + ); + + ensure!( + !matches!(component.component_type, ComponentType::CrossChain(..)), + ContractError::CrossChainComponentsCurrentlyDisabled {} + ); let contract = ADOContract::default(); ensure!( - contract.is_contract_owner(storage, sender)?, + contract.is_contract_owner(ctx.deps.storage, sender)?, ContractError::Unauthorized {} ); - let current_addr = ADO_ADDRESSES.may_load(storage, &component.name)?; - ensure!(current_addr.is_none(), ContractError::NameAlreadyTaken {}); + let idx = add_app_component(ctx.deps.storage, &component)?; + ensure!(idx < 50, ContractError::TooManyAppComponents {}); - let idx = add_app_component(storage, &component)?; + let adodb_addr = ADOContract::default().get_adodb_address(ctx.deps.storage, querier)?; + let vfs_addr = ADOContract::default().get_vfs_address(ctx.deps.storage, querier)?; let mut resp = Response::new() .add_attribute("method", "add_app_component") .add_attribute("name", component.name.clone()) .add_attribute("type", component.ado_type.clone()); - match component.component_type { - ComponentType::New(instantiate_msg) => { - let inst_msg = contract.generate_instantiate_msg( - storage, - querier, - idx, - instantiate_msg, - component.ado_type.clone(), - sender.to_string(), - )?; - resp = resp.add_submessage(inst_msg); - ADO_ADDRESSES.save(storage, &component.name, &Addr::unchecked(""))?; - } - ComponentType::Symlink(symlink) => { - let msg = VFSExecuteMsg::AddSymlink { - name: component.name, - symlink, - parent_address: None, - }; - let cosmos_msg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: AOSQuerier::vfs_address_getter( - querier, - &contract.get_kernel_address(storage)?, - )? - .to_string(), - msg: to_json_binary(&msg)?, - funds: vec![], - }); - let sub_msg = SubMsg::reply_on_error(cosmos_msg, ReplyId::RegisterPath.repr()); - resp = resp.add_submessage(sub_msg); - } - _ => return Err(ContractError::Unauthorized {}), + let app_name = APP_NAME.load(ctx.deps.storage)?; + let new_addr = component.get_new_addr( + ctx.deps.api, + &adodb_addr, + querier, + env.contract.address.clone(), + )?; + let registration_msg = component.generate_vfs_registration( + new_addr.clone(), + &env.contract.address, + &app_name, + // TODO: Fix this in future for x-chain components + None, + &adodb_addr, + &vfs_addr, + )?; + + if let Some(registration_msg) = registration_msg { + resp = resp.add_submessage(registration_msg); + } + + let inst_msg = component.generate_instantiation_message( + querier, + &adodb_addr, + &env.contract.address, + sender, + idx, + )?; + + if let Some(inst_msg) = inst_msg { + resp = resp.add_submessage(inst_msg); } + if let ComponentType::Symlink(ref val) = component.component_type { + let component_address: Addr = val.get_raw_address(&ctx.deps.as_ref())?; + ADO_ADDRESSES.save(ctx.deps.storage, &component.name, &component_address)?; + } else if let ComponentType::New(_) = component.component_type { + ensure!( + new_addr.is_some(), + ContractError::InvalidComponent { + name: "Could not generate address for new component".to_string() + } + ); + ADO_ADDRESSES.save( + ctx.deps.storage, + &component.name, + &new_addr.clone().unwrap(), + )?; + } + + let event = component.generate_event(new_addr); + resp = resp.add_event(event); + Ok(resp) } @@ -153,6 +186,7 @@ pub fn update_address( name: String, addr: String, ) -> Result { + ctx.deps.api.addr_validate(addr.as_str())?; let ExecuteContext { deps, info, .. } = ctx; let ado_addr = ADO_ADDRESSES.load(deps.storage, &name)?; ensure!( diff --git a/andromeda-core/contracts/app/andromeda-app-contract/src/mock.rs b/andromeda-core/contracts/app/andromeda-app-contract/src/mock.rs index eb702a8..577e241 100644 --- a/andromeda-core/contracts/app/andromeda-app-contract/src/mock.rs +++ b/andromeda-core/contracts/app/andromeda-app-contract/src/mock.rs @@ -2,25 +2,26 @@ use crate::contract::{execute, instantiate, query, reply}; use andromeda_app::app::{AppComponent, ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::{AnyResult, MockADO, MockContract}, }; use cosmwasm_std::{Addr, Empty}; -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; +use cw_multi_test::{AppResponse, Contract, ContractWrapper, Executor}; -pub struct MockApp(Addr); -mock_ado!(MockApp, ExecuteMsg, QueryMsg); +pub struct MockAppContract(Addr); +mock_ado!(MockAppContract, ExecuteMsg, QueryMsg); -impl MockApp { +impl MockAppContract { pub fn instantiate( code_id: u64, - sender: Addr, - app: &mut App, + sender: &Addr, + app: &mut MockApp, name: impl Into, app_components: Vec, kernel_address: impl Into, owner: Option, - ) -> MockApp { + ) -> MockAppContract { let msg = mock_app_instantiate_msg(name, app_components, kernel_address, owner); let addr = app .instantiate_contract( @@ -32,29 +33,38 @@ impl MockApp { Some(sender.to_string()), ) .unwrap(); - MockApp(Addr::unchecked(addr)) + MockAppContract(Addr::unchecked(addr)) } pub fn execute_claim_ownership( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, component_name: Option, ) -> AnyResult { self.execute(app, &mock_claim_ownership_msg(component_name), sender, &[]) } - pub fn query_components(&self, app: &App) -> Vec { + pub fn execute_add_app_component( + &self, + app: &mut MockApp, + sender: Addr, + component: AppComponent, + ) -> AnyResult { + self.execute(app, &mock_add_app_component_msg(component), sender, &[]) + } + + pub fn query_components(&self, app: &MockApp) -> Vec { self.query::>(app, mock_get_components_msg()) } - pub fn query_component_addr(&self, app: &App, name: impl Into) -> Addr { + pub fn query_component_addr(&self, app: &MockApp, name: impl Into) -> Addr { self.query::(app, mock_get_address_msg(name.into())) } pub fn query_ado_by_component_name>( &self, - app: &App, + app: &MockApp, name: impl Into, ) -> C { C::from(self.query_component_addr(app, name)) @@ -88,10 +98,18 @@ pub fn mock_claim_ownership_msg(component_name: Option) -> ExecuteMsg { } } +pub fn mock_add_app_component_msg(component: AppComponent) -> ExecuteMsg { + ExecuteMsg::AddAppComponent { component } +} + pub fn mock_get_components_msg() -> QueryMsg { QueryMsg::GetComponents {} } -pub fn mock_get_address_msg(name: String) -> QueryMsg { - QueryMsg::GetAddress { name } +pub fn mock_get_adresses_with_names_msg() -> QueryMsg { + QueryMsg::GetAddressesWithNames {} +} + +pub fn mock_get_address_msg(name: impl Into) -> QueryMsg { + QueryMsg::GetAddress { name: name.into() } } diff --git a/andromeda-core/contracts/app/andromeda-app-contract/src/reply.rs b/andromeda-core/contracts/app/andromeda-app-contract/src/reply.rs index 91c83cc..c9e5259 100644 --- a/andromeda-core/contracts/app/andromeda-app-contract/src/reply.rs +++ b/andromeda-core/contracts/app/andromeda-app-contract/src/reply.rs @@ -1,20 +1,8 @@ -use andromeda_std::{ - ado_contract::ADOContract, common::response::get_reply_address, error::ContractError, -}; -use cosmwasm_std::{DepsMut, Reply, Response}; -use enum_repr::EnumRepr; +use andromeda_std::{common::response::get_reply_address, error::ContractError}; +use cosmwasm_std::{ensure_eq, Addr, DepsMut, Reply, Response}; -use crate::execute; use crate::state::{ADO_ADDRESSES, ADO_DESCRIPTORS}; -#[EnumRepr(type = "u64")] -pub enum ReplyId { - ClaimOwnership = 101, - AssignApp = 102, - RegisterPath = 103, - CrossChainCreate = 104, -} - pub fn on_component_instantiation(deps: DepsMut, msg: Reply) -> Result { let id = msg.id.to_string(); @@ -22,21 +10,17 @@ pub fn on_component_instantiation(deps: DepsMut, msg: Reply) -> Result = Map::new("ado_addresses"); /// Stores a record of the describing structs for each ADO @@ -37,7 +41,7 @@ pub fn load_component_addresses( storage: &dyn Storage, min: Option<&str>, ) -> Result, ContractError> { - let min = Some(Bound::inclusive(min.unwrap_or("1"))); + let min = Some(Bound::inclusive(min.unwrap_or("0"))); let addresses: Vec = ADO_ADDRESSES .range(storage, min, None, Order::Ascending) .flatten() @@ -77,9 +81,10 @@ pub fn load_component_descriptors( } pub fn generate_ownership_message(addr: Addr, owner: &str) -> Result { - let msg = to_json_binary(&AndromedaMsg::UpdateOwner { - address: owner.to_string(), - })?; + let msg = to_json_binary(&AndromedaMsg::Ownership(OwnershipMessage::UpdateOwner { + new_owner: Addr::unchecked(owner), + expiration: None, + }))?; Ok(SubMsg { id: ReplyId::ClaimOwnership.repr(), reply_on: ReplyOn::Error, @@ -121,19 +126,28 @@ pub fn get_chain_info(chain_name: String, chain_info: Option>) -> } /// Creates a sub message to create a recpliant app on the target chain +/// Apps are altered to be symlinks or instantiations depending on if they are for the target chain +/// * `deps` - Standarad Dependencies +/// * `app_name` - The name of the app to be created +/// * `owner` - The owner of the app on the target chain +/// * `sender` - The sender of the message +/// * `components` - The components of the app to be created +/// * `target_chain_info` - The chain info for the target chain +/// * `all_chain_info` - The chain info for all chains pub fn create_cross_chain_message( deps: &DepsMut, app_name: String, owner: String, components: Vec, - chain_info: ChainInfo, + target_chain_info: ChainInfo, + all_chain_info: Vec, ) -> Result { let kernel_address = ADOContract::default().get_kernel_address(deps.storage)?; let curr_chain = AOSQuerier::get_current_chain(&deps.querier, &kernel_address)?; let channel_info = AOSQuerier::get_chain_info( &deps.querier, &kernel_address, - chain_info.chain_name.as_str(), + target_chain_info.chain_name.as_str(), )?; let mut new_components: Vec = Vec::new(); for component in components { @@ -143,22 +157,33 @@ pub fn create_cross_chain_message( chain, instantiate_msg, }) => { - if chain == chain_info.chain_name { + // If component for target chain instantiate component + if chain == target_chain_info.chain_name { AppComponent { name, ado_type: component.ado_type, component_type: ComponentType::New(instantiate_msg), } + // Otherwise use a symlink to the component } else { + // Unwrap the owner on the chain for this component + let chain_info = all_chain_info.iter().find(|info| info.chain_name == chain); + ensure!( + chain_info.is_some(), + ContractError::InvalidComponent { name } + ); + let owner = chain_info.unwrap().owner.clone(); + AppComponent { name: name.clone(), ado_type: component.ado_type, component_type: ComponentType::Symlink(AndrAddr::from_string(format!( - "ibc://{curr_chain}/home/{owner}/{app_name}/{name}" + "ibc://{chain}/home/{owner}/{app_name}/{name}" ))), } } } + // Must be some form of local component (symlink or new) so create symlink references _ => AppComponent { name: name.clone(), ado_type: component.ado_type, @@ -170,7 +195,7 @@ pub fn create_cross_chain_message( new_components.push(new_component); } let msg = InstantiateMsg { - owner: Some(chain_info.owner.clone()), + owner: Some(target_chain_info.owner.clone()), app_components: new_components, name: app_name, chain_info: None, @@ -180,8 +205,8 @@ pub fn create_cross_chain_message( let kernel_msg = KernelExecuteMsg::Create { ado_type: "app-contract".to_string(), msg: to_json_binary(&msg)?, - owner: Some(AndrAddr::from_string(chain_info.owner)), - chain: Some(chain_info.chain_name), + owner: Some(AndrAddr::from_string(target_chain_info.owner)), + chain: Some(target_chain_info.chain_name), }; let cosmos_msg = CosmosMsg::Wasm(WasmMsg::Execute { @@ -198,3 +223,109 @@ pub fn create_cross_chain_message( Ok(sub_msg) } + +#[cfg(test)] +mod test { + use andromeda_std::testing::mock_querier::mock_dependencies_custom; + use cosmwasm_std::from_json; + + use super::*; + + #[test] + fn test_create_cross_chain_message() { + let mut deps = mock_dependencies_custom(&[]); + let app_name = "test_app".to_string(); + let target_owner = "test_owner".to_string(); + let target_chain = "target_chain".to_string(); + let target_chain_info = ChainInfo { + chain_name: target_chain.clone(), + owner: target_owner.clone(), + }; + let second_chain_info = ChainInfo { + chain_name: "test-chain".to_string(), + owner: "test-chain-owner".to_string(), + }; + let all_chain_info = vec![target_chain_info.clone(), second_chain_info.clone()]; + let components = vec![ + AppComponent { + name: "test_component".to_string(), + ado_type: "test_ado".to_string(), + component_type: ComponentType::CrossChain(CrossChainComponent { + chain: target_chain.clone(), + instantiate_msg: to_json_binary(&"test_instantiate").unwrap(), + }), + }, + AppComponent { + name: "test_component".to_string(), + ado_type: "test_ado".to_string(), + component_type: ComponentType::CrossChain(CrossChainComponent { + chain: second_chain_info.chain_name.clone(), + instantiate_msg: to_json_binary(&"test_instantiate").unwrap(), + }), + }, + AppComponent { + name: "test_component".to_string(), + ado_type: "test_ado".to_string(), + component_type: ComponentType::New(to_json_binary(&"test_instantiate").unwrap()), + }, + ]; + let expected_components = vec![ + AppComponent { + name: "test_component".to_string(), + ado_type: "test_ado".to_string(), + component_type: ComponentType::New(to_json_binary(&"test_instantiate").unwrap()), + }, + AppComponent { + name: "test_component".to_string(), + ado_type: "test_ado".to_string(), + component_type: ComponentType::Symlink(AndrAddr::from_string(format!( + "ibc://{}/home/{}/test_app/test_component", + second_chain_info.chain_name, second_chain_info.owner + ))), + }, + AppComponent { + name: "test_component".to_string(), + ado_type: "test_ado".to_string(), + component_type: ComponentType::Symlink(AndrAddr::from_string(format!( + "ibc://andromeda/home/{}/test_app/test_component", + target_owner + ))), + }, + ]; + + let SubMsg { msg, .. } = create_cross_chain_message( + &deps.as_mut(), + app_name.clone(), + target_owner.clone(), + components, + target_chain_info, + all_chain_info, + ) + .unwrap(); + + assert!(matches!(msg, CosmosMsg::Wasm(WasmMsg::Execute { .. }))); + + let msg = match msg { + CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) => msg, + _ => panic!("Wrong message type"), + }; + match from_json(msg).unwrap() { + KernelExecuteMsg::Create { + ado_type, + msg, + owner, + chain, + } => { + assert_eq!(ado_type, "app-contract"); + assert_eq!(owner, Some(AndrAddr::from_string(target_owner.clone()))); + assert_eq!(chain, Some(target_chain)); + let msg: InstantiateMsg = from_json(msg).unwrap(); + assert_eq!(msg.name, app_name); + assert_eq!(msg.owner, Some(target_owner)); + assert_eq!(msg.chain_info, None); + assert_eq!(msg.app_components, expected_components); + } + _ => panic!("Wrong message type"), + } + } +} diff --git a/andromeda-core/contracts/app/andromeda-app-contract/src/testing/mod.rs b/andromeda-core/contracts/app/andromeda-app-contract/src/testing/mod.rs index c91d867..a617531 100644 --- a/andromeda-core/contracts/app/andromeda-app-contract/src/testing/mod.rs +++ b/andromeda-core/contracts/app/andromeda-app-contract/src/testing/mod.rs @@ -1,10 +1,14 @@ -use crate::reply::ReplyId; +use crate::state::{ADO_DESCRIPTORS, ADO_IDX}; use super::{contract::*, state::ADO_ADDRESSES}; use andromeda_app::app::{AppComponent, ComponentType, ExecuteMsg, InstantiateMsg}; -use andromeda_std::amp::AndrAddr; -use andromeda_std::os::vfs::{convert_component_name, ExecuteMsg as VFSExecuteMsg}; -use andromeda_std::testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}; +use andromeda_std::ado_base::ownership::OwnershipMessage; +// use andromeda_std::amp::AndrAddr; +// use andromeda_std::common::reply::ReplyId; +// use andromeda_std::os::vfs::{convert_component_name, ExecuteMsg as VFSExecuteMsg}; +use andromeda_std::testing::mock_querier::{ + mock_dependencies_custom, MOCK_ANCHOR_CONTRACT, MOCK_CW20_CONTRACT, MOCK_KERNEL_CONTRACT, +}; use andromeda_std::{ado_base::AndromedaMsg, error::ContractError}; @@ -13,6 +17,7 @@ use cosmwasm_std::{ testing::{mock_env, mock_info}, to_json_binary, Addr, CosmosMsg, Empty, ReplyOn, Response, StdError, SubMsg, WasmMsg, }; +use cosmwasm_std::{Binary, Event, Reply, SubMsgResponse, SubMsgResult}; #[test] fn test_empty_instantiation() { @@ -29,111 +34,113 @@ fn test_empty_instantiation() { // we can just call .unwrap() to assert this was a success let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); - assert_eq!(2, res.messages.len()); + assert_eq!(1, res.messages.len()); } -#[test] -fn test_instantiation() { - let mut deps = mock_dependencies_custom(&[]); +//TODO: Fix post CosmWasm 2.0 - let msg = InstantiateMsg { - app_components: vec![AppComponent { - name: "token".to_string(), - ado_type: "cw721".to_string(), - component_type: ComponentType::New(to_json_binary(&true).unwrap()), - }], - name: String::from("Some App"), - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - owner: None, - chain_info: None, - }; - let info = mock_info("creator", &[]); +// #[test] +// fn test_instantiation() { +// let mut deps = mock_dependencies_custom(&[]); - let res = instantiate(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - assert_eq!(3, res.messages.len()); - let inst_submsg: SubMsg = SubMsg { - id: 1, - msg: CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id: 1, - msg: to_json_binary(&true).unwrap(), - funds: vec![], - label: "Instantiate: cw721".to_string(), - admin: Some("creator".to_string()), - }), - reply_on: ReplyOn::Always, - gas_limit: None, - }; - let sender = info.sender; - let register_submsg: SubMsg = SubMsg { - id: ReplyId::RegisterPath.repr(), - msg: CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "vfs_contract".to_string(), - msg: to_json_binary(&VFSExecuteMsg::AddParentPath { - name: convert_component_name("Some App".to_string()), - parent_address: AndrAddr::from_string(format!("{sender}")), - }) - .unwrap(), - funds: vec![], - }), - reply_on: ReplyOn::Error, - gas_limit: None, - }; - let assign_msg: SubMsg = SubMsg { - id: ReplyId::AssignApp.repr(), - msg: CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "cosmos2contract".to_string(), - msg: to_json_binary(&ExecuteMsg::AssignAppToComponents {}).unwrap(), - funds: vec![], - }), - reply_on: ReplyOn::Error, - gas_limit: None, - }; - let expected = Response::new() - .add_submessage(register_submsg) - .add_submessage(inst_submsg) - .add_submessage(assign_msg) - .add_attributes(vec![ - attr("method", "instantiate"), - attr("type", "app-contract"), - attr("owner", "creator"), - attr("andr_app", "Some App"), - ]); +// let msg = InstantiateMsg { +// app_components: vec![AppComponent { +// name: "token".to_string(), +// ado_type: "cw721".to_string(), +// component_type: ComponentType::New(to_json_binary(&true).unwrap()), +// }], +// name: String::from("Some App"), +// kernel_address: MOCK_KERNEL_CONTRACT.to_string(), +// owner: None, +// chain_info: None, +// }; +// let info = mock_info("creator", &[]); - assert_eq!(expected, res); +// let res = instantiate(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); +// assert_eq!(3, res.messages.len()); +// let inst_submsg: SubMsg = SubMsg { +// id: 1, +// msg: CosmosMsg::Wasm(WasmMsg::Instantiate { +// code_id: 1, +// msg: to_json_binary(&true).unwrap(), +// funds: vec![], +// label: "Instantiate: cw721".to_string(), +// admin: Some("creator".to_string()), +// }), +// reply_on: ReplyOn::Always, +// gas_limit: None, +// }; +// let sender = info.sender; +// let register_submsg: SubMsg = SubMsg { +// id: ReplyId::RegisterPath.repr(), +// msg: CosmosMsg::Wasm(WasmMsg::Execute { +// contract_addr: "vfs_contract".to_string(), +// msg: to_json_binary(&VFSExecuteMsg::AddChild { +// name: convert_component_name("Some App"), +// parent_address: AndrAddr::from_string(format!("{sender}")), +// }) +// .unwrap(), +// funds: vec![], +// }), +// reply_on: ReplyOn::Error, +// gas_limit: None, +// }; +// let assign_msg: SubMsg = SubMsg { +// id: ReplyId::AssignApp.repr(), +// msg: CosmosMsg::Wasm(WasmMsg::Execute { +// contract_addr: "cosmos2contract".to_string(), +// msg: to_json_binary(&ExecuteMsg::AssignAppToComponents {}).unwrap(), +// funds: vec![], +// }), +// reply_on: ReplyOn::Error, +// gas_limit: None, +// }; +// let expected = Response::new() +// .add_submessage(register_submsg) +// .add_submessage(inst_submsg) +// .add_submessage(assign_msg) +// .add_attributes(vec![ +// attr("method", "instantiate"), +// attr("type", "app-contract"), +// attr("owner", "creator"), +// attr("andr_app", "Some App"), +// ]); - assert_eq!( - Addr::unchecked(""), - ADO_ADDRESSES.load(deps.as_ref().storage, "token").unwrap() - ); -} +// assert_eq!(expected, res); -#[test] -fn test_instantiation_duplicate_components() { - let mut deps = mock_dependencies_custom(&[]); +// assert_eq!( +// Addr::unchecked(""), +// ADO_ADDRESSES.load(deps.as_ref().storage, "token").unwrap() +// ); +// } - let msg = InstantiateMsg { - app_components: vec![ - AppComponent { - name: "component".to_string(), - ado_type: "cw721".to_string(), - component_type: ComponentType::New(to_json_binary(&true).unwrap()), - }, - AppComponent { - name: "component".to_string(), - ado_type: "cw20".to_string(), - component_type: ComponentType::New(to_json_binary(&true).unwrap()), - }, - ], - name: String::from("Some App"), - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - owner: None, - chain_info: None, - }; - let info = mock_info("creator", &[]); +// #[test] +// fn test_instantiation_duplicate_components() { +// let mut deps = mock_dependencies_custom(&[]); - let res = instantiate(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::NameAlreadyTaken {}, res.unwrap_err()); -} +// let msg = InstantiateMsg { +// app_components: vec![ +// AppComponent { +// name: "component".to_string(), +// ado_type: "cw721".to_string(), +// component_type: ComponentType::New(to_json_binary(&true).unwrap()), +// }, +// AppComponent { +// name: "component".to_string(), +// ado_type: "cw20".to_string(), +// component_type: ComponentType::New(to_json_binary(&true).unwrap()), +// }, +// ], +// name: String::from("Some App"), +// kernel_address: MOCK_KERNEL_CONTRACT.to_string(), +// owner: None, +// chain_info: None, +// }; +// let info = mock_info("creator", &[]); + +// let res = instantiate(deps.as_mut(), mock_env(), info, msg); +// assert_eq!(ContractError::NameAlreadyTaken {}, res.unwrap_err()); +// } #[test] fn test_add_app_component_unauthorized() { @@ -163,96 +170,96 @@ fn test_add_app_component_unauthorized() { assert_eq!(ContractError::Unauthorized {}, err); } -#[test] -fn test_add_app_component_duplicate_name() { - let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let info = mock_info("creator", &[]); - let inst_msg = InstantiateMsg { - app_components: vec![AppComponent { - name: "token".to_string(), - ado_type: "cw721".to_string(), - component_type: ComponentType::New(to_json_binary(&true).unwrap()), - }], - name: String::from("Some App"), - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - owner: None, - chain_info: None, - }; - - instantiate(deps.as_mut(), env.clone(), info.clone(), inst_msg).unwrap(); - ADO_ADDRESSES - .save( - deps.as_mut().storage, - "token", - &Addr::unchecked("someaddress"), - ) - .unwrap(); - - let msg = ExecuteMsg::AddAppComponent { - component: AppComponent { - name: "token".to_string(), - ado_type: "cw721".to_string(), - component_type: ComponentType::New(to_json_binary(&true).unwrap()), - }, - }; +// #[test] +// fn test_add_app_component_duplicate_name() { +// let mut deps = mock_dependencies_custom(&[]); +// let env = mock_env(); +// let info = mock_info("creator", &[]); +// let inst_msg = InstantiateMsg { +// app_components: vec![AppComponent { +// name: "token".to_string(), +// ado_type: "cw721".to_string(), +// component_type: ComponentType::New(to_json_binary(&true).unwrap()), +// }], +// name: String::from("Some App"), +// kernel_address: MOCK_KERNEL_CONTRACT.to_string(), +// owner: None, +// chain_info: None, +// }; - let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(ContractError::NameAlreadyTaken {}, err); -} +// instantiate(deps.as_mut(), env.clone(), info.clone(), inst_msg).unwrap(); +// ADO_ADDRESSES +// .save( +// deps.as_mut().storage, +// "token", +// &Addr::unchecked("someaddress"), +// ) +// .unwrap(); -#[test] -fn test_add_app_component() { - let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let info = mock_info("creator", &[]); - let inst_msg = InstantiateMsg { - app_components: vec![], - name: String::from("Some App"), - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - owner: None, - chain_info: None, - }; +// let msg = ExecuteMsg::AddAppComponent { +// component: AppComponent { +// name: "token".to_string(), +// ado_type: "cw721".to_string(), +// component_type: ComponentType::New(to_json_binary(&true).unwrap()), +// }, +// }; - instantiate(deps.as_mut(), env.clone(), info.clone(), inst_msg).unwrap(); +// let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); +// assert_eq!(ContractError::NameAlreadyTaken {}, err); +// } - let msg = ExecuteMsg::AddAppComponent { - component: AppComponent { - name: "token".to_string(), - ado_type: "cw721".to_string(), - component_type: ComponentType::New(to_json_binary(&true).unwrap()), - }, - }; +// #[test] +// fn test_add_app_component() { +// let mut deps = mock_dependencies_custom(&[]); +// let env = mock_env(); +// let info = mock_info("creator", &[]); +// let inst_msg = InstantiateMsg { +// app_components: vec![], +// name: String::from("Some App"), +// kernel_address: MOCK_KERNEL_CONTRACT.to_string(), +// owner: None, +// chain_info: None, +// }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - assert_eq!(1, res.messages.len()); - let inst_submsg: SubMsg = SubMsg { - id: 1, - msg: CosmosMsg::Wasm(WasmMsg::Instantiate { - code_id: 1, - msg: to_json_binary(&true).unwrap(), - funds: vec![], - label: "Instantiate: cw721".to_string(), - admin: Some("creator".to_string()), - }), - reply_on: ReplyOn::Always, - gas_limit: None, - }; - let expected = Response::new() - .add_submessage(inst_submsg) - .add_attributes(vec![ - attr("method", "add_app_component"), - attr("name", "token"), - attr("type", "cw721"), - ]); +// instantiate(deps.as_mut(), env.clone(), info.clone(), inst_msg).unwrap(); - assert_eq!(expected, res); +// let msg = ExecuteMsg::AddAppComponent { +// component: AppComponent { +// name: "token".to_string(), +// ado_type: "cw721".to_string(), +// component_type: ComponentType::New(to_json_binary(&true).unwrap()), +// }, +// }; - assert_eq!( - Addr::unchecked(""), - ADO_ADDRESSES.load(deps.as_ref().storage, "token").unwrap() - ); -} +// let res = execute(deps.as_mut(), env, info, msg).unwrap(); +// assert_eq!(1, res.messages.len()); +// // let inst_submsg: SubMsg = SubMsg { +// // id: 1, +// // msg: CosmosMsg::Wasm(WasmMsg::Instantiate { +// // code_id: 1, +// // msg: to_json_binary(&true).unwrap(), +// // funds: vec![], +// // label: "Instantiate: cw721".to_string(), +// // admin: Some("creator".to_string()), +// // }), +// // reply_on: ReplyOn::Always, +// // gas_limit: None, +// // }; +// // let expected = Response::new() +// // .add_submessage(inst_submsg) +// // .add_attributes(vec![ +// // attr("method", "add_app_component"), +// // attr("name", "token"), +// // attr("type", "cw721"), +// // ]); + +// // assert_eq!(expected, res); + +// // assert_eq!( +// // Addr::unchecked(""), +// // ADO_ADDRESSES.load(deps.as_ref().storage, "token").unwrap() +// // ); +// } #[test] fn test_claim_ownership_unauth() { @@ -327,44 +334,43 @@ fn test_claim_ownership_empty() { assert_eq!(0, res.messages.len()); } -//TODO: Fix this test -// #[test] -// fn test_claim_ownership_all() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("creator", &[]); -// let inst_msg = InstantiateMsg { -// app_components: vec![], -// name: String::from("Some App"), -// owner: None, -// kernel_address: MOCK_KERNEL_CONTRACT.to_string(), -// chain_info: None, -// }; +#[test] +fn test_claim_ownership_all() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let info = mock_info("creator", &[]); + let inst_msg = InstantiateMsg { + app_components: vec![], + name: String::from("Some App"), + owner: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + chain_info: None, + }; -// instantiate(deps.as_mut(), env.clone(), info.clone(), inst_msg).unwrap(); -// ADO_ADDRESSES -// .save( -// deps.as_mut().storage, -// "token", -// &Addr::unchecked("tokenaddress".to_string()), -// ) -// .unwrap(); -// ADO_ADDRESSES -// .save( -// deps.as_mut().storage, -// "anchor", -// &Addr::unchecked("anchoraddress".to_string()), -// ) -// .unwrap(); + instantiate(deps.as_mut(), env.clone(), info.clone(), inst_msg).unwrap(); + ADO_ADDRESSES + .save( + deps.as_mut().storage, + "token", + &Addr::unchecked(MOCK_CW20_CONTRACT), + ) + .unwrap(); + ADO_ADDRESSES + .save( + deps.as_mut().storage, + "anchor", + &Addr::unchecked(MOCK_ANCHOR_CONTRACT), + ) + .unwrap(); -// let msg = ExecuteMsg::ClaimOwnership { -// name: None, -// new_owner: None, -// }; + let msg = ExecuteMsg::ClaimOwnership { + name: None, + new_owner: None, + }; -// let res = execute(deps.as_mut(), env, info, msg).unwrap(); -// assert_eq!(2, res.messages.len()); -// } + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + assert_eq!(2, res.messages.len()); +} #[test] fn test_claim_ownership() { @@ -404,12 +410,13 @@ fn test_claim_ownership() { assert_eq!(1, res.messages.len()); let exec_submsg: SubMsg = SubMsg { - id: 101, + id: 200, msg: CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: "tokenaddress".to_string(), - msg: to_json_binary(&AndromedaMsg::UpdateOwner { - address: "creator".to_string(), - }) + msg: to_json_binary(&AndromedaMsg::Ownership(OwnershipMessage::UpdateOwner { + new_owner: Addr::unchecked("creator"), + expiration: None, + })) .unwrap(), funds: vec![], }), @@ -613,68 +620,83 @@ fn test_update_address() { assert_eq!(Addr::unchecked("newtokenaddress"), addr) } -// TODO: UPDATE WITH 1.2 CHANGES -// #[test] -// fn test_reply_assign_app() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let mock_app_component = AppComponent { -// ado_type: "cw721".to_string(), -// name: "token".to_string(), -// instantiate_msg: to_json_binary(&true).unwrap(), -// }; -// let component_idx = 1; -// ADO_DESCRIPTORS -// .save( -// deps.as_mut().storage, -// &component_idx.to_string(), -// &mock_app_component, -// ) -// .unwrap(); +#[test] +fn test_add_app_component_limit() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let info = mock_info("creator", &[]); -// let mock_reply_event = Event::new("instantiate") -// .add_attribute("contract_address".to_string(), "tokenaddress".to_string()); + let msg = InstantiateMsg { + app_components: vec![], + name: String::from("Some App"), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + chain_info: None, + }; -// let instantiate_reply = MsgInstantiateContractResponse { -// contract_address: "tokenaddress".to_string(), -// data: vec![], -// }; -// let mut encoded_instantiate_reply = Vec::::with_capacity(instantiate_reply.encoded_len()); + // we can just call .unwrap() to assert this was a success + instantiate(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); -// instantiate_reply -// .encode(&mut encoded_instantiate_reply) -// .unwrap(); + let mut i = 0; + while i < 50 { + i += 1; + ADO_ADDRESSES + .save(deps.as_mut().storage, &i.to_string(), &Addr::unchecked("")) + .unwrap(); + } + ADO_IDX.save(deps.as_mut().storage, &50).unwrap(); -// let mock_reply = Reply { -// id: component_idx, -// result: SubMsgResult::Ok(SubMsgResponse { -// data: Some(encoded_instantiate_reply.into()), -// events: vec![mock_reply_event], -// }), -// }; + let msg = ExecuteMsg::AddAppComponent { + component: AppComponent { + name: "token".to_string(), + ado_type: "cw721".to_string(), + component_type: ComponentType::New(to_json_binary(&true).unwrap()), + }, + }; -// let res = reply(deps.as_mut(), env.clone(), mock_reply).unwrap(); -// assert_eq!(1, res.messages.len()); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!(ContractError::TooManyAppComponents {}, err); +} -// let exec_submsg: SubMsg = SubMsg { -// id: 103, -// msg: CosmosMsg::Wasm(WasmMsg::Execute { -// contract_addr: "tokenaddress".to_string(), -// msg: to_json_binary(&ExecuteMsg::AndrReceive(AndromedaMsg::UpdateAppContract { -// address: env.contract.address.to_string(), -// })) -// .unwrap(), -// funds: vec![], -// }), -// reply_on: ReplyOn::Error, -// gas_limit: None, -// }; -// let expected = Response::new().add_submessage(exec_submsg); +#[test] +fn test_reply_assign_app() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let mock_app_component = AppComponent { + ado_type: "cw721".to_string(), + name: "token".to_string(), + component_type: ComponentType::New(to_json_binary(&true).unwrap()), + }; + let component_idx = 1; + ADO_DESCRIPTORS + .save( + deps.as_mut().storage, + &component_idx.to_string(), + &mock_app_component, + ) + .unwrap(); + ADO_ADDRESSES + .save( + deps.as_mut().storage, + &mock_app_component.name, + &Addr::unchecked("cosmos2contract"), + ) + .unwrap(); -// assert_eq!(expected, res); + let mock_reply_event = Event::new("instantiate").add_attribute( + "contract_address".to_string(), + "cosmos2contract".to_string(), + ); -// assert_eq!( -// Addr::unchecked("tokenaddress"), -// ADO_ADDRESSES.load(deps.as_ref().storage, "token").unwrap() -// ); -// } + let reply_resp = "Cg9jb3Ntb3MyY29udHJhY3QSAA=="; + let mock_reply = Reply { + id: component_idx, + result: SubMsgResult::Ok(SubMsgResponse { + data: Some(Binary::from_base64(reply_resp).unwrap()), + events: vec![mock_reply_event], + }), + }; + + let res = reply(deps.as_mut(), env, mock_reply).unwrap(); + assert!(res.messages.is_empty()); +} diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/.cargo/config b/andromeda-core/contracts/data-storage/andromeda-boolean/.cargo/config new file mode 100644 index 0000000..336b618 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/Cargo.toml b/andromeda-core/contracts/data-storage/andromeda-boolean/Cargo.toml new file mode 100644 index 0000000..e5b5760 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "andromeda-boolean" +version = "2.0.2" +authors = ["Mitar Djakovic "] +edition = "2021" +rust-version = "1.75.0" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +testing = ["cw-multi-test", "andromeda-testing"] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +cw20 = { workspace = true } + + +andromeda-std = { workspace = true, features = ["rates"] } +andromeda-data-storage = { workspace = true } + + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/examples/schema.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/examples/schema.rs new file mode 100644 index 0000000..d435a54 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/examples/schema.rs @@ -0,0 +1,10 @@ +use andromeda_data_storage::boolean::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + + } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/contract.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/contract.rs new file mode 100644 index 0000000..3e8675a --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/contract.rs @@ -0,0 +1,94 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response}; + +use crate::{ + execute::handle_execute, + query::{get_data_owner, get_value}, + state::RESTRICTION, +}; +use andromeda_data_storage::boolean::{BooleanRestriction, ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::{ + ado_base::{ + permissioning::{LocalPermission, Permission}, + InstantiateMsg as BaseInstantiateMsg, MigrateMsg, + }, + ado_contract::ADOContract, + common::{context::ExecuteContext, encode_binary}, + error::ContractError, +}; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:andromeda-boolean"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub const SET_DELETE_VALUE_ACTION: &str = "set_delete_value"; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let resp = ADOContract::default().instantiate( + deps.storage, + env, + deps.api, + &deps.querier, + info.clone(), + BaseInstantiateMsg { + ado_type: CONTRACT_NAME.to_string(), + ado_version: CONTRACT_VERSION.to_string(), + kernel_address: msg.kernel_address, + owner: msg.owner.clone(), + }, + )?; + RESTRICTION.save(deps.storage, &msg.restriction)?; + + if msg.restriction == BooleanRestriction::Private { + ADOContract::default().permission_action(SET_DELETE_VALUE_ACTION, deps.storage)?; + + ADOContract::set_permission( + deps.storage, + SET_DELETE_VALUE_ACTION, + match msg.owner.clone() { + None => info.sender, + Some(owner) => Addr::unchecked(owner), + }, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + + Ok(resp) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let ctx = ExecuteContext::new(deps, info, env); + match msg { + ExecuteMsg::AMPReceive(pkt) => { + ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) + } + _ => handle_execute(ctx, msg), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::GetValue {} => encode_binary(&get_value(deps.storage)?), + QueryMsg::GetDataOwner {} => encode_binary(&get_data_owner(deps.storage)?), + _ => ADOContract::default().query(deps, env, msg), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/execute.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/execute.rs new file mode 100644 index 0000000..fe43e2c --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/execute.rs @@ -0,0 +1,184 @@ +use andromeda_data_storage::boolean::{BooleanRestriction, ExecuteMsg}; +use andromeda_std::{ + ado_base::rates::{Rate, RatesMessage}, + ado_contract::ADOContract, + common::{actions::call_action, context::ExecuteContext, rates::get_tax_amount, Funds}, + error::ContractError, +}; +use cosmwasm_std::{ + coin, ensure, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, Response, SubMsg, Uint128, +}; +use cw_utils::nonpayable; + +use crate::{ + contract::SET_DELETE_VALUE_ACTION, + state::{DATA, DATA_OWNER, RESTRICTION}, +}; + +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + match msg.clone() { + ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), + ExecuteMsg::SetValue { value } => set_value(ctx, value, action), + ExecuteMsg::DeleteValue {} => delete_value(ctx), + ExecuteMsg::Rates(rates_message) => match rates_message { + RatesMessage::SetRate { rate, .. } => match rate { + Rate::Local(local_rate) => { + // Percent rates aren't applicable in this case, so we enforce Flat rates + ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); + ADOContract::default().execute(ctx, msg) + } + Rate::Contract(_) => ADOContract::default().execute(ctx, msg), + }, + RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), + }, + _ => ADOContract::default().execute(ctx, msg), + } +} + +pub fn update_restriction( + ctx: ExecuteContext, + restriction: BooleanRestriction, +) -> Result { + nonpayable(&ctx.info)?; + let sender = ctx.info.sender; + ensure!( + ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, + ContractError::Unauthorized {} + ); + RESTRICTION.save(ctx.deps.storage, &restriction)?; + Ok(Response::new() + .add_attribute("method", "update_restriction") + .add_attribute("sender", sender)) +} + +pub fn set_value( + mut ctx: ExecuteContext, + value: bool, + action: String, +) -> Result { + let sender = ctx.info.sender.clone(); + let restriction = RESTRICTION.load(ctx.deps.storage)?; + if restriction == BooleanRestriction::Private { + let has_permission = ADOContract::default() + .is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + SET_DELETE_VALUE_ACTION, + ctx.info.sender.clone(), + ) + .is_ok(); + ensure!(has_permission, ContractError::Unauthorized {}); + } else if restriction == BooleanRestriction::Restricted { + let addr = sender.as_str(); + let is_operator = ADOContract::default().is_owner_or_operator(ctx.deps.storage, addr)?; + let allowed = match DATA_OWNER.load(ctx.deps.storage).ok() { + Some(owner) => addr == owner, + None => true, + }; + ensure!(is_operator || allowed, ContractError::Unauthorized {}); + } + + let tax_response = tax_set_value(ctx.deps.as_ref(), &ctx.info, action)?; + + DATA.save(ctx.deps.storage, &value.clone())?; + DATA_OWNER.save(ctx.deps.storage, &sender)?; + + let mut response = Response::new() + .add_attribute("method", "set_value") + .add_attribute("sender", sender) + .add_attribute("value", format!("{value:?}")); + + if let Some(tax_response) = tax_response { + response = response.add_submessages(tax_response.1); + let refund = tax_response.0.try_get_coin()?; + if !refund.amount.is_zero() { + return Ok(response.add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: ctx.info.sender.into_string(), + amount: vec![refund], + }))); + } + } + + Ok(response) +} + +pub fn delete_value(mut ctx: ExecuteContext) -> Result { + nonpayable(&ctx.info)?; + let sender = ctx.info.sender.clone(); + let restriction = RESTRICTION.load(ctx.deps.storage)?; + if restriction == BooleanRestriction::Private { + let has_permission = ADOContract::default() + .is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + SET_DELETE_VALUE_ACTION, + ctx.info.sender.clone(), + ) + .is_ok(); + ensure!(has_permission, ContractError::Unauthorized {}); + } else if restriction == BooleanRestriction::Restricted { + let addr = sender.as_str(); + let is_operator = ADOContract::default().is_owner_or_operator(ctx.deps.storage, addr)?; + let allowed = match DATA_OWNER.load(ctx.deps.storage).ok() { + Some(owner) => addr == owner, + None => true, + }; + ensure!(is_operator || allowed, ContractError::Unauthorized {}); + } + + DATA.remove(ctx.deps.storage); + DATA_OWNER.remove(ctx.deps.storage); + Ok(Response::new() + .add_attribute("method", "delete_value") + .add_attribute("sender", sender)) +} + +fn tax_set_value( + deps: Deps, + info: &MessageInfo, + action: String, +) -> Result)>, ContractError> { + let default_coin = coin(0_u128, "uandr".to_string()); + let sent_funds = info.funds.first().unwrap_or(&default_coin); + + let transfer_response = ADOContract::default().query_deducted_funds( + deps, + action, + Funds::Native(sent_funds.clone()), + )?; + + if let Some(transfer_response) = transfer_response { + let remaining_funds = transfer_response.leftover_funds.try_get_coin()?; + let tax_amount = get_tax_amount( + &transfer_response.msgs, + remaining_funds.amount, + remaining_funds.amount, + ); + + let refund = if sent_funds.amount > tax_amount { + sent_funds.amount.checked_sub(tax_amount)? + } else { + Uint128::zero() + }; + + let after_tax_payment = Coin { + denom: remaining_funds.denom, + amount: refund, + }; + Ok(Some(( + Funds::Native(after_tax_payment), + transfer_response.msgs, + ))) + } else { + Ok(None) + } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/lib.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/lib.rs new file mode 100644 index 0000000..36553fb --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/lib.rs @@ -0,0 +1,9 @@ +pub mod contract; +mod execute; +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; +mod query; +mod state; + +#[cfg(test)] +mod testing; diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/mock.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/mock.rs new file mode 100644 index 0000000..6e4a4da --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/mock.rs @@ -0,0 +1,112 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +use crate::contract::{execute, instantiate, query}; +use andromeda_data_storage::boolean::{ + Boolean, BooleanRestriction, ExecuteMsg, GetDataOwnerResponse, GetValueResponse, + InstantiateMsg, QueryMsg, +}; +use andromeda_std::ado_base::rates::{Rate, RatesMessage}; +use andromeda_testing::mock::MockApp; +use andromeda_testing::{ + mock_ado, + mock_contract::{ExecuteResult, MockADO, MockContract}, +}; +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockBoolean(Addr); +mock_ado!(MockBoolean, ExecuteMsg, QueryMsg); + +impl MockBoolean { + pub fn instantiate( + code_id: u64, + sender: Addr, + app: &mut MockApp, + kernel_address: String, + owner: Option, + restriction: BooleanRestriction, + ) -> MockBoolean { + let msg = mock_boolean_instantiate_msg(kernel_address, owner, restriction); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "Boolean Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockBoolean(Addr::unchecked(addr)) + } + + pub fn execute_set_value( + &self, + app: &mut MockApp, + sender: Addr, + value: Boolean, + funds: Option, + ) -> ExecuteResult { + let msg = mock_store_value_msg(value); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_add_rate( + &self, + app: &mut MockApp, + sender: Addr, + action: String, + rate: Rate, + ) -> ExecuteResult { + self.execute(app, &mock_set_rate_msg(action, rate), sender, &[]) + } + + pub fn query_value(&self, app: &mut MockApp) -> GetValueResponse { + let msg = mock_boolean_get_value(); + let res: GetValueResponse = self.query(app, msg); + res + } + + pub fn query_data_owner(&self, app: &mut MockApp) -> GetDataOwnerResponse { + let msg = mock_boolean_get_data_owner(); + let res: GetDataOwnerResponse = self.query(app, msg); + res + } +} + +pub fn mock_andromeda_boolean() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} + +pub fn mock_boolean_instantiate_msg( + kernel_address: String, + owner: Option, + restriction: BooleanRestriction, +) -> InstantiateMsg { + InstantiateMsg { + kernel_address, + owner, + restriction, + } +} + +/// Used to generate a message to store a string storage value +pub fn mock_store_value_msg(value: Boolean) -> ExecuteMsg { + ExecuteMsg::SetValue { value } +} + +pub fn mock_set_rate_msg(action: String, rate: Rate) -> ExecuteMsg { + ExecuteMsg::Rates(RatesMessage::SetRate { action, rate }) +} + +pub fn mock_boolean_get_value() -> QueryMsg { + QueryMsg::GetValue {} +} + +pub fn mock_boolean_get_data_owner() -> QueryMsg { + QueryMsg::GetDataOwner {} +} diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/query.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/query.rs new file mode 100644 index 0000000..6765012 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/query.rs @@ -0,0 +1,16 @@ +use crate::state::{DATA, DATA_OWNER}; +use andromeda_data_storage::boolean::{GetDataOwnerResponse, GetValueResponse}; +use andromeda_std::{amp::AndrAddr, error::ContractError}; +use cosmwasm_std::Storage; + +pub fn get_value(storage: &dyn Storage) -> Result { + let value = DATA.load(storage)?; + Ok(GetValueResponse { value }) +} + +pub fn get_data_owner(storage: &dyn Storage) -> Result { + let owner = DATA_OWNER.load(storage)?; + Ok(GetDataOwnerResponse { + owner: AndrAddr::from_string(owner), + }) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/state.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/state.rs new file mode 100644 index 0000000..dc9240e --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/state.rs @@ -0,0 +1,7 @@ +use andromeda_data_storage::boolean::BooleanRestriction; +use cosmwasm_std::Addr; +use cw_storage_plus::Item; + +pub const DATA: Item = Item::new("data"); +pub const DATA_OWNER: Item = Item::new("data_owner"); +pub const RESTRICTION: Item = Item::new("restriction"); diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mock.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mock.rs new file mode 100644 index 0000000..04566a2 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mock.rs @@ -0,0 +1,59 @@ +use crate::contract::{execute, instantiate, query}; +use andromeda_data_storage::boolean::{ + BooleanRestriction, ExecuteMsg, GetValueResponse, InstantiateMsg, QueryMsg, +}; +use andromeda_std::{ + error::ContractError, + testing::mock_querier::{mock_dependencies_custom, WasmMockQuerier, MOCK_KERNEL_CONTRACT}, +}; +use cosmwasm_std::{ + from_json, + testing::{mock_env, mock_info, MockApi, MockStorage}, + Coin, Deps, DepsMut, MessageInfo, OwnedDeps, Response, +}; + +pub type MockDeps = OwnedDeps; + +pub fn proper_initialization(restriction: BooleanRestriction) -> (MockDeps, MessageInfo) { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("creator", &[]); + let msg = InstantiateMsg { + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + restriction, + }; + let env = mock_env(); + instantiate(deps.as_mut(), env, info.clone(), msg).unwrap(); + (deps, info) +} + +pub fn query_value(deps: Deps) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetValue {}); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} + +pub fn set_value(deps: DepsMut<'_>, value: &bool, sender: &str) -> Result { + let msg = ExecuteMsg::SetValue { value: *value }; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn set_value_with_funds( + deps: DepsMut<'_>, + value: &bool, + sender: &str, + coin: Coin, +) -> Result { + let msg = ExecuteMsg::SetValue { value: *value }; + let info = mock_info(sender, &[coin]); + execute(deps, mock_env(), info, msg) +} + +pub fn delete_value(deps: DepsMut<'_>, sender: &str) -> Result { + let msg = ExecuteMsg::DeleteValue {}; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mod.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mod.rs new file mode 100644 index 0000000..3bfda28 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/mod.rs @@ -0,0 +1,2 @@ +mod mock; +mod tests; diff --git a/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/tests.rs b/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/tests.rs new file mode 100644 index 0000000..060bd13 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-boolean/src/testing/tests.rs @@ -0,0 +1,268 @@ +use crate::contract::{execute, query}; +use andromeda_data_storage::boolean::{ + BooleanRestriction, ExecuteMsg, GetDataOwnerResponse, GetValueResponse, QueryMsg, +}; +use cosmwasm_std::{ + coin, from_json, testing::mock_env, BankMsg, CosmosMsg, Decimal, Response, SubMsg, +}; + +use andromeda_std::{ + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate, RatesMessage}, + ado_contract::ADOContract, + amp::{AndrAddr, Recipient}, + error::ContractError, +}; + +use super::mock::{ + delete_value, proper_initialization, query_value, set_value, set_value_with_funds, +}; + +#[test] +fn test_instantiation() { + proper_initialization(BooleanRestriction::Private); +} + +#[test] +fn test_set_and_update_value() { + let (mut deps, info) = proper_initialization(BooleanRestriction::Private); + let value = true; + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + + let query_res: GetValueResponse = query_value(deps.as_ref()).unwrap(); + + assert_eq!(GetValueResponse { value }, query_res); + + let value = true; + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + + let query_res: GetValueResponse = query_value(deps.as_ref()).unwrap(); + + assert_eq!(GetValueResponse { value }, query_res); +} + +#[test] +fn test_set_value_with_tax() { + let (mut deps, info) = proper_initialization(BooleanRestriction::Private); + let value = true; + let tax_recipient = "tax_recipient"; + + // Set percent rates + let set_percent_rate_msg = ExecuteMsg::Rates(RatesMessage::SetRate { + action: "BooleanSetValue".to_string(), + rate: Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::one(), + }), + description: None, + }), + }); + + let err = execute( + deps.as_mut(), + mock_env(), + info.clone(), + set_percent_rate_msg, + ) + .unwrap_err(); + + assert_eq!(err, ContractError::InvalidRate {}); + + let rate: Rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string(tax_recipient.to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(20_u128, "uandr")), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "SetValue", rate) + .unwrap(); + + // Sent the exact amount required for tax + let res = set_value_with_funds( + deps.as_mut(), + &value, + info.sender.as_ref(), + coin(20_u128, "uandr".to_string()), + ) + .unwrap(); + let expected_response: Response = Response::new() + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: tax_recipient.to_string(), + amount: vec![coin(20, "uandr")], + }))) + .add_attributes(vec![("method", "set_value"), ("sender", "creator")]) + .add_attribute("value", format!("{value:?}")); + assert_eq!(expected_response, res); + + // Sent less than amount required for tax + let err = set_value_with_funds( + deps.as_mut(), + &value, + info.sender.as_ref(), + coin(19_u128, "uandr".to_string()), + ) + .unwrap_err(); + assert_eq!(err, ContractError::InsufficientFunds {}); + + // Sent more than required amount for tax + let res = set_value_with_funds( + deps.as_mut(), + &value, + info.sender.as_ref(), + coin(200_u128, "uandr".to_string()), + ) + .unwrap(); + let expected_response: Response = Response::new() + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: tax_recipient.to_string(), + amount: vec![coin(20, "uandr")], + }))) + // 200 was sent, but the tax is only 20, so we send back the difference + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: "creator".to_string(), + amount: vec![coin(180, "uandr")], + }))) + .add_attributes(vec![("method", "set_value"), ("sender", "creator")]) + .add_attribute("value", format!("{value:?}")); + assert_eq!(expected_response, res); +} + +#[test] +fn test_delete_value() { + let (mut deps, info) = proper_initialization(BooleanRestriction::Private); + let value = true; + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + query_value(deps.as_ref()).unwrap_err(); +} + +#[test] +fn test_restriction_private() { + let (mut deps, info) = proper_initialization(BooleanRestriction::Private); + + let value = true; + let external_user = "external".to_string(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user + // This should error + set_value(deps.as_mut(), &value, &external_user).unwrap_err(); + // Set a value by owner so we can test delete for it + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Delete value set by owner by external user + // This will error + delete_value(deps.as_mut(), &external_user).unwrap_err(); + + // Value is still present + query_value(deps.as_ref()).unwrap(); +} + +#[test] +fn test_restriction_public() { + let (mut deps, info) = proper_initialization(BooleanRestriction::Public); + + let value = true; + let external_user = "external".to_string(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user + set_value(deps.as_mut(), &value, &external_user).unwrap(); + delete_value(deps.as_mut(), &external_user).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Delete the value as external user + delete_value(deps.as_mut(), &external_user).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); +} + +#[test] +fn test_restriction_restricted() { + let (mut deps, info) = proper_initialization(BooleanRestriction::Restricted); + + let value = true; + let value2 = false; + let external_user = "external".to_string(); + let external_user2 = "external2".to_string(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user + set_value(deps.as_mut(), &value, &external_user).unwrap(); + delete_value(deps.as_mut(), &external_user).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as owner and try to delete as external user + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Try to modify it as external user + set_value(deps.as_mut(), &value2, &external_user).unwrap_err(); + // Delete the value as external user, this should error + delete_value(deps.as_mut(), &external_user).unwrap_err(); + + query_value(deps.as_ref()).unwrap(); + + // Set Value as external user and try to delete as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Delete the value as external user, this will success as owner has permission to do anything + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user 1 and try to delete as external user 2 + set_value(deps.as_mut(), &value, &external_user).unwrap(); + // Delete the value as external user, this will error + delete_value(deps.as_mut(), &external_user2).unwrap_err(); + + query_value(deps.as_ref()).unwrap(); +} + +#[test] +fn test_query_data_owner() { + let (mut deps, _) = proper_initialization(BooleanRestriction::Restricted); + let external_user = "external".to_string(); + let external_user2 = "external2".to_string(); + let value = true; + set_value(deps.as_mut(), &value, &external_user.clone()).unwrap(); + + let res: GetDataOwnerResponse = + from_json(query(deps.as_ref(), mock_env(), QueryMsg::GetDataOwner {}).unwrap()).unwrap(); + + assert_eq!( + res, + GetDataOwnerResponse { + owner: AndrAddr::from_string(external_user.clone()) + } + ); + + let res = delete_value(deps.as_mut(), &external_user2).unwrap_err(); + assert_eq!(res, ContractError::Unauthorized {}); + + delete_value(deps.as_mut(), &external_user).unwrap(); + + query(deps.as_ref(), mock_env(), QueryMsg::GetDataOwner {}).unwrap_err(); +} diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/.cargo/config b/andromeda-core/contracts/data-storage/andromeda-counter/.cargo/config new file mode 100644 index 0000000..336b618 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/Cargo.toml b/andromeda-core/contracts/data-storage/andromeda-counter/Cargo.toml new file mode 100644 index 0000000..65697c3 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "andromeda-counter" +version = "1.0.2" +authors = ["Mitar Djakovic "] +edition = "2021" +rust-version = "1.75.0" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +testing = ["cw-multi-test", "andromeda-testing"] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +cw20 = { workspace = true } + + +andromeda-std = { workspace = true, features = ["rates"] } +andromeda-data-storage = { workspace = true } + + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/examples/schema.rs b/andromeda-core/contracts/data-storage/andromeda-counter/examples/schema.rs new file mode 100644 index 0000000..1248c18 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/examples/schema.rs @@ -0,0 +1,10 @@ +use andromeda_data_storage::counter::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + + } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/src/contract.rs b/andromeda-core/contracts/data-storage/andromeda-counter/src/contract.rs new file mode 100644 index 0000000..73a3af7 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/src/contract.rs @@ -0,0 +1,301 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + attr, ensure, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, Storage, +}; + +use andromeda_data_storage::counter::{CounterRestriction, ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_data_storage::counter::{ + GetCurrentAmountResponse, GetDecreaseAmountResponse, GetIncreaseAmountResponse, + GetInitialAmountResponse, GetRestrictionResponse, +}; +use andromeda_std::{ + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_contract::ADOContract, + common::{actions::call_action, context::ExecuteContext, encode_binary}, + error::ContractError, +}; +use cw_utils::nonpayable; + +use crate::state::{CURRENT_AMOUNT, DECREASE_AMOUNT, INCREASE_AMOUNT, INITIAL_AMOUNT, RESTRICTION}; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:andromeda-counter"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +const DEFAULT_INITIAL_AMOUNT: u64 = 0; +const DEFAULT_INCREASE_AMOUNT: u64 = 1; +const DEFAULT_DECREASE_AMOUNT: u64 = 1; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let resp = ADOContract::default().instantiate( + deps.storage, + env, + deps.api, + &deps.querier, + info, + BaseInstantiateMsg { + ado_type: CONTRACT_NAME.to_string(), + ado_version: CONTRACT_VERSION.to_string(), + kernel_address: msg.kernel_address, + owner: msg.owner, + }, + )?; + + RESTRICTION.save(deps.storage, &msg.restriction)?; + + let initial_amount = msg + .initial_state + .initial_amount + .unwrap_or(DEFAULT_INITIAL_AMOUNT); + INITIAL_AMOUNT.save(deps.storage, &initial_amount)?; + CURRENT_AMOUNT.save(deps.storage, &initial_amount)?; + + let increase_amount = msg + .initial_state + .increase_amount + .unwrap_or(DEFAULT_INCREASE_AMOUNT); + INCREASE_AMOUNT.save(deps.storage, &increase_amount)?; + + let decrease_amount = msg + .initial_state + .decrease_amount + .unwrap_or(DEFAULT_DECREASE_AMOUNT); + DECREASE_AMOUNT.save(deps.storage, &decrease_amount)?; + + Ok(resp) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let ctx = ExecuteContext::new(deps, info, env); + match msg { + ExecuteMsg::AMPReceive(pkt) => { + ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) + } + _ => handle_execute(ctx, msg), + } +} + +fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + let res = match msg { + ExecuteMsg::Increment {} => execute_increment(ctx, action), + ExecuteMsg::Decrement {} => execute_decrement(ctx, action), + ExecuteMsg::Reset {} => execute_reset(ctx, action), + ExecuteMsg::UpdateRestriction { restriction } => { + execute_update_restriction(ctx, restriction, action) + } + ExecuteMsg::SetIncreaseAmount { increase_amount } => { + execute_set_increase_amount(ctx, increase_amount, action) + } + ExecuteMsg::SetDecreaseAmount { decrease_amount } => { + execute_set_decrease_amount(ctx, decrease_amount, action) + } + _ => ADOContract::default().execute(ctx, msg), + }?; + + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) +} + +pub fn execute_increment(ctx: ExecuteContext, action: String) -> Result { + nonpayable(&ctx.info)?; + + let sender = ctx.info.sender.clone(); + ensure!( + has_permission(ctx.deps.storage, &sender)?, + ContractError::Unauthorized {} + ); + + let increase_amount = INCREASE_AMOUNT.load(ctx.deps.storage)?; + let current_amount = CURRENT_AMOUNT + .load(ctx.deps.storage)? + .checked_add(increase_amount) + .ok_or(ContractError::Overflow {})?; + + CURRENT_AMOUNT.save(ctx.deps.storage, ¤t_amount)?; + + Ok(Response::new().add_attributes(vec![ + attr("action", action), + attr("sender", sender), + attr("current_amount", current_amount.to_string()), + ])) +} + +pub fn execute_decrement(ctx: ExecuteContext, action: String) -> Result { + nonpayable(&ctx.info)?; + + let sender = ctx.info.sender.clone(); + ensure!( + has_permission(ctx.deps.storage, &sender)?, + ContractError::Unauthorized {} + ); + + let decrease_amount = DECREASE_AMOUNT.load(ctx.deps.storage)?; + let current_amount = CURRENT_AMOUNT + .load(ctx.deps.storage)? + .saturating_sub(decrease_amount); + + CURRENT_AMOUNT.save(ctx.deps.storage, ¤t_amount)?; + + Ok(Response::new().add_attributes(vec![ + attr("action", action), + attr("sender", sender), + attr("current_amount", current_amount.to_string()), + ])) +} + +pub fn execute_reset(ctx: ExecuteContext, action: String) -> Result { + let sender = ctx.info.sender.clone(); + ensure!( + has_permission(ctx.deps.storage, &sender)?, + ContractError::Unauthorized {} + ); + + let initial_amount = INITIAL_AMOUNT.load(ctx.deps.storage)?; + CURRENT_AMOUNT.save(ctx.deps.storage, &initial_amount)?; + + Ok(Response::new().add_attributes(vec![ + attr("action", action), + attr("sender", sender), + attr("current_amount", initial_amount.to_string()), + ])) +} + +pub fn execute_update_restriction( + ctx: ExecuteContext, + restriction: CounterRestriction, + action: String, +) -> Result { + nonpayable(&ctx.info)?; + let sender = ctx.info.sender; + ensure!( + ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, + ContractError::Unauthorized {} + ); + RESTRICTION.save(ctx.deps.storage, &restriction)?; + + Ok(Response::new().add_attributes(vec![attr("action", action), attr("sender", sender)])) +} + +pub fn execute_set_increase_amount( + ctx: ExecuteContext, + increase_amount: u64, + action: String, +) -> Result { + let sender = ctx.info.sender; + ensure!( + ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, + ContractError::Unauthorized {} + ); + + INCREASE_AMOUNT.save(ctx.deps.storage, &increase_amount)?; + + Ok(Response::new().add_attributes(vec![ + attr("action", action), + attr("sender", sender), + attr("increase_amount", increase_amount.to_string()), + ])) +} + +pub fn execute_set_decrease_amount( + ctx: ExecuteContext, + decrease_amount: u64, + action: String, +) -> Result { + let sender = ctx.info.sender; + ensure!( + ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, + ContractError::Unauthorized {} + ); + + DECREASE_AMOUNT.save(ctx.deps.storage, &decrease_amount)?; + + Ok(Response::new().add_attributes(vec![ + attr("action", action), + attr("sender", sender), + attr("decrease_amount", decrease_amount.to_string()), + ])) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::GetInitialAmount {} => encode_binary(&get_initial_amount(deps.storage)?), + QueryMsg::GetCurrentAmount {} => encode_binary(&get_current_amount(deps.storage)?), + QueryMsg::GetIncreaseAmount {} => encode_binary(&get_increase_amount(deps.storage)?), + QueryMsg::GetDecreaseAmount {} => encode_binary(&get_decrease_amount(deps.storage)?), + QueryMsg::GetRestriction {} => encode_binary(&get_restriction(deps.storage)?), + _ => ADOContract::default().query(deps, env, msg), + } +} + +pub fn get_initial_amount( + storage: &dyn Storage, +) -> Result { + let initial_amount = INITIAL_AMOUNT.load(storage)?; + Ok(GetInitialAmountResponse { initial_amount }) +} + +pub fn get_current_amount( + storage: &dyn Storage, +) -> Result { + let current_amount = CURRENT_AMOUNT.load(storage)?; + Ok(GetCurrentAmountResponse { current_amount }) +} + +pub fn get_increase_amount( + storage: &dyn Storage, +) -> Result { + let increase_amount = INCREASE_AMOUNT.load(storage)?; + Ok(GetIncreaseAmountResponse { increase_amount }) +} + +pub fn get_decrease_amount( + storage: &dyn Storage, +) -> Result { + let decrease_amount = DECREASE_AMOUNT.load(storage)?; + Ok(GetDecreaseAmountResponse { decrease_amount }) +} + +pub fn get_restriction(storage: &dyn Storage) -> Result { + let restriction = RESTRICTION.load(storage)?; + Ok(GetRestrictionResponse { restriction }) +} + +pub fn has_permission(storage: &dyn Storage, addr: &Addr) -> Result { + let is_operator = ADOContract::default().is_owner_or_operator(storage, addr.as_str())?; + let allowed = match RESTRICTION.load(storage)? { + CounterRestriction::Private => is_operator, + CounterRestriction::Public => true, + }; + Ok(is_operator || allowed) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/src/lib.rs b/andromeda-core/contracts/data-storage/andromeda-counter/src/lib.rs new file mode 100644 index 0000000..bcbc58b --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/src/lib.rs @@ -0,0 +1,7 @@ +pub mod contract; +pub mod state; +#[cfg(test)] +pub mod testing; + +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/src/mock.rs b/andromeda-core/contracts/data-storage/andromeda-counter/src/mock.rs new file mode 100644 index 0000000..a6f4ce3 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/src/mock.rs @@ -0,0 +1,216 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +use crate::contract::{execute, instantiate, query}; +use andromeda_data_storage::counter::{CounterRestriction, ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_data_storage::counter::{ + GetCurrentAmountResponse, GetDecreaseAmountResponse, GetIncreaseAmountResponse, + GetInitialAmountResponse, GetRestrictionResponse, +}; +use andromeda_std::ado_base::rates::{Rate, RatesMessage}; +use andromeda_testing::mock::MockApp; +use andromeda_testing::{ + mock_ado, + mock_contract::{ExecuteResult, MockADO, MockContract}, +}; +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockCounter(Addr); +mock_ado!(MockCounter, ExecuteMsg, QueryMsg); + +impl MockCounter { + pub fn instantiate( + code_id: u64, + sender: Addr, + app: &mut MockApp, + kernel_address: String, + owner: Option, + restriction: CounterRestriction, + initial_amount: Option, + increase_amount: Option, + decrease_amount: Option, + ) -> MockCounter { + let msg = mock_counter_instantiate_msg( + kernel_address, + owner, + restriction, + initial_amount, + increase_amount, + decrease_amount, + ); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "Counter Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockCounter(Addr::unchecked(addr)) + } + + pub fn execute_increment( + &self, + app: &mut MockApp, + sender: Addr, + funds: Option, + ) -> ExecuteResult { + let msg = mock_execute_increment_msg(); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_decrement( + &self, + app: &mut MockApp, + sender: Addr, + funds: Option, + ) -> ExecuteResult { + let msg = mock_execute_increment_msg(); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_reset( + &self, + app: &mut MockApp, + sender: Addr, + funds: Option, + ) -> ExecuteResult { + let msg = mock_execute_reset_msg(); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_update_restriction( + &self, + app: &mut MockApp, + sender: Addr, + restriction: CounterRestriction, + funds: Option, + ) -> ExecuteResult { + let msg = mock_execute_update_restriction_msg(restriction); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_set_increase_amount( + &self, + app: &mut MockApp, + sender: Addr, + increase_amount: u64, + funds: Option, + ) -> ExecuteResult { + let msg = mock_execute_set_increase_amount_msg(increase_amount); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_set_decrease_amount( + &self, + app: &mut MockApp, + sender: Addr, + decrease_amount: u64, + funds: Option, + ) -> ExecuteResult { + let msg = mock_execute_set_decrease_amount_msg(decrease_amount); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn query_initial_amount(&self, app: &mut MockApp) -> GetInitialAmountResponse { + let msg = QueryMsg::GetInitialAmount {}; + let res: GetInitialAmountResponse = self.query(app, msg); + res + } + + pub fn query_current_amount(&self, app: &mut MockApp) -> GetCurrentAmountResponse { + let msg = QueryMsg::GetCurrentAmount {}; + let res: GetCurrentAmountResponse = self.query(app, msg); + res + } + + pub fn query_increase_amount(&self, app: &mut MockApp) -> GetIncreaseAmountResponse { + let msg = QueryMsg::GetIncreaseAmount {}; + let res: GetIncreaseAmountResponse = self.query(app, msg); + res + } + + pub fn query_decrease_amount(&self, app: &mut MockApp) -> GetDecreaseAmountResponse { + let msg = QueryMsg::GetDecreaseAmount {}; + let res: GetDecreaseAmountResponse = self.query(app, msg); + res + } + + pub fn query_restriction(&self, app: &mut MockApp) -> GetRestrictionResponse { + let msg = QueryMsg::GetRestriction {}; + let res: GetRestrictionResponse = self.query(app, msg); + res + } +} + +pub fn mock_andromeda_counter() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} + +pub fn mock_counter_instantiate_msg( + kernel_address: String, + owner: Option, + restriction: CounterRestriction, + initial_amount: Option, + increase_amount: Option, + decrease_amount: Option, +) -> InstantiateMsg { + InstantiateMsg { + kernel_address, + owner, + restriction, + initial_amount, + increase_amount, + decrease_amount, + } +} + +pub fn mock_execute_increment_msg() -> ExecuteMsg { + ExecuteMsg::Increment {} +} + +pub fn mock_execute_decrement_msg() -> ExecuteMsg { + ExecuteMsg::Decrement {} +} + +pub fn mock_execute_reset_msg() -> ExecuteMsg { + ExecuteMsg::Reset {} +} + +pub fn mock_execute_update_restriction_msg(restriction: CounterRestriction) -> ExecuteMsg { + ExecuteMsg::UpdateRestriction { restriction } +} + +pub fn mock_execute_set_increase_amount_msg(increase_amount: u64) -> ExecuteMsg { + ExecuteMsg::SetIncreaseAmount { increase_amount } +} + +pub fn mock_execute_set_decrease_amount_msg(decrease_amount: u64) -> ExecuteMsg { + ExecuteMsg::SetDecreaseAmount { decrease_amount } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/src/state.rs b/andromeda-core/contracts/data-storage/andromeda-counter/src/state.rs new file mode 100644 index 0000000..9112846 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/src/state.rs @@ -0,0 +1,10 @@ +use andromeda_data_storage::counter::CounterRestriction; +use cw_storage_plus::Item; + +pub const INITIAL_AMOUNT: Item = Item::new("initial_amount"); +pub const INCREASE_AMOUNT: Item = Item::new("increase_amount"); +pub const DECREASE_AMOUNT: Item = Item::new("decrease_amount"); + +pub const CURRENT_AMOUNT: Item = Item::new("current_amount"); + +pub const RESTRICTION: Item = Item::new("restriction"); diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mock.rs b/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mock.rs new file mode 100644 index 0000000..7f32bfd --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mock.rs @@ -0,0 +1,124 @@ +use andromeda_data_storage::counter::{CounterRestriction, ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_data_storage::counter::{ + GetCurrentAmountResponse, GetDecreaseAmountResponse, GetIncreaseAmountResponse, + GetInitialAmountResponse, GetRestrictionResponse, State, +}; +use andromeda_std::{ + error::ContractError, + testing::mock_querier::{mock_dependencies_custom, WasmMockQuerier, MOCK_KERNEL_CONTRACT}, +}; +use cosmwasm_std::{ + from_json, + testing::{mock_env, mock_info, MockApi, MockStorage}, + Deps, DepsMut, MessageInfo, OwnedDeps, Response, +}; + +use crate::contract::{execute, instantiate, query}; + +pub type MockDeps = OwnedDeps; + +pub fn proper_initialization( + restriction: CounterRestriction, + initial_state: State, +) -> (MockDeps, MessageInfo) { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("creator", &[]); + let msg = InstantiateMsg { + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + restriction, + initial_state, + }; + let env = mock_env(); + let res = instantiate(deps.as_mut(), env, info.clone(), msg).unwrap(); + assert_eq!(0, res.messages.len()); + (deps, info) +} + +pub fn increment(deps: DepsMut<'_>, sender: &str) -> Result { + let msg = ExecuteMsg::Increment {}; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn decrement(deps: DepsMut<'_>, sender: &str) -> Result { + let msg = ExecuteMsg::Decrement {}; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn reset(deps: DepsMut<'_>, sender: &str) -> Result { + let msg = ExecuteMsg::Reset {}; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn update_restriction( + deps: DepsMut<'_>, + restriction: CounterRestriction, + sender: &str, +) -> Result { + let msg = ExecuteMsg::UpdateRestriction { restriction }; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn set_increase_amount( + deps: DepsMut<'_>, + increase_amount: u64, + sender: &str, +) -> Result { + let msg = ExecuteMsg::SetIncreaseAmount { increase_amount }; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn set_decrease_amount( + deps: DepsMut<'_>, + decrease_amount: u64, + sender: &str, +) -> Result { + let msg = ExecuteMsg::SetDecreaseAmount { decrease_amount }; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn query_initial_amount(deps: Deps) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetInitialAmount {}); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} + +pub fn query_current_amount(deps: Deps) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetCurrentAmount {}); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} + +pub fn query_increase_amount(deps: Deps) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetIncreaseAmount {}); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} + +pub fn query_decrease_amount(deps: Deps) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetDecreaseAmount {}); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} + +pub fn query_restriction(deps: Deps) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetRestriction {}); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mod.rs b/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mod.rs new file mode 100644 index 0000000..3bfda28 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/mod.rs @@ -0,0 +1,2 @@ +mod mock; +mod tests; diff --git a/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/tests.rs b/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/tests.rs new file mode 100644 index 0000000..bfe612f --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-counter/src/testing/tests.rs @@ -0,0 +1,220 @@ +use super::mock::{ + decrement, increment, proper_initialization, query_current_amount, query_decrease_amount, + query_increase_amount, query_initial_amount, query_restriction, reset, set_decrease_amount, + set_increase_amount, update_restriction, +}; +use andromeda_data_storage::counter::{CounterRestriction, State}; +use andromeda_std::error::ContractError; +use cosmwasm_std::Attribute; + +#[test] +fn test_instantiation_private() { + let (deps, _) = proper_initialization( + CounterRestriction::Private, + State { + initial_amount: None, + increase_amount: None, + decrease_amount: None, + }, + ); + let initial_amount = query_initial_amount(deps.as_ref()).unwrap().initial_amount; + assert_eq!(initial_amount, 0); + let increase_amount = query_increase_amount(deps.as_ref()) + .unwrap() + .increase_amount; + assert_eq!(increase_amount, 1); + let decrease_amount = query_decrease_amount(deps.as_ref()) + .unwrap() + .decrease_amount; + assert_eq!(decrease_amount, 1); + let restriction = query_restriction(deps.as_ref()).unwrap().restriction; + assert_eq!(restriction, CounterRestriction::Private); +} + +#[test] +fn test_instantiation_public() { + let (deps, _) = proper_initialization( + CounterRestriction::Public, + State { + initial_amount: None, + increase_amount: None, + decrease_amount: None, + }, + ); + let initial_amount = query_initial_amount(deps.as_ref()).unwrap().initial_amount; + assert_eq!(initial_amount, 0); + let increase_amount = query_increase_amount(deps.as_ref()) + .unwrap() + .increase_amount; + assert_eq!(increase_amount, 1); + let decrease_amount = query_decrease_amount(deps.as_ref()) + .unwrap() + .decrease_amount; + assert_eq!(decrease_amount, 1); + let restriction = query_restriction(deps.as_ref()).unwrap().restriction; + assert_eq!(restriction, CounterRestriction::Public); +} + +#[test] +fn test_update_restriction() { + let (mut deps, info) = proper_initialization( + CounterRestriction::Public, + State { + initial_amount: None, + increase_amount: None, + decrease_amount: None, + }, + ); + let external_user = "external".to_string(); + let res = + update_restriction(deps.as_mut(), CounterRestriction::Private, &external_user).unwrap_err(); + assert_eq!(res, ContractError::Unauthorized {}); + let restriction = query_restriction(deps.as_ref()).unwrap().restriction; + assert_eq!(restriction, CounterRestriction::Public); + update_restriction( + deps.as_mut(), + CounterRestriction::Private, + info.sender.as_ref(), + ) + .unwrap(); + let restriction = query_restriction(deps.as_ref()).unwrap().restriction; + assert_eq!(restriction, CounterRestriction::Private); +} + +#[test] +fn test_increment_decrement() { + let (mut deps, info) = proper_initialization( + CounterRestriction::Private, + State { + initial_amount: None, + increase_amount: None, + decrease_amount: None, + }, + ); + let res = increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + + assert_eq!( + res.attributes, + vec![ + Attribute { + key: "action".to_string(), + value: "Increment".to_string() + }, + Attribute { + key: "sender".to_string(), + value: "creator".to_string() + }, + Attribute { + key: "current_amount".to_string(), + value: 1.to_string() + }, + ] + ); + + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 1); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 2); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 3); + decrement(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 2); + decrement(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 1); + decrement(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 0); + decrement(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 0); +} + +#[test] +fn test_reset_initial_is_0() { + let (mut deps, info) = proper_initialization( + CounterRestriction::Private, + State { + initial_amount: None, + increase_amount: None, + decrease_amount: None, + }, + ); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 3); + + reset(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 0); +} + +#[test] +fn test_reset_initial_is_not_0() { + let (mut deps, info) = proper_initialization( + CounterRestriction::Private, + State { + initial_amount: Some(100), + increase_amount: None, + decrease_amount: None, + }, + ); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + increment(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 103); + + reset(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 100); + decrement(deps.as_mut(), info.sender.as_ref()).unwrap(); + decrement(deps.as_mut(), info.sender.as_ref()).unwrap(); + let current_amount = query_current_amount(deps.as_ref()).unwrap().current_amount; + assert_eq!(current_amount, 98); +} + +#[test] +fn test_set_increase_decrease_amount() { + let (mut deps, info) = proper_initialization( + CounterRestriction::Private, + State { + initial_amount: None, + increase_amount: None, + decrease_amount: None, + }, + ); + set_increase_amount(deps.as_mut(), 5, info.sender.as_ref()).unwrap(); + set_decrease_amount(deps.as_mut(), 5, info.sender.as_ref()).unwrap(); + let external_user = "external".to_string(); + set_increase_amount(deps.as_mut(), 10, &external_user).unwrap_err(); + set_decrease_amount(deps.as_mut(), 10, &external_user).unwrap_err(); + let increase_amount = query_increase_amount(deps.as_ref()) + .unwrap() + .increase_amount; + assert_eq!(increase_amount, 5); + let decrease_amount = query_decrease_amount(deps.as_ref()) + .unwrap() + .decrease_amount; + assert_eq!(decrease_amount, 5); +} + +#[test] +fn test_set_increment_private() { + let (mut deps, _) = proper_initialization( + CounterRestriction::Private, + State { + initial_amount: None, + increase_amount: None, + decrease_amount: None, + }, + ); + let external_user = "external".to_string(); + let res = increment(deps.as_mut(), &external_user).unwrap_err(); + assert_eq!(res, ContractError::Unauthorized {}); +} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/Cargo.toml b/andromeda-core/contracts/data-storage/andromeda-primitive/Cargo.toml index b98aa10..fc2ffa7 100644 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/Cargo.toml +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "andromeda-primitive" -version = "0.2.0" +version = "2.0.3" authors = [ "Connor Barr ", "Anshudhar Kumar Singh ", ] edition = "2021" -rust-version = "1.69.0" +rust-version = "1.75.0" exclude = [ # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. @@ -24,7 +24,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] cosmwasm-std = { workspace = true } @@ -32,12 +32,12 @@ cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw20 = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["module_hooks"] } + +andromeda-std = { workspace = true, features = ["rates"] } andromeda-data-storage = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/README.md b/andromeda-core/contracts/data-storage/andromeda-primitive/README.md new file mode 100644 index 0000000..623fcf7 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/README.md @@ -0,0 +1,21 @@ +# Overview + +The Primitive ADO is a smart contract that is used to store data. It is a simple contract that allows us to store key/value pairs acting like a database. It supports storage of the following data types: + +```rust +pub enum Primitive { + Uint128(Uint128), + Decimal(Decimal), + Coin(Coin), + Addr(Addr), + String(String), + Bool(bool), + Binary(Binary), +} +``` +The Primitive ADO can be set to one of the following: +- Private: Only accessible by the contract owner of the ADO. +- Public: Accessible by anyone. +- Restricted: Only accessible to the key owner. + +**Note**: This ADO is not released yet. Once released, a link to full documentation will be provided. \ No newline at end of file diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/andromeda-primitive.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/andromeda-primitive.json deleted file mode 100644 index 27d7c88..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/andromeda-primitive.json +++ /dev/null @@ -1,1704 +0,0 @@ -{ - "contract_name": "andromeda-primitive", - "contract_version": "0.2.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "restriction" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "restriction": { - "$ref": "#/definitions/PrimitiveRestriction" - } - }, - "additionalProperties": false, - "definitions": { - "PrimitiveRestriction": { - "type": "string", - "enum": [ - "private", - "public", - "restricted" - ] - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "If key is not specified the default key will be used.", - "type": "object", - "required": [ - "set_value" - ], - "properties": { - "set_value": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "key": { - "type": [ - "string", - "null" - ] - }, - "value": { - "$ref": "#/definitions/Primitive" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If key is not specified the default key will be used.", - "type": "object", - "required": [ - "delete_value" - ], - "properties": { - "delete_value": { - "type": "object", - "properties": { - "key": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_restriction" - ], - "properties": { - "update_restriction": { - "type": "object", - "required": [ - "restriction" - ], - "properties": { - "restriction": { - "$ref": "#/definitions/PrimitiveRestriction" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Primitive": { - "oneOf": [ - { - "type": "object", - "required": [ - "uint128" - ], - "properties": { - "uint128": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "decimal" - ], - "properties": { - "decimal": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "coin" - ], - "properties": { - "coin": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "string" - ], - "properties": { - "string": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "bool" - ], - "properties": { - "bool": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vec" - ], - "properties": { - "vec": { - "type": "array", - "items": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "binary" - ], - "properties": { - "binary": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "object" - ], - "properties": { - "object": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - } - ] - }, - "PrimitiveRestriction": { - "type": "string", - "enum": [ - "private", - "public", - "restricted" - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "get_value" - ], - "properties": { - "get_value": { - "type": "object", - "properties": { - "key": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "all_keys" - ], - "properties": { - "all_keys": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner_keys" - ], - "properties": { - "owner_keys": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "all_keys": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "get_value": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetValueResponse", - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Primitive" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Primitive": { - "oneOf": [ - { - "type": "object", - "required": [ - "uint128" - ], - "properties": { - "uint128": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "decimal" - ], - "properties": { - "decimal": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "coin" - ], - "properties": { - "coin": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "string" - ], - "properties": { - "string": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "bool" - ], - "properties": { - "bool": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vec" - ], - "properties": { - "vec": { - "type": "array", - "items": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "binary" - ], - "properties": { - "binary": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "object" - ], - "properties": { - "object": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner_keys": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/execute.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/execute.json deleted file mode 100644 index 48fcf7b..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/execute.json +++ /dev/null @@ -1,721 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "If key is not specified the default key will be used.", - "type": "object", - "required": [ - "set_value" - ], - "properties": { - "set_value": { - "type": "object", - "required": [ - "value" - ], - "properties": { - "key": { - "type": [ - "string", - "null" - ] - }, - "value": { - "$ref": "#/definitions/Primitive" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If key is not specified the default key will be used.", - "type": "object", - "required": [ - "delete_value" - ], - "properties": { - "delete_value": { - "type": "object", - "properties": { - "key": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_restriction" - ], - "properties": { - "update_restriction": { - "type": "object", - "required": [ - "restriction" - ], - "properties": { - "restriction": { - "$ref": "#/definitions/PrimitiveRestriction" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Primitive": { - "oneOf": [ - { - "type": "object", - "required": [ - "uint128" - ], - "properties": { - "uint128": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "decimal" - ], - "properties": { - "decimal": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "coin" - ], - "properties": { - "coin": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "string" - ], - "properties": { - "string": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "bool" - ], - "properties": { - "bool": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vec" - ], - "properties": { - "vec": { - "type": "array", - "items": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "binary" - ], - "properties": { - "binary": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "object" - ], - "properties": { - "object": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - } - ] - }, - "PrimitiveRestriction": { - "type": "string", - "enum": [ - "private", - "public", - "restricted" - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/instantiate.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/instantiate.json deleted file mode 100644 index 6936a04..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/instantiate.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "restriction" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "restriction": { - "$ref": "#/definitions/PrimitiveRestriction" - } - }, - "additionalProperties": false, - "definitions": { - "PrimitiveRestriction": { - "type": "string", - "enum": [ - "private", - "public", - "restricted" - ] - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/query.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/query.json deleted file mode 100644 index 4e217e3..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/query.json +++ /dev/null @@ -1,414 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "get_value" - ], - "properties": { - "get_value": { - "type": "object", - "properties": { - "key": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "all_keys" - ], - "properties": { - "all_keys": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner_keys" - ], - "properties": { - "owner_keys": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_all_keys.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_all_keys.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_all_keys.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6c5ba13..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_balance.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_get_value.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_get_value.json deleted file mode 100644 index ca6cfe2..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_get_value.json +++ /dev/null @@ -1,169 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetValueResponse", - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "type": "string" - }, - "value": { - "$ref": "#/definitions/Primitive" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Primitive": { - "oneOf": [ - { - "type": "object", - "required": [ - "uint128" - ], - "properties": { - "uint128": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "decimal" - ], - "properties": { - "decimal": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "coin" - ], - "properties": { - "coin": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "string" - ], - "properties": { - "string": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "bool" - ], - "properties": { - "bool": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "vec" - ], - "properties": { - "vec": { - "type": "array", - "items": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "binary" - ], - "properties": { - "binary": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "object" - ], - "properties": { - "object": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/Primitive" - } - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_operators.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner_keys.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner_keys.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_owner_keys.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissions.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_type.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_version.json b/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/src/contract.rs b/andromeda-core/contracts/data-storage/andromeda-primitive/src/contract.rs index d2ede94..6d39656 100644 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/src/contract.rs +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/src/contract.rs @@ -1,20 +1,18 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{ensure, Binary, Deps, DepsMut, Env, MessageInfo, Response}; -use cw2::{get_contract_version, set_contract_version}; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response}; -use andromeda_data_storage::primitive::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use andromeda_data_storage::primitive::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, common::{context::ExecuteContext, encode_binary}, - error::{from_semver, ContractError}, + error::ContractError, }; -use semver::Version; use crate::{ execute::handle_execute, - query::{all_keys, get_value, owner_keys}, + query::{all_keys, get_type, get_value, owner_keys}, state::RESTRICTION, }; @@ -29,16 +27,15 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let resp = ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "primitive".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -65,42 +62,14 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::GetValue { key } => encode_binary(&get_value(deps.storage, key)?), + QueryMsg::GetType { key } => encode_binary(&get_type(deps.storage, key)?), QueryMsg::AllKeys {} => encode_binary(&all_keys(deps.storage)?), QueryMsg::OwnerKeys { owner } => encode_binary(&owner_keys(&deps, owner)?), _ => ADOContract::default().query(deps, env, msg), diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/src/execute.rs b/andromeda-core/contracts/data-storage/andromeda-primitive/src/execute.rs index 73fde78..7cf61a6 100644 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/src/execute.rs +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/src/execute.rs @@ -1,8 +1,13 @@ use andromeda_data_storage::primitive::{ExecuteMsg, Primitive, PrimitiveRestriction}; use andromeda_std::{ - ado_contract::ADOContract, common::context::ExecuteContext, error::ContractError, + ado_base::rates::{Rate, RatesMessage}, + ado_contract::ADOContract, + common::{actions::call_action, context::ExecuteContext, rates::get_tax_amount, Funds}, + error::ContractError, +}; +use cosmwasm_std::{ + coin, ensure, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, Response, StdError, SubMsg, Uint128, }; -use cosmwasm_std::{ensure, Response, StdError}; use cw_utils::nonpayable; use crate::{ @@ -10,11 +15,31 @@ use crate::{ state::{DATA, KEY_OWNER, RESTRICTION}, }; -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - match msg { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + match msg.clone() { ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), - ExecuteMsg::SetValue { key, value } => set_value(ctx, key, value), + ExecuteMsg::SetValue { key, value } => set_value(ctx, key, value, action), ExecuteMsg::DeleteValue { key } => delete_value(ctx, key), + ExecuteMsg::Rates(rates_message) => match rates_message { + RatesMessage::SetRate { rate, .. } => match rate { + Rate::Local(local_rate) => { + // Percent rates aren't applicable in this case, so we enforce Flat rates + ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); + ADOContract::default().execute(ctx, msg) + } + Rate::Contract(_) => ADOContract::default().execute(ctx, msg), + }, + RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), + }, _ => ADOContract::default().execute(ctx, msg), } } @@ -39,14 +64,19 @@ pub fn set_value( ctx: ExecuteContext, key: Option, value: Primitive, + action: String, ) -> Result { - nonpayable(&ctx.info)?; - let sender = ctx.info.sender; + let sender = ctx.info.sender.clone(); let key: &str = get_key_or_default(&key); ensure!( has_key_permission(ctx.deps.storage, &sender, key)?, ContractError::Unauthorized {} ); + // Validate the primitive value + value.validate(ctx.deps.api)?; + + let tax_response = tax_set_value(ctx.deps.as_ref(), &ctx.info, action)?; + DATA.update::<_, StdError>(ctx.deps.storage, key, |old| match old { Some(_) => Ok(value.clone()), None => Ok(value.clone()), @@ -57,11 +87,24 @@ pub fn set_value( None => Ok(sender.clone()), })?; - Ok(Response::new() + let mut response = Response::new() .add_attribute("method", "set_value") .add_attribute("sender", sender) .add_attribute("key", key) - .add_attribute("value", format!("{value:?}"))) + .add_attribute("value", format!("{value:?}")); + + if let Some(tax_response) = tax_response { + response = response.add_submessages(tax_response.1); + let refund = tax_response.0.try_get_coin()?; + if !refund.amount.is_zero() { + return Ok(response.add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: ctx.info.sender.into_string(), + amount: vec![refund], + }))); + } + } + + Ok(response) } pub fn delete_value(ctx: ExecuteContext, key: Option) -> Result { @@ -80,3 +123,44 @@ pub fn delete_value(ctx: ExecuteContext, key: Option) -> Result Result)>, ContractError> { + let default_coin = coin(0_u128, "uandr".to_string()); + let sent_funds = info.funds.first().unwrap_or(&default_coin); + + let transfer_response = ADOContract::default().query_deducted_funds( + deps, + action, + Funds::Native(sent_funds.clone()), + )?; + + if let Some(transfer_response) = transfer_response { + let remaining_funds = transfer_response.leftover_funds.try_get_coin()?; + let tax_amount = get_tax_amount( + &transfer_response.msgs, + remaining_funds.amount, + remaining_funds.amount, + ); + + let refund = if sent_funds.amount > tax_amount { + sent_funds.amount.checked_sub(tax_amount)? + } else { + Uint128::zero() + }; + + let after_tax_payment = Coin { + denom: remaining_funds.denom, + amount: refund, + }; + Ok(Some(( + Funds::Native(after_tax_payment), + transfer_response.msgs, + ))) + } else { + Ok(None) + } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/src/mock.rs b/andromeda-core/contracts/data-storage/andromeda-primitive/src/mock.rs index 3302180..2243472 100644 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/src/mock.rs +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/src/mock.rs @@ -2,10 +2,82 @@ use crate::contract::{execute, instantiate, query}; use andromeda_data_storage::primitive::{ - ExecuteMsg, InstantiateMsg, Primitive, PrimitiveRestriction, QueryMsg, + ExecuteMsg, GetTypeResponse, GetValueResponse, InstantiateMsg, Primitive, PrimitiveRestriction, + QueryMsg, }; -use cosmwasm_std::{Addr, Empty}; -use cw_multi_test::{Contract, ContractWrapper}; +use andromeda_std::ado_base::rates::{Rate, RatesMessage}; +use andromeda_testing::mock::MockApp; +use andromeda_testing::{ + mock_ado, + mock_contract::{ExecuteResult, MockADO, MockContract}, +}; +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockPrimitive(Addr); +mock_ado!(MockPrimitive, ExecuteMsg, QueryMsg); + +impl MockPrimitive { + pub fn instantiate( + code_id: u64, + sender: Addr, + app: &mut MockApp, + kernel_address: String, + owner: Option, + restriction: PrimitiveRestriction, + ) -> MockPrimitive { + let msg = mock_primitive_instantiate_msg(kernel_address, owner, restriction); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "Primitive Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockPrimitive(Addr::unchecked(addr)) + } + + pub fn execute_set_value( + &self, + app: &mut MockApp, + sender: Addr, + key: Option, + value: Primitive, + funds: Option, + ) -> ExecuteResult { + let msg = mock_store_value_msg(key, value); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_add_rate( + &self, + app: &mut MockApp, + sender: Addr, + action: String, + rate: Rate, + ) -> ExecuteResult { + self.execute(app, &mock_set_rate_msg(action, rate), sender, &[]) + } + + pub fn query_value(&self, app: &mut MockApp, key: Option) -> GetValueResponse { + let msg = mock_primitive_get_value(key); + let res: GetValueResponse = self.query(app, msg); + res + } + + pub fn query_type(&self, app: &mut MockApp, key: Option) -> GetTypeResponse { + let msg = mock_primitive_get_type(key); + let res: GetTypeResponse = self.query(app, msg); + res + } +} pub fn mock_andromeda_primitive() -> Box> { let contract = ContractWrapper::new_with_empty(execute, instantiate, query); @@ -37,6 +109,14 @@ pub fn mock_store_address_msgs(key: String, address: Addr) -> ExecuteMsg { } } +pub fn mock_set_rate_msg(action: String, rate: Rate) -> ExecuteMsg { + ExecuteMsg::Rates(RatesMessage::SetRate { action, rate }) +} + pub fn mock_primitive_get_value(key: Option) -> QueryMsg { QueryMsg::GetValue { key } } + +pub fn mock_primitive_get_type(key: Option) -> QueryMsg { + QueryMsg::GetType { key } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/src/query.rs b/andromeda-core/contracts/data-storage/andromeda-primitive/src/query.rs index 0b987d8..4dfb8c3 100644 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/src/query.rs +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/src/query.rs @@ -1,5 +1,5 @@ use crate::state::{DATA, DEFAULT_KEY, KEY_OWNER, RESTRICTION}; -use andromeda_data_storage::primitive::{GetValueResponse, PrimitiveRestriction}; +use andromeda_data_storage::primitive::{GetTypeResponse, GetValueResponse, PrimitiveRestriction}; use andromeda_std::{ado_contract::ADOContract, amp::AndrAddr, error::ContractError}; use cosmwasm_std::{Addr, Deps, Storage}; @@ -56,3 +56,12 @@ pub fn get_value( value, }) } + +pub fn get_type( + storage: &dyn Storage, + key: Option, +) -> Result { + let key = get_key_or_default(&key); + let value_type = DATA.load(storage, key)?.to_string(); + Ok(GetTypeResponse { value_type }) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/mock.rs b/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/mock.rs index 6f056c8..b9918fd 100644 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/mock.rs +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/mock.rs @@ -8,7 +8,7 @@ use andromeda_std::{ use cosmwasm_std::{ from_json, testing::{mock_env, mock_info, MockApi, MockStorage}, - Deps, DepsMut, MessageInfo, OwnedDeps, Response, + Coin, Deps, DepsMut, MessageInfo, OwnedDeps, Response, }; use crate::contract::{execute, instantiate, query}; @@ -50,6 +50,21 @@ pub fn set_value( execute(deps, mock_env(), info, msg) } +pub fn set_value_with_funds( + deps: DepsMut<'_>, + key: &Option, + value: &Primitive, + sender: &str, + coin: Coin, +) -> Result { + let msg = ExecuteMsg::SetValue { + key: key.clone(), + value: value.clone(), + }; + let info = mock_info(sender, &[coin]); + execute(deps, mock_env(), info, msg) +} + pub fn delete_value( deps: DepsMut<'_>, key: &Option, diff --git a/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/tests.rs b/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/tests.rs index c7bcfa6..70ff41c 100644 --- a/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/tests.rs +++ b/andromeda-core/contracts/data-storage/andromeda-primitive/src/testing/tests.rs @@ -1,14 +1,22 @@ -use cosmwasm_schema::schemars::Map; -use cosmwasm_std::{from_json, testing::mock_env}; - -use crate::{contract::query, state::DEFAULT_KEY}; +use crate::contract::{execute, query}; use andromeda_data_storage::primitive::{ - GetValueResponse, Primitive, PrimitiveRestriction, QueryMsg, + ExecuteMsg, GetValueResponse, Primitive, PrimitiveRestriction, QueryMsg, +}; +use cosmwasm_std::{ + coin, from_json, testing::mock_env, BankMsg, Binary, CosmosMsg, Decimal, Response, SubMsg, }; -use andromeda_std::amp::AndrAddr; +use andromeda_std::{ + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate, RatesMessage}, + ado_contract::ADOContract, + amp::{AndrAddr, Recipient}, + error::ContractError, + testing::mock_querier::mock_dependencies_custom, +}; -use super::mock::{delete_value, proper_initialization, query_value, set_value}; +use super::mock::{ + delete_value, proper_initialization, query_value, set_value, set_value_with_funds, +}; #[test] fn test_instantiation() { @@ -18,32 +26,172 @@ fn test_instantiation() { #[test] fn test_set_and_update_value_with_key() { let (mut deps, info) = proper_initialization(PrimitiveRestriction::Private); - let key = Some(String::from("key")); + let key = String::from("key"); let value = Primitive::String("value".to_string()); - set_value(deps.as_mut(), &key, &value, info.sender.as_ref()).unwrap(); + set_value( + deps.as_mut(), + &Some(key.clone()), + &value, + info.sender.as_ref(), + ) + .unwrap(); - let query_res: GetValueResponse = query_value(deps.as_ref(), &key).unwrap(); + let query_res: GetValueResponse = query_value(deps.as_ref(), &Some(key.clone())).unwrap(); assert_eq!( GetValueResponse { - key: key.clone().unwrap_or("default".into()), + key: key.clone(), value }, query_res ); let value = Primitive::String("value2".to_string()); - set_value(deps.as_mut(), &key, &value, info.sender.as_ref()).unwrap(); + set_value( + deps.as_mut(), + &Some(key.clone()), + &value, + info.sender.as_ref(), + ) + .unwrap(); - let query_res: GetValueResponse = query_value(deps.as_ref(), &key).unwrap(); + let query_res: GetValueResponse = query_value(deps.as_ref(), &Some(key.clone())).unwrap(); + assert_eq!(GetValueResponse { key, value }, query_res); +} + +#[test] +fn test_set_value_with_tax() { + let (mut deps, info) = proper_initialization(PrimitiveRestriction::Private); + let key = String::from("key"); + let value = Primitive::String("value".to_string()); + let tax_recipient = "tax_recipient"; + + // Set percent rates + let set_percent_rate_msg = ExecuteMsg::Rates(RatesMessage::SetRate { + action: "PrimitiveSetValue".to_string(), + rate: Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::one(), + }), + description: None, + }), + }); + + let err = execute( + deps.as_mut(), + mock_env(), + info.clone(), + set_percent_rate_msg, + ) + .unwrap_err(); + + assert_eq!(err, ContractError::InvalidRate {}); + + // Make sure sender is set as recipient when the recipients vector is empty + let rate: Rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![], + value: LocalRateValue::Flat(coin(20_u128, "uandr")), + description: None, + }); + + let msg = ExecuteMsg::Rates(RatesMessage::SetRate { + action: "SetValue".to_string(), + rate, + }); + execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); + + let queried_rates = ADOContract::default() + .get_rates(deps.as_ref(), "SetValue".to_string()) + .unwrap(); assert_eq!( - GetValueResponse { - key: key.unwrap_or("default".into()), - value - }, - query_res + queried_rates.unwrap(), + Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient::new(AndrAddr::from_string("creator"), None)], + value: LocalRateValue::Flat(coin(20_u128, "uandr")), + description: None, + }) ); + + let rate: Rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string(tax_recipient.to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(20_u128, "uandr")), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "SetValue", rate) + .unwrap(); + + // Sent the exact amount required for tax + let res = set_value_with_funds( + deps.as_mut(), + &Some(key.clone()), + &value, + info.sender.as_ref(), + coin(20_u128, "uandr".to_string()), + ) + .unwrap(); + let expected_response: Response = Response::new() + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: tax_recipient.to_string(), + amount: vec![coin(20, "uandr")], + }))) + .add_attributes(vec![ + ("method", "set_value"), + ("sender", "creator"), + ("key", "key"), + ]) + .add_attribute("value", format!("{value:?}")); + assert_eq!(expected_response, res); + + // Sent less than amount required for tax + let err = set_value_with_funds( + deps.as_mut(), + &Some(key.clone()), + &value, + info.sender.as_ref(), + coin(19_u128, "uandr".to_string()), + ) + .unwrap_err(); + assert_eq!(err, ContractError::InsufficientFunds {}); + + // Sent more than required amount for tax + let res = set_value_with_funds( + deps.as_mut(), + &Some(key.clone()), + &value, + info.sender.as_ref(), + coin(200_u128, "uandr".to_string()), + ) + .unwrap(); + let expected_response: Response = Response::new() + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: tax_recipient.to_string(), + amount: vec![coin(20, "uandr")], + }))) + // 200 was sent, but the tax is only 20, so we send back the difference + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: "creator".to_string(), + amount: vec![coin(180, "uandr")], + }))) + .add_attributes(vec![ + ("method", "set_value"), + ("sender", "creator"), + ("key", "key"), + ]) + .add_attribute("value", format!("{value:?}")); + assert_eq!(expected_response, res); } #[test] @@ -70,13 +218,53 @@ fn test_set_and_update_value_without_key() { assert_eq!( GetValueResponse { - key: key.unwrap_or("default".into()), + key: "default".to_string(), value }, query_res ); } +struct TestHandlePrimitive { + name: &'static str, + primitive: Primitive, + expected_error: Option, +} + +#[test] +fn test_set_value_invalid() { + let test_cases = vec![ + TestHandlePrimitive { + name: "Empty String", + primitive: Primitive::String("".to_string()), + expected_error: Some(ContractError::EmptyString {}), + }, + TestHandlePrimitive { + name: "Empty coin denom", + primitive: Primitive::Coin(coin(1_u128, "".to_string())), + expected_error: Some(ContractError::InvalidDenom { msg: None }), + }, + TestHandlePrimitive { + name: "Empty Binary", + primitive: Primitive::Binary(Binary::default()), + expected_error: Some(ContractError::EmptyString {}), + }, + ]; + + for test in test_cases { + let deps = mock_dependencies_custom(&[]); + + let res = test.primitive.validate(&deps.api); + + if let Some(err) = test.expected_error { + assert_eq!(res.unwrap_err(), err, "{}", test.name); + continue; + } + + assert!(res.is_ok()) + } +} + #[test] fn test_delete_value() { let (mut deps, info) = proper_initialization(PrimitiveRestriction::Private); @@ -270,29 +458,3 @@ fn test_query_owner_keys() { .unwrap(); assert!(res.len() == 2, "assertion failed {res:?}", res = res); } - -#[test] -fn test_set_object() { - let (mut deps, info) = proper_initialization(PrimitiveRestriction::Private); - - let mut map = Map::new(); - map.insert("key".to_string(), Primitive::Bool(true)); - - set_value( - deps.as_mut(), - &None, - &Primitive::Object(map.clone()), - info.sender.as_ref(), - ) - .unwrap(); - - let query_res: GetValueResponse = query_value(deps.as_ref(), &None).unwrap(); - - assert_eq!( - GetValueResponse { - key: DEFAULT_KEY.to_string(), - value: Primitive::Object(map.clone()) - }, - query_res - ); -} diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/.cargo/config b/andromeda-core/contracts/data-storage/andromeda-string-storage/.cargo/config new file mode 100644 index 0000000..336b618 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/Cargo.toml b/andromeda-core/contracts/data-storage/andromeda-string-storage/Cargo.toml new file mode 100644 index 0000000..7c824e6 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "andromeda-string-storage" +version = "1.0.2" +authors = ["Mitar Djakovic "] +edition = "2021" +rust-version = "1.75.0" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +testing = ["cw-multi-test", "andromeda-testing"] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +cw20 = { workspace = true } + + +andromeda-std = { workspace = true, features = ["rates"] } +andromeda-data-storage = { workspace = true } + + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/examples/schema.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/examples/schema.rs new file mode 100644 index 0000000..6e88537 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/examples/schema.rs @@ -0,0 +1,10 @@ +use andromeda_data_storage::string_storage::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + + } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/contract.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/contract.rs new file mode 100644 index 0000000..2662d51 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/contract.rs @@ -0,0 +1,74 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response}; + +use crate::{ + execute::handle_execute, + query::{get_data_owner, get_value}, + state::RESTRICTION, +}; +use andromeda_data_storage::string_storage::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::{ + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_contract::ADOContract, + common::{context::ExecuteContext, encode_binary}, + error::ContractError, +}; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:andromeda-string-storage"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let resp = ADOContract::default().instantiate( + deps.storage, + env, + deps.api, + &deps.querier, + info, + BaseInstantiateMsg { + ado_type: CONTRACT_NAME.to_string(), + ado_version: CONTRACT_VERSION.to_string(), + kernel_address: msg.kernel_address, + owner: msg.owner, + }, + )?; + RESTRICTION.save(deps.storage, &msg.restriction)?; + Ok(resp) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let ctx = ExecuteContext::new(deps, info, env); + match msg { + ExecuteMsg::AMPReceive(pkt) => { + ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) + } + _ => handle_execute(ctx, msg), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::GetValue {} => encode_binary(&get_value(deps.storage)?), + QueryMsg::GetDataOwner {} => encode_binary(&get_data_owner(deps.storage)?), + _ => ADOContract::default().query(deps, env, msg), + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/execute.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/execute.rs new file mode 100644 index 0000000..70120fb --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/execute.rs @@ -0,0 +1,153 @@ +use andromeda_data_storage::string_storage::{ExecuteMsg, StringStorage, StringStorageRestriction}; +use andromeda_std::{ + ado_base::rates::{Rate, RatesMessage}, + ado_contract::ADOContract, + common::{actions::call_action, context::ExecuteContext, rates::get_tax_amount, Funds}, + error::ContractError, +}; +use cosmwasm_std::{ + coin, ensure, BankMsg, Coin, CosmosMsg, Deps, MessageInfo, Response, SubMsg, Uint128, +}; +use cw_utils::nonpayable; + +use crate::{ + query::has_permission, + state::{DATA, DATA_OWNER, RESTRICTION}, +}; + +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + match msg.clone() { + ExecuteMsg::UpdateRestriction { restriction } => update_restriction(ctx, restriction), + ExecuteMsg::SetValue { value } => set_value(ctx, value, action), + ExecuteMsg::DeleteValue {} => delete_value(ctx), + ExecuteMsg::Rates(rates_message) => match rates_message { + RatesMessage::SetRate { rate, .. } => match rate { + Rate::Local(local_rate) => { + // Percent rates aren't applicable in this case, so we enforce Flat rates + ensure!(local_rate.value.is_flat(), ContractError::InvalidRate {}); + ADOContract::default().execute(ctx, msg) + } + Rate::Contract(_) => ADOContract::default().execute(ctx, msg), + }, + RatesMessage::RemoveRate { .. } => ADOContract::default().execute(ctx, msg), + }, + _ => ADOContract::default().execute(ctx, msg), + } +} + +pub fn update_restriction( + ctx: ExecuteContext, + restriction: StringStorageRestriction, +) -> Result { + nonpayable(&ctx.info)?; + let sender = ctx.info.sender; + ensure!( + ADOContract::default().is_owner_or_operator(ctx.deps.storage, sender.as_ref())?, + ContractError::Unauthorized {} + ); + RESTRICTION.save(ctx.deps.storage, &restriction)?; + Ok(Response::new() + .add_attribute("method", "update_restriction") + .add_attribute("sender", sender)) +} + +pub fn set_value( + ctx: ExecuteContext, + value: StringStorage, + action: String, +) -> Result { + let sender = ctx.info.sender.clone(); + ensure!( + has_permission(ctx.deps.storage, &sender)?, + ContractError::Unauthorized {} + ); + + value.validate()?; + + let tax_response = tax_set_value(ctx.deps.as_ref(), &ctx.info, action)?; + + DATA.save(ctx.deps.storage, &value.clone())?; + DATA_OWNER.save(ctx.deps.storage, &sender)?; + + let mut response = Response::new() + .add_attribute("method", "set_value") + .add_attribute("sender", sender) + .add_attribute("value", format!("{value:?}")); + + if let Some(tax_response) = tax_response { + response = response.add_submessages(tax_response.1); + let refund = tax_response.0.try_get_coin()?; + if !refund.amount.is_zero() { + return Ok(response.add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: ctx.info.sender.into_string(), + amount: vec![refund], + }))); + } + } + + Ok(response) +} + +pub fn delete_value(ctx: ExecuteContext) -> Result { + nonpayable(&ctx.info)?; + let sender = ctx.info.sender; + ensure!( + has_permission(ctx.deps.storage, &sender)?, + ContractError::Unauthorized {} + ); + DATA.remove(ctx.deps.storage); + DATA_OWNER.remove(ctx.deps.storage); + Ok(Response::new() + .add_attribute("method", "delete_value") + .add_attribute("sender", sender)) +} + +fn tax_set_value( + deps: Deps, + info: &MessageInfo, + action: String, +) -> Result)>, ContractError> { + let default_coin = coin(0_u128, "uandr".to_string()); + let sent_funds = info.funds.first().unwrap_or(&default_coin); + + let transfer_response = ADOContract::default().query_deducted_funds( + deps, + action, + Funds::Native(sent_funds.clone()), + )?; + + if let Some(transfer_response) = transfer_response { + let remaining_funds = transfer_response.leftover_funds.try_get_coin()?; + let tax_amount = get_tax_amount( + &transfer_response.msgs, + remaining_funds.amount, + remaining_funds.amount, + ); + + let refund = if sent_funds.amount > tax_amount { + sent_funds.amount.checked_sub(tax_amount)? + } else { + Uint128::zero() + }; + + let after_tax_payment = Coin { + denom: remaining_funds.denom, + amount: refund, + }; + Ok(Some(( + Funds::Native(after_tax_payment), + transfer_response.msgs, + ))) + } else { + Ok(None) + } +} diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/lib.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/lib.rs new file mode 100644 index 0000000..36553fb --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/lib.rs @@ -0,0 +1,9 @@ +pub mod contract; +mod execute; +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; +mod query; +mod state; + +#[cfg(test)] +mod testing; diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/mock.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/mock.rs new file mode 100644 index 0000000..bd37664 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/mock.rs @@ -0,0 +1,112 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +use crate::contract::{execute, instantiate, query}; +use andromeda_data_storage::string_storage::{ + ExecuteMsg, GetDataOwnerResponse, GetValueResponse, InstantiateMsg, QueryMsg, StringStorage, + StringStorageRestriction, +}; +use andromeda_std::ado_base::rates::{Rate, RatesMessage}; +use andromeda_testing::mock::MockApp; +use andromeda_testing::{ + mock_ado, + mock_contract::{ExecuteResult, MockADO, MockContract}, +}; +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockStringStorage(Addr); +mock_ado!(MockStringStorage, ExecuteMsg, QueryMsg); + +impl MockStringStorage { + pub fn instantiate( + code_id: u64, + sender: Addr, + app: &mut MockApp, + kernel_address: String, + owner: Option, + restriction: StringStorageRestriction, + ) -> MockStringStorage { + let msg = mock_string_storage_instantiate_msg(kernel_address, owner, restriction); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "String Storage Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockStringStorage(Addr::unchecked(addr)) + } + + pub fn execute_set_value( + &self, + app: &mut MockApp, + sender: Addr, + value: StringStorage, + funds: Option, + ) -> ExecuteResult { + let msg = mock_store_value_msg(value); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn execute_add_rate( + &self, + app: &mut MockApp, + sender: Addr, + action: String, + rate: Rate, + ) -> ExecuteResult { + self.execute(app, &mock_set_rate_msg(action, rate), sender, &[]) + } + + pub fn query_value(&self, app: &mut MockApp) -> GetValueResponse { + let msg = mock_string_storage_get_value(); + let res: GetValueResponse = self.query(app, msg); + res + } + + pub fn query_data_owner(&self, app: &mut MockApp) -> GetDataOwnerResponse { + let msg = mock_string_storage_get_data_owner(); + let res: GetDataOwnerResponse = self.query(app, msg); + res + } +} + +pub fn mock_andromeda_string_storage() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} + +pub fn mock_string_storage_instantiate_msg( + kernel_address: String, + owner: Option, + restriction: StringStorageRestriction, +) -> InstantiateMsg { + InstantiateMsg { + kernel_address, + owner, + restriction, + } +} + +/// Used to generate a message to store a string storage value +pub fn mock_store_value_msg(value: StringStorage) -> ExecuteMsg { + ExecuteMsg::SetValue { value } +} + +pub fn mock_set_rate_msg(action: String, rate: Rate) -> ExecuteMsg { + ExecuteMsg::Rates(RatesMessage::SetRate { action, rate }) +} + +pub fn mock_string_storage_get_value() -> QueryMsg { + QueryMsg::GetValue {} +} + +pub fn mock_string_storage_get_data_owner() -> QueryMsg { + QueryMsg::GetDataOwner {} +} diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/query.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/query.rs new file mode 100644 index 0000000..013fc2f --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/query.rs @@ -0,0 +1,31 @@ +use crate::state::{DATA, DATA_OWNER, RESTRICTION}; +use andromeda_data_storage::string_storage::{ + GetDataOwnerResponse, GetValueResponse, StringStorageRestriction, +}; +use andromeda_std::{ado_contract::ADOContract, amp::AndrAddr, error::ContractError}; +use cosmwasm_std::{Addr, Storage}; + +pub fn has_permission(storage: &dyn Storage, addr: &Addr) -> Result { + let is_operator = ADOContract::default().is_owner_or_operator(storage, addr.as_str())?; + let allowed = match RESTRICTION.load(storage)? { + StringStorageRestriction::Private => is_operator, + StringStorageRestriction::Public => true, + StringStorageRestriction::Restricted => match DATA_OWNER.load(storage).ok() { + Some(owner) => addr == owner, + None => true, + }, + }; + Ok(is_operator || allowed) +} + +pub fn get_value(storage: &dyn Storage) -> Result { + let value = DATA.load(storage)?.into(); + Ok(GetValueResponse { value }) +} + +pub fn get_data_owner(storage: &dyn Storage) -> Result { + let owner = DATA_OWNER.load(storage)?; + Ok(GetDataOwnerResponse { + owner: AndrAddr::from_string(owner), + }) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/state.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/state.rs new file mode 100644 index 0000000..9424f34 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/state.rs @@ -0,0 +1,7 @@ +use andromeda_data_storage::string_storage::{StringStorage, StringStorageRestriction}; +use cosmwasm_std::Addr; +use cw_storage_plus::Item; + +pub const DATA: Item = Item::new("data"); +pub const DATA_OWNER: Item = Item::new("data_owner"); +pub const RESTRICTION: Item = Item::new("restriction"); diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mock.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mock.rs new file mode 100644 index 0000000..db8278c --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mock.rs @@ -0,0 +1,68 @@ +use andromeda_data_storage::string_storage::{ + ExecuteMsg, GetValueResponse, InstantiateMsg, QueryMsg, StringStorage, StringStorageRestriction, +}; +use andromeda_std::{ + error::ContractError, + testing::mock_querier::{mock_dependencies_custom, WasmMockQuerier, MOCK_KERNEL_CONTRACT}, +}; +use cosmwasm_std::{ + from_json, + testing::{mock_env, mock_info, MockApi, MockStorage}, + Coin, Deps, DepsMut, MessageInfo, OwnedDeps, Response, +}; + +use crate::contract::{execute, instantiate, query}; + +pub type MockDeps = OwnedDeps; + +pub fn proper_initialization(restriction: StringStorageRestriction) -> (MockDeps, MessageInfo) { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("creator", &[]); + let msg = InstantiateMsg { + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + restriction, + }; + let env = mock_env(); + instantiate(deps.as_mut(), env, info.clone(), msg).unwrap(); + (deps, info) +} + +pub fn query_value(deps: Deps) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetValue {}); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} + +pub fn set_value( + deps: DepsMut<'_>, + value: &StringStorage, + sender: &str, +) -> Result { + let msg = ExecuteMsg::SetValue { + value: value.clone(), + }; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} + +pub fn set_value_with_funds( + deps: DepsMut<'_>, + value: &StringStorage, + sender: &str, + coin: Coin, +) -> Result { + let msg = ExecuteMsg::SetValue { + value: value.clone(), + }; + let info = mock_info(sender, &[coin]); + execute(deps, mock_env(), info, msg) +} + +pub fn delete_value(deps: DepsMut<'_>, sender: &str) -> Result { + let msg = ExecuteMsg::DeleteValue {}; + let info = mock_info(sender, &[]); + execute(deps, mock_env(), info, msg) +} diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mod.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mod.rs new file mode 100644 index 0000000..3bfda28 --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/mod.rs @@ -0,0 +1,2 @@ +mod mock; +mod tests; diff --git a/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/tests.rs b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/tests.rs new file mode 100644 index 0000000..df9cc8b --- /dev/null +++ b/andromeda-core/contracts/data-storage/andromeda-string-storage/src/testing/tests.rs @@ -0,0 +1,305 @@ +use crate::contract::{execute, query}; +use andromeda_data_storage::string_storage::{ + ExecuteMsg, GetDataOwnerResponse, GetValueResponse, QueryMsg, StringStorage, + StringStorageRestriction, +}; +use cosmwasm_std::{ + coin, from_json, testing::mock_env, BankMsg, CosmosMsg, Decimal, Response, SubMsg, +}; + +use andromeda_std::{ + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate, RatesMessage}, + ado_contract::ADOContract, + amp::{AndrAddr, Recipient}, + error::ContractError, +}; + +use super::mock::{ + delete_value, proper_initialization, query_value, set_value, set_value_with_funds, +}; + +#[test] +fn test_instantiation() { + proper_initialization(StringStorageRestriction::Private); +} + +#[test] +fn test_set_and_update_value() { + let (mut deps, info) = proper_initialization(StringStorageRestriction::Private); + let value = StringStorage::String("value".to_string()); + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + + let query_res: GetValueResponse = query_value(deps.as_ref()).unwrap(); + + assert_eq!( + GetValueResponse { + value: value.into() + }, + query_res + ); + + let value = StringStorage::String("value2".to_string()); + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + + let query_res: GetValueResponse = query_value(deps.as_ref()).unwrap(); + + assert_eq!( + GetValueResponse { + value: value.into() + }, + query_res + ); +} + +#[test] +fn test_set_value_with_tax() { + let (mut deps, info) = proper_initialization(StringStorageRestriction::Private); + let value = StringStorage::String("value".to_string()); + let tax_recipient = "tax_recipient"; + + // Set percent rates + let set_percent_rate_msg = ExecuteMsg::Rates(RatesMessage::SetRate { + action: "StringStorageSetValue".to_string(), + rate: Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::one(), + }), + description: None, + }), + }); + + let err = execute( + deps.as_mut(), + mock_env(), + info.clone(), + set_percent_rate_msg, + ) + .unwrap_err(); + + assert_eq!(err, ContractError::InvalidRate {}); + + let rate: Rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string(tax_recipient.to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(20_u128, "uandr")), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "SetValue", rate) + .unwrap(); + + // Sent the exact amount required for tax + let res = set_value_with_funds( + deps.as_mut(), + &value, + info.sender.as_ref(), + coin(20_u128, "uandr".to_string()), + ) + .unwrap(); + let expected_response: Response = Response::new() + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: tax_recipient.to_string(), + amount: vec![coin(20, "uandr")], + }))) + .add_attributes(vec![("method", "set_value"), ("sender", "creator")]) + .add_attribute("value", format!("{value:?}")); + assert_eq!(expected_response, res); + + // Sent less than amount required for tax + let err = set_value_with_funds( + deps.as_mut(), + &value, + info.sender.as_ref(), + coin(19_u128, "uandr".to_string()), + ) + .unwrap_err(); + assert_eq!(err, ContractError::InsufficientFunds {}); + + // Sent more than required amount for tax + let res = set_value_with_funds( + deps.as_mut(), + &value, + info.sender.as_ref(), + coin(200_u128, "uandr".to_string()), + ) + .unwrap(); + let expected_response: Response = Response::new() + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: tax_recipient.to_string(), + amount: vec![coin(20, "uandr")], + }))) + // 200 was sent, but the tax is only 20, so we send back the difference + .add_submessage(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: "creator".to_string(), + amount: vec![coin(180, "uandr")], + }))) + .add_attributes(vec![("method", "set_value"), ("sender", "creator")]) + .add_attribute("value", format!("{value:?}")); + assert_eq!(expected_response, res); +} + +struct TestHandleStringStorage { + name: &'static str, + string_storage: StringStorage, + expected_error: Option, +} + +#[test] +fn test_set_value_invalid() { + let test_cases = vec![TestHandleStringStorage { + name: "Empty String", + string_storage: StringStorage::String("".to_string()), + expected_error: Some(ContractError::EmptyString {}), + }]; + + for test in test_cases { + let res = test.string_storage.validate(); + + if let Some(err) = test.expected_error { + assert_eq!(res.unwrap_err(), err, "{}", test.name); + continue; + } + + assert!(res.is_ok()) + } +} + +#[test] +fn test_delete_value() { + let (mut deps, info) = proper_initialization(StringStorageRestriction::Private); + let value = StringStorage::String("value".to_string()); + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + query_value(deps.as_ref()).unwrap_err(); +} + +#[test] +fn test_restriction_private() { + let (mut deps, info) = proper_initialization(StringStorageRestriction::Private); + + let value = StringStorage::String("value".to_string()); + let external_user = "external".to_string(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user + // This should error + set_value(deps.as_mut(), &value, &external_user).unwrap_err(); + // Set a value by owner so we can test delete for it + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Delete value set by owner by external user + // This will error + delete_value(deps.as_mut(), &external_user).unwrap_err(); + + // Value is still present + query_value(deps.as_ref()).unwrap(); +} + +#[test] +fn test_restriction_public() { + let (mut deps, info) = proper_initialization(StringStorageRestriction::Public); + + let value = StringStorage::String("value".to_string()); + let external_user = "external".to_string(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user + set_value(deps.as_mut(), &value, &external_user).unwrap(); + delete_value(deps.as_mut(), &external_user).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Delete the value as external user + delete_value(deps.as_mut(), &external_user).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); +} + +#[test] +fn test_restriction_restricted() { + let (mut deps, info) = proper_initialization(StringStorageRestriction::Restricted); + + let value = StringStorage::String("value".to_string()); + let value2 = StringStorage::String("value2".to_string()); + let external_user = "external".to_string(); + let external_user2 = "external2".to_string(); + + // Set Value as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user + set_value(deps.as_mut(), &value, &external_user).unwrap(); + delete_value(deps.as_mut(), &external_user).unwrap(); + // This should error + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as owner and try to delete as external user + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Try to modify it as external user + set_value(deps.as_mut(), &value2, &external_user).unwrap_err(); + // Delete the value as external user, this should error + delete_value(deps.as_mut(), &external_user).unwrap_err(); + + query_value(deps.as_ref()).unwrap(); + + // Set Value as external user and try to delete as owner + set_value(deps.as_mut(), &value, info.sender.as_ref()).unwrap(); + // Delete the value as external user, this will success as owner has permission to do anything + delete_value(deps.as_mut(), info.sender.as_ref()).unwrap(); + + query_value(deps.as_ref()).unwrap_err(); + + // Set Value as external user 1 and try to delete as external user 2 + set_value(deps.as_mut(), &value, &external_user).unwrap(); + // Delete the value as external user, this will error + delete_value(deps.as_mut(), &external_user2).unwrap_err(); + + query_value(deps.as_ref()).unwrap(); +} + +#[test] +fn test_query_data_owner() { + let (mut deps, _) = proper_initialization(StringStorageRestriction::Restricted); + let external_user = "external".to_string(); + let external_user2 = "external2".to_string(); + let value = StringStorage::String("value".to_string()); + set_value(deps.as_mut(), &value, &external_user.clone()).unwrap(); + + let res: GetDataOwnerResponse = + from_json(query(deps.as_ref(), mock_env(), QueryMsg::GetDataOwner {}).unwrap()).unwrap(); + + assert_eq!( + res, + GetDataOwnerResponse { + owner: AndrAddr::from_string(external_user.clone()) + } + ); + + let res = delete_value(deps.as_mut(), &external_user2).unwrap_err(); + assert_eq!(res, ContractError::Unauthorized {}); + + delete_value(deps.as_mut(), &external_user).unwrap(); + + query(deps.as_ref(), mock_env(), QueryMsg::GetDataOwner {}).unwrap_err(); +} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/Cargo.toml b/andromeda-core/contracts/ecosystem/andromeda-vault/Cargo.toml index 815a757..6add2ce 100644 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/Cargo.toml +++ b/andromeda-core/contracts/ecosystem/andromeda-vault/Cargo.toml @@ -1,27 +1,26 @@ -[package] -name = "andromeda-vault" -version = "0.2.0" -edition = "2021" -rust-version = "1.65.0" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - +[package] +name = "andromeda-vault" +version = "1.1.0" +edition = "2021" +rust-version = "1.75.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + [lib] crate-type = ["cdylib", "rlib"] [dependencies] -cosmwasm-std = { workspace = true } -cosmwasm-schema = { workspace = true } -cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } -cw-utils = { workspace = true } - -andromeda-ecosystem = { workspace = true } -andromeda-std = { workspace = true, features = ["withdraw"] } - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -cw-multi-test = { workspace = true, optional = true } +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } + +cw-utils = { workspace = true } + +andromeda-ecosystem = { workspace = true } +andromeda-std = { workspace = true } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } [features] testing = ["cw-multi-test"] diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/README.md b/andromeda-core/contracts/ecosystem/andromeda-vault/README.md new file mode 100644 index 0000000..0120e22 --- /dev/null +++ b/andromeda-core/contracts/ecosystem/andromeda-vault/README.md @@ -0,0 +1,2 @@ +# Note +This ADO is depricated. \ No newline at end of file diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/andromeda-vault.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/andromeda-vault.json deleted file mode 100644 index 0af9b8c..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/andromeda-vault.json +++ /dev/null @@ -1,1380 +0,0 @@ -{ - "contract_name": "andromeda-vault", - "contract_version": "0.2.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "withdraw_vault" - ], - "properties": { - "withdraw_vault": { - "type": "object", - "required": [ - "withdrawals" - ], - "properties": { - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/Recipient" - }, - { - "type": "null" - } - ] - }, - "strategy": { - "anyOf": [ - { - "$ref": "#/definitions/StrategyType" - }, - { - "type": "null" - } - ] - }, - "withdrawals": { - "type": "array", - "items": { - "$ref": "#/definitions/Withdrawal" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_strategy" - ], - "properties": { - "update_strategy": { - "type": "object", - "required": [ - "address", - "strategy" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "strategy": { - "$ref": "#/definitions/StrategyType" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deposit" - ], - "properties": { - "deposit": { - "type": "object", - "properties": { - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "withdraw" - ], - "properties": { - "withdraw": { - "type": "object", - "properties": { - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/Recipient" - }, - { - "type": "null" - } - ] - }, - "tokens_to_withdraw": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Withdrawal" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "StrategyType": { - "type": "string", - "enum": [ - "anchor" - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "Withdrawal": { - "type": "object", - "required": [ - "token" - ], - "properties": { - "token": { - "type": "string" - }, - "withdrawal_type": { - "anyOf": [ - { - "$ref": "#/definitions/WithdrawalType" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "vault_balance" - ], - "properties": { - "vault_balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "denom": { - "type": [ - "string", - "null" - ] - }, - "strategy": { - "anyOf": [ - { - "$ref": "#/definitions/StrategyType" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "strategy_address" - ], - "properties": { - "strategy_address": { - "type": "object", - "required": [ - "strategy" - ], - "properties": { - "strategy": { - "$ref": "#/definitions/StrategyType" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "StrategyType": { - "type": "string", - "enum": [ - "anchor" - ] - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "strategy_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "vault_balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/execute.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/execute.json deleted file mode 100644 index 3c89b9d..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/execute.json +++ /dev/null @@ -1,747 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "withdraw_vault" - ], - "properties": { - "withdraw_vault": { - "type": "object", - "required": [ - "withdrawals" - ], - "properties": { - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/Recipient" - }, - { - "type": "null" - } - ] - }, - "strategy": { - "anyOf": [ - { - "$ref": "#/definitions/StrategyType" - }, - { - "type": "null" - } - ] - }, - "withdrawals": { - "type": "array", - "items": { - "$ref": "#/definitions/Withdrawal" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_strategy" - ], - "properties": { - "update_strategy": { - "type": "object", - "required": [ - "address", - "strategy" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "strategy": { - "$ref": "#/definitions/StrategyType" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deposit" - ], - "properties": { - "deposit": { - "type": "object", - "properties": { - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "withdraw" - ], - "properties": { - "withdraw": { - "type": "object", - "properties": { - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/Recipient" - }, - { - "type": "null" - } - ] - }, - "tokens_to_withdraw": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Withdrawal" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "StrategyType": { - "type": "string", - "enum": [ - "anchor" - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "Withdrawal": { - "type": "object", - "required": [ - "token" - ], - "properties": { - "token": { - "type": "string" - }, - "withdrawal_type": { - "anyOf": [ - { - "$ref": "#/definitions/WithdrawalType" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/instantiate.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/instantiate.json deleted file mode 100644 index 7727d50..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/instantiate.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/query.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/query.json deleted file mode 100644 index 56963e3..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/query.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "vault_balance" - ], - "properties": { - "vault_balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "denom": { - "type": [ - "string", - "null" - ] - }, - "strategy": { - "anyOf": [ - { - "$ref": "#/definitions/StrategyType" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "strategy_address" - ], - "properties": { - "strategy_address": { - "type": "object", - "required": [ - "strategy" - ], - "properties": { - "strategy": { - "$ref": "#/definitions/StrategyType" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "StrategyType": { - "type": "string", - "enum": [ - "anchor" - ] - } - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_balance.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_operators.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_owner.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissions.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_strategy_address.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_strategy_address.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_strategy_address.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_type.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_vault_balance.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_vault_balance.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_vault_balance.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_version.json b/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/src/contract.rs b/andromeda-core/contracts/ecosystem/andromeda-vault/src/contract.rs index 253c54b..67d4b8d 100644 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/src/contract.rs +++ b/andromeda-core/contracts/ecosystem/andromeda-vault/src/contract.rs @@ -1,20 +1,17 @@ use andromeda_ecosystem::vault::{ - DepositMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, StrategyAddressResponse, - StrategyType, BALANCES, STRATEGY_CONTRACT_ADDRESSES, + DepositMsg, ExecuteMsg, InstantiateMsg, QueryMsg, StrategyAddressResponse, StrategyType, + BALANCES, STRATEGY_CONTRACT_ADDRESSES, }; +use andromeda_std::ado_base::ownership::ContractOwnerResponse; use andromeda_std::ado_contract::ADOContract; - use andromeda_std::amp::{AndrAddr, Recipient}; - +use andromeda_std::common::actions::call_action; use andromeda_std::common::context::ExecuteContext; use andromeda_std::common::encode_binary; use andromeda_std::{ ado_base::withdraw::{Withdrawal, WithdrawalType}, - ado_base::{ - operators::IsOperatorResponse, AndromedaMsg, AndromedaQuery, - InstantiateMsg as BaseInstantiateMsg, - }, - error::{from_semver, ContractError}, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + error::ContractError, }; use cosmwasm_std::{ @@ -22,9 +19,7 @@ use cosmwasm_std::{ ContractResult, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Order, QueryRequest, Reply, ReplyOn, Response, StdError, SubMsg, SystemResult, Uint128, WasmMsg, WasmQuery, }; -use cw2::{get_contract_version, set_contract_version}; use cw_utils::nonpayable; -use semver::Version; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-vault"; @@ -37,17 +32,15 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "vault".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, owner: msg.owner, kernel_address: msg.kernel_address, }, @@ -82,7 +75,14 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; match msg { ExecuteMsg::Deposit { recipient, msg } => execute_deposit(ctx, recipient, msg), ExecuteMsg::WithdrawVault { @@ -316,7 +316,7 @@ pub fn withdraw_strategy( } let addr = addr_opt.unwrap(); - let withdraw_exec = to_json_binary(&AndromedaMsg::Withdraw { + let withdraw_exec = to_json_binary(&ExecuteMsg::Withdraw { recipient: Some(recipient), tokens_to_withdraw: Some(withdrawals), })?; @@ -357,14 +357,21 @@ fn execute_update_strategy( // strategy_addr.clone(), // &deps.querier, // )?; - let strategy_is_operator: IsOperatorResponse = deps.querier.query_wasm_smart( - strategy_addr.clone(), - &QueryMsg::IsOperator { - address: env.contract.address.to_string(), - }, - )?; + + // Replaced operator with owner check + // let strategy_is_operator: IsOperatorResponse = deps.querier.query_wasm_smart( + // strategy_addr.clone(), + // &QueryMsg::IsOperator { + // address: env.contract.address.to_string(), + // }, + // )?; + + let strategy_owner: ContractOwnerResponse = deps + .querier + .query_wasm_smart(strategy_addr.clone(), &QueryMsg::Owner {})?; + ensure!( - strategy_is_operator.is_operator, + strategy_owner.owner == env.contract.address, ContractError::NotAssignedOperator { msg: Some("Vault contract is not an operator for the given address".to_string()), } @@ -384,36 +391,7 @@ fn execute_update_strategy( #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -439,10 +417,16 @@ fn query_balance( ) -> Result { if let Some(strategy) = strategy { let strategy_addr = STRATEGY_CONTRACT_ADDRESSES.load(deps.storage, strategy.to_string())?; + ensure!(false, ContractError::TemporarilyDisabled {}); // DEV NOTE: Why does this ensure! a generic type when not using custom query? + // let query: QueryRequest = QueryRequest::Wasm(WasmQuery::Smart { + // contract_addr: strategy_addr, + // msg: to_json_binary(&AndromedaQuery::WithdrawableBalance { address })?, + // }); + // TODO: Below code to be replaced with above code once WithdrawableBalance is re-enabled let query: QueryRequest = QueryRequest::Wasm(WasmQuery::Smart { contract_addr: strategy_addr, - msg: to_json_binary(&AndromedaQuery::Balance { address })?, + msg: to_json_binary(&Binary::default())?, }); match deps.querier.raw_query(&to_json_binary(&query)?) { SystemResult::Ok(ContractResult::Ok(value)) => Ok(value), diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mock_querier.rs b/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mock_querier.rs index 1ab72a1..2b1801f 100644 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mock_querier.rs @@ -1,18 +1,20 @@ +use andromeda_std::ado_base::ownership::ContractOwnerResponse; +use andromeda_std::ado_base::AndromedaQuery; //use andromeda_ecosystem::anchor_earn::PositionResponse; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; use andromeda_std::{ - ado_base::{operators::IsOperatorResponse, AndromedaQuery, InstantiateMsg}, - ado_contract::ADOContract, - amp::Recipient, + ado_base::InstantiateMsg, ado_contract::ADOContract, amp::Recipient, testing::mock_querier::MOCK_KERNEL_CONTRACT, }; use cosmwasm_schema::cw_serde; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, Uint128, WasmQuery, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, + WasmQuery, }; +use cosmwasm_std::{to_json_binary, Binary, ContractResult}; // This is here since anchor_earn is defunct now. #[cw_serde] @@ -44,11 +46,11 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "vault".to_string(), ado_version: "test".to_string(), - operators: None, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -91,16 +93,16 @@ impl WasmMockQuerier { fn handle_anchor_balance_query(&self, msg: &Binary) -> QuerierResult { match from_json(msg).unwrap() { - AndromedaQuery::Balance { address } => { - let msg_response = PositionResponse { - recipient: Recipient::from_string(address), - aust_amount: Uint128::from(10u128), - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&msg_response).unwrap())) - } - AndromedaQuery::IsOperator { address } => { - let msg_response = IsOperatorResponse { - is_operator: address == MOCK_VAULT_CONTRACT, + // AndromedaQuery::WithdrawableBalance { address } => { + // let msg_response = PositionResponse { + // recipient: Recipient::from_string(address), + // aust_amount: Uint128::from(10u128), + // }; + // SystemResult::Ok(ContractResult::Ok(to_json_binary(&msg_response).unwrap())) + // } + AndromedaQuery::Owner {} => { + let msg_response = ContractOwnerResponse { + owner: MOCK_VAULT_CONTRACT.to_owned(), }; SystemResult::Ok(ContractResult::Ok(to_json_binary(&msg_response).unwrap())) } diff --git a/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mod.rs b/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mod.rs index 02f6979..3b08b09 100644 --- a/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mod.rs +++ b/andromeda-core/contracts/ecosystem/andromeda-vault/src/testing/mod.rs @@ -2,7 +2,7 @@ mod mock_querier; use self::mock_querier::{MOCK_ANCHOR_CONTRACT, MOCK_VAULT_CONTRACT}; use crate::contract::*; -use crate::testing::mock_querier::{mock_dependencies_custom, PositionResponse}; +use crate::testing::mock_querier::mock_dependencies_custom; use andromeda_ecosystem::vault::{ DepositMsg, ExecuteMsg, InstantiateMsg, QueryMsg, StrategyAddressResponse, StrategyType, YieldStrategy, BALANCES, STRATEGY_CONTRACT_ADDRESSES, @@ -11,7 +11,6 @@ use andromeda_std::amp::{AndrAddr, Recipient}; use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; use andromeda_std::{ ado_base::withdraw::{Withdrawal, WithdrawalType}, - ado_base::AndromedaMsg, error::ContractError, }; use cosmwasm_std::attr; @@ -737,7 +736,7 @@ fn test_withdraw_single_strategy() { }; let res = execute(deps.as_mut(), env, info, msg).unwrap(); - let withdraw_exec = to_json_binary(&AndromedaMsg::Withdraw { + let withdraw_exec = to_json_binary(&ExecuteMsg::Withdraw { recipient: Some(Recipient::from_string("depositor")), tokens_to_withdraw: Some(withdrawals), }) @@ -848,18 +847,21 @@ fn test_query_strategy_balance() { strategy: Some(StrategyType::Anchor), denom: None, }; - - let resp = query(deps.as_ref(), env, single_query).unwrap(); - let balance: PositionResponse = from_json(resp).unwrap(); - assert_eq!(Uint128::from(10u128), balance.aust_amount); - assert_eq!( - "depositor".to_string(), - balance - .recipient - .address - .get_raw_address(&deps.as_ref()) - .unwrap() - ); + let resp = query(deps.as_ref(), env, single_query).unwrap_err(); + assert_eq!(resp, ContractError::TemporarilyDisabled {}); + + // let resp = query(deps.as_ref(), env, single_query).unwrap(); + + // let balance: PositionResponse = from_json(resp).unwrap(); + // assert_eq!(Uint128::from(10u128), balance.aust_amount); + // assert_eq!( + // "depositor".to_string(), + // balance + // .recipient + // .address + // .get_raw_address(&deps.as_ref()) + // .unwrap() + // ); } #[test] diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/.cargo/config b/andromeda-core/contracts/finance/andromeda-conditional-splitter/.cargo/config new file mode 100644 index 0000000..336b618 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/.gitignore b/andromeda-core/contracts/finance/andromeda-conditional-splitter/.gitignore new file mode 100644 index 0000000..869df07 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock \ No newline at end of file diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/Cargo.toml b/andromeda-core/contracts/finance/andromeda-conditional-splitter/Cargo.toml new file mode 100644 index 0000000..915ade2 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "andromeda-conditional-splitter" +version = "1.2.2" +edition = "2021" +rust-version = "1.75.0" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +testing = ["cw-multi-test", "andromeda-testing"] + + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } + +andromeda-std = { workspace = true } +andromeda-finance = { workspace = true } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } + +[dev-dependencies] +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/README.md b/andromeda-core/contracts/finance/andromeda-conditional-splitter/README.md new file mode 100644 index 0000000..5224f18 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/README.md @@ -0,0 +1,6 @@ +# Overview + +The Conditional Splitter ADO is a smart contract used to split funds to specified recipients based on the amount that is sent. At instantiation, the owner specifies the recipient sets along with the minimum amount of funds needed for each set. +The ADO can be locked by the owner meaning that the recipient lists cannot be changed for the duration of the lock. + +**Note**: This ADO is not released yet. Once released, a link to full documentation will be provided. diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/examples/schema.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/examples/schema.rs new file mode 100644 index 0000000..29a173a --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/examples/schema.rs @@ -0,0 +1,11 @@ +use andromeda_finance::conditional_splitter::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + + } +} diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/contract.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/contract.rs new file mode 100644 index 0000000..c1f0733 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/contract.rs @@ -0,0 +1,315 @@ +use crate::state::CONDITIONAL_SPLITTER; +use andromeda_finance::conditional_splitter::{ + get_threshold, ConditionalSplitter, ExecuteMsg, GetConditionalSplitterConfigResponse, + InstantiateMsg, QueryMsg, Threshold, +}; +use std::vec; + +use andromeda_std::{ + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + amp::messages::AMPPkt, + common::{ + actions::call_action, encode_binary, Milliseconds, MillisecondsDuration, + MillisecondsExpiration, + }, + error::ContractError, +}; +use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; +use cosmwasm_std::{ + attr, ensure, entry_point, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, + Reply, Response, StdError, SubMsg, Uint128, +}; +use cw_utils::nonpayable; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:andromeda-conditional-splitter"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +// 1 day in milliseconds +const ONE_DAY: u64 = 86_400_000; +// 1 year in milliseconds +const ONE_YEAR: u64 = 31_536_000_000; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let mut conditional_splitter = ConditionalSplitter { + thresholds: msg.thresholds.clone(), + lock_time: MillisecondsExpiration::zero(), + }; + + if let Some(lock_time) = msg.lock_time { + let time = lock_time.get_time(&env.block); + // New lock time can't be too short + ensure!( + time >= Milliseconds::from_seconds(env.block.time.seconds()) + .plus_milliseconds(Milliseconds(ONE_DAY)), + ContractError::LockTimeTooShort {} + ); + + // New lock time can't be too long + ensure!( + time <= Milliseconds::from_seconds(env.block.time.seconds()) + .plus_milliseconds(Milliseconds(ONE_YEAR)), + ContractError::LockTimeTooLong {} + ); + + conditional_splitter.lock_time = time; + } + + // Validate thresholds + conditional_splitter.validate(deps.as_ref())?; + + // Save kernel address after validating it + CONDITIONAL_SPLITTER.save(deps.storage, &conditional_splitter)?; + + let inst_resp = ADOContract::default().instantiate( + deps.storage, + env, + deps.api, + &deps.querier, + info, + BaseInstantiateMsg { + ado_type: CONTRACT_NAME.to_string(), + ado_version: CONTRACT_VERSION.to_string(), + kernel_address: msg.kernel_address.clone(), + owner: msg.owner.clone(), + }, + )?; + + Ok(inst_resp) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { + if msg.result.is_err() { + return Err(ContractError::Std(StdError::generic_err( + msg.result.unwrap_err(), + ))); + } + + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let ctx = ExecuteContext::new(deps, info, env); + + match msg { + ExecuteMsg::AMPReceive(pkt) => { + ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) + } + _ => handle_execute(ctx, msg), + } +} + +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { + ExecuteMsg::UpdateThresholds { thresholds } => execute_update_thresholds(ctx, thresholds), + ExecuteMsg::UpdateLock { lock_time } => execute_update_lock(ctx, lock_time), + ExecuteMsg::Send {} => execute_send(ctx), + _ => ADOContract::default().execute(ctx, msg), + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) +} + +fn execute_send(ctx: ExecuteContext) -> Result { + let ExecuteContext { deps, info, .. } = ctx; + + ensure!( + !info.funds.is_empty(), + ContractError::InvalidFunds { + msg: "At least one coin should to be sent".to_string(), + } + ); + ensure!( + info.funds.len() < 5, + ContractError::ExceedsMaxAllowedCoins {} + ); + for coin in info.funds.clone() { + ensure!( + !coin.amount.is_zero(), + ContractError::InvalidFunds { + msg: "Amount must be non-zero".to_string(), + } + ); + } + + let conditional_splitter = CONDITIONAL_SPLITTER.load(deps.storage)?; + + let mut msgs: Vec = Vec::new(); + let mut amp_funds: Vec = Vec::new(); + + let mut remainder_funds = info.funds.clone(); + + let mut pkt = AMPPkt::from_ctx(ctx.amp_ctx, ctx.env.contract.address.to_string()); + + for (i, coin) in info.funds.clone().iter().enumerate() { + // Find the relevant threshold + let threshold = get_threshold(&conditional_splitter.thresholds, coin.amount)?; + + for address_percent in threshold.address_percent { + let recipient_percent = address_percent.percent; + let amount_owed = coin.amount.mul_floor(recipient_percent); + + if !amount_owed.is_zero() { + let mut vec_coin: Vec = Vec::new(); + let mut recip_coin: Coin = coin.clone(); + + recip_coin.amount = amount_owed; + + remainder_funds[i].amount = + remainder_funds[i].amount.checked_sub(recip_coin.amount)?; + vec_coin.push(recip_coin.clone()); + amp_funds.push(recip_coin); + + let amp_msg = address_percent + .recipient + .generate_amp_msg(&deps.as_ref(), Some(vec_coin))?; + pkt = pkt.add_message(amp_msg); + } + } + } + + remainder_funds.retain(|x| x.amount > Uint128::zero()); + + if !remainder_funds.is_empty() { + msgs.push(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: info.sender.to_string(), + amount: remainder_funds, + }))); + } + let kernel_address = ADOContract::default().get_kernel_address(deps.as_ref().storage)?; + if !pkt.messages.is_empty() { + let distro_msg = pkt.to_sub_msg(kernel_address, Some(amp_funds), 1)?; + msgs.push(distro_msg); + } + + Ok(Response::new() + .add_submessages(msgs) + .add_attribute("action", "send") + .add_attribute("sender", info.sender.to_string())) +} + +fn execute_update_thresholds( + ctx: ExecuteContext, + thresholds: Vec, +) -> Result { + let ExecuteContext { + deps, info, env, .. + } = ctx; + + nonpayable(&info)?; + + ensure!( + ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + let conditional_splitter = CONDITIONAL_SPLITTER.load(deps.storage)?; + + // Can't call this function while the lock isn't expired + ensure!( + conditional_splitter.lock_time.is_expired(&env.block), + ContractError::ContractLocked {} + ); + + let updated_conditional_splitter = ConditionalSplitter { + thresholds, + lock_time: conditional_splitter.lock_time, + }; + // Validate the updated conditional splitter + updated_conditional_splitter.validate(deps.as_ref())?; + + CONDITIONAL_SPLITTER.save(deps.storage, &updated_conditional_splitter)?; + + Ok(Response::default().add_attributes(vec![attr("action", "update_thresholds")])) +} + +fn execute_update_lock( + ctx: ExecuteContext, + lock_time: MillisecondsDuration, +) -> Result { + let ExecuteContext { + deps, info, env, .. + } = ctx; + + nonpayable(&info)?; + + ensure!( + ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + let mut conditional_splitter = CONDITIONAL_SPLITTER.load(deps.storage)?; + + // Can't call this function while the lock isn't expired + ensure!( + conditional_splitter.lock_time.is_expired(&env.block), + ContractError::ContractLocked {} + ); + + // Get current time + let current_time = Milliseconds::from_seconds(env.block.time.seconds()); + + // New lock time can't be too short + ensure!( + lock_time.seconds() >= ONE_DAY, + ContractError::LockTimeTooShort {} + ); + + // New lock time can't be unreasonably long + ensure!( + lock_time.seconds() <= ONE_YEAR, + ContractError::LockTimeTooLong {} + ); + + // Set new lock time + let new_expiration = current_time.plus_milliseconds(lock_time); + + conditional_splitter.lock_time = new_expiration; + + CONDITIONAL_SPLITTER.save(deps.storage, &conditional_splitter)?; + + Ok(Response::default().add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", new_expiration.to_string()), + ])) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::GetConditionalSplitterConfig {} => encode_binary(&query_splitter(deps)?), + _ => ADOContract::default().query(deps, env, msg), + } +} + +fn query_splitter(deps: Deps) -> Result { + let splitter = CONDITIONAL_SPLITTER.load(deps.storage)?; + + Ok(GetConditionalSplitterConfigResponse { config: splitter }) +} diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/lib.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/lib.rs new file mode 100644 index 0000000..abf4af6 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/lib.rs @@ -0,0 +1,8 @@ +pub mod contract; +pub mod state; + +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; + +#[cfg(test)] +mod testing; diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/mock.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/mock.rs new file mode 100644 index 0000000..396b275 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/mock.rs @@ -0,0 +1,67 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] + +use crate::contract::{execute, instantiate, query, reply}; +use andromeda_finance::conditional_splitter::{ExecuteMsg, InstantiateMsg, QueryMsg, Threshold}; +use andromeda_std::common::expiration::Expiry; +use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract, +}; +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockConditionalSplitter(Addr); +mock_ado!(MockConditionalSplitter, ExecuteMsg, QueryMsg); + +impl MockConditionalSplitter { + pub fn instantiate( + app: &mut MockApp, + code_id: u64, + sender: Addr, + thresholds: Vec, + kernel_address: impl Into, + lock_time: Option, + owner: Option, + ) -> Self { + let msg = + mock_conditional_splitter_instantiate_msg(thresholds, kernel_address, lock_time, owner); + let res = app.instantiate_contract( + code_id, + sender, + &msg, + &[], + "Andromeda Conditional Splitter", + None, + ); + + Self(res.unwrap()) + } + + pub fn execute_send(&self, app: &mut MockApp, sender: Addr, funds: &[Coin]) -> ExecuteResult { + let msg = mock_splitter_send_msg(); + + self.execute(app, &msg, sender, funds) + } +} + +pub fn mock_andromeda_conditional_splitter() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query).with_reply(reply); + Box::new(contract) +} + +pub fn mock_conditional_splitter_instantiate_msg( + thresholds: Vec, + kernel_address: impl Into, + lock_time: Option, + owner: Option, +) -> InstantiateMsg { + InstantiateMsg { + thresholds, + lock_time, + kernel_address: kernel_address.into(), + owner, + } +} + +pub fn mock_splitter_send_msg() -> ExecuteMsg { + ExecuteMsg::Send {} +} diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/state.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/state.rs new file mode 100644 index 0000000..30ff5b8 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/state.rs @@ -0,0 +1,4 @@ +use andromeda_finance::conditional_splitter::ConditionalSplitter; +use cw_storage_plus::Item; + +pub const CONDITIONAL_SPLITTER: Item = Item::new("conditional_splitter"); diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mock_querier.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mock_querier.rs new file mode 100644 index 0000000..abe4b9a --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mock_querier.rs @@ -0,0 +1,82 @@ +use andromeda_std::ado_base::InstantiateMsg; +use andromeda_std::ado_contract::ADOContract; +use andromeda_std::testing::mock_querier::MockAndromedaQuerier; +use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; +use cosmwasm_std::{ + from_json, + testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, +}; + +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; + +/// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. +/// +/// Automatically assigns a kernel address as MOCK_KERNEL_CONTRACT. +pub fn mock_dependencies_custom( + contract_balance: &[Coin], +) -> OwnedDeps { + let custom_querier: WasmMockQuerier = + WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); + let storage = MockStorage::default(); + let mut deps = OwnedDeps { + storage, + api: MockApi::default(), + querier: custom_querier, + custom_query_type: std::marker::PhantomData, + }; + ADOContract::default() + .instantiate( + &mut deps.storage, + mock_env(), + &deps.api, + &QuerierWrapper::new(&deps.querier), + mock_info("sender", &[]), + InstantiateMsg { + ado_type: "splitter".to_string(), + ado_version: "test".to_string(), + + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + }, + ) + .unwrap(); + deps +} + +pub struct WasmMockQuerier { + pub base: MockQuerier, + pub contract_address: String, + pub tokens_left_to_burn: usize, +} + +impl Querier for WasmMockQuerier { + fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { + // MockQuerier doesn't support Custom, so we ignore it completely here + let request: QueryRequest = match from_json(bin_request) { + Ok(v) => v, + Err(e) => { + return SystemResult::Err(SystemError::InvalidRequest { + error: format!("Parsing query request: {e}"), + request: bin_request.into(), + }) + } + }; + self.handle_query(&request) + } +} + +impl WasmMockQuerier { + pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { + MockAndromedaQuerier::default().handle_query(&self.base, request) + } + + pub fn new(base: MockQuerier) -> Self { + WasmMockQuerier { + base, + contract_address: mock_env().contract.address.to_string(), + tokens_left_to_burn: 2, + } + } +} diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mod.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mod.rs new file mode 100644 index 0000000..a1e507b --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/mod.rs @@ -0,0 +1,2 @@ +mod mock_querier; +mod tests; diff --git a/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs new file mode 100644 index 0000000..ffd3d40 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-conditional-splitter/src/testing/tests.rs @@ -0,0 +1,826 @@ +use andromeda_std::{ + amp::{ + messages::{AMPMsg, AMPPkt}, + recipient::Recipient, + }, + common::{expiration::Expiry, Milliseconds}, + error::ContractError, +}; +use andromeda_testing::economics_msg::generate_economics_message; +use cosmwasm_std::{ + attr, from_json, + testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, + to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, DepsMut, Response, SubMsg, Timestamp, + Uint128, +}; +pub const OWNER: &str = "creator"; + +use super::mock_querier::MOCK_KERNEL_CONTRACT; + +use crate::{ + contract::{execute, instantiate, query}, + state::CONDITIONAL_SPLITTER, + testing::mock_querier::mock_dependencies_custom, +}; +use andromeda_finance::{ + conditional_splitter::{ + ConditionalSplitter, ExecuteMsg, GetConditionalSplitterConfigResponse, InstantiateMsg, + QueryMsg, Threshold, + }, + splitter::AddressPercent, +}; + +fn init(deps: DepsMut) -> Response { + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![ + Threshold::new( + Uint128::zero(), + vec![AddressPercent::new( + Recipient::from_string(String::from("some_address")), + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + )], + ), + Threshold::new( + Uint128::new(11), + vec![AddressPercent::new( + Recipient::from_string(String::from("some_address")), + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + )], + ), + ], + lock_time: Some(Expiry::FromNow(Milliseconds::from_seconds(100_000))), + }; + + let info = mock_info("owner", &[]); + instantiate(deps, mock_env(), info, msg).unwrap() +} + +#[test] +fn test_instantiate() { + let mut deps = mock_dependencies_custom(&[]); + let res = init(deps.as_mut()); + assert_eq!(0, res.messages.len()); +} + +#[test] +fn test_different_lock_times() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + // Current time + env.block.time = Timestamp::from_seconds(1724920577); + // Set a lock time that's less than 1 day in milliseconds + let mut lock_time = Expiry::FromNow(Milliseconds(60_000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + + assert_eq!(err, ContractError::LockTimeTooShort {}); + + // Set a lock time that's more than 1 year in milliseconds + lock_time = Expiry::FromNow(Milliseconds(31_708_800_000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![], + lock_time: Some(lock_time), + }; + + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + + assert_eq!(err, ContractError::LockTimeTooLong {}); + + // Set a lock time for 20 days in milliseconds + lock_time = Expiry::FromNow(Milliseconds(1728000000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![Threshold::new( + Uint128::zero(), + vec![AddressPercent::new( + Recipient::from_string(String::from("some_address")), + Decimal::percent(100), + )], + )], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let res = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // Here we begin testing Expiry::AtTime + // Set a lock time that's less than 1 day from current time + lock_time = Expiry::AtTime(Milliseconds(1724934977000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + assert_eq!(err, ContractError::LockTimeTooShort {}); + + // Set a lock time that's more than 1 year from current time in milliseconds + lock_time = Expiry::AtTime(Milliseconds(1788006977000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + assert_eq!(err, ContractError::LockTimeTooLong {}); + + // Set a valid lock time + lock_time = Expiry::AtTime(Milliseconds(1725021377000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![Threshold::new( + Uint128::zero(), + vec![AddressPercent::new( + Recipient::from_string(String::from("some_address")), + Decimal::percent(100), + )], + )], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let res = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + assert_eq!(0, res.messages.len()); +} + +#[test] +fn test_execute_update_lock() { + let mut deps = mock_dependencies_custom(&[]); + let _res = init(deps.as_mut()); + + let env = mock_env(); + + let current_time = env.block.time.seconds(); + let lock_time = 100_000_000; + + // Start off with an expiration that's behind current time (expired) + let splitter = ConditionalSplitter { + lock_time: Milliseconds::zero(), + thresholds: vec![Threshold { + min: Uint128::zero(), + address_percent: vec![], + }], + }; + + CONDITIONAL_SPLITTER + .save(deps.as_mut().storage, &splitter) + .unwrap(); + + let msg = ExecuteMsg::UpdateLock { + lock_time: Milliseconds::from_seconds(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + let new_lock = Milliseconds::from_seconds(current_time + lock_time); + assert_eq!( + Response::default() + .add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", new_lock.to_string()) + ]) + .add_submessage(generate_economics_message(OWNER, "UpdateLock")), + res + ); + + //check result + let splitter = CONDITIONAL_SPLITTER.load(deps.as_ref().storage).unwrap(); + assert!(!splitter.lock_time.is_expired(&env.block)); + assert_eq!(new_lock, splitter.lock_time); + + // Shouldn't be able to update lock while current lock isn't expired + let msg = ExecuteMsg::UpdateLock { + lock_time: Milliseconds::from_seconds(lock_time), + }; + let info = mock_info(OWNER, &[]); + let err = execute(deps.as_mut(), env.clone(), info, msg).unwrap_err(); + assert_eq!(err, ContractError::ContractLocked {}); +} + +#[test] +fn test_execute_update_thresholds() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res = init(deps.as_mut()); + + let recip_address1 = "address1".to_string(); + let recip_address2 = "address2".to_string(); + let recip1 = Recipient::from_string(recip_address1); + let recip2 = Recipient::from_string(recip_address2); + + let first_thresholds = vec![Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + recip1.clone(), // 50% + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + ), + AddressPercent::new( + recip2.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + ], + )]; + let splitter = ConditionalSplitter { + lock_time: Milliseconds::zero(), + thresholds: first_thresholds, + }; + + CONDITIONAL_SPLITTER + .save(deps.as_mut().storage, &splitter) + .unwrap(); + + // Duplicate recipients + let duplicate_recipients = vec![Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + recip1.clone(), // 50% + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + ), + AddressPercent::new( + recip1.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + ], + )]; + let msg = ExecuteMsg::UpdateThresholds { + thresholds: duplicate_recipients, + }; + + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(ContractError::DuplicateRecipient {}, res.unwrap_err()); + + let new_threshold = vec![ + Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + recip1.clone(), // 50% + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + ), + AddressPercent::new( + recip2.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + ], + ), + Threshold::new( + Uint128::new(20), + vec![ + AddressPercent::new( + recip1.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + AddressPercent::new( + recip2.clone(), // 10% + Decimal::from_ratio(Uint128::one(), Uint128::new(10)), + ), + ], + ), + ]; + let msg = ExecuteMsg::UpdateThresholds { + thresholds: new_threshold.clone(), + }; + + let info = mock_info("incorrect_owner", &[]); + let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); + assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); + + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + assert_eq!( + Response::default() + .add_attributes(vec![attr("action", "update_thresholds")]) + .add_submessage(generate_economics_message(OWNER, "UpdateThresholds")), + res + ); + + //check result + let splitter = CONDITIONAL_SPLITTER.load(deps.as_ref().storage).unwrap(); + assert_eq!(splitter.thresholds, new_threshold); +} + +#[test] +fn test_execute_send() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + + let recip_address1 = "address1".to_string(); + let recip_address2 = "address2".to_string(); + + let second_threshold = Uint128::new(10); + + let recip1 = Recipient::from_string(recip_address1); + let recip2 = Recipient::from_string(recip_address2); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![ + Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + recip1.clone(), // 50% + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + ), + AddressPercent::new( + recip2.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + ], + ), + Threshold::new( + second_threshold, + vec![ + AddressPercent::new( + recip1.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + AddressPercent::new( + recip2.clone(), // 10% + Decimal::from_ratio(Uint128::one(), Uint128::new(10)), + ), + ], + ), + Threshold::new( + Uint128::new(50), + vec![ + AddressPercent::new( + recip1.clone(), // 50% + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + ), + AddressPercent::new( + recip2.clone(), // 50% + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + ), + ], + ), + ], + lock_time: Some(Expiry::FromNow(Milliseconds::from_seconds(100_000))), + }; + + let info = mock_info("owner", &[]); + instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + + // First batch will test first threshold + let first_batch = 8u128; + + // Second batch will test the second threshold + let second_batch = 10u128; + + // Third batch will test the third threshold + let third_batch = 100u128; + + // First batch + let info = mock_info(OWNER, &[Coin::new(first_batch, "uandr")]); + let msg = ExecuteMsg::Send {}; + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // 50 percent + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(4, "uandr")])) + .unwrap(); + // 20 percent, 1.6 which is rounded down to 1 + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1, "uandr")])) + .unwrap(); + let amp_pkt = AMPPkt::new( + MOCK_CONTRACT_ADDR.to_string(), + MOCK_CONTRACT_ADDR.to_string(), + vec![amp_msg_1, amp_msg_2], + ); + let amp_msg = amp_pkt + .to_sub_msg( + MOCK_KERNEL_CONTRACT, + Some(vec![Coin::new(4, "uandr"), Coin::new(1, "uandr")]), + 1, + ) + .unwrap(); + + let expected_res = Response::new() + .add_submessages(vec![ + SubMsg::new( + // refunds remainder to sender + CosmosMsg::Bank(BankMsg::Send { + to_address: OWNER.to_string(), + amount: vec![Coin::new(3, "uandr")], // 8 - (0.5 * 8) - (0.2 * 8) remainder + }), + ), + amp_msg, + ]) + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) + .add_submessage(generate_economics_message(OWNER, "Send")); + + assert_eq!(res, expected_res); + + // Second batch + let info = mock_info(OWNER, &[Coin::new(second_batch, "uandr")]); + let msg = ExecuteMsg::Send {}; + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // 20 percent + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(2, "uandr")])) + .unwrap(); + // 10 percent + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1, "uandr")])) + .unwrap(); + let amp_pkt = AMPPkt::new( + MOCK_CONTRACT_ADDR.to_string(), + MOCK_CONTRACT_ADDR.to_string(), + vec![amp_msg_1, amp_msg_2], + ); + let amp_msg = amp_pkt + .to_sub_msg( + MOCK_KERNEL_CONTRACT, + Some(vec![Coin::new(2, "uandr"), Coin::new(1, "uandr")]), + 1, + ) + .unwrap(); + + let expected_res = Response::new() + .add_submessages(vec![ + SubMsg::new( + // refunds remainder to sender + CosmosMsg::Bank(BankMsg::Send { + to_address: OWNER.to_string(), + amount: vec![Coin::new(7, "uandr")], // 10 - (0.2 * 10) - (0.1 * 10) remainder + }), + ), + amp_msg, + ]) + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) + .add_submessage(generate_economics_message(OWNER, "Send")); + + assert_eq!(res, expected_res); + + // Third batch + let info = mock_info(OWNER, &[Coin::new(third_batch, "uandr")]); + let msg = ExecuteMsg::Send {}; + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + + // amount 100 * 50% = 50 + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(50, "uandr")])) + .unwrap(); + // amount 100 * 50% = 50 + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(50, "uandr")])) + .unwrap(); + let amp_pkt = AMPPkt::new( + MOCK_CONTRACT_ADDR.to_string(), + MOCK_CONTRACT_ADDR.to_string(), + vec![amp_msg_1, amp_msg_2], + ); + let amp_msg = amp_pkt + .to_sub_msg( + MOCK_KERNEL_CONTRACT, + Some(vec![Coin::new(50, "uandr"), Coin::new(50, "uandr")]), + 1, + ) + .unwrap(); + + let expected_res = Response::new() + // No refund for the sender since the percentages add up to 100 + .add_submessage(amp_msg) + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) + .add_submessage(generate_economics_message(OWNER, "Send")); + + assert_eq!(res, expected_res); +} + +#[test] +fn test_execute_send_threshold_not_found() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let recip_address1 = "address1".to_string(); + let recip_address2 = "address2".to_string(); + let second_threshold = Uint128::new(10); + let recip1 = Recipient::from_string(recip_address1); + let recip2 = Recipient::from_string(recip_address2); + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + thresholds: vec![ + Threshold::new( + Uint128::new(7), + vec![ + AddressPercent::new( + recip1.clone(), // 50% + Decimal::from_ratio(Uint128::one(), Uint128::new(2)), + ), + AddressPercent::new( + recip2.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + ], + ), + Threshold::new( + second_threshold, + vec![ + AddressPercent::new( + recip1.clone(), // 20% + Decimal::from_ratio(Uint128::one(), Uint128::new(5)), + ), + AddressPercent::new( + recip2.clone(), // 10% + Decimal::from_ratio(Uint128::one(), Uint128::new(10)), + ), + ], + ), + ], + lock_time: Some(Expiry::FromNow(Milliseconds::from_seconds(100_000))), + }; + + let info = mock_info("owner", &[]); + instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + + // This batch is lower than the lowest threshold which is 7 + let first_batch = 6u128; + + // First batch + let info = mock_info(OWNER, &[Coin::new(first_batch, "uandr")]); + let msg = ExecuteMsg::Send {}; + let err = execute(deps.as_mut(), env.clone(), info, msg).unwrap_err(); + + assert_eq!( + err, + ContractError::InvalidAmount { + msg: "The amount sent does not meet any threshold".to_string(), + } + ); +} + +// #[test] +// fn test_execute_send_ado_recipient() { +// let mut deps = mock_dependencies_custom(&[]); +// let env = mock_env(); +// let _res: Response = init(deps.as_mut()); + +// let sender_funds_amount = 10000u128; +// let info = mock_info(OWNER, &[Coin::new(sender_funds_amount, "uluna")]); + +// let recip_address1 = "address1".to_string(); +// let recip_percent1 = 10; // 10% + +// let recip_address2 = "address2".to_string(); +// let recip_percent2 = 20; // 20% + +// let recip1 = Recipient::from_string(recip_address1); +// let recip2 = Recipient::from_string(recip_address2); + +// let recipient = vec![ +// AddressFunds { +// recipient: recip1.clone(), +// percent: Decimal::percent(recip_percent1), +// }, +// AddressFunds { +// recipient: recip2.clone(), +// percent: Decimal::percent(recip_percent2), +// }, +// ]; +// let msg = ExecuteMsg::Send {}; + +// let amp_msg_1 = recip1 +// .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1000, "uluna")])) +// .unwrap(); +// let amp_msg_2 = recip2 +// .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(2000, "uluna")])) +// .unwrap(); +// let amp_pkt = AMPPkt::new( +// MOCK_CONTRACT_ADDR.to_string(), +// MOCK_CONTRACT_ADDR.to_string(), +// vec![amp_msg_1, amp_msg_2], +// ); +// let amp_msg = amp_pkt +// .to_sub_msg( +// MOCK_KERNEL_CONTRACT, +// Some(vec![Coin::new(1000, "uluna"), Coin::new(2000, "uluna")]), +// 1, +// ) +// .unwrap(); + +// let splitter = ConditionalSplitter { +// recipients: recipient, +// lock: Milliseconds::default(), +// }; + +// CONDITIONAL_SPLITTER +// .save(deps.as_mut().storage, &splitter) +// .unwrap(); + +// let res = execute(deps.as_mut(), env, info.clone(), msg).unwrap(); + +// let expected_res = Response::new() +// .add_submessages(vec![ +// SubMsg::new( +// // refunds remainder to sender +// CosmosMsg::Bank(BankMsg::Send { +// to_address: info.sender.to_string(), +// amount: vec![Coin::new(7000, "uluna")], // 10000 * 0.7 remainder +// }), +// ), +// amp_msg, +// ]) +// .add_attribute("action", "send") +// .add_attribute("sender", "creator") +// .add_submessage(generate_economics_message(OWNER, "Send")); + +// assert_eq!(res, expected_res); +// } + +#[test] +fn test_handle_packet_exit_with_error_true() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res: Response = init(deps.as_mut()); + + let sender_funds_amount = 0u128; + let info = mock_info(OWNER, &[Coin::new(sender_funds_amount, "uluna")]); + + let recip_address1 = "address1".to_string(); + let recip_percent1 = 10; // 10% + + let recip_percent2 = 20; // 20% + + let address_percent = vec![ + AddressPercent { + recipient: Recipient::from_string(recip_address1.clone()), + percent: Decimal::percent(recip_percent1), + }, + AddressPercent { + recipient: Recipient::from_string(recip_address1.clone()), + percent: Decimal::percent(recip_percent2), + }, + ]; + let pkt = AMPPkt::new( + info.clone().sender, + "cosmos2contract", + vec![AMPMsg::new( + recip_address1, + to_json_binary(&ExecuteMsg::Send {}).unwrap(), + Some(vec![Coin::new(0, "uluna")]), + )], + ); + let msg = ExecuteMsg::AMPReceive(pkt); + + let splitter = ConditionalSplitter { + lock_time: Milliseconds::zero(), + thresholds: vec![Threshold::new(Uint128::zero(), address_percent)], + }; + + CONDITIONAL_SPLITTER + .save(deps.as_mut().storage, &splitter) + .unwrap(); + + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + + assert_eq!( + err, + ContractError::InvalidFunds { + msg: "Amount must be non-zero".to_string(), + } + ); +} + +#[test] +fn test_query_splitter() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let splitter = ConditionalSplitter { + lock_time: Milliseconds::zero(), + thresholds: vec![Threshold::new(Uint128::zero(), vec![])], + }; + + CONDITIONAL_SPLITTER + .save(deps.as_mut().storage, &splitter) + .unwrap(); + + let query_msg = QueryMsg::GetConditionalSplitterConfig {}; + let res = query(deps.as_ref(), env, query_msg).unwrap(); + let val: GetConditionalSplitterConfigResponse = from_json(res).unwrap(); + + assert_eq!(val.config, splitter); +} + +#[test] +fn test_execute_send_error() { + //Executes send with more than 5 tokens [ACK-04] + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res: Response = init(deps.as_mut()); + + let sender_funds_amount = 10000u128; + let owner = "creator"; + let info = mock_info( + owner, + &vec![ + Coin::new(sender_funds_amount, "uluna"), + Coin::new(sender_funds_amount, "uluna"), + Coin::new(sender_funds_amount, "uluna"), + Coin::new(sender_funds_amount, "uluna"), + Coin::new(sender_funds_amount, "uluna"), + Coin::new(sender_funds_amount, "uluna"), + ], + ); + + let recip_address1 = "address1".to_string(); + let recip_percent1 = 10; // 10% + + let recip_address2 = "address2".to_string(); + let recip_percent2 = 20; // 20% + + let address_percent = vec![ + AddressPercent { + recipient: Recipient::from_string(recip_address1), + percent: Decimal::percent(recip_percent1), + }, + AddressPercent { + recipient: Recipient::from_string(recip_address2), + percent: Decimal::percent(recip_percent2), + }, + ]; + let msg = ExecuteMsg::Send {}; + + let splitter = ConditionalSplitter { + thresholds: vec![Threshold::new(Uint128::zero(), address_percent)], + lock_time: Milliseconds::zero(), + }; + + CONDITIONAL_SPLITTER + .save(deps.as_mut().storage, &splitter) + .unwrap(); + + let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); + + let expected_res = ContractError::ExceedsMaxAllowedCoins {}; + + assert_eq!(res, expected_res); +} + +#[test] +fn test_update_app_contract() { + let mut deps = mock_dependencies_custom(&[]); + let _res: Response = init(deps.as_mut()); + + let info = mock_info(OWNER, &[]); + + let msg = ExecuteMsg::UpdateAppContract { + address: "app_contract".to_string(), + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "update_app_contract") + .add_attribute("address", "app_contract") + .add_submessage(generate_economics_message(OWNER, "UpdateAppContract")), + res + ); +} + +#[test] +fn test_update_app_contract_invalid_recipient() { + let mut deps = mock_dependencies_custom(&[]); + let _res: Response = init(deps.as_mut()); + + let info = mock_info(OWNER, &[]); + + let msg = ExecuteMsg::UpdateAppContract { + address: "z".to_string(), + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg); + assert!(res.is_err()) +} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/Cargo.toml b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/Cargo.toml index c8241d9..7e79443 100644 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/Cargo.toml +++ b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-cross-chain-swap" -version = "0.2.0" +version = "1.1.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -20,7 +20,6 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } schemars = { version = "0.8.10" } serde = { version = "1.0.127", default-features = false, features = ["derive"] } semver = { workspace = true } @@ -32,4 +31,4 @@ andromeda-finance = { workspace = true } cw-multi-test = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/README.md b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/README.md new file mode 100644 index 0000000..e69de29 diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/andromeda-cross-chain-swap.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/andromeda-cross-chain-swap.json deleted file mode 100644 index 723b42a..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/andromeda-cross-chain-swap.json +++ /dev/null @@ -1,1444 +0,0 @@ -{ - "contract_name": "andromeda-cross-chain-swap", - "contract_version": "0.2.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "get_splitter_config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/execute.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/execute.json deleted file mode 100644 index ef569be..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/execute.json +++ /dev/null @@ -1,632 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/instantiate.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/instantiate.json deleted file mode 100644 index c3a53e7..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/instantiate.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/query.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/query.json deleted file mode 100644 index 2001067..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/query.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_balance.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_get_splitter_config.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_get_splitter_config.json deleted file mode 100644 index 7b5e612..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_get_splitter_config.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_operators.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_owner.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissions.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_type.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_version.json b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/contract.rs b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/contract.rs index 665f2a5..6a7eced 100644 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/contract.rs +++ b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/contract.rs @@ -1,24 +1,22 @@ use andromeda_finance::cross_chain_swap::{ - ExecuteMsg, InstantiateMsg, MigrateMsg, OsmosisSwapResponse, QueryMsg, + ExecuteMsg, InstantiateMsg, OsmosisSwapResponse, QueryMsg, }; - +use andromeda_std::common::actions::call_action; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, amp::{ messages::{AMPMsg, AMPPkt}, AndrAddr, }, - error::{from_semver, ContractError}, + error::ContractError, }; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; use cosmwasm_std::{ - attr, ensure, entry_point, Binary, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, - Response, StdError, SubMsg, + attr, entry_point, Binary, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, Reply, Response, + StdError, SubMsg, }; -use cw2::{get_contract_version, set_contract_version}; use cw_utils::one_coin; -use semver::Version; use crate::{ dex::{execute_swap_osmo, parse_swap_reply, MSG_FORWARD_ID, MSG_SWAP_ID}, @@ -36,17 +34,15 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let inst_resp = ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "andromeda-cross-chain-swap".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -139,8 +135,15 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { let _contract = ADOContract::default(); + call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; match msg { ExecuteMsg::SwapAndForward { dex, @@ -218,36 +221,7 @@ fn execute_swap_and_forward( #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/mock.rs b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/mock.rs index 717f33c..7800b48 100644 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/mock.rs +++ b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/mock.rs @@ -19,7 +19,7 @@ pub fn mock_splitter_instantiate_msg( InstantiateMsg { recipients, lock_time, - modules: None, + kernel_address: Some(kernel_address.into()), } } diff --git a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/testing/mock_querier.rs b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/testing/mock_querier.rs index 51d84f3..abe4b9a 100644 --- a/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/finance/andromeda-cross-chain-swap/src/testing/mock_querier.rs @@ -2,15 +2,14 @@ use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, }; -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -32,11 +31,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "splitter".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/Cargo.toml b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/Cargo.toml index 3b19561..fd9e80b 100644 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/Cargo.toml +++ b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-rate-limiting-withdrawals" -version = "0.2.1" +version = "2.0.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -21,14 +21,14 @@ cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw20 = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } + +andromeda-std = { workspace = true } andromeda-finance = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/README.md b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/README.md new file mode 100644 index 0000000..cb7a30a --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/README.md @@ -0,0 +1,5 @@ +# Overview + +The Rate Limiting Withdrawals ADO acts as a bank account that limits the frequency and size of an account holder's withdrawals. Only one type of coin can be used. A user can deposit funds for themselves or another user and these funds can be withdrawn according the the specified limits. + +[Rate Limiting Withdrawals Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/rate-limiting-withdrawals) diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/examples/schema.rs b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/examples/schema.rs index fb68c82..c315539 100644 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/examples/schema.rs +++ b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/examples/schema.rs @@ -1,4 +1,4 @@ -use andromeda_finance::splitter::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_finance::rate_limiting_withdrawals::{ExecuteMsg, InstantiateMsg, QueryMsg}; use cosmwasm_schema::write_api; fn main() { diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/andromeda-rate-limiting-withdrawals.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/andromeda-rate-limiting-withdrawals.json deleted file mode 100644 index 27a67ab..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/andromeda-rate-limiting-withdrawals.json +++ /dev/null @@ -1,1611 +0,0 @@ -{ - "contract_name": "andromeda-rate-limiting-withdrawals", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "get_splitter_config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/execute.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/execute.json deleted file mode 100644 index 5dc847c..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/execute.json +++ /dev/null @@ -1,722 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/instantiate.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/instantiate.json deleted file mode 100644 index c3a53e7..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/instantiate.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/query.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/query.json deleted file mode 100644 index 06f3f4f..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/query.json +++ /dev/null @@ -1,245 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_balance.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_get_splitter_config.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_get_splitter_config.json deleted file mode 100644 index 7b5e612..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_get_splitter_config.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_operators.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_owner.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissions.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_type.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_version.json b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs index aece77b..060f69d 100644 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs +++ b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/contract.rs @@ -1,25 +1,21 @@ use crate::state::{ACCOUNTS, ALLOWED_COIN}; - use andromeda_finance::rate_limiting_withdrawals::{ - AccountDetails, CoinAllowance, ExecuteMsg, InstantiateMsg, MigrateMsg, MinimumFrequency, - QueryMsg, + AccountDetails, CoinAllowance, ExecuteMsg, InstantiateMsg, MinimumFrequency, QueryMsg, }; + +use andromeda_std::ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}; use andromeda_std::ado_contract::ADOContract; +use andromeda_std::common::actions::call_action; use andromeda_std::common::context::ExecuteContext; -use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, - common::encode_binary, - error::{from_semver, ContractError}, -}; +use andromeda_std::common::Milliseconds; +use andromeda_std::{common::encode_binary, error::ContractError}; use cosmwasm_std::{ ensure, entry_point, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, Uint128, }; -use cw2::{get_contract_version, set_contract_version}; use cw_utils::{nonpayable, one_coin}; -use semver::Version; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-rate-limiting-withdrawals"; @@ -32,61 +28,46 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - match msg.minimal_withdrawal_frequency { - MinimumFrequency::Time { time } => ALLOWED_COIN.save( - deps.storage, - &CoinAllowance { - coin: msg.allowed_coin.coin, - limit: msg.allowed_coin.limit, - minimal_withdrawal_frequency: time, - }, - )?, - //NOTE temporary until a replacement for primitive is implemented - _ => ALLOWED_COIN.save( - deps.storage, - &CoinAllowance { - coin: msg.allowed_coin.coin, - limit: msg.allowed_coin.limit, - minimal_withdrawal_frequency: Uint128::zero(), - }, - )?, - // MinimumFrequency::AddressAndKey { address_and_key } => ALLOWED_COIN.save( - // deps.storage, - // &CoinAllowance { - // coin: msg.allowed_coin.clone().coin, - // limit: msg.allowed_coin.limit, - // minimal_withdrawal_frequency: query_primitive::( - // deps.querier, - // address_and_key.contract_address, - // address_and_key.key, - // )? - // .value - // .try_get_uint128()?, - // }, - // )?, + MinimumFrequency::Time { time } => { + ensure!(!time.is_zero(), ContractError::InvalidZeroAmount {}); + + ensure!( + !msg.allowed_coin.limit.is_zero(), + ContractError::InvalidZeroAmount {} + ); + + ensure!( + !msg.allowed_coin.coin.is_empty(), + ContractError::EmptyString {} + ); + + ALLOWED_COIN.save( + deps.storage, + &CoinAllowance { + coin: msg.allowed_coin.coin, + limit: msg.allowed_coin.limit, + minimal_withdrawal_frequency: time, + }, + )? + } } let inst_resp = ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info.clone(), BaseInstantiateMsg { - ado_type: "rate-limiting-withdrawals".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; - let mod_resp = - ADOContract::default().register_modules(info.sender.as_str(), deps.storage, msg.modules)?; - Ok(inst_resp - .add_attributes(mod_resp.attributes) - .add_submessages(mod_resp.messages)) + Ok(inst_resp) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -96,20 +77,6 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - let contract = ADOContract::default(); - - if !matches!(msg, ExecuteMsg::UpdateAppContract { .. }) - && !matches!(msg, ExecuteMsg::UpdateOwner { .. }) - { - contract.module_hook::( - &deps.as_ref(), - AndromedaHook::OnExecute { - sender: info.sender.to_string(), - payload: encode_binary(&msg)?, - }, - )?; - } - let ctx = ExecuteContext::new(deps, info, env); match msg { @@ -120,12 +87,24 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - match msg { - ExecuteMsg::Deposits { recipient } => execute_deposit(ctx, recipient), - ExecuteMsg::Withdraws { amount } => execute_withdraw(ctx, amount), +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + let res = match msg { + ExecuteMsg::Deposit { recipient } => execute_deposit(ctx, recipient), + ExecuteMsg::Withdraw { amount } => execute_withdraw(ctx, amount), _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } fn execute_deposit( @@ -136,16 +115,18 @@ fn execute_deposit( // The contract only supports one type of coin one_coin(&info)?; + let funds = &info.funds[0]; + // Coin has to be in the allowed list let coin = ALLOWED_COIN.load(deps.storage)?; ensure!( - coin.coin == info.funds[0].denom, + coin.coin == funds.denom, ContractError::InvalidFunds { msg: "Coin must be part of the allowed list".to_string(), } ); - let user = recipient.unwrap_or_else(|| info.sender.to_string()); + let user = recipient.unwrap_or(info.sender.to_string()); // Load list of accounts let account = ACCOUNTS.may_load(deps.storage, user.clone())?; @@ -155,7 +136,7 @@ fn execute_deposit( // If the user does have an account in that coin // Calculate new amount of coins - let new_amount = account.balance + info.funds[0].amount; + let new_amount = account.balance.checked_add(funds.amount)?; // add new balance with updated coin let new_details = AccountDetails { @@ -169,7 +150,7 @@ fn execute_deposit( // If user doesn't have an account at all } else { let new_account_details = AccountDetails { - balance: info.funds[0].amount, + balance: funds.amount, latest_withdrawal: None, }; // save changes @@ -178,7 +159,8 @@ fn execute_deposit( let res = Response::new() .add_attribute("action", "funded account") - .add_attribute("account", info.sender.to_string()); + .add_attribute("account", info.sender.to_string()) + .add_attribute("amount", funds.amount); Ok(res) } @@ -188,126 +170,68 @@ fn execute_withdraw(ctx: ExecuteContext, amount: Uint128) -> Result= minimum_withdrawal_frequency, - ContractError::FundsAreLocked {} - ); - - // make sure the funds requested don't exceed the user's balance - ensure!( - account.balance >= amount, - ContractError::InsufficientFunds {} - ); - - // make sure the funds don't exceed the withdrawal limit - let limit = ALLOWED_COIN.load(deps.storage)?; - ensure!( - limit.limit >= amount, - ContractError::WithdrawalLimitExceeded {} - ); - // Update amount - let new_amount = account.balance - amount; + // check if sender has an account + let account = ACCOUNTS + .load(deps.storage, info.sender.to_string()) + .map_err(|_err| ContractError::AccountNotFound {})?; + + let allowed_coin = ALLOWED_COIN.load(deps.storage)?; + + // Calculate time since last withdrawal + if let Some(latest_withdrawal) = account.latest_withdrawal { + let minimum_withdrawal_frequency = allowed_coin.minimal_withdrawal_frequency; + let current_time = Milliseconds::from_seconds(env.block.time.seconds()); + let seconds_since_withdrawal = current_time.minus_seconds(latest_withdrawal.seconds()); + + // make sure enough time has elapsed since the latest withdrawal + ensure!( + seconds_since_withdrawal >= minimum_withdrawal_frequency, + ContractError::FundsAreLocked {} + ); + } - // Update account details - let new_details = AccountDetails { - balance: new_amount, - latest_withdrawal: Some(env.block.time), - }; + // make sure the funds requested don't exceed the user's balance + ensure!( + account.balance >= amount, + ContractError::InsufficientFunds {} + ); - // Save changes - ACCOUNTS.save(deps.storage, info.sender.to_string(), &new_details)?; - } else { - // make sure the funds requested don't exceed the user's balance - ensure!( - account.balance >= amount, - ContractError::InsufficientFunds {} - ); + // make sure the funds don't exceed the withdrawal limit + let limit = allowed_coin.limit; + ensure!(limit >= amount, ContractError::WithdrawalLimitExceeded {}); - // make sure the funds don't exceed the withdrawal limit - let limit = ALLOWED_COIN.load(deps.storage)?; - ensure!( - limit.limit >= amount, - ContractError::WithdrawalLimitExceeded {} - ); + // Update amount + let new_amount = account.balance.checked_sub(amount)?; - // Update amount - let new_amount = account.balance - amount; + // Update account details + let new_details = AccountDetails { + balance: new_amount, + latest_withdrawal: Some(env.block.time), + }; - // Update account details - let new_details = AccountDetails { - balance: new_amount, - latest_withdrawal: Some(env.block.time), - }; + // Save changes + ACCOUNTS.save(deps.storage, info.sender.to_string(), &new_details)?; - // Save changes - ACCOUNTS.save(deps.storage, info.sender.to_string(), &new_details)?; - } - - let coin = Coin { - denom: ALLOWED_COIN.load(deps.storage)?.coin, - amount, - }; + let coin = Coin { + denom: allowed_coin.coin, + amount, + }; - // Transfer funds - let res = Response::new() - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: info.sender.to_string(), - amount: vec![coin.clone()], - })) - .add_attribute("action", "withdrew funds") - .add_attribute("coin", coin.to_string()); - Ok(res) - } else { - Err(ContractError::AccountNotFound {}) - } + // Transfer funds + let res = Response::new() + .add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![coin.clone()], + })) + .add_attribute("action", "withdrew funds") + .add_attribute("coin", coin.to_string()); + Ok(res) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[entry_point] diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/mock_querier.rs b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/mock_querier.rs index b426f92..ffd951f 100644 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/mock_querier.rs @@ -1,23 +1,18 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg, Uint128}; -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; +// pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; +// pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -39,11 +34,11 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "splitter".to_string(), ado_version: "test".to_string(), - operators: None, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -77,91 +72,14 @@ impl Querier for WasmMockQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } - } + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: _, + msg: _, + }) => MockAndromedaQuerier::default().handle_query(&self.base, request), _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/tests.rs b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/tests.rs index 57ea2de..1cc2f67 100644 --- a/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/tests.rs +++ b/andromeda-core/contracts/finance/andromeda-rate-limiting-withdrawals/src/testing/tests.rs @@ -1,5 +1,4 @@ -use andromeda_std::{ado_base::modules::Module, error::ContractError}; - +use andromeda_std::{common::Milliseconds, error::ContractError}; use cosmwasm_std::{ coin, testing::{mock_env, mock_info}, @@ -18,9 +17,8 @@ use andromeda_finance::rate_limiting_withdrawals::{ AccountDetails, CoinAndLimit, ExecuteMsg, InstantiateMsg, MinimumFrequency, }; -fn init(deps: DepsMut, modules: Option>) -> Response { +fn init(deps: DepsMut) -> Response { let msg = InstantiateMsg { - modules, owner: Some(OWNER.to_owned()), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), allowed_coin: CoinAndLimit { @@ -28,7 +26,7 @@ fn init(deps: DepsMut, modules: Option>) -> Response { limit: Uint128::from(50_u64), }, minimal_withdrawal_frequency: MinimumFrequency::Time { - time: Uint128::from(10_u16), + time: Milliseconds::from_seconds(10), }, }; @@ -39,7 +37,7 @@ fn init(deps: DepsMut, modules: Option>) -> Response { #[test] fn test_instantiate_works() { let mut deps = mock_dependencies_custom(&[]); - let res = init(deps.as_mut(), None); + let res = init(deps.as_mut()); assert_eq!(0, res.messages.len()); } @@ -47,18 +45,18 @@ fn test_instantiate_works() { fn test_deposit_zero_funds() { let mut deps = mock_dependencies_custom(&[]); let info = mock_info("creator", &[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - let exec = ExecuteMsg::Deposits { recipient: None }; + let exec = ExecuteMsg::Deposit { recipient: None }; let _err = execute(deps.as_mut(), mock_env(), info, exec).unwrap_err(); } #[test] fn test_deposit_invalid_funds() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("me".to_string()), }; @@ -76,9 +74,9 @@ fn test_deposit_invalid_funds() { #[test] fn test_deposit_new_account_works() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("andromedauser".to_string()), }; @@ -98,16 +96,16 @@ fn test_deposit_new_account_works() { #[test] fn test_deposit_existing_account_works() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("andromedauser".to_string()), }; let info = mock_info("creator", &[coin(30, "junox")]); let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); - let exec = ExecuteMsg::Deposits { recipient: None }; + let exec = ExecuteMsg::Deposit { recipient: None }; let info = mock_info("andromedauser", &[coin(70, "junox")]); @@ -125,9 +123,9 @@ fn test_deposit_existing_account_works() { #[test] fn test_withdraw_account_not_found() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("andromedauser".to_string()), }; @@ -136,7 +134,7 @@ fn test_withdraw_account_not_found() { let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); let info = mock_info("random", &[]); - let exec = ExecuteMsg::Withdraws { + let exec = ExecuteMsg::Withdraw { amount: Uint128::from(19_u16), }; let err = execute(deps.as_mut(), mock_env(), info, exec).unwrap_err(); @@ -146,9 +144,9 @@ fn test_withdraw_account_not_found() { #[test] fn test_withdraw_over_account_limit() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("andromedauser".to_string()), }; @@ -157,7 +155,7 @@ fn test_withdraw_over_account_limit() { let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); let info = mock_info("andromedauser", &[]); - let exec = ExecuteMsg::Withdraws { + let exec = ExecuteMsg::Withdraw { amount: Uint128::from(31_u16), }; let err = execute(deps.as_mut(), mock_env(), info, exec).unwrap_err(); @@ -167,9 +165,9 @@ fn test_withdraw_over_account_limit() { #[test] fn test_withdraw_funds_locked() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("andromedauser".to_string()), }; @@ -178,13 +176,13 @@ fn test_withdraw_funds_locked() { let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); let info = mock_info("andromedauser", &[]); - let exec = ExecuteMsg::Withdraws { + let exec = ExecuteMsg::Withdraw { amount: Uint128::from(10_u16), }; let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); let info = mock_info("andromedauser", &[]); - let exec = ExecuteMsg::Withdraws { + let exec = ExecuteMsg::Withdraw { amount: Uint128::from(10_u16), }; @@ -199,19 +197,18 @@ fn test_withdraw_over_allowed_limit() { let env = mock_env(); let info = mock_info("creator", &[]); let msg = InstantiateMsg { - modules: None, allowed_coin: CoinAndLimit { coin: "junox".to_string(), limit: Uint128::from(20_u64), }, minimal_withdrawal_frequency: MinimumFrequency::Time { - time: Uint128::from(10_u16), + time: Milliseconds::from_seconds(10), }, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }; let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("andromedauser".to_string()), }; @@ -220,7 +217,7 @@ fn test_withdraw_over_allowed_limit() { let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); let info = mock_info("andromedauser", &[]); - let exec = ExecuteMsg::Withdraws { + let exec = ExecuteMsg::Withdraw { amount: Uint128::from(21_u16), }; let err = execute(deps.as_mut(), mock_env(), info, exec).unwrap_err(); @@ -233,19 +230,18 @@ fn test_withdraw_works() { let env = mock_env(); let info = mock_info("creator", &[]); let msg = InstantiateMsg { - modules: None, allowed_coin: CoinAndLimit { coin: "junox".to_string(), limit: Uint128::from(50_u64), }, minimal_withdrawal_frequency: MinimumFrequency::Time { - time: Uint128::from(10_u16), + time: Milliseconds::from_seconds(10), }, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }; let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - let exec = ExecuteMsg::Deposits { + let exec = ExecuteMsg::Deposit { recipient: Some("andromedauser".to_string()), }; @@ -254,7 +250,7 @@ fn test_withdraw_works() { let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); let info = mock_info("andromedauser", &[]); - let exec = ExecuteMsg::Withdraws { + let exec = ExecuteMsg::Withdraw { amount: Uint128::from(10_u16), }; let _res = execute(deps.as_mut(), mock_env(), info, exec).unwrap(); diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/.cargo/config b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/.cargo/config new file mode 100644 index 0000000..336b618 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/.gitignore b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/.gitignore new file mode 100644 index 0000000..869df07 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock \ No newline at end of file diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/Cargo.toml b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/Cargo.toml new file mode 100644 index 0000000..bae7530 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "andromeda-set-amount-splitter" +version = "1.0.2" +edition = "2021" +rust-version = "1.75.0" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +testing = ["cw-multi-test", "andromeda-testing"] + + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } + +andromeda-std = { workspace = true } +andromeda-finance = { workspace = true } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } + +[dev-dependencies] +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/examples/schema.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/examples/schema.rs new file mode 100644 index 0000000..fb68c82 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/examples/schema.rs @@ -0,0 +1,11 @@ +use andromeda_finance::splitter::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + + } +} diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/contract.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/contract.rs new file mode 100644 index 0000000..7169e61 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/contract.rs @@ -0,0 +1,325 @@ +use std::collections::HashSet; + +use crate::state::SPLITTER; +use andromeda_finance::set_amount_splitter::{ + validate_recipient_list, AddressAmount, ExecuteMsg, GetSplitterConfigResponse, InstantiateMsg, + QueryMsg, Splitter, +}; +use andromeda_std::{ + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + amp::messages::AMPPkt, + common::{actions::call_action, encode_binary, Milliseconds, MillisecondsDuration}, + error::ContractError, +}; +use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; +use cosmwasm_std::{ + attr, coins, ensure, entry_point, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, + MessageInfo, Reply, Response, StdError, SubMsg, +}; +use cw_utils::nonpayable; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:andromeda-set-amount-splitter"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +// 1 day in seconds +const ONE_DAY: u64 = 86_400; +// 1 year in seconds +const ONE_YEAR: u64 = 31_536_000; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let splitter = match msg.lock_time { + Some(ref lock_time) => { + // New lock time can't be too short + ensure!( + lock_time.get_time(&env.block).seconds() >= ONE_DAY, + ContractError::LockTimeTooShort {} + ); + + // New lock time can't be too long + ensure!( + lock_time.get_time(&env.block).seconds() <= ONE_YEAR, + ContractError::LockTimeTooLong {} + ); + Splitter { + recipients: msg.recipients.clone(), + lock: lock_time.get_time(&env.block), + } + } + None => { + Splitter { + recipients: msg.recipients.clone(), + // If locking isn't desired upon instantiation, it's automatically set to 0 + lock: Milliseconds::default(), + } + } + }; + // Save kernel address after validating it + + SPLITTER.save(deps.storage, &splitter)?; + + let inst_resp = ADOContract::default().instantiate( + deps.storage, + env, + deps.api, + &deps.querier, + info, + BaseInstantiateMsg { + ado_type: CONTRACT_NAME.to_string(), + ado_version: CONTRACT_VERSION.to_string(), + kernel_address: msg.kernel_address.clone(), + owner: msg.owner.clone(), + }, + )?; + + msg.validate(deps.as_ref())?; + + Ok(inst_resp) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { + if msg.result.is_err() { + return Err(ContractError::Std(StdError::generic_err( + msg.result.unwrap_err(), + ))); + } + + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let ctx = ExecuteContext::new(deps, info, env); + + match msg { + ExecuteMsg::AMPReceive(pkt) => { + ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) + } + _ => handle_execute(ctx, msg), + } +} + +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { + ExecuteMsg::UpdateRecipients { recipients } => execute_update_recipients(ctx, recipients), + ExecuteMsg::UpdateLock { lock_time } => execute_update_lock(ctx, lock_time), + ExecuteMsg::Send {} => execute_send(ctx), + _ => ADOContract::default().execute(ctx, msg), + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) +} + +fn execute_send(ctx: ExecuteContext) -> Result { + let ExecuteContext { deps, info, .. } = ctx; + + ensure!( + info.funds.len() == 1 || info.funds.len() == 2, + ContractError::InvalidFunds { + msg: "A minimim of 1 and a maximum of 2 coins are allowed".to_string(), + } + ); + + // Check against zero amounts and duplicate denoms + let mut denom_set = HashSet::new(); + for coin in info.funds.clone() { + ensure!( + !coin.amount.is_zero(), + ContractError::InvalidFunds { + msg: "Amount must be non-zero".to_string(), + } + ); + ensure!( + !denom_set.contains(&coin.denom), + ContractError::DuplicateCoinDenoms {} + ); + denom_set.insert(coin.denom); + } + + let splitter = SPLITTER.load(deps.storage)?; + + let mut msgs: Vec = Vec::new(); + let mut amp_funds: Vec = Vec::new(); + + let mut pkt = AMPPkt::from_ctx(ctx.amp_ctx, ctx.env.contract.address.to_string()); + + // Iterate through the sent funds + for coin in info.funds { + let mut remainder_funds = coin.amount; + let denom = coin.denom; + + for recipient in &splitter.recipients { + // Find the recipient's corresponding denom for the current iteration of the sent funds + let recipient_coin = recipient + .coins + .clone() + .into_iter() + .find(|coin| coin.denom == denom); + + if let Some(recipient_coin) = recipient_coin { + // Deduct from total amount + remainder_funds = remainder_funds + .checked_sub(recipient_coin.amount) + .map_err(|_| ContractError::InsufficientFunds {})?; + + let recipient_funds = + cosmwasm_std::coin(recipient_coin.amount.u128(), recipient_coin.denom); + + let amp_msg = recipient + .recipient + .generate_amp_msg(&deps.as_ref(), Some(vec![recipient_funds.clone()]))?; + + pkt = pkt.add_message(amp_msg); + + amp_funds.push(recipient_funds); + } + } + + // Refund message for sender + if !remainder_funds.is_zero() { + let msg = SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: info.sender.clone().into_string(), + amount: coins(remainder_funds.u128(), denom), + })); + msgs.push(msg); + } + } + + let kernel_address = ADOContract::default().get_kernel_address(deps.as_ref().storage)?; + + if !pkt.messages.is_empty() { + let distro_msg = pkt.to_sub_msg(kernel_address, Some(amp_funds), 1)?; + msgs.push(distro_msg); + } + + Ok(Response::new() + .add_submessages(msgs) + .add_attribute("action", "send") + .add_attribute("sender", info.sender.to_string())) +} + +fn execute_update_recipients( + ctx: ExecuteContext, + recipients: Vec, +) -> Result { + let ExecuteContext { + deps, info, env, .. + } = ctx; + + nonpayable(&info)?; + + ensure!( + ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + validate_recipient_list(deps.as_ref(), recipients.clone())?; + + let mut splitter = SPLITTER.load(deps.storage)?; + // Can't call this function while the lock isn't expired + + ensure!( + splitter.lock.is_expired(&env.block), + ContractError::ContractLocked {} + ); + // Max 100 recipients + ensure!( + recipients.len() <= 100, + ContractError::ReachedRecipientLimit {} + ); + + splitter.recipients = recipients; + SPLITTER.save(deps.storage, &splitter)?; + + Ok(Response::default().add_attributes(vec![attr("action", "update_recipients")])) +} + +fn execute_update_lock( + ctx: ExecuteContext, + lock_time: MillisecondsDuration, +) -> Result { + let ExecuteContext { + deps, info, env, .. + } = ctx; + + nonpayable(&info)?; + + ensure!( + ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + let mut splitter = SPLITTER.load(deps.storage)?; + + // Can't call this function while the lock isn't expired + ensure!( + splitter.lock.is_expired(&env.block), + ContractError::ContractLocked {} + ); + + // Get current time + let current_time = Milliseconds::from_seconds(env.block.time.seconds()); + + // New lock time can't be too short + ensure!( + lock_time.seconds() >= ONE_DAY, + ContractError::LockTimeTooShort {} + ); + + // New lock time can't be unreasonably long + ensure!( + lock_time.seconds() <= ONE_YEAR, + ContractError::LockTimeTooLong {} + ); + + // Set new lock time + let new_expiration = current_time.plus_milliseconds(lock_time); + + splitter.lock = new_expiration; + + SPLITTER.save(deps.storage, &splitter)?; + + Ok(Response::default().add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", new_expiration.to_string()), + ])) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::GetSplitterConfig {} => encode_binary(&query_splitter(deps)?), + _ => ADOContract::default().query(deps, env, msg), + } +} + +fn query_splitter(deps: Deps) -> Result { + let splitter = SPLITTER.load(deps.storage)?; + + Ok(GetSplitterConfigResponse { config: splitter }) +} diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/lib.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/lib.rs new file mode 100644 index 0000000..abf4af6 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/lib.rs @@ -0,0 +1,8 @@ +pub mod contract; +pub mod state; + +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; + +#[cfg(test)] +mod testing; diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/mock.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/mock.rs new file mode 100644 index 0000000..04b3e2c --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/mock.rs @@ -0,0 +1,60 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] + +use crate::contract::{execute, instantiate, query, reply}; +use andromeda_finance::set_amount_splitter::{AddressAmount, ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::common::expiration::Expiry; +use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract, +}; +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockSetAmountSplitter(Addr); +mock_ado!(MockSetAmountSplitter, ExecuteMsg, QueryMsg); + +impl MockSetAmountSplitter { + pub fn instantiate( + app: &mut MockApp, + code_id: u64, + sender: Addr, + recipients: Vec, + kernel_address: impl Into, + lock_time: Option, + owner: Option, + ) -> Self { + let msg = + mock_set_amount_splitter_instantiate_msg(recipients, kernel_address, lock_time, owner); + let res = app.instantiate_contract(code_id, sender, &msg, &[], "Andromeda Splitter", None); + + Self(res.unwrap()) + } + + pub fn execute_send(&self, app: &mut MockApp, sender: Addr, funds: &[Coin]) -> ExecuteResult { + let msg = mock_set_amount_splitter_send_msg(); + + self.execute(app, &msg, sender, funds) + } +} + +pub fn mock_andromeda_set_amount_splitter() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query).with_reply(reply); + Box::new(contract) +} + +pub fn mock_set_amount_splitter_instantiate_msg( + recipients: Vec, + kernel_address: impl Into, + lock_time: Option, + owner: Option, +) -> InstantiateMsg { + InstantiateMsg { + recipients, + lock_time, + kernel_address: kernel_address.into(), + owner, + } +} + +pub fn mock_set_amount_splitter_send_msg() -> ExecuteMsg { + ExecuteMsg::Send {} +} diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/state.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/state.rs new file mode 100644 index 0000000..e6398d3 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/state.rs @@ -0,0 +1,4 @@ +use andromeda_finance::set_amount_splitter::Splitter; +use cw_storage_plus::Item; + +pub const SPLITTER: Item = Item::new("set-amount-splitter"); diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mock_querier.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mock_querier.rs new file mode 100644 index 0000000..d7d944b --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mock_querier.rs @@ -0,0 +1,91 @@ +use andromeda_std::ado_base::InstantiateMsg; +use andromeda_std::ado_contract::ADOContract; +use andromeda_std::testing::mock_querier::MockAndromedaQuerier; +use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; +use cosmwasm_std::{ + from_json, + testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, +}; + +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; + +/// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. +/// +/// Automatically assigns a kernel address as MOCK_KERNEL_CONTRACT. +pub fn mock_dependencies_custom( + contract_balance: &[Coin], +) -> OwnedDeps { + let custom_querier: WasmMockQuerier = + WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); + let storage = MockStorage::default(); + let mut deps = OwnedDeps { + storage, + api: MockApi::default(), + querier: custom_querier, + custom_query_type: std::marker::PhantomData, + }; + ADOContract::default() + .instantiate( + &mut deps.storage, + mock_env(), + &deps.api, + &QuerierWrapper::new(&deps.querier), + mock_info("sender", &[]), + InstantiateMsg { + ado_type: "splitter".to_string(), + ado_version: "test".to_string(), + + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + }, + ) + .unwrap(); + deps +} + +pub struct WasmMockQuerier { + pub base: MockQuerier, + pub contract_address: String, + pub tokens_left_to_burn: usize, +} + +impl Querier for WasmMockQuerier { + fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { + // MockQuerier doesn't support Custom, so we ignore it completely here + let request: QueryRequest = match from_json(bin_request) { + Ok(v) => v, + Err(e) => { + return SystemResult::Err(SystemError::InvalidRequest { + error: format!("Parsing query request: {e}"), + request: bin_request.into(), + }) + } + }; + self.handle_query(&request) + } +} + +impl WasmMockQuerier { + pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { + match &request { + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) + } + _ => MockAndromedaQuerier::default().handle_query(&self.base, request), + } + } + + pub fn new(base: MockQuerier) -> Self { + WasmMockQuerier { + base, + contract_address: mock_env().contract.address.to_string(), + tokens_left_to_burn: 2, + } + } +} diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mod.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mod.rs new file mode 100644 index 0000000..a1e507b --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/mod.rs @@ -0,0 +1,2 @@ +mod mock_querier; +mod tests; diff --git a/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/tests.rs b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/tests.rs new file mode 100644 index 0000000..ca9205a --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-set-amount-splitter/src/testing/tests.rs @@ -0,0 +1,494 @@ +use andromeda_std::{ + amp::{ + messages::{AMPMsg, AMPPkt}, + recipient::Recipient, + }, + common::{expiration::Expiry, Milliseconds}, + error::ContractError, +}; +use andromeda_testing::economics_msg::generate_economics_message; +use cosmwasm_std::{ + attr, coin, coins, from_json, + testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, + to_json_binary, BankMsg, Coin, CosmosMsg, DepsMut, Response, SubMsg, +}; +pub const OWNER: &str = "creator"; + +use super::mock_querier::MOCK_KERNEL_CONTRACT; + +use crate::{ + contract::{execute, instantiate, query}, + state::SPLITTER, + testing::mock_querier::mock_dependencies_custom, +}; +use andromeda_finance::set_amount_splitter::{ + AddressAmount, ExecuteMsg, GetSplitterConfigResponse, InstantiateMsg, QueryMsg, Splitter, +}; + +fn init(deps: DepsMut) -> Response { + let mock_recipient: Vec = vec![AddressAmount { + recipient: Recipient::from_string(String::from("some_address")), + coins: coins(1_u128, "uandr"), + }]; + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + recipients: mock_recipient, + lock_time: Some(Expiry::AtTime(Milliseconds::from_seconds(100_000))), + }; + + let info = mock_info("owner", &[]); + instantiate(deps, mock_env(), info, msg).unwrap() +} + +#[test] +fn test_instantiate() { + let mut deps = mock_dependencies_custom(&[]); + let res = init(deps.as_mut()); + assert_eq!(0, res.messages.len()); +} + +#[test] +fn test_execute_update_lock() { + let mut deps = mock_dependencies_custom(&[]); + let _res = init(deps.as_mut()); + + let env = mock_env(); + + let current_time = env.block.time.seconds(); + let lock_time = 100_000; + + // Start off with an expiration that's behind current time (expired) + let splitter = Splitter { + recipients: vec![], + lock: Milliseconds::from_seconds(current_time - 1), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + let msg = ExecuteMsg::UpdateLock { + lock_time: Milliseconds::from_seconds(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + let new_lock = Milliseconds::from_seconds(current_time + lock_time); + assert_eq!( + Response::default() + .add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", new_lock.to_string()) + ]) + .add_submessage(generate_economics_message(OWNER, "UpdateLock")), + res + ); + + //check result + let splitter = SPLITTER.load(deps.as_ref().storage).unwrap(); + assert!(!splitter.lock.is_expired(&env.block)); + assert_eq!(new_lock, splitter.lock); +} + +#[test] +fn test_execute_update_recipients() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res = init(deps.as_mut()); + + let splitter = Splitter { + recipients: vec![], + lock: Milliseconds::from_seconds(0), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + // Duplicate recipients + let duplicate_recipients = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("addr1")), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(String::from("addr1")), + coins: coins(1_u128, "uandr"), + }, + ]; + let msg = ExecuteMsg::UpdateRecipients { + recipients: duplicate_recipients, + }; + + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(ContractError::DuplicateRecipient {}, res.unwrap_err()); + + let recipients = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("addr1")), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(String::from("addr2")), + coins: coins(1_u128, "uandr"), + }, + ]; + let msg = ExecuteMsg::UpdateRecipients { + recipients: recipients.clone(), + }; + + let info = mock_info("incorrect_owner", &[]); + let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); + assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); + + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + assert_eq!( + Response::default() + .add_attributes(vec![attr("action", "update_recipients")]) + .add_submessage(generate_economics_message(OWNER, "UpdateRecipients")), + res + ); + + //check result + let splitter = SPLITTER.load(deps.as_ref().storage).unwrap(); + assert_eq!(splitter.recipients, recipients); +} + +#[test] +fn test_execute_send() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res: Response = init(deps.as_mut()); + + let sender_funds_amount = 10000u128; + + let info = mock_info( + OWNER, + &[ + Coin::new(sender_funds_amount, "uandr"), + Coin::new(50_u128, "usdc"), + ], + ); + + let recip_address1 = "address1".to_string(); + + let recip_address2 = "address2".to_string(); + + let recip1 = Recipient::from_string(recip_address1); + let recip2 = Recipient::from_string(recip_address2); + + let recipient = vec![ + AddressAmount { + recipient: recip1.clone(), + coins: vec![coin(1_u128, "uandr"), coin(30_u128, "usdc")], + }, + AddressAmount { + recipient: recip2.clone(), + coins: vec![coin(1_u128, "uandr"), coin(20_u128, "usdc")], + }, + ]; + let msg = ExecuteMsg::Send {}; + + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1, "uandr")])) + .unwrap(); + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1, "uandr")])) + .unwrap(); + + let amp_msg_3 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(30, "usdc")])) + .unwrap(); + let amp_msg_4 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(20, "usdc")])) + .unwrap(); + + let amp_pkt = AMPPkt::new( + MOCK_CONTRACT_ADDR.to_string(), + MOCK_CONTRACT_ADDR.to_string(), + vec![amp_msg_1, amp_msg_2, amp_msg_3, amp_msg_4], + ); + let amp_msg = amp_pkt + .to_sub_msg( + MOCK_KERNEL_CONTRACT, + Some(vec![ + Coin::new(1, "uandr"), + Coin::new(1, "uandr"), + Coin::new(30, "usdc"), + Coin::new(20, "usdc"), + ]), + 1, + ) + .unwrap(); + + let splitter = Splitter { + recipients: recipient, + lock: Milliseconds::default(), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + + let expected_res = Response::new() + .add_submessages(vec![ + SubMsg::new( + // refunds remainder to sender + CosmosMsg::Bank(BankMsg::Send { + to_address: OWNER.to_string(), + amount: vec![Coin::new(9998, "uandr")], + }), + ), + amp_msg, + ]) + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) + .add_submessage(generate_economics_message(OWNER, "Send")); + + assert_eq!(res, expected_res); +} + +#[test] +fn test_execute_send_ado_recipient() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res: Response = init(deps.as_mut()); + + let sender_funds_amount = 10_000u128; + let info = mock_info(OWNER, &[Coin::new(sender_funds_amount, "uandr")]); + + let recip_address1 = "address1".to_string(); + + let recip_address2 = "address2".to_string(); + + let recip1 = Recipient::from_string(recip_address1); + let recip2 = Recipient::from_string(recip_address2); + + let recipient = vec![ + AddressAmount { + recipient: recip1.clone(), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: recip2.clone(), + coins: coins(1_u128, "uandr"), + }, + ]; + let msg = ExecuteMsg::Send {}; + + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1, "uandr")])) + .unwrap(); + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1, "uandr")])) + .unwrap(); + let amp_pkt = AMPPkt::new( + MOCK_CONTRACT_ADDR.to_string(), + MOCK_CONTRACT_ADDR.to_string(), + vec![amp_msg_1, amp_msg_2], + ); + let amp_msg = amp_pkt + .to_sub_msg( + MOCK_KERNEL_CONTRACT, + Some(vec![Coin::new(1, "uandr"), Coin::new(1, "uandr")]), + 1, + ) + .unwrap(); + + let splitter = Splitter { + recipients: recipient, + lock: Milliseconds::default(), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + let res = execute(deps.as_mut(), env, info.clone(), msg).unwrap(); + + let expected_res = Response::new() + .add_submessages(vec![ + SubMsg::new( + // refunds remainder to sender + CosmosMsg::Bank(BankMsg::Send { + to_address: info.sender.to_string(), + amount: vec![Coin::new(9_998, "uandr")], + }), + ), + amp_msg, + ]) + .add_attribute("action", "send") + .add_attribute("sender", "creator") + .add_submessage(generate_economics_message(OWNER, "Send")); + + assert_eq!(res, expected_res); +} + +#[test] +fn test_handle_packet_exit_with_error_true() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res: Response = init(deps.as_mut()); + + let sender_funds_amount = 0u128; + let info = mock_info(OWNER, &[Coin::new(sender_funds_amount, "uandr")]); + + let recip_address1 = "address1".to_string(); + + let recipient = vec![ + AddressAmount { + recipient: Recipient::from_string(recip_address1.clone()), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(recip_address1.clone()), + coins: coins(1_u128, "uandr"), + }, + ]; + let pkt = AMPPkt::new( + info.clone().sender, + "cosmos2contract", + vec![AMPMsg::new( + recip_address1, + to_json_binary(&ExecuteMsg::Send {}).unwrap(), + Some(vec![Coin::new(0, "uandr")]), + )], + ); + let msg = ExecuteMsg::AMPReceive(pkt); + + let splitter = Splitter { + recipients: recipient, + lock: Milliseconds::default(), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + + assert_eq!( + err, + ContractError::InvalidFunds { + msg: "Amount must be non-zero".to_string(), + } + ); +} + +#[test] +fn test_query_splitter() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let splitter = Splitter { + recipients: vec![], + lock: Milliseconds::default(), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + let query_msg = QueryMsg::GetSplitterConfig {}; + let res = query(deps.as_ref(), env, query_msg).unwrap(); + let val: GetSplitterConfigResponse = from_json(res).unwrap(); + + assert_eq!(val.config, splitter); +} + +#[test] +fn test_execute_send_error() { + //Executes send with more than 5 tokens [ACK-04] + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res: Response = init(deps.as_mut()); + + let sender_funds_amount = 10000u128; + let owner = "creator"; + let info = mock_info( + owner, + &vec![ + Coin::new(sender_funds_amount, "uandr"), + Coin::new(sender_funds_amount, "uandr"), + Coin::new(sender_funds_amount, "uandr"), + Coin::new(sender_funds_amount, "uandr"), + Coin::new(sender_funds_amount, "uandr"), + Coin::new(sender_funds_amount, "uandr"), + ], + ); + + let recip_address1 = "address1".to_string(); + + let recip_address2 = "address2".to_string(); + + let recipient = vec![ + AddressAmount { + recipient: Recipient::from_string(recip_address1), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(recip_address2), + coins: coins(1_u128, "uandr"), + }, + ]; + let msg = ExecuteMsg::Send {}; + + let splitter = Splitter { + recipients: recipient, + lock: Milliseconds::default(), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + let res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap_err(); + + let expected_res = ContractError::InvalidFunds { + msg: "A minimim of 1 and a maximum of 2 coins are allowed".to_string(), + }; + + assert_eq!(res, expected_res); + + // Insufficient funds + let info = mock_info(owner, &[Coin::new(1_u128, "uandr")]); + + let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); + + let expected_res = ContractError::InsufficientFunds {}; + + assert_eq!(res, expected_res); +} + +#[test] +fn test_update_app_contract() { + let mut deps = mock_dependencies_custom(&[]); + let _res: Response = init(deps.as_mut()); + + let info = mock_info(OWNER, &[]); + + let msg = ExecuteMsg::UpdateAppContract { + address: "app_contract".to_string(), + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "update_app_contract") + .add_attribute("address", "app_contract") + .add_submessage(generate_economics_message(OWNER, "UpdateAppContract")), + res + ); +} + +#[test] +fn test_update_app_contract_invalid_recipient() { + let mut deps = mock_dependencies_custom(&[]); + let _res: Response = init(deps.as_mut()); + + let info = mock_info(OWNER, &[]); + + let msg = ExecuteMsg::UpdateAppContract { + address: "z".to_string(), + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg); + + // assert_eq!( + // ContractError::InvalidComponent { + // name: "z".to_string() + // }, + // res.unwrap_err() + // ); + assert!(res.is_err()) +} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/Cargo.toml b/andromeda-core/contracts/finance/andromeda-splitter/Cargo.toml index 619ebe3..4cfc888 100644 --- a/andromeda-core/contracts/finance/andromeda-splitter/Cargo.toml +++ b/andromeda-core/contracts/finance/andromeda-splitter/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-splitter" -version = "0.2.3" +version = "2.1.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -20,15 +20,13 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } andromeda-std = { workspace = true } andromeda-finance = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } -andromeda-testing = { workspace = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-splitter/README.md b/andromeda-core/contracts/finance/andromeda-splitter/README.md new file mode 100644 index 0000000..ad8bde2 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-splitter/README.md @@ -0,0 +1,5 @@ +# Overview + +The Splitter ADO is a smart contract used to split funds to a preset number of addresses. Each of the addresses has a specific percentage assigned by the contract owner. The splitter can be locked for a specified time as a kind of insurance for recipients that their percentages will not be changed for a certain period of time. Whenever funds are sent to the splitter using the `Send` execute message, they are automatically distributed to the recipient set. + +[Splitter Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/splitter) diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/andromeda-splitter.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/andromeda-splitter.json deleted file mode 100644 index cebf918..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/andromeda-splitter.json +++ /dev/null @@ -1,1444 +0,0 @@ -{ - "contract_name": "andromeda-splitter", - "contract_version": "0.2.3", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "get_splitter_config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/execute.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/execute.json deleted file mode 100644 index ef569be..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/execute.json +++ /dev/null @@ -1,632 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/instantiate.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/instantiate.json deleted file mode 100644 index c3a53e7..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/instantiate.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/query.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/query.json deleted file mode 100644 index 2001067..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/query.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_balance.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_get_splitter_config.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_get_splitter_config.json deleted file mode 100644 index 7b5e612..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_get_splitter_config.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressPercent": { - "type": "object", - "required": [ - "percent", - "recipient" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - }, - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressPercent" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_operators.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_owner.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissions.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_type.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_version.json b/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/finance/andromeda-splitter/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-splitter/src/contract.rs b/andromeda-core/contracts/finance/andromeda-splitter/src/contract.rs index 50473de..59211c9 100644 --- a/andromeda-core/contracts/finance/andromeda-splitter/src/contract.rs +++ b/andromeda-core/contracts/finance/andromeda-splitter/src/contract.rs @@ -1,31 +1,28 @@ use crate::state::SPLITTER; use andromeda_finance::splitter::{ validate_recipient_list, AddressPercent, ExecuteMsg, GetSplitterConfigResponse, InstantiateMsg, - MigrateMsg, QueryMsg, Splitter, + QueryMsg, Splitter, }; - use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, amp::messages::AMPPkt, - common::encode_binary, - error::{from_semver, ContractError}, + common::{actions::call_action, encode_binary, Milliseconds, MillisecondsDuration}, + error::ContractError, }; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; use cosmwasm_std::{ attr, ensure, entry_point, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, - Reply, Response, StdError, SubMsg, Timestamp, Uint128, + Reply, Response, StdError, SubMsg, Uint128, }; -use cw2::{get_contract_version, set_contract_version}; -use cw_utils::{nonpayable, Expiration}; -use semver::Version; +use cw_utils::nonpayable; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-splitter"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); -// 1 day in seconds -const ONE_DAY: u64 = 86_400; -// 1 year in seconds -const ONE_YEAR: u64 = 31_536_000; +// 1 day in milliseconds +const ONE_DAY: u64 = 86_400_000; +// 1 year in milliseconds +const ONE_YEAR: u64 = 31_536_000_000; #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( @@ -34,34 +31,32 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - msg.validate()?; - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Max 100 recipients - ensure!( - msg.recipients.len() <= 100, - ContractError::ReachedRecipientLimit {} - ); - - let current_time = env.block.time.seconds(); let splitter = match msg.lock_time { - Some(lock_time) => { + Some(ref lock_time) => { + let time = lock_time.get_time(&env.block); // New lock time can't be too short - ensure!(lock_time >= ONE_DAY, ContractError::LockTimeTooShort {}); + ensure!( + time >= Milliseconds::from_seconds(env.block.time.seconds()) + .plus_milliseconds(Milliseconds(ONE_DAY)), + ContractError::LockTimeTooShort {} + ); // New lock time can't be too long - ensure!(lock_time <= ONE_YEAR, ContractError::LockTimeTooLong {}); - + ensure!( + time <= Milliseconds::from_seconds(env.block.time.seconds()) + .plus_milliseconds(Milliseconds(ONE_YEAR)), + ContractError::LockTimeTooLong {} + ); Splitter { - recipients: msg.recipients, - lock: Expiration::AtTime(Timestamp::from_seconds(lock_time + current_time)), + recipients: msg.recipients.clone(), + lock: time, } } None => { Splitter { - recipients: msg.recipients, + recipients: msg.recipients.clone(), // If locking isn't desired upon instantiation, it's automatically set to 0 - lock: Expiration::AtTime(Timestamp::from_seconds(current_time)), + lock: Milliseconds::default(), } } }; @@ -73,16 +68,18 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "splitter".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, - kernel_address: msg.kernel_address, - owner: msg.owner, + kernel_address: msg.kernel_address.clone(), + owner: msg.owner.clone(), }, )?; + msg.validate(deps.as_ref())?; + Ok(inst_resp) } @@ -114,13 +111,24 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - match msg { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { ExecuteMsg::UpdateRecipients { recipients } => execute_update_recipients(ctx, recipients), ExecuteMsg::UpdateLock { lock_time } => execute_update_lock(ctx, lock_time), ExecuteMsg::Send {} => execute_send(ctx), _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } fn execute_send(ctx: ExecuteContext) -> Result { @@ -162,18 +170,22 @@ fn execute_send(ctx: ExecuteContext) -> Result { let recipient_percent = recipient_addr.percent; let mut vec_coin: Vec = Vec::new(); for (i, coin) in info.funds.clone().iter().enumerate() { - let mut recip_coin: Coin = coin.clone(); - recip_coin.amount = coin.amount * recipient_percent; - remainder_funds[i].amount -= recip_coin.amount; - vec_coin.push(recip_coin.clone()); - amp_funds.push(recip_coin); + let amount_owed = coin.amount.mul_floor(recipient_percent); + if !amount_owed.is_zero() { + let mut recip_coin: Coin = coin.clone(); + recip_coin.amount = amount_owed; + remainder_funds[i].amount = + remainder_funds[i].amount.checked_sub(recip_coin.amount)?; + vec_coin.push(recip_coin.clone()); + amp_funds.push(recip_coin); + } + } + if !vec_coin.is_empty() { + let amp_msg = recipient_addr + .recipient + .generate_amp_msg(&deps.as_ref(), Some(vec_coin))?; + pkt = pkt.add_message(amp_msg); } - - // let direct_message = recipient_addr - // .recipient - // .generate_direct_msg(&deps.as_ref(), vec_coin)?; - let amp_msg = recipient_addr.recipient.generate_amp_msg(Some(vec_coin)); - pkt = pkt.add_message(amp_msg); } remainder_funds.retain(|x| x.amount > Uint128::zero()); @@ -189,8 +201,11 @@ fn execute_send(ctx: ExecuteContext) -> Result { }))); } let kernel_address = ADOContract::default().get_kernel_address(deps.as_ref().storage)?; - let distro_msg = pkt.to_sub_msg(kernel_address, Some(amp_funds), 1)?; - msgs.push(distro_msg); + + if !pkt.messages.is_empty() { + let distro_msg = pkt.to_sub_msg(kernel_address, Some(amp_funds), 1)?; + msgs.push(distro_msg); + } Ok(Response::new() .add_submessages(msgs) @@ -213,7 +228,7 @@ fn execute_update_recipients( ContractError::Unauthorized {} ); - validate_recipient_list(recipients.clone())?; + validate_recipient_list(deps.as_ref(), recipients.clone())?; let mut splitter = SPLITTER.load(deps.storage)?; // Can't call this function while the lock isn't expired @@ -234,7 +249,10 @@ fn execute_update_recipients( Ok(Response::default().add_attributes(vec![attr("action", "update_recipients")])) } -fn execute_update_lock(ctx: ExecuteContext, lock_time: u64) -> Result { +fn execute_update_lock( + ctx: ExecuteContext, + lock_time: MillisecondsDuration, +) -> Result { let ExecuteContext { deps, info, env, .. } = ctx; @@ -249,65 +267,42 @@ fn execute_update_lock(ctx: ExecuteContext, lock_time: u64) -> Result= ONE_DAY, ContractError::LockTimeTooShort {}); + ensure!( + lock_time.seconds() >= ONE_DAY, + ContractError::LockTimeTooShort {} + ); // New lock time can't be unreasonably long - ensure!(lock_time <= ONE_YEAR, ContractError::LockTimeTooLong {}); + ensure!( + lock_time.seconds() <= ONE_YEAR, + ContractError::LockTimeTooLong {} + ); // Set new lock time - let new_lock = Expiration::AtTime(Timestamp::from_seconds(lock_time + current_time)); + let new_expiration = current_time.plus_milliseconds(lock_time); - splitter.lock = new_lock; + splitter.lock = new_expiration; SPLITTER.save(deps.storage, &splitter)?; Ok(Response::default().add_attributes(vec![ attr("action", "update_lock"), - attr("locked", new_lock.to_string()), + attr("locked", new_expiration.to_string()), ])) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/andromeda-core/contracts/finance/andromeda-splitter/src/mock.rs b/andromeda-core/contracts/finance/andromeda-splitter/src/mock.rs index daa6b7c..22ef84e 100644 --- a/andromeda-core/contracts/finance/andromeda-splitter/src/mock.rs +++ b/andromeda-core/contracts/finance/andromeda-splitter/src/mock.rs @@ -2,21 +2,24 @@ use crate::contract::{execute, instantiate, query, reply}; use andromeda_finance::splitter::{AddressPercent, ExecuteMsg, InstantiateMsg, QueryMsg}; -use andromeda_testing::{mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; +use andromeda_std::common::expiration::Expiry; +use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract, +}; use cosmwasm_std::{Addr, Coin, Empty}; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; pub struct MockSplitter(Addr); mock_ado!(MockSplitter, ExecuteMsg, QueryMsg); impl MockSplitter { pub fn instantiate( - app: &mut App, + app: &mut MockApp, code_id: u64, sender: Addr, recipients: Vec, kernel_address: impl Into, - lock_time: Option, + lock_time: Option, owner: Option, ) -> Self { let msg = mock_splitter_instantiate_msg(recipients, kernel_address, lock_time, owner); @@ -25,7 +28,7 @@ impl MockSplitter { Self(res.unwrap()) } - pub fn execute_send(&self, app: &mut App, sender: Addr, funds: &[Coin]) -> ExecuteResult { + pub fn execute_send(&self, app: &mut MockApp, sender: Addr, funds: &[Coin]) -> ExecuteResult { let msg = mock_splitter_send_msg(); self.execute(app, &msg, sender, funds) @@ -40,7 +43,7 @@ pub fn mock_andromeda_splitter() -> Box> { pub fn mock_splitter_instantiate_msg( recipients: Vec, kernel_address: impl Into, - lock_time: Option, + lock_time: Option, owner: Option, ) -> InstantiateMsg { InstantiateMsg { diff --git a/andromeda-core/contracts/finance/andromeda-splitter/src/state.rs b/andromeda-core/contracts/finance/andromeda-splitter/src/state.rs index 42b99ca..02f1a9a 100644 --- a/andromeda-core/contracts/finance/andromeda-splitter/src/state.rs +++ b/andromeda-core/contracts/finance/andromeda-splitter/src/state.rs @@ -1,6 +1,4 @@ use andromeda_finance::splitter::Splitter; -use cosmwasm_std::Addr; use cw_storage_plus::Item; pub const SPLITTER: Item = Item::new("splitter"); -pub const KERNEL_ADDRESS: Item = Item::new("kernel_address"); diff --git a/andromeda-core/contracts/finance/andromeda-splitter/src/testing/mock_querier.rs b/andromeda-core/contracts/finance/andromeda-splitter/src/testing/mock_querier.rs index b426f92..d7d944b 100644 --- a/andromeda-core/contracts/finance/andromeda-splitter/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/finance/andromeda-splitter/src/testing/mock_querier.rs @@ -1,23 +1,15 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg, Uint128}; -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; - -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -39,11 +31,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "splitter".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -77,91 +70,17 @@ impl Querier for WasmMockQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) } _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/finance/andromeda-splitter/src/testing/tests.rs b/andromeda-core/contracts/finance/andromeda-splitter/src/testing/tests.rs index 3783adf..c58e9e3 100644 --- a/andromeda-core/contracts/finance/andromeda-splitter/src/testing/tests.rs +++ b/andromeda-core/contracts/finance/andromeda-splitter/src/testing/tests.rs @@ -3,15 +3,15 @@ use andromeda_std::{ messages::{AMPMsg, AMPPkt}, recipient::Recipient, }, + common::{expiration::Expiry, Milliseconds}, error::ContractError, }; - +use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{ attr, from_json, testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, to_json_binary, BankMsg, Coin, CosmosMsg, Decimal, DepsMut, Response, SubMsg, Timestamp, }; -use cw_utils::Expiration; pub const OWNER: &str = "creator"; use super::mock_querier::MOCK_KERNEL_CONTRACT; @@ -34,7 +34,7 @@ fn init(deps: DepsMut) -> Response { owner: Some(OWNER.to_owned()), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), recipients: mock_recipient, - lock_time: Some(100_000), + lock_time: Some(Expiry::FromNow(Milliseconds(86400000))), }; let info = mock_info("owner", &[]); @@ -48,6 +48,105 @@ fn test_instantiate() { assert_eq!(0, res.messages.len()); } +#[test] +fn test_different_lock_times() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + // Current time + env.block.time = Timestamp::from_seconds(1724920577); + // Set a lock time that's less than 1 day in milliseconds + let mut lock_time = Expiry::FromNow(Milliseconds(60_000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + recipients: vec![], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + + assert_eq!(err, ContractError::LockTimeTooShort {}); + + // Set a lock time that's more than 1 year in milliseconds + lock_time = Expiry::FromNow(Milliseconds(31_708_800_000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + recipients: vec![], + lock_time: Some(lock_time), + }; + + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + + assert_eq!(err, ContractError::LockTimeTooLong {}); + + // Set a lock time for 20 days in milliseconds + lock_time = Expiry::FromNow(Milliseconds(1728000000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + recipients: vec![AddressPercent { + recipient: Recipient::from_string(String::from("some_address")), + percent: Decimal::percent(100), + }], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let res = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + assert_eq!(0, res.messages.len()); + + // Here we begin testing Expiry::AtTime + // Set a lock time that's less than 1 day from current time + lock_time = Expiry::AtTime(Milliseconds(1724934977000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + recipients: vec![], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + assert_eq!(err, ContractError::LockTimeTooShort {}); + + // Set a lock time that's more than 1 year from current time in milliseconds + lock_time = Expiry::AtTime(Milliseconds(1788006977000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + recipients: vec![], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let err = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + assert_eq!(err, ContractError::LockTimeTooLong {}); + + // Set a valid lock time + lock_time = Expiry::AtTime(Milliseconds(1725021377000)); + + let msg = InstantiateMsg { + owner: Some(OWNER.to_owned()), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + recipients: vec![AddressPercent { + recipient: Recipient::from_string(String::from("some_address")), + percent: Decimal::percent(100), + }], + lock_time: Some(lock_time), + }; + + let info = mock_info(OWNER, &[]); + let res = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + assert_eq!(0, res.messages.len()); +} + #[test] fn test_execute_update_lock() { let mut deps = mock_dependencies_custom(&[]); @@ -56,26 +155,31 @@ fn test_execute_update_lock() { let env = mock_env(); let current_time = env.block.time.seconds(); - let lock_time = 100_000; + // 2 days in milliseconds + let lock_time = 172800000; // Start off with an expiration that's behind current time (expired) let splitter = Splitter { recipients: vec![], - lock: Expiration::AtTime(Timestamp::from_seconds(current_time - 1)), + lock: Milliseconds::from_seconds(current_time - 1), }; SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); - let msg = ExecuteMsg::UpdateLock { lock_time }; + let msg = ExecuteMsg::UpdateLock { + lock_time: Milliseconds::from_seconds(lock_time), + }; let info = mock_info(OWNER, &[]); let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - let new_lock = Expiration::AtTime(Timestamp::from_seconds(current_time + lock_time)); + let new_lock = Milliseconds::from_seconds(current_time + lock_time); assert_eq!( - Response::default().add_attributes(vec![ - attr("action", "update_lock"), - attr("locked", new_lock.to_string()) - ]), + Response::default() + .add_attributes(vec![ + attr("action", "update_lock"), + attr("locked", new_lock.to_string()) + ]) + .add_submessage(generate_economics_message(OWNER, "UpdateLock")), res ); @@ -91,7 +195,15 @@ fn test_execute_update_recipients() { let env = mock_env(); let _res = init(deps.as_mut()); - let recipient = vec![ + let splitter = Splitter { + recipients: vec![], + lock: Milliseconds::from_seconds(0), + }; + + SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + + // Duplicate recipients + let duplicate_recipients = vec![ AddressPercent { recipient: Recipient::from_string(String::from("addr1")), percent: Decimal::percent(40), @@ -102,15 +214,26 @@ fn test_execute_update_recipients() { }, ]; let msg = ExecuteMsg::UpdateRecipients { - recipients: recipient.clone(), + recipients: duplicate_recipients, }; - let splitter = Splitter { - recipients: vec![], - lock: Expiration::AtTime(Timestamp::from_seconds(0)), - }; + let info = mock_info(OWNER, &[]); + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(ContractError::DuplicateRecipient {}, res.unwrap_err()); - SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); + let recipients = vec![ + AddressPercent { + recipient: Recipient::from_string(String::from("addr1")), + percent: Decimal::percent(40), + }, + AddressPercent { + recipient: Recipient::from_string(String::from("addr2")), + percent: Decimal::percent(60), + }, + ]; + let msg = ExecuteMsg::UpdateRecipients { + recipients: recipients.clone(), + }; let info = mock_info("incorrect_owner", &[]); let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); @@ -119,13 +242,15 @@ fn test_execute_update_recipients() { let info = mock_info(OWNER, &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::default().add_attributes(vec![attr("action", "update_recipients")]), + Response::default() + .add_attributes(vec![attr("action", "update_recipients")]) + .add_submessage(generate_economics_message(OWNER, "UpdateRecipients")), res ); //check result let splitter = SPLITTER.load(deps.as_ref().storage).unwrap(); - assert_eq!(splitter.recipients, recipient); + assert_eq!(splitter.recipients, recipients); } #[test] @@ -159,8 +284,12 @@ fn test_execute_send() { ]; let msg = ExecuteMsg::Send {}; - let amp_msg_1 = recip1.generate_amp_msg(Some(vec![Coin::new(1000, "uluna")])); - let amp_msg_2 = recip2.generate_amp_msg(Some(vec![Coin::new(2000, "uluna")])); + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1000, "uluna")])) + .unwrap(); + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(2000, "uluna")])) + .unwrap(); let amp_pkt = AMPPkt::new( MOCK_CONTRACT_ADDR.to_string(), MOCK_CONTRACT_ADDR.to_string(), @@ -176,7 +305,7 @@ fn test_execute_send() { let splitter = Splitter { recipients: recipient, - lock: Expiration::AtTime(Timestamp::from_seconds(0)), + lock: Milliseconds::default(), }; SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); @@ -194,7 +323,8 @@ fn test_execute_send() { ), amp_msg, ]) - .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]); + .add_attributes(vec![attr("action", "send"), attr("sender", "creator")]) + .add_submessage(generate_economics_message(OWNER, "Send")); assert_eq!(res, expected_res); } @@ -229,8 +359,12 @@ fn test_execute_send_ado_recipient() { ]; let msg = ExecuteMsg::Send {}; - let amp_msg_1 = recip1.generate_amp_msg(Some(vec![Coin::new(1000, "uluna")])); - let amp_msg_2 = recip2.generate_amp_msg(Some(vec![Coin::new(2000, "uluna")])); + let amp_msg_1 = recip1 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(1000, "uluna")])) + .unwrap(); + let amp_msg_2 = recip2 + .generate_amp_msg(&deps.as_ref(), Some(vec![Coin::new(2000, "uluna")])) + .unwrap(); let amp_pkt = AMPPkt::new( MOCK_CONTRACT_ADDR.to_string(), MOCK_CONTRACT_ADDR.to_string(), @@ -246,7 +380,7 @@ fn test_execute_send_ado_recipient() { let splitter = Splitter { recipients: recipient, - lock: Expiration::AtTime(Timestamp::from_seconds(0)), + lock: Milliseconds::default(), }; SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); @@ -265,7 +399,8 @@ fn test_execute_send_ado_recipient() { amp_msg, ]) .add_attribute("action", "send") - .add_attribute("sender", "creator"); + .add_attribute("sender", "creator") + .add_submessage(generate_economics_message(OWNER, "Send")); assert_eq!(res, expected_res); } @@ -282,7 +417,6 @@ fn test_handle_packet_exit_with_error_true() { let recip_address1 = "address1".to_string(); let recip_percent1 = 10; // 10% - let recip_address2 = "address2".to_string(); let recip_percent2 = 20; // 20% let recipient = vec![ @@ -298,24 +432,17 @@ fn test_handle_packet_exit_with_error_true() { let pkt = AMPPkt::new( info.clone().sender, "cosmos2contract", - vec![ - AMPMsg::new( - recip_address1, - to_json_binary(&ExecuteMsg::Send {}).unwrap(), - Some(vec![Coin::new(0, "uluna")]), - ), - AMPMsg::new( - recip_address2, - to_json_binary(&ExecuteMsg::Send {}).unwrap(), - Some(vec![Coin::new(0, "uluna")]), - ), - ], + vec![AMPMsg::new( + recip_address1, + to_json_binary(&ExecuteMsg::Send {}).unwrap(), + Some(vec![Coin::new(0, "uluna")]), + )], ); let msg = ExecuteMsg::AMPReceive(pkt); let splitter = Splitter { recipients: recipient, - lock: Expiration::AtTime(Timestamp::from_seconds(0)), + lock: Milliseconds::default(), }; SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); @@ -336,7 +463,7 @@ fn test_query_splitter() { let env = mock_env(); let splitter = Splitter { recipients: vec![], - lock: Expiration::AtTime(Timestamp::from_seconds(0)), + lock: Milliseconds::default(), }; SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); @@ -389,7 +516,7 @@ fn test_execute_send_error() { let splitter = Splitter { recipients: recipient, - lock: Expiration::AtTime(Timestamp::from_seconds(0)), + lock: Milliseconds::default(), }; SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); @@ -417,7 +544,8 @@ fn test_update_app_contract() { assert_eq!( Response::new() .add_attribute("action", "update_app_contract") - .add_attribute("address", "app_contract"), + .add_attribute("address", "app_contract") + .add_submessage(generate_economics_message(OWNER, "UpdateAppContract")), res ); } diff --git a/andromeda-core/contracts/finance/andromeda-timelock/Cargo.toml b/andromeda-core/contracts/finance/andromeda-timelock/Cargo.toml index 3bb51be..93c5740 100644 --- a/andromeda-core/contracts/finance/andromeda-timelock/Cargo.toml +++ b/andromeda-core/contracts/finance/andromeda-timelock/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-timelock" -version = "0.2.1" +version = "2.0.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -20,8 +20,6 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } andromeda-std = { workspace = true } andromeda-finance = { workspace = true } @@ -29,5 +27,7 @@ andromeda-finance = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } + [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } +andromeda-testing = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-timelock/README.md b/andromeda-core/contracts/finance/andromeda-timelock/README.md new file mode 100644 index 0000000..ea301c7 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-timelock/README.md @@ -0,0 +1,10 @@ +# Overview + +The Timelock ADO or Escrow ADO is a smart contract built to hold funds (Native coins) for a period of time until the set condition is satisfied. +There are two main conditions that can be used by the contract: +- **Expiration:** A time expiration to when the funds can be released. +- **MinimumFunds:** A minimum amount of funds to be deposited before they can be released. + +Once a condition is satisfied, the funds can be released. + +[Timelock Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/timelock) diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/andromeda-timelock.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/andromeda-timelock.json deleted file mode 100644 index dfe86b6..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/andromeda-timelock.json +++ /dev/null @@ -1,1768 +0,0 @@ -{ - "contract_name": "andromeda-timelock", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Hold funds in Escrow", - "type": "object", - "required": [ - "hold_funds" - ], - "properties": { - "hold_funds": { - "type": "object", - "properties": { - "condition": { - "anyOf": [ - { - "$ref": "#/definitions/EscrowCondition" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/Recipient" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Release funds all held in Escrow for the given recipient", - "type": "object", - "required": [ - "release_funds" - ], - "properties": { - "release_funds": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "recipient_addr": { - "type": [ - "string", - "null" - ] - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "release_specific_funds" - ], - "properties": { - "release_specific_funds": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - }, - "recipient_addr": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "EscrowCondition": { - "description": "Enum used to specify the condition which must be met in order for the Escrow to unlock.", - "oneOf": [ - { - "description": "Requires a given time or block height to be reached.", - "type": "object", - "required": [ - "expiration" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - { - "description": "Requires a minimum amount of funds to be deposited.", - "type": "object", - "required": [ - "minimum_funds" - ], - "properties": { - "minimum_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Queries funds held by an address", - "type": "object", - "required": [ - "get_locked_funds" - ], - "properties": { - "get_locked_funds": { - "type": "object", - "required": [ - "owner", - "recipient" - ], - "properties": { - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the funds for the given recipient.", - "type": "object", - "required": [ - "get_locked_funds_for_recipient" - ], - "properties": { - "get_locked_funds_for_recipient": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "recipient": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "get_locked_funds": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetLockedFundsResponse", - "type": "object", - "properties": { - "funds": { - "anyOf": [ - { - "$ref": "#/definitions/Escrow" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Escrow": { - "description": "Struct used to define funds being held in Escrow", - "type": "object", - "required": [ - "coins", - "recipient", - "recipient_addr" - ], - "properties": { - "coins": { - "description": "Funds being held within the Escrow", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "condition": { - "description": "Optional condition for the Escrow", - "anyOf": [ - { - "$ref": "#/definitions/EscrowCondition" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "description": "The recipient of the funds once Condition is satisfied", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "recipient_addr": { - "description": "Used for indexing.", - "type": "string" - } - }, - "additionalProperties": false - }, - "EscrowCondition": { - "description": "Enum used to specify the condition which must be met in order for the Escrow to unlock.", - "oneOf": [ - { - "description": "Requires a given time or block height to be reached.", - "type": "object", - "required": [ - "expiration" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - { - "description": "Requires a minimum amount of funds to be deposited.", - "type": "object", - "required": [ - "minimum_funds" - ], - "properties": { - "minimum_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "get_locked_funds_for_recipient": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetLockedFundsForRecipientResponse", - "type": "object", - "required": [ - "funds" - ], - "properties": { - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Escrow" - } - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Escrow": { - "description": "Struct used to define funds being held in Escrow", - "type": "object", - "required": [ - "coins", - "recipient", - "recipient_addr" - ], - "properties": { - "coins": { - "description": "Funds being held within the Escrow", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "condition": { - "description": "Optional condition for the Escrow", - "anyOf": [ - { - "$ref": "#/definitions/EscrowCondition" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "description": "The recipient of the funds once Condition is satisfied", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "recipient_addr": { - "description": "Used for indexing.", - "type": "string" - } - }, - "additionalProperties": false - }, - "EscrowCondition": { - "description": "Enum used to specify the condition which must be met in order for the Escrow to unlock.", - "oneOf": [ - { - "description": "Requires a given time or block height to be reached.", - "type": "object", - "required": [ - "expiration" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - { - "description": "Requires a minimum amount of funds to be deposited.", - "type": "object", - "required": [ - "minimum_funds" - ], - "properties": { - "minimum_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/execute.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/execute.json deleted file mode 100644 index 4c87de1..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/execute.json +++ /dev/null @@ -1,682 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Hold funds in Escrow", - "type": "object", - "required": [ - "hold_funds" - ], - "properties": { - "hold_funds": { - "type": "object", - "properties": { - "condition": { - "anyOf": [ - { - "$ref": "#/definitions/EscrowCondition" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "anyOf": [ - { - "$ref": "#/definitions/Recipient" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Release funds all held in Escrow for the given recipient", - "type": "object", - "required": [ - "release_funds" - ], - "properties": { - "release_funds": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "recipient_addr": { - "type": [ - "string", - "null" - ] - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "release_specific_funds" - ], - "properties": { - "release_specific_funds": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - }, - "recipient_addr": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "EscrowCondition": { - "description": "Enum used to specify the condition which must be met in order for the Escrow to unlock.", - "oneOf": [ - { - "description": "Requires a given time or block height to be reached.", - "type": "object", - "required": [ - "expiration" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - { - "description": "Requires a minimum amount of funds to be deposited.", - "type": "object", - "required": [ - "minimum_funds" - ], - "properties": { - "minimum_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/instantiate.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/instantiate.json deleted file mode 100644 index 2173324..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/instantiate.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/query.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/query.json deleted file mode 100644 index 8955465..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/query.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Queries funds held by an address", - "type": "object", - "required": [ - "get_locked_funds" - ], - "properties": { - "get_locked_funds": { - "type": "object", - "required": [ - "owner", - "recipient" - ], - "properties": { - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the funds for the given recipient.", - "type": "object", - "required": [ - "get_locked_funds_for_recipient" - ], - "properties": { - "get_locked_funds_for_recipient": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "recipient": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_balance.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds.json deleted file mode 100644 index 7212b20..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds.json +++ /dev/null @@ -1,215 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetLockedFundsResponse", - "type": "object", - "properties": { - "funds": { - "anyOf": [ - { - "$ref": "#/definitions/Escrow" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Escrow": { - "description": "Struct used to define funds being held in Escrow", - "type": "object", - "required": [ - "coins", - "recipient", - "recipient_addr" - ], - "properties": { - "coins": { - "description": "Funds being held within the Escrow", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "condition": { - "description": "Optional condition for the Escrow", - "anyOf": [ - { - "$ref": "#/definitions/EscrowCondition" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "description": "The recipient of the funds once Condition is satisfied", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "recipient_addr": { - "description": "Used for indexing.", - "type": "string" - } - }, - "additionalProperties": false - }, - "EscrowCondition": { - "description": "Enum used to specify the condition which must be met in order for the Escrow to unlock.", - "oneOf": [ - { - "description": "Requires a given time or block height to be reached.", - "type": "object", - "required": [ - "expiration" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - { - "description": "Requires a minimum amount of funds to be deposited.", - "type": "object", - "required": [ - "minimum_funds" - ], - "properties": { - "minimum_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds_for_recipient.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds_for_recipient.json deleted file mode 100644 index 9a7c928..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_get_locked_funds_for_recipient.json +++ /dev/null @@ -1,214 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetLockedFundsForRecipientResponse", - "type": "object", - "required": [ - "funds" - ], - "properties": { - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Escrow" - } - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Escrow": { - "description": "Struct used to define funds being held in Escrow", - "type": "object", - "required": [ - "coins", - "recipient", - "recipient_addr" - ], - "properties": { - "coins": { - "description": "Funds being held within the Escrow", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "condition": { - "description": "Optional condition for the Escrow", - "anyOf": [ - { - "$ref": "#/definitions/EscrowCondition" - }, - { - "type": "null" - } - ] - }, - "recipient": { - "description": "The recipient of the funds once Condition is satisfied", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "recipient_addr": { - "description": "Used for indexing.", - "type": "string" - } - }, - "additionalProperties": false - }, - "EscrowCondition": { - "description": "Enum used to specify the condition which must be met in order for the Escrow to unlock.", - "oneOf": [ - { - "description": "Requires a given time or block height to be reached.", - "type": "object", - "required": [ - "expiration" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - } - }, - "additionalProperties": false - }, - { - "description": "Requires a minimum amount of funds to be deposited.", - "type": "object", - "required": [ - "minimum_funds" - ], - "properties": { - "minimum_funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_operators.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_owner.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissions.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_type.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_version.json b/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/finance/andromeda-timelock/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-timelock/src/contract.rs b/andromeda-core/contracts/finance/andromeda-timelock/src/contract.rs index 3cb087d..0f4e0e0 100644 --- a/andromeda-core/contracts/finance/andromeda-timelock/src/contract.rs +++ b/andromeda-core/contracts/finance/andromeda-timelock/src/contract.rs @@ -1,21 +1,17 @@ use andromeda_finance::timelock::{ Escrow, EscrowCondition, ExecuteMsg, GetLockedFundsForRecipientResponse, - GetLockedFundsResponse, InstantiateMsg, MigrateMsg, QueryMsg, + GetLockedFundsResponse, InstantiateMsg, QueryMsg, }; - use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, amp::Recipient, - common::encode_binary, - error::{from_semver, ContractError}, + common::{actions::call_action, encode_binary}, + error::ContractError, }; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; use cosmwasm_std::{ attr, ensure, entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response, SubMsg, }; -use cw2::{get_contract_version, set_contract_version}; - -use semver::Version; use crate::state::{escrows, get_key, get_keys_for_recipient}; @@ -30,18 +26,16 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let contract = ADOContract::default(); let resp = contract.instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "timelock".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -67,8 +61,15 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - match msg { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { ExecuteMsg::HoldFunds { condition, recipient, @@ -84,7 +85,11 @@ pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_release_specific_funds(ctx, owner, recipient_addr), _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } fn execute_hold_funds( @@ -197,36 +202,7 @@ fn execute_release_specific_funds( #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/andromeda-core/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs b/andromeda-core/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs index b426f92..970f59b 100644 --- a/andromeda-core/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/finance/andromeda-timelock/src/testing/mock_querier.rs @@ -1,23 +1,14 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg, Uint128}; - -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; - -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -39,11 +30,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "splitter".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -77,91 +69,17 @@ impl Querier for WasmMockQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) } _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/finance/andromeda-timelock/src/testing/tests.rs b/andromeda-core/contracts/finance/andromeda-timelock/src/testing/tests.rs index 2002029..bf6ad24 100644 --- a/andromeda-core/contracts/finance/andromeda-timelock/src/testing/tests.rs +++ b/andromeda-core/contracts/finance/andromeda-timelock/src/testing/tests.rs @@ -1,11 +1,3 @@ -use andromeda_std::{amp::Recipient, error::ContractError}; -use cosmwasm_std::{ - attr, coin, coins, from_json, - testing::{mock_env, mock_info}, - BankMsg, Coin, Response, Timestamp, -}; -use cw_utils::Expiration; - use crate::{ contract::{execute, query}, testing::mock_querier::mock_dependencies_custom, @@ -13,32 +5,46 @@ use crate::{ use andromeda_finance::timelock::{ Escrow, EscrowCondition, ExecuteMsg, GetLockedFundsResponse, QueryMsg, }; +use andromeda_std::{ + amp::Recipient, + common::{expiration::Expiry, Milliseconds}, + error::ContractError, +}; +use andromeda_testing::economics_msg::generate_economics_message; +use cosmwasm_std::{ + attr, coin, coins, from_json, + testing::{mock_env, mock_info}, + BankMsg, Coin, Response, Timestamp, +}; #[test] fn test_execute_hold_funds() { let mut deps = mock_dependencies_custom(&[]); - let mut env = mock_env(); + let env = mock_env(); let owner = "owner"; let funds = vec![Coin::new(1000, "uusd")]; - let condition = EscrowCondition::Expiration(Expiration::AtHeight(1)); + let condition = EscrowCondition::Expiration(Expiry::AtTime(Milliseconds::from_seconds( + env.block.time.seconds() + 1, + ))); let info = mock_info(owner, &funds); let msg = ExecuteMsg::HoldFunds { condition: Some(condition.clone()), recipient: None, }; - env.block.height = 0; let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - let expected = Response::default().add_attributes(vec![ - attr("action", "hold_funds"), - attr("sender", info.sender.to_string()), - attr( - "recipient", - format!("{:?}", Recipient::from_string(info.sender.to_string())), - ), - attr("condition", format!("{:?}", Some(condition.clone()))), - ]); + let expected = Response::default() + .add_attributes(vec![ + attr("action", "hold_funds"), + attr("sender", info.sender.to_string()), + attr( + "recipient", + format!("{:?}", Recipient::from_string(info.sender.to_string())), + ), + attr("condition", format!("{:?}", Some(condition.clone()))), + ]) + .add_submessage(generate_economics_message("owner", "HoldFunds")); assert_eq!(expected, res); let query_msg = QueryMsg::GetLockedFunds { @@ -67,20 +73,24 @@ fn test_execute_hold_funds_escrow_updated() { let info = mock_info(owner, &coins(100, "uusd")); let msg = ExecuteMsg::HoldFunds { - condition: Some(EscrowCondition::Expiration(Expiration::AtHeight(10))), + condition: Some(EscrowCondition::Expiration(Expiry::AtTime( + Milliseconds::from_seconds(env.block.time.seconds() + 1), + ))), recipient: Some(Recipient::from_string("recipient".to_string())), }; - env.block.height = 0; - let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let msg = ExecuteMsg::HoldFunds { - condition: Some(EscrowCondition::Expiration(Expiration::AtHeight(100))), + condition: Some(EscrowCondition::Expiration(Expiry::AtTime( + Milliseconds::from_seconds(env.block.time.seconds() + 1), + ))), recipient: Some(Recipient::from_string("recipient".to_string())), }; - env.block.height = 120; + env.block.time = Milliseconds::from_seconds(env.block.time.seconds()) + .plus_seconds(1) + .into(); let info = mock_info(owner, &[coin(100, "uusd"), coin(100, "uluna")]); let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); @@ -90,13 +100,15 @@ fn test_execute_hold_funds_escrow_updated() { recipient: "recipient".to_string(), }; - let res = query(deps.as_ref(), env, query_msg).unwrap(); + let res = query(deps.as_ref(), env.clone(), query_msg).unwrap(); let val: GetLockedFundsResponse = from_json(res).unwrap(); let expected = Escrow { // Coins get merged. coins: vec![coin(200, "uusd"), coin(100, "uluna")], // Original expiration remains. - condition: Some(EscrowCondition::Expiration(Expiration::AtHeight(10))), + condition: Some(EscrowCondition::Expiration(Expiry::AtTime( + Milliseconds::from_seconds(env.block.time.seconds()), + ))), recipient: Recipient::from_string("recipient".to_string()), recipient_addr: "recipient".to_string(), }; @@ -104,40 +116,6 @@ fn test_execute_hold_funds_escrow_updated() { assert_eq!(val.funds.unwrap(), expected); } -#[test] -fn test_execute_release_funds_block_condition() { - let mut deps = mock_dependencies_custom(&[]); - let mut env = mock_env(); - let owner = "owner"; - - let info = mock_info(owner, &[coin(100, "uusd")]); - let msg = ExecuteMsg::HoldFunds { - condition: Some(EscrowCondition::Expiration(Expiration::AtHeight(1))), - recipient: None, - }; - env.block.height = 0; - let _res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - - env.block.height = 2; - let msg = ExecuteMsg::ReleaseFunds { - recipient_addr: None, - start_after: None, - limit: None, - }; - let res = execute(deps.as_mut(), env, info.clone(), msg).unwrap(); - let bank_msg = BankMsg::Send { - to_address: "owner".into(), - amount: info.funds, - }; - assert_eq!( - Response::new().add_message(bank_msg).add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]), - res - ); -} - #[test] fn test_execute_release_funds_no_condition() { let mut deps = mock_dependencies_custom(&[]); @@ -162,10 +140,13 @@ fn test_execute_release_funds_no_condition() { amount: info.funds, }; assert_eq!( - Response::new().add_message(bank_msg).add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]), + Response::new() + .add_message(bank_msg) + .add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]) + .add_submessage(generate_economics_message(owner, "ReleaseFunds")), res ); } @@ -208,7 +189,8 @@ fn test_execute_release_multiple_escrows() { .add_attributes(vec![ attr("action", "release_funds"), attr("recipient_addr", "recipient"), - ]), + ]) + .add_submessage(generate_economics_message("sender2", "ReleaseFunds")), res ); } @@ -221,8 +203,8 @@ fn test_execute_release_funds_time_condition() { let info = mock_info(owner, &[coin(100, "uusd")]); let msg = ExecuteMsg::HoldFunds { - condition: Some(EscrowCondition::Expiration(Expiration::AtTime( - Timestamp::from_seconds(100), + condition: Some(EscrowCondition::Expiration(Expiry::AtTime( + Milliseconds::from_seconds(100), ))), recipient: None, }; @@ -242,10 +224,13 @@ fn test_execute_release_funds_time_condition() { amount: info.funds, }; assert_eq!( - Response::new().add_message(bank_msg).add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]), + Response::new() + .add_message(bank_msg) + .add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]) + .add_submessage(generate_economics_message(owner, "ReleaseFunds")), res ); } @@ -258,8 +243,8 @@ fn test_execute_release_funds_locked() { let info = mock_info(owner, &[coin(100, "uusd")]); let msg = ExecuteMsg::HoldFunds { - condition: Some(EscrowCondition::Expiration(Expiration::AtTime( - Timestamp::from_seconds(100), + condition: Some(EscrowCondition::Expiration(Expiry::FromNow( + Milliseconds::from_seconds(100), ))), recipient: None, }; @@ -323,10 +308,13 @@ fn test_execute_release_funds_min_funds_condition() { amount: vec![coin(210, "uusd"), coin(120, "uluna")], }; assert_eq!( - Response::new().add_message(bank_msg).add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]), + Response::new() + .add_message(bank_msg) + .add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]) + .add_submessage(generate_economics_message(owner, "ReleaseFunds")), res ); } @@ -369,10 +357,13 @@ fn test_execute_release_specific_funds_no_condition() { amount: info.funds, }; assert_eq!( - Response::new().add_message(bank_msg).add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]), + Response::new() + .add_message(bank_msg) + .add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]) + .add_submessage(generate_economics_message(owner, "ReleaseSpecificFunds")), res ); } @@ -385,8 +376,8 @@ fn test_execute_release_specific_funds_time_condition() { let info = mock_info(owner, &[coin(100, "uusd")]); let msg = ExecuteMsg::HoldFunds { - condition: Some(EscrowCondition::Expiration(Expiration::AtTime( - Timestamp::from_seconds(100), + condition: Some(EscrowCondition::Expiration(Expiry::AtTime( + Milliseconds::from_seconds(100), ))), recipient: None, }; @@ -405,10 +396,13 @@ fn test_execute_release_specific_funds_time_condition() { amount: info.funds, }; assert_eq!( - Response::new().add_message(bank_msg).add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]), + Response::new() + .add_message(bank_msg) + .add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]) + .add_submessage(generate_economics_message(owner, "ReleaseSpecificFunds")), res ); } @@ -458,10 +452,13 @@ fn test_execute_release_specific_funds_min_funds_condition() { amount: vec![coin(210, "uusd"), coin(120, "uluna")], }; assert_eq!( - Response::new().add_message(bank_msg).add_attributes(vec![ - attr("action", "release_funds"), - attr("recipient_addr", "owner"), - ]), + Response::new() + .add_message(bank_msg) + .add_attributes(vec![ + attr("action", "release_funds"), + attr("recipient_addr", "owner"), + ]) + .add_submessage(generate_economics_message(owner, "ReleaseSpecificFunds")), res ); } diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/Cargo.toml b/andromeda-core/contracts/finance/andromeda-validator-staking/Cargo.toml index 090dfd1..c1deb67 100644 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/Cargo.toml +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-validator-staking" -version = "0.1.0" +version = "0.2.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -15,7 +15,7 @@ library = [] testing = ["cw-multi-test"] [dependencies] -cosmwasm-std = { workspace = true, features = ["staking"] } +cosmwasm-std = { workspace = true, features = ["staking"] } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw2 = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/examples/schema.rs b/andromeda-core/contracts/finance/andromeda-validator-staking/examples/schema.rs index b1e6e0f..b3c84bd 100644 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/examples/schema.rs +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/examples/schema.rs @@ -1,8 +1,10 @@ -use andromeda_finance::validator_staking::InstantiateMsg; +use andromeda_finance::validator_staking::{ExecuteMsg, InstantiateMsg, QueryMsg}; use cosmwasm_schema::write_api; fn main() { write_api! { instantiate: InstantiateMsg, + execute:ExecuteMsg, + query:QueryMsg } } diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/schema/andromeda-validator-staking.json b/andromeda-core/contracts/finance/andromeda-validator-staking/schema/andromeda-validator-staking.json deleted file mode 100644 index 7498866..0000000 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/schema/andromeda-validator-staking.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "contract_name": "andromeda-validator-staking", - "contract_version": "0.1.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "default_validator", - "kernel_address" - ], - "properties": { - "default_validator": { - "$ref": "#/definitions/Addr" - }, - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "execute": null, - "query": null, - "migrate": null, - "sudo": null, - "responses": null -} diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/schema/raw/instantiate.json b/andromeda-core/contracts/finance/andromeda-validator-staking/schema/raw/instantiate.json deleted file mode 100644 index d4e67a0..0000000 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/schema/raw/instantiate.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "default_validator", - "kernel_address" - ], - "properties": { - "default_validator": { - "$ref": "#/definitions/Addr" - }, - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/src/contract.rs b/andromeda-core/contracts/finance/andromeda-validator-staking/src/contract.rs index a6fcaa0..fe36012 100644 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/src/contract.rs +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/src/contract.rs @@ -1,9 +1,10 @@ -use std::str::FromStr; - -use crate::state::{DEFAULT_VALIDATOR, UNSTAKING_QUEUE}; +use crate::{ + state::{DEFAULT_VALIDATOR, UNSTAKING_QUEUE}, + util::decode_unstaking_response_data, +}; use cosmwasm_std::{ - ensure, entry_point, Addr, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, DistributionMsg, - Env, FullDelegation, MessageInfo, Reply, Response, StakingMsg, StdError, SubMsg, Timestamp, + coin, ensure, entry_point, Addr, BankMsg, Binary, CosmosMsg, Deps, DepsMut, DistributionMsg, + Env, FullDelegation, MessageInfo, Reply, Response, StakingMsg, SubMsg, Timestamp, Uint128, }; use cw2::set_contract_version; @@ -12,7 +13,7 @@ use andromeda_finance::validator_staking::{ }; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::AndrAddr, common::{context::ExecuteContext, encode_binary}, @@ -28,6 +29,7 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[EnumRepr(type = "u64")] pub enum ReplyId { ValidatorUnstake = 201, + SetWithdrawAddress = 202, } #[cfg_attr(not(feature = "library"), entry_point)] @@ -46,11 +48,11 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "validator-staking".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -78,17 +80,24 @@ pub fn execute( pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { ExecuteMsg::Stake { validator } => execute_stake(ctx, validator), - ExecuteMsg::Unstake { validator } => execute_unstake(ctx, validator), - ExecuteMsg::Claim { - validator, - recipient, - } => execute_claim(ctx, validator, recipient), - ExecuteMsg::WithdrawFunds {} => execute_withdraw_fund(ctx), + ExecuteMsg::Unstake { validator, amount } => execute_unstake(ctx, validator, amount), + ExecuteMsg::Claim { validator } => execute_claim(ctx, validator), + ExecuteMsg::WithdrawFunds { denom, recipient } => { + execute_withdraw_fund(ctx, denom, recipient) + } + ExecuteMsg::UpdateDefaultValidator { validator } => { + execute_update_default_validator(ctx, validator) + } _ => ADOContract::default().execute(ctx, msg), } } +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { @@ -138,6 +147,7 @@ fn execute_stake(ctx: ExecuteContext, validator: Option) -> Result, + amount: Option, ) -> Result { let ExecuteContext { deps, info, env, .. @@ -156,69 +166,78 @@ fn execute_unstake( // Check if the validator is valid before unstaking is_validator(&deps, &validator)?; - let Some(res) = deps.querier.query_delegation(delegator.to_string(), validator.to_string())? else { - return Err(ContractError::InvalidValidatorOperation { operation: "Unstake".to_string(), validator: validator.to_string() }); + let Some(res) = deps + .querier + .query_delegation(delegator.to_string(), validator.to_string())? + else { + return Err(ContractError::InvalidValidatorOperation { + operation: "Unstake".to_string(), + validator: validator.to_string(), + }); }; + let unstake_amount = amount.unwrap_or(res.amount.amount); + ensure!( - !res.amount.amount.is_zero(), + !unstake_amount.is_zero() && unstake_amount <= res.amount.amount, ContractError::InvalidValidatorOperation { operation: "Unstake".to_string(), validator: validator.to_string(), } ); + let fund = coin(unstake_amount.u128(), res.amount.denom); let undelegate_msg = CosmosMsg::Staking(StakingMsg::Undelegate { validator: validator.to_string(), - amount: res.amount, + amount: fund.clone(), + }); + + let mut unstaking_queue = UNSTAKING_QUEUE.load(deps.storage).unwrap_or_default(); + unstaking_queue.push(UnstakingTokens { + fund, + payout_at: Timestamp::default(), }); + + UNSTAKING_QUEUE.save(deps.storage, &unstaking_queue)?; + let undelegate_msg = SubMsg::reply_on_success(undelegate_msg, ReplyId::ValidatorUnstake.repr()); let res = Response::new() .add_submessage(undelegate_msg) .add_attribute("action", "validator-unstake") + .add_attribute("amount", unstake_amount) .add_attribute("from", info.sender) .add_attribute("to", validator.to_string()); Ok(res) } -fn execute_claim( - ctx: ExecuteContext, - validator: Option, - recipient: Option, -) -> Result { +fn execute_claim(ctx: ExecuteContext, validator: Option) -> Result { let ExecuteContext { deps, info, env, .. } = ctx; - // Ensure sender is the contract owner - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let default_validator = DEFAULT_VALIDATOR.load(deps.storage)?; let validator = validator.unwrap_or(default_validator); // Check if the validator is valid before unstaking is_validator(&deps, &validator)?; - let recipient = if let Some(recipient) = recipient { - recipient.get_raw_address(&deps.as_ref())? - } else { - info.sender - }; - - // Ensure recipient is the contract owner + // Ensure msg sender is the contract owner ensure!( - ADOContract::default().is_contract_owner(deps.storage, recipient.as_str())?, + ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); let delegator = env.contract.address; - let Some(res) = deps.querier.query_delegation(delegator.to_string(), validator.to_string())? else { - return Err(ContractError::InvalidValidatorOperation { operation: "Claim".to_string(), validator: validator.to_string() }); + let Some(res) = deps + .querier + .query_delegation(delegator.to_string(), validator.to_string())? + else { + return Err(ContractError::InvalidValidatorOperation { + operation: "Claim".to_string(), + validator: validator.to_string(), + }); }; // No reward to claim exist @@ -228,20 +247,20 @@ fn execute_claim( ); let res = Response::new() - .add_message(DistributionMsg::SetWithdrawAddress { - address: recipient.to_string(), - }) .add_message(DistributionMsg::WithdrawDelegatorReward { validator: validator.to_string(), }) .add_attribute("action", "validator-claim-reward") - .add_attribute("recipient", recipient) .add_attribute("validator", validator.to_string()); Ok(res) } -fn execute_withdraw_fund(ctx: ExecuteContext) -> Result { +fn execute_withdraw_fund( + ctx: ExecuteContext, + denom: Option, + recipient: Option, +) -> Result { let ExecuteContext { deps, info, env, .. } = ctx; @@ -252,35 +271,61 @@ fn execute_withdraw_fund(ctx: ExecuteContext) -> Result ContractError::Unauthorized {} ); - let mut funds = Vec::::new(); - loop { - match UNSTAKING_QUEUE.front(deps.storage).unwrap() { - Some(UnstakingTokens { payout_at, .. }) if payout_at <= env.block.time => { - if let Some(UnstakingTokens { fund, .. }) = - UNSTAKING_QUEUE.pop_front(deps.storage)? - { - funds.push(fund) - } - } - _ => break, - } - } + let recipient = recipient.map_or(Ok(info.sender), |r| r.get_raw_address(&deps.as_ref()))?; + let funds = denom.map_or( + deps.querier + .query_all_balances(env.contract.address.clone())?, + |d| { + deps.querier + .query_balance(env.contract.address.clone(), d) + .map(|fund| vec![fund]) + .expect("Invalid denom") + }, + ); + + // Remove expired unstaking requests + let mut unstaking_queue = UNSTAKING_QUEUE.load(deps.storage)?; + unstaking_queue.retain(|token| token.payout_at > env.block.time); + UNSTAKING_QUEUE.save(deps.storage, &unstaking_queue)?; ensure!( !funds.is_empty(), ContractError::InvalidWithdrawal { - msg: Some("No unstaked funds to withdraw".to_string()) + msg: Some("No funds to withdraw".to_string()) } ); let res = Response::new() .add_message(BankMsg::Send { - to_address: info.sender.to_string(), + to_address: recipient.to_string(), amount: funds, }) .add_attribute("action", "withdraw-funds") .add_attribute("from", env.contract.address) - .add_attribute("to", info.sender.into_string()); + .add_attribute("to", recipient.into_string()); + + Ok(res) +} + +fn execute_update_default_validator( + ctx: ExecuteContext, + validator: Addr, +) -> Result { + let ExecuteContext { deps, info, .. } = ctx; + + ensure!( + ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + // Check if the validator is valid before setting to default validator + is_validator(&deps, &validator)?; + + DEFAULT_VALIDATOR.save(deps.storage, &validator)?; + + let res = Response::new() + .add_attribute("action", "update-default-validator") + .add_attribute("default_validator", validator.into_string()); Ok(res) } @@ -295,29 +340,22 @@ fn query_staked_tokens( // Use default validator if validator is not specified let validator = validator.unwrap_or(default_validator); - let Some(res) = deps.querier.query_delegation(delegator.to_string(), validator.to_string())? else { + let Some(res) = deps + .querier + .query_delegation(delegator.to_string(), validator.to_string())? + else { return Err(ContractError::InvalidDelegation {}); }; Ok(res) } fn query_unstaked_tokens(deps: Deps) -> Result, ContractError> { - let iter = UNSTAKING_QUEUE.iter(deps.storage).unwrap(); - let mut res = Vec::::new(); - - for data in iter { - res.push(data.unwrap()); - } + let res = UNSTAKING_QUEUE.load(deps.storage)?; Ok(res) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - if msg.result.is_err() { - return Err(ContractError::Std(StdError::generic_err( - msg.result.unwrap_err(), - ))); - } match ReplyId::from_repr(msg.id) { Some(ReplyId::ValidatorUnstake) => on_validator_unstake(deps, msg), _ => Ok(Response::default()), @@ -325,21 +363,32 @@ pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result Result { - let attributes = &msg.result.unwrap().events[0].attributes; - let mut fund = Coin::default(); - let mut payout_at = Timestamp::default(); - for attr in attributes { - if attr.key == "amount" { - fund = Coin::from_str(&attr.value).unwrap(); - } else if attr.key == "completion_time" { - let completion_time = DateTime::parse_from_rfc3339(&attr.value).unwrap(); - let seconds = completion_time.timestamp() as u64; - let nanos = completion_time.timestamp_subsec_nanos() as u64; - payout_at = Timestamp::from_seconds(seconds); - payout_at = payout_at.plus_nanos(nanos); + let res = msg.result.unwrap(); + let mut unstaking_queue = UNSTAKING_QUEUE.load(deps.storage).unwrap_or_default(); + let payout_at = if res.data.is_some() { + let data = res.data; + let (seconds, nanos) = decode_unstaking_response_data(data.unwrap()); + let payout_at = Timestamp::from_seconds(seconds); + payout_at.plus_nanos(nanos) + } else { + let attributes = &res.events[0].attributes; + let mut payout_at = Timestamp::default(); + for attr in attributes { + if attr.key == "completion_time" { + let completion_time = DateTime::parse_from_rfc3339(&attr.value).unwrap(); + let seconds = completion_time.timestamp() as u64; + let nanos = completion_time.timestamp_subsec_nanos() as u64; + payout_at = Timestamp::from_seconds(seconds); + payout_at = payout_at.plus_nanos(nanos); + } } - } - UNSTAKING_QUEUE.push_back(deps.storage, &UnstakingTokens { fund, payout_at })?; + payout_at + }; + let mut unstake_req = unstaking_queue.pop().unwrap(); + unstake_req.payout_at = payout_at; + + unstaking_queue.push(unstake_req); + UNSTAKING_QUEUE.save(deps.storage, &unstaking_queue)?; Ok(Response::default()) } diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/src/lib.rs b/andromeda-core/contracts/finance/andromeda-validator-staking/src/lib.rs index ab995a7..d3a7e60 100644 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/src/lib.rs +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/src/lib.rs @@ -1,8 +1,8 @@ pub mod contract; pub mod state; - #[cfg(test)] mod testing; +pub mod util; #[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] pub mod mock; diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/src/mock.rs b/andromeda-core/contracts/finance/andromeda-validator-staking/src/mock.rs index 18784f4..bfe78df 100644 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/src/mock.rs +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/src/mock.rs @@ -1,12 +1,13 @@ use andromeda_finance::validator_staking::{ExecuteMsg, InstantiateMsg, QueryMsg, UnstakingTokens}; -use cosmwasm_std::{Addr, Coin, Delegation, Empty}; +use cosmwasm_std::{Addr, Coin, Delegation, Empty, Uint128}; use crate::contract::{execute, instantiate, query, reply}; use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::{ExecuteResult, MockADO, MockContract}, }; -use cw_multi_test::{App, Contract, ContractWrapper}; +use cw_multi_test::{Contract, ContractWrapper}; use andromeda_std::{amp::AndrAddr, error::ContractError}; @@ -16,7 +17,7 @@ mock_ado!(MockValidatorStaking, ExecuteMsg, QueryMsg); impl MockValidatorStaking { pub fn execute_stake( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, validator: Option, funds: Vec, @@ -27,33 +28,43 @@ impl MockValidatorStaking { pub fn execute_unstake( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, validator: Option, + amount: Option, ) -> ExecuteResult { - let msg = mock_execute_unstake(validator); + let msg = mock_execute_unstake(validator, amount); self.execute(app, &msg, sender, &[]) } pub fn execute_claim_reward( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, validator: Option, - recipient: Option, ) -> ExecuteResult { - let msg = mock_execute_claim_reward(validator, recipient); + let msg = mock_execute_claim_reward(validator); self.execute(app, &msg, sender, &[]) } - pub fn execute_withdraw_fund(&self, app: &mut App, sender: Addr) -> ExecuteResult { - let msg = mock_execute_withdraw_fund(); + pub fn execute_withdraw_fund(&self, app: &mut MockApp, sender: Addr) -> ExecuteResult { + let msg = mock_execute_withdraw_fund(None, None); + self.execute(app, &msg, sender, &[]) + } + + pub fn execute_update_default_validator( + &self, + app: &mut MockApp, + sender: Addr, + validator: Addr, + ) -> ExecuteResult { + let msg = mock_execute_update_default_validator(validator); self.execute(app, &msg, sender, &[]) } pub fn query_staked_tokens( &self, - app: &App, + app: &MockApp, validator: Option, ) -> Result { let msg = mock_get_staked_tokens(validator); @@ -61,7 +72,10 @@ impl MockValidatorStaking { .wrap() .query_wasm_smart::(self.addr().clone(), &msg)?) } - pub fn query_unstaked_tokens(&self, app: &App) -> Result, ContractError> { + pub fn query_unstaked_tokens( + &self, + app: &MockApp, + ) -> Result, ContractError> { let msg = mock_get_unstaked_tokens(); Ok(app .wrap() @@ -90,22 +104,23 @@ pub fn mock_execute_stake(validator: Option) -> ExecuteMsg { ExecuteMsg::Stake { validator } } -pub fn mock_execute_unstake(validator: Option) -> ExecuteMsg { - ExecuteMsg::Unstake { validator } +pub fn mock_execute_unstake(validator: Option, amount: Option) -> ExecuteMsg { + ExecuteMsg::Unstake { validator, amount } } -pub fn mock_execute_claim_reward( - validator: Option, +pub fn mock_execute_claim_reward(validator: Option) -> ExecuteMsg { + ExecuteMsg::Claim { validator } +} + +pub fn mock_execute_withdraw_fund( + denom: Option, recipient: Option, ) -> ExecuteMsg { - ExecuteMsg::Claim { - validator, - recipient, - } + ExecuteMsg::WithdrawFunds { denom, recipient } } -pub fn mock_execute_withdraw_fund() -> ExecuteMsg { - ExecuteMsg::WithdrawFunds {} +pub fn mock_execute_update_default_validator(validator: Addr) -> ExecuteMsg { + ExecuteMsg::UpdateDefaultValidator { validator } } pub fn mock_get_staked_tokens(validator: Option) -> QueryMsg { diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/src/state.rs b/andromeda-core/contracts/finance/andromeda-validator-staking/src/state.rs index a661368..774ff16 100644 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/src/state.rs +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/src/state.rs @@ -1,8 +1,8 @@ use andromeda_finance::validator_staking::UnstakingTokens; -use cw_storage_plus::{Deque, Item}; +use cw_storage_plus::Item; use cosmwasm_std::Addr; pub const DEFAULT_VALIDATOR: Item = Item::new("default_validator"); -pub const UNSTAKING_QUEUE: Deque = Deque::new("unstaking_queue"); +pub const UNSTAKING_QUEUE: Item> = Item::new("unstaking_queue"); diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/src/testing/tests.rs b/andromeda-core/contracts/finance/andromeda-validator-staking/src/testing/tests.rs index 4656dc0..d319a92 100644 --- a/andromeda-core/contracts/finance/andromeda-validator-staking/src/testing/tests.rs +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/src/testing/tests.rs @@ -3,9 +3,7 @@ use crate::{ testing::mock_querier::{mock_dependencies_custom, DEFAULT_VALIDATOR, VALID_VALIDATOR}, }; -use andromeda_std::{ - amp::AndrAddr, error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT, -}; +use andromeda_std::{error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT}; use cosmwasm_std::{ coin, testing::{mock_env, mock_info}, @@ -15,6 +13,7 @@ use cosmwasm_std::{ use andromeda_finance::validator_staking::{ExecuteMsg, InstantiateMsg}; const OWNER: &str = "owner"; +const ANYONE: &str = "anyone"; fn init(deps: DepsMut, default_validator: Addr) -> Result { let msg = InstantiateMsg { @@ -143,6 +142,7 @@ fn test_unauthorized_unstake() { let msg = ExecuteMsg::Unstake { validator: Some(valid_validator), + amount: None, }; let info = mock_info("other", &[coin(100, "uandr")]); @@ -167,19 +167,9 @@ fn test_unauthorized_claim() { let msg = ExecuteMsg::Claim { validator: Some(valid_validator.clone()), - recipient: Some(AndrAddr::from_string("other")), - }; - - let info = mock_info(OWNER, &[coin(100, "uandr")]); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); - assert_eq!(res, ContractError::Unauthorized {}); - - let msg = ExecuteMsg::Claim { - validator: Some(valid_validator), - recipient: Some(AndrAddr::from_string(OWNER)), }; - let info = mock_info("other", &[coin(100, "uandr")]); + let info = mock_info(ANYONE, &[coin(100, "uandr")]); let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); assert_eq!(res, ContractError::Unauthorized {}); } diff --git a/andromeda-core/contracts/finance/andromeda-validator-staking/src/util.rs b/andromeda-core/contracts/finance/andromeda-validator-staking/src/util.rs new file mode 100644 index 0000000..7078f82 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-validator-staking/src/util.rs @@ -0,0 +1,82 @@ +use cosmwasm_std::Binary; + +pub fn decode_leb128(buf: &[u8]) -> u64 { + let mut ret: u64 = 0; + let mut offset = 0; + + while offset < buf.len() { + let item: u8 = *buf.get(offset).unwrap_or(&0); + ret += u64::from(item) << (7 * offset); + + if item < 0x80 { + return ret; + } else { + ret -= 0x80 << (7 * offset); + } + offset += 1; + } + ret +} + +pub fn decode_unstaking_response_data(data: Binary) -> (u64, u64) { + /* extract seconds and nanoseconds from unstaking submessage reply data + the unstaking reply data structure is as follow + + + |--0 ~ 2--|-----------3 ~ 7----------|------|------------ 9~ --------------| + | headers | seconds in leb128 format | 0x10 | nano second in leb128 format | + Bytes 0 - 2 and 8 is used to identify proto tag and length, etc. + Bytes 3 - 7 represent seconds in LEB128 format. + Bytes 9 - represent nano seconds in LEB128 format. + + Additional data can come after the nano second data depending on the cosmos sdk version used by the network. The decode algorithm will ignore additional data. + + Check unstaking response proto here for additional information(https://docs.cosmos.network/v0.46/modules/staking/03_messages.html) + */ + let data = data.to_vec(); + let seconds = decode_leb128(&data[3..8]); + + let nano_seconds = decode_leb128(&data[9..]); + (seconds, nano_seconds) +} + +#[test] +fn test_decode_leb128() { + let input = vec![0xd1, 0xfb, 0xc2, 0xb6, 0x06]; + let output = decode_leb128(&input); + let expected_output = 1724956113; + assert_eq!(output, expected_output); + + let input = vec![0xb8, 0xe3, 0xdd, 0xed, 0x02]; + let output = decode_leb128(&input); + let expected_output = 766996920; + assert_eq!(output, expected_output); + + let input = vec![0x9b, 0x96, 0xbd, 0xb6, 0x06]; + let output = decode_leb128(&input); + let expected_output = 1724861211; + assert_eq!(output, expected_output); + + let input = vec![0xda, 0xda, 0xa1, 0x4b]; + let output = decode_leb128(&input); + let expected_output = 157838682; + assert_eq!(output, expected_output); +} +#[test] +fn test_decode_unstaking_response_data() { + let data = Binary::from(vec![ + 0x0a, 0x0b, 0x08, 0x9b, 0x96, 0xbd, 0xb6, 0x06, 0x10, 0xda, 0xda, 0xa1, 0x4b, + ]); + let (sec, nsec) = decode_unstaking_response_data(data); + + let expected_output = (1724861211, 157838682); + assert_eq!((sec, nsec), expected_output); + + let data = Binary::from(vec![ + 0x0a, 0x0c, 0x08, 0xd1, 0xfb, 0xc2, 0xb6, 0x06, 0x10, 0xb8, 0xe3, 0xdd, 0xed, 0x02, + ]); + let (sec, nsec) = decode_unstaking_response_data(data); + + let expected_output = (1724956113, 766996920); + assert_eq!((sec, nsec), expected_output); +} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/Cargo.toml b/andromeda-core/contracts/finance/andromeda-vesting/Cargo.toml index d332110..be5af0c 100644 --- a/andromeda-core/contracts/finance/andromeda-vesting/Cargo.toml +++ b/andromeda-core/contracts/finance/andromeda-vesting/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-vesting" -version = "0.2.1" +version = "3.0.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -21,14 +21,13 @@ cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw-asset = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } andromeda-std = { workspace = true } andromeda-finance = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/andromeda-vesting.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/andromeda-vesting.json deleted file mode 100644 index 718bd65..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/andromeda-vesting.json +++ /dev/null @@ -1,1940 +0,0 @@ -{ - "contract_name": "andromeda-vesting", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "denom", - "is_multi_batch_enabled", - "kernel_address", - "recipient", - "unbonding_duration" - ], - "properties": { - "denom": { - "description": "The denom of the coin being vested.", - "type": "string" - }, - "is_multi_batch_enabled": { - "description": "Whether or not multi-batching has been enabled.", - "type": "boolean" - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipient": { - "description": "The recipient of all funds locked in this contract.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "unbonding_duration": { - "description": "The unbonding duration of the native staking module.", - "allOf": [ - { - "$ref": "#/definitions/Duration" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Claim the number of batches specified starting from the beginning. If not specified then the max will be claimed.", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "required": [ - "batch_id" - ], - "properties": { - "batch_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "number_of_claims": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claims tokens from all batches using a paginated approach. If `up_to_time` is specified then it will only claim up to a specific time, otherwise it it will claim to the most recent release.", - "type": "object", - "required": [ - "claim_all" - ], - "properties": { - "claim_all": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "up_to_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Creates a new batch", - "type": "object", - "required": [ - "create_batch" - ], - "properties": { - "create_batch": { - "type": "object", - "required": [ - "release_amount", - "release_unit" - ], - "properties": { - "lockup_duration": { - "description": "Specifying None would mean no lock up period and funds start vesting right away.", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "release_amount": { - "description": "Specifies how much is to be released after each `release_unit`. If it is a percentage, it would be the percentage of the original amount.", - "allOf": [ - { - "$ref": "#/definitions/WithdrawalType" - } - ] - }, - "release_unit": { - "description": "How often releases occur in seconds.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "validator_to_delegate_to": { - "description": "The validator to delegate to. If specified, funds will be delegated to it.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Delegates the given amount of tokens, or all if not specified.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "validator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Redelegates the given amount of tokens, or all from the `from` validator to the `to` validator.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "from", - "to" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "from": { - "type": "string" - }, - "to": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Undelegates the given amount of tokens, or all if not specified.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "validator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Withdraws rewards from all delegations to the sender.", - "type": "object", - "required": [ - "withdraw_rewards" - ], - "properties": { - "withdraw_rewards": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Votes on the specified proposal with the specified vote.", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "$ref": "#/definitions/VoteOption" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "VoteOption": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "no_with_veto" - ] - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Queries the config.", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the batch with the given id.", - "type": "object", - "required": [ - "batch" - ], - "properties": { - "batch": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the batches with pagination.", - "type": "object", - "required": [ - "batches" - ], - "properties": { - "batches": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "batch": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BatchResponse", - "type": "object", - "required": [ - "amount", - "amount_available_to_claim", - "amount_claimed", - "id", - "last_claimed_release_time", - "lockup_end", - "number_of_available_claims", - "release_amount", - "release_unit" - ], - "properties": { - "amount": { - "description": "The amount of tokens in the batch", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_available_to_claim": { - "description": "The amount of tokens available to claim right now.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_claimed": { - "description": "The amount of tokens that have been claimed.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "id": { - "description": "The id.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "last_claimed_release_time": { - "description": "The time at which the last claim took place in seconds.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lockup_end": { - "description": "When the lockup ends.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "number_of_available_claims": { - "description": "The number of available claims.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "release_amount": { - "description": "Specifies how much is to be released after each `release_unit`. If it is a percentage, it would be the percentage of the original amount.", - "allOf": [ - { - "$ref": "#/definitions/WithdrawalType" - } - ] - }, - "release_unit": { - "description": "How often releases occur.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } - }, - "batches": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_BatchResponse", - "type": "array", - "items": { - "$ref": "#/definitions/BatchResponse" - }, - "definitions": { - "BatchResponse": { - "type": "object", - "required": [ - "amount", - "amount_available_to_claim", - "amount_claimed", - "id", - "last_claimed_release_time", - "lockup_end", - "number_of_available_claims", - "release_amount", - "release_unit" - ], - "properties": { - "amount": { - "description": "The amount of tokens in the batch", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_available_to_claim": { - "description": "The amount of tokens available to claim right now.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_claimed": { - "description": "The amount of tokens that have been claimed.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "id": { - "description": "The id.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "last_claimed_release_time": { - "description": "The time at which the last claim took place in seconds.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lockup_end": { - "description": "When the lockup ends.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "number_of_available_claims": { - "description": "The number of available claims.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "release_amount": { - "description": "Specifies how much is to be released after each `release_unit`. If it is a percentage, it would be the percentage of the original amount.", - "allOf": [ - { - "$ref": "#/definitions/WithdrawalType" - } - ] - }, - "release_unit": { - "description": "How often releases occur.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "type": "object", - "required": [ - "denom", - "is_multi_batch_enabled", - "recipient", - "unbonding_duration" - ], - "properties": { - "denom": { - "description": "The denom of the coin being vested.", - "type": "string" - }, - "is_multi_batch_enabled": { - "description": "Whether or not multiple batches are supported.", - "type": "boolean" - }, - "recipient": { - "description": "The recipient of each batch.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "unbonding_duration": { - "description": "The unbonding duration of the native staking module.", - "allOf": [ - { - "$ref": "#/definitions/Duration" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/execute.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/execute.json deleted file mode 100644 index 03db71a..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/execute.json +++ /dev/null @@ -1,813 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Claim the number of batches specified starting from the beginning. If not specified then the max will be claimed.", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "required": [ - "batch_id" - ], - "properties": { - "batch_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "number_of_claims": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claims tokens from all batches using a paginated approach. If `up_to_time` is specified then it will only claim up to a specific time, otherwise it it will claim to the most recent release.", - "type": "object", - "required": [ - "claim_all" - ], - "properties": { - "claim_all": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "up_to_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Creates a new batch", - "type": "object", - "required": [ - "create_batch" - ], - "properties": { - "create_batch": { - "type": "object", - "required": [ - "release_amount", - "release_unit" - ], - "properties": { - "lockup_duration": { - "description": "Specifying None would mean no lock up period and funds start vesting right away.", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "release_amount": { - "description": "Specifies how much is to be released after each `release_unit`. If it is a percentage, it would be the percentage of the original amount.", - "allOf": [ - { - "$ref": "#/definitions/WithdrawalType" - } - ] - }, - "release_unit": { - "description": "How often releases occur in seconds.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "validator_to_delegate_to": { - "description": "The validator to delegate to. If specified, funds will be delegated to it.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Delegates the given amount of tokens, or all if not specified.", - "type": "object", - "required": [ - "delegate" - ], - "properties": { - "delegate": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "validator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Redelegates the given amount of tokens, or all from the `from` validator to the `to` validator.", - "type": "object", - "required": [ - "redelegate" - ], - "properties": { - "redelegate": { - "type": "object", - "required": [ - "from", - "to" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "from": { - "type": "string" - }, - "to": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Undelegates the given amount of tokens, or all if not specified.", - "type": "object", - "required": [ - "undelegate" - ], - "properties": { - "undelegate": { - "type": "object", - "required": [ - "validator" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "validator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Withdraws rewards from all delegations to the sender.", - "type": "object", - "required": [ - "withdraw_rewards" - ], - "properties": { - "withdraw_rewards": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Votes on the specified proposal with the specified vote.", - "type": "object", - "required": [ - "vote" - ], - "properties": { - "vote": { - "type": "object", - "required": [ - "proposal_id", - "vote" - ], - "properties": { - "proposal_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "vote": { - "$ref": "#/definitions/VoteOption" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - }, - "VoteOption": { - "type": "string", - "enum": [ - "yes", - "no", - "abstain", - "no_with_veto" - ] - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/instantiate.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/instantiate.json deleted file mode 100644 index 4cd0b02..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/instantiate.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "denom", - "is_multi_batch_enabled", - "kernel_address", - "recipient", - "unbonding_duration" - ], - "properties": { - "denom": { - "description": "The denom of the coin being vested.", - "type": "string" - }, - "is_multi_batch_enabled": { - "description": "Whether or not multi-batching has been enabled.", - "type": "boolean" - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipient": { - "description": "The recipient of all funds locked in this contract.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "unbonding_duration": { - "description": "The unbonding duration of the native staking module.", - "allOf": [ - { - "$ref": "#/definitions/Duration" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/query.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/query.json deleted file mode 100644 index efb98f5..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/query.json +++ /dev/null @@ -1,263 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Queries the config.", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the batch with the given id.", - "type": "object", - "required": [ - "batch" - ], - "properties": { - "batch": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the batches with pagination.", - "type": "object", - "required": [ - "batches" - ], - "properties": { - "batches": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_balance.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batch.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batch.json deleted file mode 100644 index 6d3e02e..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batch.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BatchResponse", - "type": "object", - "required": [ - "amount", - "amount_available_to_claim", - "amount_claimed", - "id", - "last_claimed_release_time", - "lockup_end", - "number_of_available_claims", - "release_amount", - "release_unit" - ], - "properties": { - "amount": { - "description": "The amount of tokens in the batch", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_available_to_claim": { - "description": "The amount of tokens available to claim right now.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_claimed": { - "description": "The amount of tokens that have been claimed.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "id": { - "description": "The id.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "last_claimed_release_time": { - "description": "The time at which the last claim took place in seconds.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lockup_end": { - "description": "When the lockup ends.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "number_of_available_claims": { - "description": "The number of available claims.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "release_amount": { - "description": "Specifies how much is to be released after each `release_unit`. If it is a percentage, it would be the percentage of the original amount.", - "allOf": [ - { - "$ref": "#/definitions/WithdrawalType" - } - ] - }, - "release_unit": { - "description": "How often releases occur.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batches.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batches.json deleted file mode 100644 index b2951f2..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_batches.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_BatchResponse", - "type": "array", - "items": { - "$ref": "#/definitions/BatchResponse" - }, - "definitions": { - "BatchResponse": { - "type": "object", - "required": [ - "amount", - "amount_available_to_claim", - "amount_claimed", - "id", - "last_claimed_release_time", - "lockup_end", - "number_of_available_claims", - "release_amount", - "release_unit" - ], - "properties": { - "amount": { - "description": "The amount of tokens in the batch", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_available_to_claim": { - "description": "The amount of tokens available to claim right now.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_claimed": { - "description": "The amount of tokens that have been claimed.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "id": { - "description": "The id.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "last_claimed_release_time": { - "description": "The time at which the last claim took place in seconds.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lockup_end": { - "description": "When the lockup ends.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "number_of_available_claims": { - "description": "The number of available claims.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "release_amount": { - "description": "Specifies how much is to be released after each `release_unit`. If it is a percentage, it would be the percentage of the original amount.", - "allOf": [ - { - "$ref": "#/definitions/WithdrawalType" - } - ] - }, - "release_unit": { - "description": "How often releases occur.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WithdrawalType": { - "oneOf": [ - { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "percentage" - ], - "properties": { - "percentage": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_config.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_config.json deleted file mode 100644 index aa57ab5..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_config.json +++ /dev/null @@ -1,115 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "type": "object", - "required": [ - "denom", - "is_multi_batch_enabled", - "recipient", - "unbonding_duration" - ], - "properties": { - "denom": { - "description": "The denom of the coin being vested.", - "type": "string" - }, - "is_multi_batch_enabled": { - "description": "Whether or not multiple batches are supported.", - "type": "boolean" - }, - "recipient": { - "description": "The recipient of each batch.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - }, - "unbonding_duration": { - "description": "The unbonding duration of the native staking module.", - "allOf": [ - { - "$ref": "#/definitions/Duration" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Duration": { - "description": "Duration is a delta of time. You can add it to a BlockInfo or Expiration to move that further in the future. Note that an height-based Duration and a time-based Expiration cannot be combined", - "oneOf": [ - { - "type": "object", - "required": [ - "height" - ], - "properties": { - "height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "Time in seconds", - "type": "object", - "required": [ - "time" - ], - "properties": { - "time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_operators.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_owner.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissions.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_type.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_version.json b/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/finance/andromeda-vesting/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/src/contract.rs b/andromeda-core/contracts/finance/andromeda-vesting/src/contract.rs index 92556be..c39d684 100644 --- a/andromeda-core/contracts/finance/andromeda-vesting/src/contract.rs +++ b/andromeda-core/contracts/finance/andromeda-vesting/src/contract.rs @@ -1,30 +1,26 @@ use andromeda_std::{ ado_contract::ADOContract, - common::{context::ExecuteContext, withdraw::WithdrawalType}, + common::{actions::call_action, context::ExecuteContext, withdraw::WithdrawalType}, error::ContractError, }; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure, Binary, Coin, CosmosMsg, Deps, DepsMut, DistributionMsg, Env, GovMsg, MessageInfo, - QuerierWrapper, Response, StakingMsg, Uint128, VoteOption, + ensure, Binary, Coin, Decimal, Deps, DepsMut, Env, MessageInfo, QuerierWrapper, Response, + Uint128, }; -use cw2::{get_contract_version, set_contract_version}; use cw_asset::AssetInfo; - use cw_utils::nonpayable; -use semver::Version; use std::cmp; use crate::state::{ batches, get_all_batches_with_ids, get_claimable_batches_with_ids, save_new_batch, Batch, CONFIG, }; -use andromeda_finance::vesting::{ - BatchResponse, Config, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, -}; +use andromeda_finance::vesting::{BatchResponse, Config, ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, common::encode_binary, error::from_semver, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + common::encode_binary, }; const CONTRACT_NAME: &str = "crates.io:andromeda-vesting"; @@ -37,13 +33,10 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let config = Config { is_multi_batch_enabled: msg.is_multi_batch_enabled, recipient: msg.recipient, denom: msg.denom, - unbonding_duration: msg.unbonding_duration, }; CONFIG.save(deps.storage, &config)?; @@ -52,11 +45,11 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "vesting".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -82,32 +75,25 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; match msg { ExecuteMsg::CreateBatch { lockup_duration, release_unit, release_amount, - validator_to_delegate_to, - } => execute_create_batch( - ctx, - lockup_duration, - release_unit, - release_amount, - validator_to_delegate_to, - ), + } => execute_create_batch(ctx, lockup_duration, release_unit, release_amount), ExecuteMsg::Claim { number_of_claims, batch_id, } => execute_claim(ctx, number_of_claims, batch_id), ExecuteMsg::ClaimAll { limit, up_to_time } => execute_claim_all(ctx, limit, up_to_time), - ExecuteMsg::Delegate { amount, validator } => { - execute_delegate(ctx.deps, ctx.env, ctx.info, amount, validator) - } - ExecuteMsg::Redelegate { amount, from, to } => execute_redelegate(ctx, amount, from, to), - ExecuteMsg::Undelegate { amount, validator } => execute_undelegate(ctx, amount, validator), - ExecuteMsg::WithdrawRewards {} => execute_withdraw_rewards(ctx), - ExecuteMsg::Vote { proposal_id, vote } => execute_vote(ctx, proposal_id, vote), _ => ADOContract::default().execute(ctx, msg), } @@ -118,7 +104,6 @@ fn execute_create_batch( lockup_duration: Option, release_unit: u64, release_amount: WithdrawalType, - validator_to_delegate_to: Option, ) -> Result { let ExecuteContext { deps, info, env, .. @@ -148,15 +133,36 @@ fn execute_create_batch( ); ensure!( - !funds.amount.is_zero(), + release_unit > 0 && !release_amount.is_zero(), + ContractError::InvalidZeroAmount {} + ); + ensure!( + !release_amount.get_amount(funds.amount)?.is_zero(), + ContractError::InvalidZeroAmount {} + ); + + let min_fund = match release_amount { + WithdrawalType::Amount(amount) => amount, + WithdrawalType::Percentage(_) => Uint128::from(100u128), + }; + ensure!( + funds.amount >= min_fund, ContractError::InvalidFunds { - msg: "Funds must be non-zero".to_string(), + msg: format!("Funds must be at least {min_fund}"), } ); + let current_balance = deps + .querier + .query_balance(env.contract.address.to_string(), funds.denom) + .unwrap() + .amount; + let max_fund = Uint128::MAX - current_balance; ensure!( - release_unit > 0 && !release_amount.is_zero(), - ContractError::InvalidZeroAmount {} + funds.amount <= max_fund, + ContractError::InvalidFunds { + msg: format!("Funds can not exceed {max_fund}"), + } ); let lockup_end = if let Some(duration) = lockup_duration { @@ -178,22 +184,12 @@ fn execute_create_batch( save_new_batch(deps.storage, batch, &config)?; - let mut response = Response::new() + Ok(Response::new() .add_attribute("action", "create_batch") .add_attribute("amount", funds.amount) .add_attribute("lockup_end", lockup_end.to_string()) .add_attribute("release_unit", release_unit.to_string()) - .add_attribute("release_amount", release_amount_string); - - if let Some(validator) = validator_to_delegate_to { - let delegate_response = execute_delegate(deps, env, info, Some(funds.amount), validator)?; - response = response - .add_attributes(delegate_response.attributes) - .add_submessages(delegate_response.messages) - .add_events(delegate_response.events); - } - - Ok(response) + .add_attribute("release_amount", release_amount_string)) } fn execute_claim( @@ -282,7 +278,7 @@ fn execute_claim_all( Some(num_available_claims), )?; - total_amount_to_send += amount_to_send; + total_amount_to_send = total_amount_to_send.checked_add(amount_to_send)?; key.save(deps.storage, &batch)?; } @@ -303,150 +299,6 @@ fn execute_claim_all( .add_attribute("last_batch_id_processed", last_batch_id)) } -fn execute_delegate( - deps: DepsMut, - env: Env, - info: MessageInfo, - amount: Option, - validator: String, -) -> Result { - let sender = info.sender.to_string(); - ensure!( - ADOContract::default().is_contract_owner(deps.storage, &sender)?, - ContractError::Unauthorized {} - ); - let config = CONFIG.load(deps.storage)?; - let asset = AssetInfo::native(config.denom.clone()); - let max_amount = asset.query_balance(&deps.querier, env.contract.address)?; - let amount = cmp::min(max_amount, amount.unwrap_or(max_amount)); - - ensure!(!amount.is_zero(), ContractError::InvalidZeroAmount {}); - - let msg: CosmosMsg = CosmosMsg::Staking(StakingMsg::Delegate { - validator: validator.clone(), - amount: Coin { - denom: config.denom, - amount, - }, - }); - - Ok(Response::new() - .add_message(get_set_withdraw_address_msg(sender)) - .add_message(msg) - .add_attribute("action", "delegate") - .add_attribute("validator", validator) - .add_attribute("amount", amount)) -} - -fn execute_redelegate( - ctx: ExecuteContext, - amount: Option, - from: String, - to: String, -) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - let sender = info.sender.to_string(); - ensure!( - ADOContract::default().is_contract_owner(deps.storage, &sender)?, - ContractError::Unauthorized {} - ); - let config = CONFIG.load(deps.storage)?; - let max_amount = get_amount_delegated( - &deps.querier, - env.contract.address.to_string(), - from.clone(), - )?; - let amount = cmp::min(max_amount, amount.unwrap_or(max_amount)); - - ensure!(!amount.is_zero(), ContractError::InvalidZeroAmount {}); - - let msg: CosmosMsg = CosmosMsg::Staking(StakingMsg::Redelegate { - src_validator: from.clone(), - dst_validator: to.clone(), - amount: Coin { - denom: config.denom, - amount, - }, - }); - - Ok(Response::new() - .add_message(get_set_withdraw_address_msg(sender)) - .add_message(msg) - .add_attribute("action", "redelegate") - .add_attribute("from", from) - .add_attribute("to", to) - .add_attribute("amount", amount)) -} - -fn execute_undelegate( - ctx: ExecuteContext, - amount: Option, - validator: String, -) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - let sender = info.sender.to_string(); - ensure!( - ADOContract::default().is_contract_owner(deps.storage, &sender)?, - ContractError::Unauthorized {} - ); - let config = CONFIG.load(deps.storage)?; - let max_amount = get_amount_delegated( - &deps.querier, - env.contract.address.to_string(), - validator.clone(), - )?; - let amount = cmp::min(max_amount, amount.unwrap_or(max_amount)); - - ensure!(!amount.is_zero(), ContractError::InvalidZeroAmount {}); - - let msg: CosmosMsg = CosmosMsg::Staking(StakingMsg::Undelegate { - validator: validator.clone(), - amount: Coin { - denom: config.denom, - amount, - }, - }); - - Ok(Response::new() - .add_message(get_set_withdraw_address_msg(sender)) - .add_message(msg) - .add_attribute("action", "undelegate") - .add_attribute("validator", validator) - .add_attribute("amount", amount)) -} - -fn execute_withdraw_rewards(ctx: ExecuteContext) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - - let sender = info.sender.to_string(); - ensure!( - ADOContract::default().is_contract_owner(deps.storage, &sender)?, - ContractError::Unauthorized {} - ); - let withdraw_rewards_msgs: Vec = deps - .querier - .query_all_delegations(env.contract.address)? - .into_iter() - .map(|d| { - CosmosMsg::Distribution(DistributionMsg::WithdrawDelegatorReward { - validator: d.validator, - }) - }) - .collect(); - - Ok(Response::new() - .add_attribute("action", "withdraw_rewards") - .add_message(get_set_withdraw_address_msg(sender)) - .add_messages(withdraw_rewards_msgs)) -} - fn claim_batch( querier: &QuerierWrapper, env: &Env, @@ -459,8 +311,6 @@ fn claim_batch( batch.lockup_end <= current_time, ContractError::FundsAreLocked {} ); - let amount_per_claim = batch.release_amount.get_amount(batch.amount)?; - let total_amount = AssetInfo::native(config.denom.to_owned()) .query_balance(querier, env.contract.address.to_owned())?; @@ -472,90 +322,43 @@ fn claim_batch( num_available_claims, ); - let amount_to_send = amount_per_claim * Uint128::from(number_of_claims); + let amount_per_claim = batch.release_amount.get_amount(batch.amount)?; + + let amount_to_send = amount_per_claim + .checked_mul(Decimal::from_ratio(number_of_claims, Uint128::one()))? + .to_uint_floor(); let amount_available = cmp::min(batch.amount - batch.amount_claimed, total_amount); let amount_to_send = cmp::min(amount_to_send, amount_available); // We dont want to update the last_claim_time when there are no funds to claim. if !amount_to_send.is_zero() { - batch.amount_claimed += amount_to_send; - batch.last_claimed_release_time += number_of_claims * batch.release_unit; + batch.amount_claimed = batch.amount_claimed.checked_add(amount_to_send)?; + + // Safe math version + let claims_release_unit = number_of_claims.checked_mul(batch.release_unit); + if let Some(claims_release_unit) = claims_release_unit { + let new_claimed_release_time = batch + .last_claimed_release_time + .checked_add(claims_release_unit); + if let Some(new_claimed_release_time) = new_claimed_release_time { + batch.last_claimed_release_time = new_claimed_release_time; + } else { + return Err(ContractError::Overflow {}); + } + } else { + return Err(ContractError::Overflow {}); + } + // The unsafe version + // batch.last_claimed_release_time += number_of_claims * batch.release_unit; } Ok(amount_to_send) } -fn execute_vote( - ctx: ExecuteContext, - proposal_id: u64, - vote: VoteOption, -) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - nonpayable(&info)?; - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let msg: CosmosMsg = CosmosMsg::Gov(GovMsg::Vote { - proposal_id, - vote: vote.clone(), - }); - Ok(Response::new() - .add_message(msg) - .add_attribute("action", "vote") - .add_attribute("proposal_id", proposal_id.to_string()) - .add_attribute("vote", format!("{vote:?}"))) -} - -fn get_amount_delegated( - querier: &QuerierWrapper, - delegator: String, - validator: String, -) -> Result { - let res = querier.query_delegation(delegator, validator)?; - match res { - None => Ok(Uint128::zero()), - Some(full_delegation) => Ok(full_delegation.amount.amount), - } -} - -fn get_set_withdraw_address_msg(address: String) -> CosmosMsg { - CosmosMsg::Distribution(DistributionMsg::SetWithdrawAddress { address }) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -614,7 +417,10 @@ fn get_batch_response( Uint128::zero() }; let amount_per_release = batch.release_amount.get_amount(batch.amount)?; - let number_of_available_claims = amount_available_to_claim / amount_per_release; + let number_of_available_claims = Decimal::from_ratio(amount_available_to_claim, Uint128::one()) + .checked_div(amount_per_release) + .unwrap() + .to_uint_floor(); let res = BatchResponse { id: batch_id, amount: batch.amount, diff --git a/andromeda-core/contracts/finance/andromeda-vesting/src/lib.rs b/andromeda-core/contracts/finance/andromeda-vesting/src/lib.rs index e56a112..8e593a3 100644 --- a/andromeda-core/contracts/finance/andromeda-vesting/src/lib.rs +++ b/andromeda-core/contracts/finance/andromeda-vesting/src/lib.rs @@ -1,4 +1,6 @@ pub mod contract; +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; pub mod state; #[cfg(test)] mod testing; diff --git a/andromeda-core/contracts/finance/andromeda-vesting/src/mock.rs b/andromeda-core/contracts/finance/andromeda-vesting/src/mock.rs new file mode 100644 index 0000000..3159b57 --- /dev/null +++ b/andromeda-core/contracts/finance/andromeda-vesting/src/mock.rs @@ -0,0 +1,73 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +use crate::contract::{execute, instantiate, query}; +use andromeda_finance::vesting::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::amp::Recipient; +use andromeda_testing::{ + mock::MockApp, + mock_ado, + mock_contract::{MockADO, MockContract}, +}; +use cosmwasm_std::{Addr, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; +use cw_utils::Duration; + +pub struct MockVestingContract(Addr); +mock_ado!(MockVestingContract, ExecuteMsg, QueryMsg); + +impl MockVestingContract { + #[allow(clippy::too_many_arguments)] + pub fn instantiate( + code_id: u64, + sender: &Addr, + app: &mut MockApp, + is_multi_batch_enabled: bool, + unbonding_duration: Duration, + recipient: Recipient, + denom: String, + kernel_address: impl Into, + owner: Option, + ) -> MockVestingContract { + let msg = mock_vesting_instantiate_msg( + is_multi_batch_enabled, + unbonding_duration, + recipient, + denom, + kernel_address, + owner, + ); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "App Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockVestingContract(Addr::unchecked(addr)) + } +} + +pub fn mock_andromeda_vesting() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} + +pub fn mock_vesting_instantiate_msg( + is_multi_batch_enabled: bool, + unbonding_duration: Duration, + recipient: Recipient, + denom: String, + kernel_address: impl Into, + owner: Option, +) -> InstantiateMsg { + InstantiateMsg { + is_multi_batch_enabled, + unbonding_duration, + recipient, + denom, + kernel_address: kernel_address.into(), + owner, + } +} diff --git a/andromeda-core/contracts/finance/andromeda-vesting/src/testing/mock_querier.rs b/andromeda-core/contracts/finance/andromeda-vesting/src/testing/mock_querier.rs index e52a24c..2ed9a90 100644 --- a/andromeda-core/contracts/finance/andromeda-vesting/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/finance/andromeda-vesting/src/testing/mock_querier.rs @@ -1,23 +1,15 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg, Uint128}; -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; - -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -39,11 +31,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "lockdrop".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -75,91 +68,17 @@ impl Querier for WasmMockQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) } _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base } } diff --git a/andromeda-core/contracts/finance/andromeda-vesting/src/testing/tests.rs b/andromeda-core/contracts/finance/andromeda-vesting/src/testing/tests.rs index 6c38d10..fa65fb7 100644 --- a/andromeda-core/contracts/finance/andromeda-vesting/src/testing/tests.rs +++ b/andromeda-core/contracts/finance/andromeda-vesting/src/testing/tests.rs @@ -3,10 +3,9 @@ use andromeda_std::{ testing::mock_querier::MOCK_KERNEL_CONTRACT, }; use cosmwasm_std::{ - coin, coins, from_json, - testing::{mock_env, mock_info, MockQuerier, MOCK_CONTRACT_ADDR}, - Addr, BankMsg, Coin, CosmosMsg, Decimal, DepsMut, DistributionMsg, FullDelegation, GovMsg, - Response, StakingMsg, Uint128, Validator, VoteOption, + coins, from_json, + testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, + BankMsg, Decimal, DepsMut, Response, Uint128, }; use cw_utils::Duration; @@ -18,7 +17,6 @@ use crate::{ use andromeda_finance::vesting::{BatchResponse, Config, ExecuteMsg, InstantiateMsg, QueryMsg}; -const DEFAULT_VALIDATOR: &str = "validator"; const UNBONDING_BLOCK_DURATION: u64 = 5; fn init(deps: DepsMut) -> Response { @@ -29,42 +27,12 @@ fn init(deps: DepsMut) -> Response { unbonding_duration: Duration::Height(UNBONDING_BLOCK_DURATION), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let info = mock_info("owner", &[]); instantiate(deps, mock_env(), info, msg).unwrap() } -fn sample_validator(addr: &str) -> Validator { - Validator { - address: addr.into(), - commission: Decimal::percent(3), - max_commission: Decimal::percent(10), - max_change_rate: Decimal::percent(1), - } -} - -fn sample_delegation(addr: &str, amount: Coin) -> FullDelegation { - let can_redelegate = amount.clone(); - let accumulated_rewards = coins(0, &amount.denom); - FullDelegation { - validator: addr.into(), - delegator: Addr::unchecked(MOCK_CONTRACT_ADDR), - amount, - can_redelegate, - accumulated_rewards, - } -} - -fn set_delegation(querier: &mut MockQuerier, amount: u128, denom: &str) { - querier.update_staking( - "ustake", - &[sample_validator(DEFAULT_VALIDATOR)], - &[sample_delegation(DEFAULT_VALIDATOR, coin(amount, denom))], - ) -} - fn create_batch( deps: DepsMut, lockup_duration: Option, @@ -76,7 +44,6 @@ fn create_batch( lockup_duration, release_unit, release_amount, - validator_to_delegate_to: None, }; let info = mock_info("owner", &coins(100, "uusd")); @@ -92,7 +59,9 @@ fn test_instantiate() { assert_eq!( Response::new() .add_attribute("method", "instantiate") - .add_attribute("type", "vesting"), + .add_attribute("type", "vesting") + .add_attribute("kernel_address", MOCK_KERNEL_CONTRACT) + .add_attribute("owner", "owner"), res ); @@ -101,7 +70,6 @@ fn test_instantiate() { recipient: Recipient::from_string("recipient"), is_multi_batch_enabled: true, denom: "uusd".to_string(), - unbonding_duration: Duration::Height(UNBONDING_BLOCK_DURATION) }, CONFIG.load(deps.as_ref().storage).unwrap() ); @@ -118,7 +86,6 @@ fn test_create_batch_unauthorized() { lockup_duration: None, release_unit: 1, release_amount: WithdrawalType::Amount(Uint128::zero()), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info, msg); @@ -138,7 +105,6 @@ fn test_create_batch_no_funds() { lockup_duration: None, release_unit: 1, release_amount: WithdrawalType::Amount(Uint128::zero()), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info, msg); @@ -162,7 +128,6 @@ fn test_create_batch_invalid_denom() { lockup_duration: None, release_unit: 1, release_amount: WithdrawalType::Amount(Uint128::zero()), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info, msg); @@ -186,17 +151,11 @@ fn test_create_batch_valid_denom_zero_amount() { lockup_duration: None, release_unit: 1, release_amount: WithdrawalType::Amount(Uint128::zero()), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!( - ContractError::InvalidFunds { - msg: "Funds must be non-zero".to_string() - }, - res.unwrap_err() - ); + assert_eq!(ContractError::InvalidZeroAmount {}, res.unwrap_err()); } #[test] @@ -210,7 +169,6 @@ fn test_create_batch_release_unit_zero() { lockup_duration: None, release_unit: 0, release_amount: WithdrawalType::Amount(Uint128::zero()), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info, msg); @@ -229,7 +187,6 @@ fn test_create_batch_release_amount_zero() { lockup_duration: None, release_unit: 10, release_amount: WithdrawalType::Amount(Uint128::zero()), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info, msg); @@ -248,7 +205,6 @@ fn test_create_batch() { lockup_duration: None, release_unit: 10, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -285,7 +241,6 @@ fn test_create_batch() { lockup_duration: Some(100), release_unit: 10, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); @@ -317,50 +272,6 @@ fn test_create_batch() { assert_eq!(3, NEXT_ID.load(deps.as_ref().storage).unwrap()); } -#[test] -fn test_create_batch_and_delegate() { - let mut deps = mock_dependencies_custom(&[coin(1000, "uusd")]); - init(deps.as_mut()); - - let info = mock_info("owner", &coins(100, "uusd")); - - deps.querier - .base - .update_balance(MOCK_CONTRACT_ADDR, coins(100, "uusd")); - - let msg = ExecuteMsg::CreateBatch { - lockup_duration: None, - release_unit: 10, - release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: Some(DEFAULT_VALIDATOR.to_owned()), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - let current_time = mock_env().block.time.seconds(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Staking(StakingMsg::Delegate { - validator: DEFAULT_VALIDATOR.to_string(), - amount: coin(100, "uusd") - })) - .add_attribute("action", "create_batch") - .add_attribute("amount", "100") - .add_attribute("lockup_end", current_time.to_string()) - .add_attribute("release_unit", "10") - .add_attribute("release_amount", "Amount(Uint128(10))") - .add_attribute("action", "delegate") - .add_attribute("validator", DEFAULT_VALIDATOR) - .add_attribute("amount", "100"), - res - ); -} - #[test] fn test_create_batch_multi_batch_not_supported() { let mut deps = mock_dependencies_custom(&[]); @@ -371,7 +282,6 @@ fn test_create_batch_multi_batch_not_supported() { unbonding_duration: Duration::Height(0u64), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let info = mock_info("owner", &[]); @@ -383,7 +293,6 @@ fn test_create_batch_multi_batch_not_supported() { lockup_duration: Some(100), release_unit: 10, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let res = execute(deps.as_mut(), mock_env(), info.clone(), msg.clone()).unwrap(); @@ -449,7 +358,6 @@ fn test_claim_batch_still_locked() { lockup_duration: Some(100), release_unit: 10, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -476,55 +384,10 @@ fn test_claim_batch_no_funds_available() { lockup_duration: None, release_unit: 10, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, - }; - - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - // Claim batch. - let msg = ExecuteMsg::Claim { - number_of_claims: None, - batch_id: 1, - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - // This is because, the first payment becomes available after 10 seconds. - assert_eq!(ContractError::WithdrawalIsEmpty {}, res.unwrap_err()); -} - -#[test] -fn test_claim_batch_all_funds_delegated() { - let mut deps = mock_dependencies_custom(&[coin(1000, "uusd")]); - init(deps.as_mut()); - let info = mock_info("owner", &coins(100, "uusd")); - - // Create batch. - let msg = ExecuteMsg::CreateBatch { - lockup_duration: None, - release_unit: 10, - release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, - }; - - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - deps.querier - .base - .update_balance(MOCK_CONTRACT_ADDR, coins(100, "uusd")); - - // Delegate tokens - let msg = ExecuteMsg::Delegate { - amount: None, - validator: DEFAULT_VALIDATOR.to_owned(), }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - // Skip time to first release. - let mut env = mock_env(); - env.block.time = env.block.time.plus_seconds(10); - // Claim batch. let msg = ExecuteMsg::Claim { number_of_claims: None, @@ -537,65 +400,6 @@ fn test_claim_batch_all_funds_delegated() { assert_eq!(ContractError::WithdrawalIsEmpty {}, res.unwrap_err()); } -#[test] -fn test_claim_batch_some_funds_delegated() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - let info = mock_info("owner", &coins(100, "uusd")); - - // Create batch. - let msg = ExecuteMsg::CreateBatch { - lockup_duration: None, - release_unit: 10, - release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, - }; - - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - deps.querier - .base - .update_balance(MOCK_CONTRACT_ADDR, coins(100, "uusd")); - - // Delegate tokens - let msg = ExecuteMsg::Delegate { - amount: Some(Uint128::new(70)), - validator: DEFAULT_VALIDATOR.to_owned(), - }; - - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - // Skip time to where all funds available. - let mut env = mock_env(); - env.block.time = env.block.time.plus_seconds(1000); - - deps.querier - .base - .update_balance(MOCK_CONTRACT_ADDR, coins(30, "uusd")); - - // Claim batch. - let msg = ExecuteMsg::Claim { - number_of_claims: None, - batch_id: 1, - }; - - let res = execute(deps.as_mut(), env, info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(BankMsg::Send { - to_address: "recipient".to_string(), - // Only 30 are available - amount: coins(30, "uusd") - }) - .add_attribute("action", "claim") - .add_attribute("amount", "30") - .add_attribute("batch_id", "1") - .add_attribute("amount_left", "70"), - res - ); -} - #[test] fn test_claim_batch_single_claim() { let mut deps = mock_dependencies_custom(&[]); @@ -609,7 +413,6 @@ fn test_claim_batch_single_claim() { lockup_duration: None, release_unit, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -682,7 +485,7 @@ fn test_claim_batch_single_claim() { fn test_claim_batch_not_nice_numbers_single_release() { let mut deps = mock_dependencies_custom(&[]); init(deps.as_mut()); - let info = mock_info("owner", &coins(7, "uusd")); + let info = mock_info("owner", &coins(10, "uusd")); let release_unit = 10; @@ -691,7 +494,6 @@ fn test_claim_batch_not_nice_numbers_single_release() { lockup_duration: None, release_unit, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -722,14 +524,14 @@ fn test_claim_batch_not_nice_numbers_single_release() { .add_attribute("action", "claim") .add_attribute("amount", "7") .add_attribute("batch_id", "1") - .add_attribute("amount_left", "0"), + .add_attribute("amount_left", "3"), res ); let lockup_end = mock_env().block.time.seconds(); assert_eq!( Batch { - amount: Uint128::new(7), + amount: Uint128::new(10), amount_claimed: Uint128::new(7), lockup_end, release_unit: 10, @@ -744,23 +546,25 @@ fn test_claim_batch_not_nice_numbers_single_release() { fn test_claim_batch_not_nice_numbers_multiple_releases() { let mut deps = mock_dependencies_custom(&[]); init(deps.as_mut()); - let info = mock_info("owner", &coins(14, "uusd")); + let vesting_amount = 1_000_000_000_000_000_000u128; + let info = mock_info("owner", &coins(vesting_amount, "uusd")); - let release_unit = 10; + let release_unit = 1; // 1 second + let duration: u64 = 60 * 60 * 24 * 365 * 5; // 5 years + let percent_release = Decimal::from_ratio(Uint128::one(), Uint128::from(duration)); // Create batch. let msg = ExecuteMsg::CreateBatch { lockup_duration: None, release_unit, - release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, + release_amount: WithdrawalType::Percentage(percent_release), }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); deps.querier .base - .update_balance(MOCK_CONTRACT_ADDR, coins(14, "uusd")); + .update_balance(MOCK_CONTRACT_ADDR, coins(vesting_amount, "uusd")); // Skip time. let mut env = mock_env(); @@ -773,33 +577,61 @@ fn test_claim_batch_not_nice_numbers_multiple_releases() { batch_id: 1, }; - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); assert_eq!( Response::new() .add_message(BankMsg::Send { to_address: "recipient".to_string(), - amount: coins(14, "uusd") + amount: coins(12683916792, "uusd") }) .add_attribute("action", "claim") - .add_attribute("amount", "14") + .add_attribute("amount", "12683916792") .add_attribute("batch_id", "1") - .add_attribute("amount_left", "0"), + .add_attribute("amount_left", (vesting_amount - 12683916792).to_string()), res ); let lockup_end = mock_env().block.time.seconds(); assert_eq!( Batch { - amount: Uint128::new(14), - amount_claimed: Uint128::new(14), + amount: Uint128::new(vesting_amount), + amount_claimed: Uint128::new(12683916792), lockup_end, - release_unit: 10, - release_amount: WithdrawalType::Amount(Uint128::new(10)), + release_unit: 1, + release_amount: WithdrawalType::Percentage(percent_release), last_claimed_release_time: lockup_end + 2 * release_unit, }, batches().load(deps.as_ref().storage, 1u64).unwrap() ); + + env.block.time = env.block.time.plus_seconds(duration); + + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + assert_eq!( + Response::new() + .add_message(BankMsg::Send { + to_address: "recipient".to_string(), + amount: coins(vesting_amount - 12683916792, "uusd") + }) + .add_attribute("action", "claim") + .add_attribute("amount", (vesting_amount - 12683916792).to_string()) + .add_attribute("batch_id", "1") + .add_attribute("amount_left", "0"), + res + ); + + assert_eq!( + Batch { + amount: Uint128::new(vesting_amount), + amount_claimed: Uint128::from(vesting_amount), + lockup_end, + release_unit: 1, + release_amount: WithdrawalType::Percentage(percent_release), + last_claimed_release_time: lockup_end + duration + 2, + }, + batches().load(deps.as_ref().storage, 1u64).unwrap() + ); } #[test] @@ -815,7 +647,6 @@ fn test_claim_batch_middle_of_interval() { lockup_duration: None, release_unit, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -882,7 +713,6 @@ fn test_claim_batch_multiple_claims() { lockup_duration: None, release_unit, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -976,7 +806,6 @@ fn test_claim_batch_all_releases() { lockup_duration: None, release_unit, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -1043,7 +872,6 @@ fn test_claim_batch_too_high_of_claim() { lockup_duration: None, release_unit, release_amount: WithdrawalType::Amount(Uint128::new(10)), - validator_to_delegate_to: None, }; let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); @@ -1264,431 +1092,3 @@ fn test_claim_all() { batches().load(deps.as_ref().storage, 3u64).unwrap() ); } - -#[test] -fn test_delegate_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("not_owner", &[]); - - let msg = ExecuteMsg::Delegate { - amount: None, - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); -} - -#[test] -fn test_delegate_no_funds() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - let msg = ExecuteMsg::Delegate { - amount: None, - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::InvalidZeroAmount {}, res.unwrap_err()); -} - -#[test] -fn test_delegate() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - deps.querier - .base - .update_balance(MOCK_CONTRACT_ADDR, coins(100, "uusd")); - - let info = mock_info("owner", &[]); - - let msg = ExecuteMsg::Delegate { - amount: None, - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Staking(StakingMsg::Delegate { - validator: DEFAULT_VALIDATOR.to_string(), - amount: coin(100, "uusd") - })) - .add_attribute("action", "delegate") - .add_attribute("validator", DEFAULT_VALIDATOR) - .add_attribute("amount", "100"), - res - ); -} - -#[test] -fn test_delegate_more_than_balance() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - deps.querier - .base - .update_balance(MOCK_CONTRACT_ADDR, coins(100, "uusd")); - - let info = mock_info("owner", &[]); - - let msg = ExecuteMsg::Delegate { - amount: Some(Uint128::new(200)), - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Staking(StakingMsg::Delegate { - validator: DEFAULT_VALIDATOR.to_string(), - amount: coin(100, "uusd") - })) - .add_attribute("action", "delegate") - .add_attribute("validator", DEFAULT_VALIDATOR) - .add_attribute("amount", "100"), - res - ); -} - -#[test] -fn test_redelegate_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("not_owner", &[]); - - let msg = ExecuteMsg::Redelegate { - amount: None, - from: DEFAULT_VALIDATOR.to_string(), - to: "other_validator".to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); -} - -#[test] -fn test_redelegate_no_funds() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - let msg = ExecuteMsg::Redelegate { - amount: None, - from: DEFAULT_VALIDATOR.to_string(), - to: "other_validator".to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::InvalidZeroAmount {}, res.unwrap_err()); -} - -#[test] -fn test_redelegate() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - set_delegation(&mut deps.querier.base, 100, "uusd"); - - let msg = ExecuteMsg::Redelegate { - amount: None, - from: DEFAULT_VALIDATOR.to_string(), - to: "other_validator".to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Staking(StakingMsg::Redelegate { - src_validator: DEFAULT_VALIDATOR.to_owned(), - dst_validator: "other_validator".to_string(), - amount: coin(100, "uusd") - })) - .add_attribute("action", "redelegate") - .add_attribute("from", DEFAULT_VALIDATOR) - .add_attribute("to", "other_validator") - .add_attribute("amount", "100"), - res - ); -} - -#[test] -fn test_redelegate_more_than_max() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - set_delegation(&mut deps.querier.base, 100, "uusd"); - - let msg = ExecuteMsg::Redelegate { - amount: Some(Uint128::new(200)), - from: DEFAULT_VALIDATOR.to_string(), - to: "other_validator".to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Staking(StakingMsg::Redelegate { - src_validator: DEFAULT_VALIDATOR.to_owned(), - dst_validator: "other_validator".to_string(), - amount: coin(100, "uusd") - })) - .add_attribute("action", "redelegate") - .add_attribute("from", DEFAULT_VALIDATOR) - .add_attribute("to", "other_validator") - .add_attribute("amount", "100"), - res - ); -} - -#[test] -fn test_undelegate_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("not_owner", &[]); - - let msg = ExecuteMsg::Undelegate { - amount: None, - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); -} - -#[test] -fn test_undelegate_no_funds() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - let msg = ExecuteMsg::Undelegate { - amount: None, - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::InvalidZeroAmount {}, res.unwrap_err()); -} - -#[test] -fn test_undelegate() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - set_delegation(&mut deps.querier.base, 100, "uusd"); - - let msg = ExecuteMsg::Undelegate { - amount: None, - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Staking(StakingMsg::Undelegate { - validator: DEFAULT_VALIDATOR.to_owned(), - amount: coin(100, "uusd") - })) - .add_attribute("action", "undelegate") - .add_attribute("validator", DEFAULT_VALIDATOR) - .add_attribute("amount", "100"), - res - ); -} - -#[test] -fn test_undelegate_more_than_max() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - set_delegation(&mut deps.querier.base, 100, "uusd"); - - let msg = ExecuteMsg::Undelegate { - amount: Some(Uint128::new(200)), - validator: DEFAULT_VALIDATOR.to_string(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Staking(StakingMsg::Undelegate { - validator: DEFAULT_VALIDATOR.to_owned(), - amount: coin(100, "uusd") - })) - .add_attribute("action", "undelegate") - .add_attribute("validator", DEFAULT_VALIDATOR) - .add_attribute("amount", "100"), - res - ); -} - -#[test] -fn test_withdraw_rewards_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("not_owner", &[]); - - let msg = ExecuteMsg::WithdrawRewards {}; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); -} - -#[test] -fn test_vote_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("not_owner", &[]); - - let msg = ExecuteMsg::Vote { - proposal_id: 1, - vote: VoteOption::Yes, - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); -} - -#[test] -fn test_withdraw_rewards() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - let msg = ExecuteMsg::WithdrawRewards {}; - - deps.querier.base.update_staking( - "ustake", - &[ - sample_validator("validator1"), - sample_validator("validator2"), - sample_validator("validator3"), - ], - &[ - sample_delegation("validator1", coin(100, "ustake")), - sample_delegation("validator2", coin(100, "ustake")), - sample_delegation("validator3", coin(100, "ustake")), - ], - ); - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_attribute("action", "withdraw_rewards") - .add_message(CosmosMsg::Distribution( - DistributionMsg::SetWithdrawAddress { - address: "owner".to_string() - } - )) - .add_message(CosmosMsg::Distribution( - DistributionMsg::WithdrawDelegatorReward { - validator: "validator1".to_string() - } - )) - .add_message(CosmosMsg::Distribution( - DistributionMsg::WithdrawDelegatorReward { - validator: "validator2".to_string() - } - )) - .add_message(CosmosMsg::Distribution( - DistributionMsg::WithdrawDelegatorReward { - validator: "validator3".to_string() - } - )), - res - ); -} - -#[test] -fn test_vote() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()); - - let info = mock_info("owner", &[]); - - let msg = ExecuteMsg::Vote { - proposal_id: 1, - vote: VoteOption::Yes, - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(CosmosMsg::Gov(GovMsg::Vote { - proposal_id: 1, - vote: VoteOption::Yes - })) - .add_attribute("action", "vote") - .add_attribute("proposal_id", "1") - .add_attribute("vote", "Yes"), - res - ); -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml index a0352f2..c3a5421 100644 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml +++ b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-weighted-distribution-splitter" -version = "0.2.1" +version = "2.0.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -20,8 +20,6 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } andromeda-std = { workspace = true } andromeda-finance = { workspace = true } @@ -30,4 +28,4 @@ andromeda-finance = { workspace = true } cw-multi-test = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/andromeda-weighted-distribution-splitter.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/andromeda-weighted-distribution-splitter.json deleted file mode 100644 index 1abc56d..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/andromeda-weighted-distribution-splitter.json +++ /dev/null @@ -1,1622 +0,0 @@ -{ - "contract_name": "andromeda-weighted-distribution-splitter", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned weight.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressWeight" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressWeight": { - "type": "object", - "required": [ - "recipient", - "weight" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressWeight" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Update a specific recipient's weight. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipient_weight" - ], - "properties": { - "update_recipient_weight": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/AddressWeight" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Add a single recipient to the recipient list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "add_recipient" - ], - "properties": { - "add_recipient": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/AddressWeight" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove a single recipient from the recipient list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "remove_recipient" - ], - "properties": { - "remove_recipient": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressWeight": { - "type": "object", - "required": [ - "recipient", - "weight" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets user's allocated weight", - "type": "object", - "required": [ - "get_user_weight" - ], - "properties": { - "get_user_weight": { - "type": "object", - "required": [ - "user" - ], - "properties": { - "user": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "get_splitter_config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressWeight": { - "type": "object", - "required": [ - "recipient", - "weight" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned weight.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressWeight" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "get_user_weight": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetUserWeightResponse", - "description": "In addition to returning a specific recipient's weight, this function also returns the total weight of all recipients. This serves to put the user's weight into perspective.", - "type": "object", - "required": [ - "total_weight", - "weight" - ], - "properties": { - "total_weight": { - "$ref": "#/definitions/Uint128" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/execute.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/execute.json deleted file mode 100644 index afa8271..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/execute.json +++ /dev/null @@ -1,694 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Update the recipients list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipients" - ], - "properties": { - "update_recipients": { - "type": "object", - "required": [ - "recipients" - ], - "properties": { - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/AddressWeight" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Update a specific recipient's weight. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "update_recipient_weight" - ], - "properties": { - "update_recipient_weight": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/AddressWeight" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Add a single recipient to the recipient list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "add_recipient" - ], - "properties": { - "add_recipient": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/AddressWeight" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove a single recipient from the recipient list. Only executable by the contract owner when the contract is not locked.", - "type": "object", - "required": [ - "remove_recipient" - ], - "properties": { - "remove_recipient": { - "type": "object", - "required": [ - "recipient" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Used to lock/unlock the contract allowing the config to be updated.", - "type": "object", - "required": [ - "update_lock" - ], - "properties": { - "update_lock": { - "type": "object", - "required": [ - "lock_time" - ], - "properties": { - "lock_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Divides any attached funds to the message amongst the recipients list.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AddressWeight": { - "type": "object", - "required": [ - "recipient", - "weight" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/instantiate.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/instantiate.json deleted file mode 100644 index ca6a8c8..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/instantiate.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "recipients" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "lock_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned weight.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressWeight" - } - } - }, - "additionalProperties": false, - "definitions": { - "AddressWeight": { - "type": "object", - "required": [ - "recipient", - "weight" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/query.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/query.json deleted file mode 100644 index 8c83a82..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/query.json +++ /dev/null @@ -1,266 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "The current config of the Splitter contract", - "type": "object", - "required": [ - "get_splitter_config" - ], - "properties": { - "get_splitter_config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets user's allocated weight", - "type": "object", - "required": [ - "get_user_weight" - ], - "properties": { - "get_user_weight": { - "type": "object", - "required": [ - "user" - ], - "properties": { - "user": { - "$ref": "#/definitions/Recipient" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_balance.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_splitter_config.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_splitter_config.json deleted file mode 100644 index f4cb5c0..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_splitter_config.json +++ /dev/null @@ -1,162 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetSplitterConfigResponse", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "$ref": "#/definitions/Splitter" - } - }, - "additionalProperties": false, - "definitions": { - "AddressWeight": { - "type": "object", - "required": [ - "recipient", - "weight" - ], - "properties": { - "recipient": { - "$ref": "#/definitions/Recipient" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Splitter": { - "description": "A config struct for a `Splitter` contract.", - "type": "object", - "required": [ - "lock", - "recipients" - ], - "properties": { - "lock": { - "description": "Whether or not the contract is currently locked. This restricts updating any config related fields.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "recipients": { - "description": "The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned weight.", - "type": "array", - "items": { - "$ref": "#/definitions/AddressWeight" - } - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_user_weight.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_user_weight.json deleted file mode 100644 index 8456573..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_get_user_weight.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "GetUserWeightResponse", - "description": "In addition to returning a specific recipient's weight, this function also returns the total weight of all recipients. This serves to put the user's weight into perspective.", - "type": "object", - "required": [ - "total_weight", - "weight" - ], - "properties": { - "total_weight": { - "$ref": "#/definitions/Uint128" - }, - "weight": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_operators.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_owner.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissions.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_type.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_version.json b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs index 0aeea0f..a794e89 100644 --- a/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs +++ b/andromeda-core/contracts/finance/andromeda-weighted-distribution-splitter/src/contract.rs @@ -1,14 +1,14 @@ use crate::state::SPLITTER; use andromeda_finance::weighted_splitter::{ AddressWeight, ExecuteMsg, GetSplitterConfigResponse, GetUserWeightResponse, InstantiateMsg, - MigrateMsg, QueryMsg, Splitter, + QueryMsg, Splitter, }; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, amp::Recipient, - common::{context::ExecuteContext, encode_binary}, - error::{from_semver, ContractError}, + common::{actions::call_action, context::ExecuteContext, encode_binary}, + error::ContractError, }; use cosmwasm_std::{ @@ -17,9 +17,7 @@ use cosmwasm_std::{ }; use cw_utils::{nonpayable, Expiration}; -use semver::Version; -use cw2::{get_contract_version, set_contract_version}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-weighted-distribution-splitter"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -36,7 +34,6 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let _app_contract = ADOContract::default().get_app_contract(deps.storage)?; // Max 100 recipients ensure!( @@ -73,11 +70,11 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "weighted-distribution-splitter".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -103,7 +100,14 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; match msg { ExecuteMsg::UpdateRecipients { recipients } => execute_update_recipients(ctx, recipients), ExecuteMsg::UpdateRecipientWeight { recipient } => { @@ -230,7 +234,7 @@ fn execute_send(ctx: ExecuteContext) -> Result { ensure!( !&info.funds.is_empty(), ContractError::InvalidFunds { - msg: "ensure! at least one coin to be sent".to_string(), + msg: "At least one coin should be sent".to_string(), } ); // Can't send more than 5 types of coins @@ -247,7 +251,7 @@ fn execute_send(ctx: ExecuteContext) -> Result { // Calculate the total weight of all recipients for recipient_addr in &splitter.recipients { let recipient_weight = recipient_addr.weight; - total_weight += recipient_weight; + total_weight = total_weight.checked_add(recipient_weight)?; } // Each recipient recieves the funds * (the recipient's weight / total weight of all recipients) @@ -258,7 +262,7 @@ fn execute_send(ctx: ExecuteContext) -> Result { for (i, coin) in info.funds.iter().enumerate() { let mut recip_coin: Coin = coin.clone(); recip_coin.amount = coin.amount.multiply_ratio(recipient_weight, total_weight); - remainder_funds[i].amount -= recip_coin.amount; + remainder_funds[i].amount = remainder_funds[i].amount.checked_sub(recip_coin.amount)?; vec_coin.push(recip_coin); } // ADO receivers must use AndromedaMsg::Receive to execute their functionality @@ -447,36 +451,7 @@ fn execute_update_lock(ctx: ExecuteContext, lock_time: u64) -> Result Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[entry_point] @@ -498,7 +473,7 @@ fn query_user_weight(deps: Deps, user: Recipient) -> Result = vec![Module { - name: Some("address_list".to_string()), - address: AndrAddr::from_string(MOCK_ADDRESS_LIST_CONTRACT.to_string()), - is_mutable: false, - }]; - - let info = mock_info("app_contract", &[]); + let info = mock_info("owner", &[]); let msg = InstantiateMsg { - modules: Some(modules), recipients: vec![ AddressWeight { recipient: Recipient::new(MOCK_RECIPIENT1, None), @@ -81,7 +70,7 @@ fn test_update_app_contract() { // let info = mock_info("app_contract", &[]); // let msg = InstantiateMsg { -// modules: Some(modules), +// // recipients: vec![AddressWeight { // recipient: Recipient::new(MOCK_RECIPIENT1, None), // weight: Uint128::new(100), @@ -116,7 +105,7 @@ fn test_instantiate() { recipient: Recipient::from_string(MOCK_RECIPIENT1.to_string()), weight: Uint128::new(1), }], - modules: None, + lock_time: None, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, @@ -144,17 +133,17 @@ fn test_execute_update_lock() { SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); let msg = ExecuteMsg::UpdateLock { lock_time }; - let deps_mut = deps.as_mut(); ADOContract::default() .instantiate( - deps_mut.storage, + &mut deps.storage, mock_env(), - deps_mut.api, + &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -197,17 +186,17 @@ fn test_execute_update_lock_too_short() { SPLITTER.save(deps.as_mut().storage, &splitter).unwrap(); let msg = ExecuteMsg::UpdateLock { lock_time }; - let deps_mut = deps.as_mut(); ADOContract::default() .instantiate( - deps_mut.storage, + &mut deps.storage, mock_env(), - deps_mut.api, + &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -244,11 +233,12 @@ fn test_execute_update_lock_too_long() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -285,11 +275,12 @@ fn test_execute_update_lock_already_locked() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -326,11 +317,12 @@ fn test_execute_update_lock_unauthorized() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -370,11 +362,12 @@ fn test_execute_remove_recipient() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -461,11 +454,12 @@ fn test_execute_remove_recipient_not_on_list() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -523,11 +517,12 @@ fn test_execute_remove_recipient_contract_locked() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -593,11 +588,12 @@ fn test_execute_remove_recipient_unauthorized() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -639,11 +635,12 @@ fn test_update_recipient_weight() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -734,11 +731,12 @@ fn test_update_recipient_weight_locked_contract() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -807,11 +805,12 @@ fn test_update_recipient_weight_user_not_found() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -878,11 +877,12 @@ fn test_update_recipient_weight_invalid_weight() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -945,11 +945,12 @@ fn test_execute_add_recipient() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1049,11 +1050,12 @@ fn test_execute_add_recipient_duplicate_recipient() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1126,11 +1128,12 @@ fn test_execute_add_recipient_invalid_weight() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1195,11 +1198,12 @@ fn test_execute_add_recipient_locked_contract() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1247,11 +1251,12 @@ fn test_execute_add_recipient_unauthorized() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1282,11 +1287,12 @@ fn test_execute_update_recipients() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1352,11 +1358,12 @@ fn test_execute_update_recipients_invalid_weight() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1406,11 +1413,12 @@ fn test_execute_update_recipients_contract_locked() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1458,11 +1466,12 @@ fn test_execute_update_recipients_unauthorized() { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, mock_info(owner, &[]), BaseInstantiateMsg { ado_type: "splitter".to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -1517,7 +1526,7 @@ fn test_execute_update_recipients_unauthorized() { // BaseInstantiateMsg { // ado_type: "splitter".to_string(), // ado_version: CONTRACT_VERSION.to_string(), -// operators: None, +// // kernel_address: MOCK_KERNEL_CONTRACT.to_string(), // owner: None, // }, diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/Cargo.toml b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/Cargo.toml index b971b3c..ba8f915 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/Cargo.toml +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-cw20-exchange" -version = "0.2.2" +version = "2.0.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -20,10 +20,8 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } cw20 = { workspace = true } cw-asset = { workspace = true } -semver = { workspace = true } andromeda-std = { workspace = true } andromeda-fungible-tokens = { workspace = true } @@ -32,4 +30,4 @@ andromeda-fungible-tokens = { workspace = true } cw-multi-test = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/README.md b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/README.md new file mode 100644 index 0000000..5066b14 --- /dev/null +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/README.md @@ -0,0 +1,10 @@ +# Overview + +The CW20 Exchange ADO is used to sell CW20 tokens for other assets. The CW20 token to be sold is specified at instantiation, and then sales can be started on the token by the contract owner by sending them to this ADO. Each sale has an "asset" to purchase the tokens with. This asset can be: + +- CW20 +- Native + +Users can then purchase the CW20 token being sold by sending the required asset to the contract. + +[CW20 Exchange Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/cw20-exchange) diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/examples/schema.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/examples/schema.rs index 13e6071..941dc3e 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/examples/schema.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/examples/schema.rs @@ -1,11 +1,16 @@ -use andromeda_fungible_tokens::cw20_exchange::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use cosmwasm_schema::write_api; +use std::env::current_dir; + +use cosmwasm_schema::{export_schema_with_title, schema_for, write_api}; + +use andromeda_fungible_tokens::cw20_exchange::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg}; fn main() { + let mut out_dir = current_dir().unwrap(); + out_dir.push("schema"); write_api! { instantiate: InstantiateMsg, query: QueryMsg, execute: ExecuteMsg, - - } + }; + export_schema_with_title(&schema_for!(Cw20HookMsg), &out_dir, "cw20receive"); } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/andromeda-cw20-exchange.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/andromeda-cw20-exchange.json deleted file mode 100644 index 299a63c..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/andromeda-cw20-exchange.json +++ /dev/null @@ -1,1504 +0,0 @@ -{ - "contract_name": "andromeda-cw20-exchange", - "contract_version": "0.2.2", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "token_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "description": "Address of the CW20 token to be sold", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Cancels an ongoing sale", - "type": "object", - "required": [ - "cancel_sale" - ], - "properties": { - "cancel_sale": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "asset": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Purchases tokens with native funds", - "type": "object", - "required": [ - "purchase" - ], - "properties": { - "purchase": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Receive for CW20 tokens, used for purchasing and starting sales", - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Sale info for a given asset", - "type": "object", - "required": [ - "sale" - ], - "properties": { - "sale": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "asset": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The address of the token being purchased", - "type": "object", - "required": [ - "token_address" - ], - "properties": { - "token_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "sale_assets" - ], - "properties": { - "sale_assets": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "sale": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleResponse", - "type": "object", - "properties": { - "sale": { - "description": "The sale data if it exists", - "anyOf": [ - { - "$ref": "#/definitions/Sale" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Sale": { - "description": "Struct used to define a token sale. The asset used for the sale is defined as the key for the storage map.", - "type": "object", - "required": [ - "amount", - "end_time", - "exchange_rate", - "recipient", - "start_amount", - "start_time" - ], - "properties": { - "amount": { - "description": "The amount for sale at the given rate", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "end_time": { - "description": "The time when the sale ends", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "exchange_rate": { - "description": "The rate at which to exchange tokens (amount of exchanged asset to purchase sale asset)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "recipient": { - "description": "The recipient of the sale proceeds", - "type": "string" - }, - "start_amount": { - "description": "The amount for sale at the given rate at the start of the sale", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "start_time": { - "description": "The time when the sale starts", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "sale_assets": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleAssetsResponse", - "type": "object", - "required": [ - "assets" - ], - "properties": { - "assets": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "token_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenAddressResponse", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The address of the token being sold", - "type": "string" - } - }, - "additionalProperties": false - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/execute.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/execute.json deleted file mode 100644 index f528b1b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/execute.json +++ /dev/null @@ -1,627 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Cancels an ongoing sale", - "type": "object", - "required": [ - "cancel_sale" - ], - "properties": { - "cancel_sale": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "asset": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Purchases tokens with native funds", - "type": "object", - "required": [ - "purchase" - ], - "properties": { - "purchase": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Receive for CW20 tokens, used for purchasing and starting sales", - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/instantiate.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/instantiate.json deleted file mode 100644 index b76ad1b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/instantiate.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "token_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "description": "Address of the CW20 token to be sold", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/query.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/query.json deleted file mode 100644 index bd7bfc3..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/query.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Sale info for a given asset", - "type": "object", - "required": [ - "sale" - ], - "properties": { - "sale": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "asset": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The address of the token being purchased", - "type": "object", - "required": [ - "token_address" - ], - "properties": { - "token_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "sale_assets" - ], - "properties": { - "sale_assets": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_balance.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_operators.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_owner.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissions.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale.json deleted file mode 100644 index c164467..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleResponse", - "type": "object", - "properties": { - "sale": { - "description": "The sale data if it exists", - "anyOf": [ - { - "$ref": "#/definitions/Sale" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Sale": { - "description": "Struct used to define a token sale. The asset used for the sale is defined as the key for the storage map.", - "type": "object", - "required": [ - "amount", - "end_time", - "exchange_rate", - "recipient", - "start_amount", - "start_time" - ], - "properties": { - "amount": { - "description": "The amount for sale at the given rate", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "end_time": { - "description": "The time when the sale ends", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "exchange_rate": { - "description": "The rate at which to exchange tokens (amount of exchanged asset to purchase sale asset)", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "recipient": { - "description": "The recipient of the sale proceeds", - "type": "string" - }, - "start_amount": { - "description": "The amount for sale at the given rate at the start of the sale", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "start_time": { - "description": "The time when the sale starts", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale_assets.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale_assets.json deleted file mode 100644 index 0569db8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_sale_assets.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleAssetsResponse", - "type": "object", - "required": [ - "assets" - ], - "properties": { - "assets": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_token_address.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_token_address.json deleted file mode 100644 index 2050453..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_token_address.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenAddressResponse", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "description": "The address of the token being sold", - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_type.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_version.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs index e00fbdb..0298ed5 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/contract.rs @@ -1,27 +1,26 @@ use andromeda_fungible_tokens::cw20_exchange::{ - Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, Sale, SaleAssetsResponse, - SaleResponse, TokenAddressResponse, + Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, Sale, SaleAssetsResponse, SaleResponse, + TokenAddressResponse, }; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, common::{ + actions::call_action, context::ExecuteContext, - expiration::{expiration_from_milliseconds, MILLISECONDS_TO_NANOSECONDS_RATIO}, + expiration::{expiration_from_milliseconds, get_and_validate_start_time, Expiry}, + Milliseconds, MillisecondsDuration, }, - error::{from_semver, ContractError}, + error::ContractError, }; use cosmwasm_std::{ attr, coin, ensure, entry_point, from_json, to_json_binary, wasm_execute, BankMsg, Binary, - BlockInfo, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, SubMsg, - Uint128, + CosmosMsg, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, SubMsg, Uint128, }; -use cw2::{get_contract_version, set_contract_version}; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use cw_asset::AssetInfo; use cw_storage_plus::Bound; use cw_utils::{nonpayable, one_coin, Expiration}; -use semver::Version; use crate::state::{SALE, TOKEN_ADDRESS}; @@ -43,7 +42,6 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; TOKEN_ADDRESS.save(deps.storage, &msg.token_address)?; let contract = ADOContract::default(); @@ -51,11 +49,11 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "cw20-exchange".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -92,13 +90,24 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - match msg { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { ExecuteMsg::CancelSale { asset } => execute_cancel_sale(ctx, asset), ExecuteMsg::Purchase { recipient } => execute_purchase_native(ctx, recipient), ExecuteMsg::Receive(cw20_msg) => execute_receive(ctx, cw20_msg), _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } pub fn execute_receive( @@ -156,15 +165,23 @@ pub fn execute_start_sale( sender: String, // The recipient of the sale proceeds recipient: Option, - start_time: Option, - duration: Option, + start_time: Option, + duration: Option, ) -> Result { - let ExecuteContext { deps, info, .. } = ctx; + let ExecuteContext { + deps, env, info, .. + } = ctx; let token_addr = TOKEN_ADDRESS .load(deps.storage)? .get_raw_address(&deps.as_ref())?; + ensure!( + asset != AssetInfo::Cw20(token_addr.clone()), + ContractError::InvalidAsset { + asset: asset.to_string() + } + ); ensure!( !exchange_rate.is_zero(), ContractError::InvalidZeroAmount {} @@ -181,28 +198,18 @@ pub fn execute_start_sale( } ); - let current_time = ctx.env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; - - let start_expiration = if let Some(start_time) = start_time { - expiration_from_milliseconds(start_time)? - } else { - // Set as current time + 1 so that it isn't expired from the very start - expiration_from_milliseconds(current_time + 1)? - }; - - // Validate start time - let block_time = block_to_expiration(&ctx.env.block, start_expiration).unwrap(); - ensure!( - start_expiration.gt(&block_time), - ContractError::StartTimeInThePast { - current_time, - current_block: ctx.env.block.height, - } - ); + // If start time wasn't provided, it will be set as the current_time + let (start_expiration, _current_time) = get_and_validate_start_time(&env, start_time.clone())?; let end_expiration = if let Some(duration) = duration { - // If there's no start time, consider it as now - expiration_from_milliseconds(start_time.unwrap_or(current_time) + duration)? + ensure!(!duration.is_zero(), ContractError::InvalidExpiration {}); + expiration_from_milliseconds( + start_time + // If start time isn't provided, it is set one second in advance from the current time + .unwrap_or(Expiry::FromNow(Milliseconds::from_seconds(1))) + .get_time(&env.block) + .plus_milliseconds(duration), + )? } else { Expiration::Never {} }; @@ -331,7 +338,7 @@ pub fn execute_purchase( // Transfer exchanged asset to recipient resp = resp.add_submessage(generate_transfer_message( asset_sent.clone(), - amount_sent, + amount_sent - remainder, sale.recipient.clone(), RECIPIENT_REPLY_ID, )?); @@ -342,7 +349,7 @@ pub fn execute_purchase( attr("recipient", recipient), attr("amount", purchased), attr("purchase_asset", asset_sent.to_string()), - attr("purchase_asset_amount_send", amount_sent), + attr("purchase_asset_amount_send", amount_sent - remainder), attr("recipient", sale.recipient), ])) } @@ -414,46 +421,9 @@ pub fn execute_cancel_sale( ])) } -fn block_to_expiration(block: &BlockInfo, model: Expiration) -> Option { - match model { - Expiration::AtTime(_) => Some(Expiration::AtTime(block.time)), - Expiration::AtHeight(_) => Some(Expiration::AtHeight(block.height)), - Expiration::Never {} => None, - } -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/mock_querier.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/mock_querier.rs index d2060e4..8af252c 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/mock_querier.rs @@ -6,7 +6,7 @@ use cosmwasm_std::testing::{ }; use cosmwasm_std::{ from_json, to_json_binary, Coin, ContractResult, Empty, OwnedDeps, Querier, QuerierResult, - QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, + QuerierWrapper, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, }; use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg}; use std::collections::HashMap; @@ -28,11 +28,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "cw20-staking".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/tests.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/tests.rs index 10926c3..ee45d7b 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/tests.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-exchange/src/testing/tests.rs @@ -3,13 +3,18 @@ use andromeda_fungible_tokens::cw20_exchange::{ TokenAddressResponse, }; use andromeda_std::{ - amp::AndrAddr, common::expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, error::ContractError, + amp::AndrAddr, + common::{ + expiration::{Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}, + Milliseconds, + }, + error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT, }; use cosmwasm_std::{ attr, coin, coins, from_json, testing::{mock_env, mock_info}, - to_json_binary, wasm_execute, Addr, BankMsg, CosmosMsg, DepsMut, Empty, Response, SubMsg, + to_json_binary, wasm_execute, Addr, BankMsg, Coin, CosmosMsg, DepsMut, Empty, Response, SubMsg, Timestamp, Uint128, }; use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; @@ -29,7 +34,7 @@ fn init(deps: DepsMut) -> Result { let msg = InstantiateMsg { kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, + token_address: AndrAddr::from_string("cw20"), }; @@ -162,8 +167,8 @@ pub fn test_start_sale() { exchange_rate, recipient: None, // A start time ahead of the current time - start_time: Some(current_time + 10), - duration: Some(1), + start_time: Some(Expiry::AtTime(Milliseconds(current_time + 10))), + duration: Some(Milliseconds(1)), }; let receive_msg = Cw20ReceiveMsg { sender: owner.to_string(), @@ -253,7 +258,7 @@ pub fn test_start_sale_invalid_start_time() { asset: exchange_asset, exchange_rate, recipient: None, - start_time: Some(1), + start_time: Some(Expiry::AtTime(Milliseconds(1))), duration: None, }; let receive_msg = Cw20ReceiveMsg { @@ -892,7 +897,7 @@ pub fn test_purchase_native() { init(deps.as_mut()).unwrap(); - let exchange_rate = Uint128::from(10u128); + let exchange_rate = Uint128::from(9u128); let sale_amount = Uint128::from(100u128); SALE.save( deps.as_mut().storage, @@ -909,7 +914,6 @@ pub fn test_purchase_native() { ) .unwrap(); - // Purchase Tokens // Purchase Tokens let purchase_amount = coins(100, "test"); let msg = ExecuteMsg::Purchase { recipient: None }; @@ -917,21 +921,30 @@ pub fn test_purchase_native() { let res = execute(deps.as_mut(), env, info, msg).unwrap(); + // Check refund + let msg = res.messages[0].clone(); + let expected_wasm: CosmosMsg = CosmosMsg::Bank(BankMsg::Send { + to_address: purchaser.to_string(), + amount: vec![Coin::new(1, "test")], + }); + let expected = SubMsg::reply_on_error(expected_wasm, 1); + assert_eq!(msg, expected); + // Check transfer - let msg = res.messages.first().unwrap(); + let msg = res.messages[1].clone(); let expected_wasm: CosmosMsg = CosmosMsg::Wasm( wasm_execute( MOCK_TOKEN_ADDRESS.to_string(), &Cw20ExecuteMsg::Transfer { recipient: purchaser.to_string(), - amount: Uint128::from(10u128), + amount: Uint128::from(11u128), }, vec![], ) .unwrap(), ); let expected = SubMsg::reply_on_error(expected_wasm, 2); - assert_eq!(msg, &expected); + assert_eq!(msg, expected); // Check sale amount updated let sale = SALE @@ -940,14 +953,14 @@ pub fn test_purchase_native() { assert_eq!( sale.amount, - sale_amount.checked_sub(Uint128::from(10u128)).unwrap() + sale_amount.checked_sub(Uint128::from(11u128)).unwrap() ); // Check recipient received funds - let msg = &res.messages[1]; + let msg = &res.messages[2]; let expected_wasm: CosmosMsg = CosmosMsg::Bank(BankMsg::Send { to_address: owner.to_string(), - amount: purchase_amount.to_vec(), + amount: vec![Coin::new(99, "test")], }); let expected = SubMsg::reply_on_error(expected_wasm, 3); @@ -1306,3 +1319,33 @@ fn test_query_sale_assets() { assert_eq!(resp.assets[0], "cw20:testaddress"); assert_eq!(resp.assets[1], "native:test"); } + +#[test] +fn test_start_sale_same_asset() { + let mut deps = mock_dependencies_custom(&[]); + let token_info = mock_info("cw20", &[]); + + init(deps.as_mut()).unwrap(); + + let cw20_msg = Cw20ReceiveMsg { + sender: "owner".to_string(), + msg: to_json_binary(&Cw20HookMsg::StartSale { + asset: AssetInfo::Cw20(Addr::unchecked("cw20")), + exchange_rate: Uint128::from(10u128), + recipient: None, + start_time: None, + duration: None, + }) + .unwrap(), + amount: Uint128::from(100u128), + }; + let msg = ExecuteMsg::Receive(cw20_msg); + + let err = execute(deps.as_mut(), mock_env(), token_info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidAsset { + asset: AssetInfo::Cw20(Addr::unchecked("cw20")).to_string() + } + ); +} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml index 6fccba8..4218ed6 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-cw20-staking" -version = "0.2.1" +version = "2.0.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -20,17 +20,16 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } cw20 = { workspace = true } cw20-base = { workspace = true } cw-asset = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true } andromeda-fungible-tokens = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/README.md b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/README.md new file mode 100644 index 0000000..ee7960d --- /dev/null +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/README.md @@ -0,0 +1,5 @@ +# Overview + +This CW20 Staking ADO allows users to stake a specified CW20 token and to receive rewards in proportion to their share. The reward token does not need to be the token they stake with. + +[CW20 Staking Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/cw20-staking) diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/andromeda-cw20-staking.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/andromeda-cw20-staking.json deleted file mode 100644 index aa85129..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/andromeda-cw20-staking.json +++ /dev/null @@ -1,1907 +0,0 @@ -{ - "contract_name": "andromeda-cw20-staking", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "staking_token" - ], - "properties": { - "additional_rewards": { - "description": "Any rewards in addition to the staking token. This list cannot include the staking token.", - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/RewardTokenUnchecked" - } - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "staking_token": { - "description": "The cw20 token that can be staked.", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AllocationConfig": { - "type": "object", - "required": [ - "cycle_duration", - "cycle_rewards", - "init_timestamp", - "till_timestamp" - ], - "properties": { - "cycle_duration": { - "description": "Cycle duration in timestamps", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "cycle_rewards": { - "description": "Rewards distributed during the 1st cycle.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "init_timestamp": { - "description": "Timestamp from which Rewards will start getting accrued against the staked LP tokens", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "reward_increase": { - "description": "Percent increase in Rewards per cycle", - "anyOf": [ - { - "$ref": "#/definitions/Decimal" - }, - { - "type": "null" - } - ] - }, - "till_timestamp": { - "description": "Timestamp till which Rewards will be accrued. No staking rewards are accrued beyond this timestamp", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_String": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "RewardTokenUnchecked": { - "type": "object", - "required": [ - "asset_info" - ], - "properties": { - "allocation_config": { - "anyOf": [ - { - "$ref": "#/definitions/AllocationConfig" - }, - { - "type": "null" - } - ] - }, - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_String" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Add `reward_token` as another reward token. Owner only.", - "type": "object", - "required": [ - "add_reward_token" - ], - "properties": { - "add_reward_token": { - "type": "object", - "required": [ - "reward_token" - ], - "properties": { - "reward_token": { - "$ref": "#/definitions/RewardTokenUnchecked" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Unstakes the specified amount of assets, or all if not specified. The user's pending rewards and indexes are updated for each additional reward token.", - "type": "object", - "required": [ - "unstake_tokens" - ], - "properties": { - "unstake_tokens": { - "type": "object", - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claims any outstanding rewards from the addtional reward tokens.", - "type": "object", - "required": [ - "claim_rewards" - ], - "properties": { - "claim_rewards": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Updates the global reward index for the specified reward tokens or all of the specified ones if None. Funds may be sent along with this.", - "type": "object", - "required": [ - "update_global_indexes" - ], - "properties": { - "update_global_indexes": { - "type": "object", - "properties": { - "asset_infos": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/AssetInfoBase_for_String" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AllocationConfig": { - "type": "object", - "required": [ - "cycle_duration", - "cycle_rewards", - "init_timestamp", - "till_timestamp" - ], - "properties": { - "cycle_duration": { - "description": "Cycle duration in timestamps", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "cycle_rewards": { - "description": "Rewards distributed during the 1st cycle.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "init_timestamp": { - "description": "Timestamp from which Rewards will start getting accrued against the staked LP tokens", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "reward_increase": { - "description": "Percent increase in Rewards per cycle", - "anyOf": [ - { - "$ref": "#/definitions/Decimal" - }, - { - "type": "null" - } - ] - }, - "till_timestamp": { - "description": "Timestamp till which Rewards will be accrued. No staking rewards are accrued beyond this timestamp", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_String": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "RewardTokenUnchecked": { - "type": "object", - "required": [ - "asset_info" - ], - "properties": { - "allocation_config": { - "anyOf": [ - { - "$ref": "#/definitions/AllocationConfig" - }, - { - "type": "null" - } - ] - }, - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_String" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the config of the contract.", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the state of the contract.", - "type": "object", - "required": [ - "state" - ], - "properties": { - "state": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Returns a `StakerResponse` for the given staker. The pending rewards are updated to the present index.", - "type": "object", - "required": [ - "staker" - ], - "properties": { - "staker": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Returns a `Vec` for range of stakers. The pending rewards are updated to the present index for each staker.", - "type": "object", - "required": [ - "stakers" - ], - "properties": { - "stakers": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the current timestamp.", - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "type": "object", - "required": [ - "number_of_reward_tokens", - "staking_token" - ], - "properties": { - "number_of_reward_tokens": { - "description": "The current number of reward tokens, cannot exceed `MAX_REWARD_TOKENS`.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "staking_token": { - "description": "The token accepted for staking.", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "staker": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StakerResponse", - "type": "object", - "required": [ - "address", - "balance", - "pending_rewards", - "share" - ], - "properties": { - "address": { - "description": "Address of the staker.", - "type": "string" - }, - "balance": { - "description": "The staker's balance of tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "pending_rewards": { - "description": "The staker's pending rewards represented as [(token_1, amount_1), ..., (token_n, amount_n)]", - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "share": { - "description": "The staker's share of the tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "stakers": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_StakerResponse", - "type": "array", - "items": { - "$ref": "#/definitions/StakerResponse" - }, - "definitions": { - "StakerResponse": { - "type": "object", - "required": [ - "address", - "balance", - "pending_rewards", - "share" - ], - "properties": { - "address": { - "description": "Address of the staker.", - "type": "string" - }, - "balance": { - "description": "The staker's balance of tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "pending_rewards": { - "description": "The staker's pending rewards represented as [(token_1, amount_1), ..., (token_n, amount_n)]", - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "share": { - "description": "The staker's share of the tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "state": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "State", - "type": "object", - "required": [ - "total_share" - ], - "properties": { - "total_share": { - "description": "The total share of the staking token in the contract.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "timestamp": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "uint64", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/execute.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/execute.json deleted file mode 100644 index 4e1c76b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/execute.json +++ /dev/null @@ -1,830 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Add `reward_token` as another reward token. Owner only.", - "type": "object", - "required": [ - "add_reward_token" - ], - "properties": { - "add_reward_token": { - "type": "object", - "required": [ - "reward_token" - ], - "properties": { - "reward_token": { - "$ref": "#/definitions/RewardTokenUnchecked" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Unstakes the specified amount of assets, or all if not specified. The user's pending rewards and indexes are updated for each additional reward token.", - "type": "object", - "required": [ - "unstake_tokens" - ], - "properties": { - "unstake_tokens": { - "type": "object", - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claims any outstanding rewards from the addtional reward tokens.", - "type": "object", - "required": [ - "claim_rewards" - ], - "properties": { - "claim_rewards": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Updates the global reward index for the specified reward tokens or all of the specified ones if None. Funds may be sent along with this.", - "type": "object", - "required": [ - "update_global_indexes" - ], - "properties": { - "update_global_indexes": { - "type": "object", - "properties": { - "asset_infos": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/AssetInfoBase_for_String" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AllocationConfig": { - "type": "object", - "required": [ - "cycle_duration", - "cycle_rewards", - "init_timestamp", - "till_timestamp" - ], - "properties": { - "cycle_duration": { - "description": "Cycle duration in timestamps", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "cycle_rewards": { - "description": "Rewards distributed during the 1st cycle.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "init_timestamp": { - "description": "Timestamp from which Rewards will start getting accrued against the staked LP tokens", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "reward_increase": { - "description": "Percent increase in Rewards per cycle", - "anyOf": [ - { - "$ref": "#/definitions/Decimal" - }, - { - "type": "null" - } - ] - }, - "till_timestamp": { - "description": "Timestamp till which Rewards will be accrued. No staking rewards are accrued beyond this timestamp", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_String": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "RewardTokenUnchecked": { - "type": "object", - "required": [ - "asset_info" - ], - "properties": { - "allocation_config": { - "anyOf": [ - { - "$ref": "#/definitions/AllocationConfig" - }, - { - "type": "null" - } - ] - }, - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_String" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/instantiate.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/instantiate.json deleted file mode 100644 index edffb89..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/instantiate.json +++ /dev/null @@ -1,185 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "staking_token" - ], - "properties": { - "additional_rewards": { - "description": "Any rewards in addition to the staking token. This list cannot include the staking token.", - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/RewardTokenUnchecked" - } - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "staking_token": { - "description": "The cw20 token that can be staked.", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AllocationConfig": { - "type": "object", - "required": [ - "cycle_duration", - "cycle_rewards", - "init_timestamp", - "till_timestamp" - ], - "properties": { - "cycle_duration": { - "description": "Cycle duration in timestamps", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "cycle_rewards": { - "description": "Rewards distributed during the 1st cycle.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "init_timestamp": { - "description": "Timestamp from which Rewards will start getting accrued against the staked LP tokens", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "reward_increase": { - "description": "Percent increase in Rewards per cycle", - "anyOf": [ - { - "$ref": "#/definitions/Decimal" - }, - { - "type": "null" - } - ] - }, - "till_timestamp": { - "description": "Timestamp till which Rewards will be accrued. No staking rewards are accrued beyond this timestamp", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_String": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "RewardTokenUnchecked": { - "type": "object", - "required": [ - "asset_info" - ], - "properties": { - "allocation_config": { - "anyOf": [ - { - "$ref": "#/definitions/AllocationConfig" - }, - { - "type": "null" - } - ] - }, - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_String" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/query.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/query.json deleted file mode 100644 index bff0adb..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/query.json +++ /dev/null @@ -1,325 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the config of the contract.", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the state of the contract.", - "type": "object", - "required": [ - "state" - ], - "properties": { - "state": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Returns a `StakerResponse` for the given staker. The pending rewards are updated to the present index.", - "type": "object", - "required": [ - "staker" - ], - "properties": { - "staker": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Returns a `Vec` for range of stakers. The pending rewards are updated to the present index for each staker.", - "type": "object", - "required": [ - "stakers" - ], - "properties": { - "stakers": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Queries the current timestamp.", - "type": "object", - "required": [ - "timestamp" - ], - "properties": { - "timestamp": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_balance.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_config.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_config.json deleted file mode 100644 index cb78d5c..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_config.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "type": "object", - "required": [ - "number_of_reward_tokens", - "staking_token" - ], - "properties": { - "number_of_reward_tokens": { - "description": "The current number of reward tokens, cannot exceed `MAX_REWARD_TOKENS`.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "staking_token": { - "description": "The token accepted for staking.", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_operators.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_owner.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissions.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_staker.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_staker.json deleted file mode 100644 index 54a509e..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_staker.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StakerResponse", - "type": "object", - "required": [ - "address", - "balance", - "pending_rewards", - "share" - ], - "properties": { - "address": { - "description": "Address of the staker.", - "type": "string" - }, - "balance": { - "description": "The staker's balance of tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "pending_rewards": { - "description": "The staker's pending rewards represented as [(token_1, amount_1), ..., (token_n, amount_n)]", - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "share": { - "description": "The staker's share of the tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_stakers.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_stakers.json deleted file mode 100644 index 5c60fd4..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_stakers.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_StakerResponse", - "type": "array", - "items": { - "$ref": "#/definitions/StakerResponse" - }, - "definitions": { - "StakerResponse": { - "type": "object", - "required": [ - "address", - "balance", - "pending_rewards", - "share" - ], - "properties": { - "address": { - "description": "Address of the staker.", - "type": "string" - }, - "balance": { - "description": "The staker's balance of tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "pending_rewards": { - "description": "The staker's pending rewards represented as [(token_1, amount_1), ..., (token_n, amount_n)]", - "type": "array", - "items": { - "type": "array", - "items": [ - { - "type": "string" - }, - { - "$ref": "#/definitions/Uint128" - } - ], - "maxItems": 2, - "minItems": 2 - } - }, - "share": { - "description": "The staker's share of the tokens.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_state.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_state.json deleted file mode 100644 index fc9e677..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_state.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "State", - "type": "object", - "required": [ - "total_share" - ], - "properties": { - "total_share": { - "description": "The total share of the staking token in the contract.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_timestamp.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_timestamp.json deleted file mode 100644 index 7b729a7..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_timestamp.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "uint64", - "type": "integer", - "format": "uint64", - "minimum": 0.0 -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_type.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_version.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/allocated_rewards.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/allocated_rewards.rs index 007b63c..8018335 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/allocated_rewards.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/allocated_rewards.rs @@ -1,62 +1,87 @@ use andromeda_fungible_tokens::cw20_staking::{ AllocationConfig, AllocationState, RewardToken, RewardType, }; -use andromeda_std::error::ContractError; +use andromeda_std::{ + common::{Milliseconds, MillisecondsDuration, MillisecondsExpiration}, + error::ContractError, +}; -use cosmwasm_std::{Decimal, Decimal256, Uint128}; +use cosmwasm_std::{BlockInfo, Decimal, Decimal256, Uint128}; /// This was taken with few changes from the MARS staking contract /// https://github.com/mars-protocol/mars-periphery/blob/537ab8046a4670d0e80de6cbf6e6e0492c586fb2/contracts/lp_staking/src/contract.rs#L420 pub(crate) fn update_allocated_index( + block_info: &BlockInfo, total_share: Uint128, reward_token: &mut RewardToken, config: AllocationConfig, mut state: AllocationState, - cur_timestamp: u64, + cur_timestamp: MillisecondsExpiration, + init_timestamp: MillisecondsExpiration, ) -> Result<(), ContractError> { // If the reward distribution period is over - if state.last_distributed == config.till_timestamp { + if state.last_distributed == config.till_timestamp.get_time(block_info) + || !reward_token.is_active + { return Ok(()); } let mut last_distribution_cycle = state.current_cycle; state.current_cycle = calculate_cycles_elapsed( cur_timestamp, - config.init_timestamp, + init_timestamp, config.cycle_duration, - config.till_timestamp, + config.till_timestamp.get_time(block_info), ); let mut rewards_to_distribute = Uint128::zero(); let mut last_distribution_next_timestamp: u64; // 0 as u64; while state.current_cycle >= last_distribution_cycle { last_distribution_next_timestamp = std::cmp::min( - config.till_timestamp, + config.till_timestamp.get_time(block_info).milliseconds(), calculate_init_timestamp_for_cycle( - config.init_timestamp, + init_timestamp, last_distribution_cycle + 1, config.cycle_duration, - ), + ) + .milliseconds(), ); rewards_to_distribute += rewards_distributed_for_cycle( - Decimal::from_ratio(state.current_cycle_rewards, config.cycle_duration), - std::cmp::max(state.last_distributed, config.init_timestamp), - std::cmp::min(cur_timestamp, last_distribution_next_timestamp), + Decimal::from_ratio( + state.current_cycle_rewards, + config.cycle_duration.milliseconds(), + ), + std::cmp::max( + state.last_distributed.milliseconds(), + init_timestamp.milliseconds(), + ), + std::cmp::min( + cur_timestamp.milliseconds(), + last_distribution_next_timestamp, + ), ); state.current_cycle_rewards = calculate_cycle_rewards( state.current_cycle_rewards, config.reward_increase.unwrap_or_else(Decimal::zero), state.current_cycle == last_distribution_cycle, ); - state.last_distributed = std::cmp::min(cur_timestamp, last_distribution_next_timestamp); - last_distribution_cycle += 1; + state.last_distributed = Milliseconds(std::cmp::min( + cur_timestamp.milliseconds(), + last_distribution_next_timestamp, + )); + + let new_cycle = last_distribution_cycle.checked_add(1); + match new_cycle { + Some(new_cycle) => last_distribution_cycle = new_cycle, + None => return Err(ContractError::Overflow {}), + } } - if state.last_distributed == config.till_timestamp { + if state.last_distributed == config.till_timestamp.get_time(block_info) { state.current_cycle_rewards = Uint128::zero(); } - if total_share == Uint128::zero() || config.init_timestamp > cur_timestamp { + if total_share == Uint128::zero() || init_timestamp > cur_timestamp { return Ok(()); } @@ -64,32 +89,39 @@ pub(crate) fn update_allocated_index( reward_token.reward_type = RewardType::Allocated { allocation_config: config, allocation_state: state, + init_timestamp, }; Ok(()) } fn calculate_cycles_elapsed( - current_timestamp: u64, - config_init_timestamp: u64, - cycle_duration: u64, - config_till_timestamp: u64, + current_timestamp: MillisecondsExpiration, + config_init_timestamp: MillisecondsExpiration, + cycle_duration: MillisecondsDuration, + config_till_timestamp: MillisecondsExpiration, ) -> u64 { if config_init_timestamp >= current_timestamp { return 0u64; } - let max_cycles = (config_till_timestamp - config_init_timestamp) / cycle_duration; + let max_cycles = (config_till_timestamp.minus_milliseconds(config_init_timestamp)) + .milliseconds() + / cycle_duration.milliseconds(); - let time_elapsed = current_timestamp - config_init_timestamp; - std::cmp::min(max_cycles, time_elapsed / cycle_duration) + let time_elapsed = current_timestamp.minus_milliseconds(config_init_timestamp); + std::cmp::min( + max_cycles, + time_elapsed.milliseconds() / cycle_duration.milliseconds(), + ) } fn calculate_init_timestamp_for_cycle( - config_init_timestamp: u64, + config_init_timestamp: MillisecondsExpiration, current_cycle: u64, - cycle_duration: u64, -) -> u64 { - config_init_timestamp + (current_cycle * cycle_duration) + cycle_duration: MillisecondsDuration, +) -> Milliseconds { + config_init_timestamp + .plus_milliseconds(Milliseconds(current_cycle * cycle_duration.milliseconds())) } fn rewards_distributed_for_cycle( diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs index d25729a..8041ccd 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/contract.rs @@ -1,19 +1,18 @@ -use std::str::FromStr; +use std::{ops::Mul, str::FromStr}; use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, - error::{from_semver, ContractError}, + common::{actions::call_action, context::ExecuteContext, encode_binary, Milliseconds}, + error::ContractError, }; use cosmwasm_std::{ - attr, entry_point, Attribute, Decimal, Decimal256, Order, QuerierWrapper, Uint256, + attr, entry_point, Attribute, BlockInfo, Decimal, Decimal256, Order, QuerierWrapper, Uint256, }; use cosmwasm_std::{ ensure, from_json, Addr, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, Response, Storage, Uint128, }; -use cw2::{get_contract_version, set_contract_version}; use cw20::Cw20ReceiveMsg; use cw_asset::{Asset, AssetInfo, AssetInfoUnchecked}; @@ -26,12 +25,11 @@ use crate::{ }; use andromeda_fungible_tokens::cw20_staking::{ - Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, RewardToken, - RewardTokenUnchecked, RewardType, StakerResponse, State, + Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, RewardToken, RewardTokenUnchecked, + RewardType, StakerResponse, State, }; use cw_utils::nonpayable; -use semver::Version; // Version info, for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-cw20-staking"; @@ -44,7 +42,6 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let additional_reward_tokens = if let Some(additional_rewards) = msg.additional_rewards { ensure!( additional_rewards.len() <= MAX_REWARD_TOKENS as usize, @@ -94,21 +91,17 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info.clone(), BaseInstantiateMsg { - ado_type: "cw20-staking".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; - let modules_resp = - contract.register_modules(info.sender.as_str(), deps.storage, msg.modules)?; - Ok(resp - .add_submessages(modules_resp.messages) - .add_attributes(modules_resp.attributes)) + Ok(resp) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -128,28 +121,31 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let contract = ADOContract::default(); - - if !matches!(msg, ExecuteMsg::UpdateAppContract { .. }) - && !matches!(msg, ExecuteMsg::UpdateOwner { .. }) - { - contract.module_hook::( - &ctx.deps.as_ref(), - AndromedaHook::OnExecute { - sender: ctx.info.sender.to_string(), - payload: encode_binary(&msg)?, - }, - )?; - } - match msg { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let _contract = ADOContract::default(); + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { ExecuteMsg::Receive(msg) => receive_cw20(ctx, msg), ExecuteMsg::AddRewardToken { reward_token } => execute_add_reward_token(ctx, reward_token), + ExecuteMsg::RemoveRewardToken { reward_token } => { + execute_remove_reward_token(ctx, reward_token) + } + ExecuteMsg::ReplaceRewardToken { + origin_reward_token, + reward_token, + } => execute_replace_reward_token(ctx, origin_reward_token, reward_token), ExecuteMsg::UpdateGlobalIndexes { asset_infos } => match asset_infos { None => update_global_indexes( ctx.deps.storage, + &ctx.env.block, &ctx.deps.querier, - ctx.env.block.time.seconds(), + Milliseconds::from_seconds(ctx.env.block.time.seconds()), ctx.env.contract.address, None, ), @@ -160,8 +156,9 @@ pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result Result execute_unstake_tokens(ctx, amount), ExecuteMsg::ClaimRewards {} => execute_claim_rewards(ctx), - // _ => ADOContract::default().execute(ctx, msg), _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } fn receive_cw20(ctx: ExecuteContext, msg: Cw20ReceiveMsg) -> Result { @@ -191,8 +191,9 @@ fn receive_cw20(ctx: ExecuteContext, msg: Cw20ReceiveMsg) -> Result update_global_indexes( deps.storage, + &env.block, &deps.querier, - env.block.time.seconds(), + Milliseconds::from_seconds(env.block.time.seconds()), env.contract.address, Some(vec![AssetInfo::cw20(info.sender)]), ), @@ -212,7 +213,12 @@ fn execute_add_reward_token( ContractError::Unauthorized {} ); let mut config = CONFIG.load(deps.storage)?; - config.number_of_reward_tokens += 1; + + let new_number = config.number_of_reward_tokens.checked_add(1); + match new_number { + Some(new_number) => config.number_of_reward_tokens = new_number, + None => return Err(ContractError::Overflow {}), + } ensure!( config.number_of_reward_tokens <= MAX_REWARD_TOKENS, ContractError::MaxRewardTokensExceeded { @@ -221,8 +227,10 @@ fn execute_add_reward_token( ); let mut reward_token = reward_token.check(&env.block, deps.api)?; let reward_token_string = reward_token.to_string(); + + let reward_token_option = REWARD_TOKENS.may_load(deps.storage, &reward_token_string)?; ensure!( - !REWARD_TOKENS.has(deps.storage, &reward_token_string), + reward_token_option.map_or(true, |reward_token| !reward_token.is_active), ContractError::InvalidAsset { asset: reward_token_string, } @@ -241,8 +249,9 @@ fn execute_add_reward_token( let state = STATE.load(deps.storage)?; update_global_index( + &env.block, &deps.querier, - env.block.time.seconds(), + Milliseconds::from_seconds(env.block.time.seconds()), env.contract.address, &state, &mut reward_token, @@ -256,6 +265,146 @@ fn execute_add_reward_token( .add_attribute("added_token", reward_token_string)) } +fn execute_remove_reward_token( + ctx: ExecuteContext, + reward_token_string: String, +) -> Result { + let ExecuteContext { + deps, info, env, .. + } = ctx; + let contract = ADOContract::default(); + ensure!( + contract.is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + // Set reward token as inactive + match REWARD_TOKENS.load(deps.storage, &reward_token_string) { + Ok(mut reward_token) if reward_token.is_active => { + // Need to save current status before setting reward token as inactive + // This is important in case the reward token is allocated token + let state = STATE.load(deps.storage)?; + update_global_index( + &env.block, + &deps.querier, + Milliseconds::from_seconds(env.block.time.seconds()), + env.contract.address, + &state, + &mut reward_token, + )?; + + reward_token.is_active = false; + REWARD_TOKENS.save(deps.storage, &reward_token_string, &reward_token)?; + } + _ => { + return Err(ContractError::InvalidAsset { + asset: reward_token_string, + }) + } + } + + let mut config = CONFIG.load(deps.storage)?; + config.number_of_reward_tokens -= 1; + CONFIG.save(deps.storage, &config)?; + + Ok(Response::new() + .add_attribute("action", "remove_reward_token") + .add_attribute( + "number_of_reward_tokens", + config.number_of_reward_tokens.to_string(), + ) + .add_attribute("removed_token", reward_token_string)) +} + +fn execute_replace_reward_token( + ctx: ExecuteContext, + origin_reward_token_string: String, + reward_token: RewardTokenUnchecked, +) -> Result { + let ExecuteContext { + deps, info, env, .. + } = ctx; + let contract = ADOContract::default(); + + // Only owner can replace reward token + ensure!( + contract.is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + let config = CONFIG.load(deps.storage)?; + + // Validate token to be replaced + let mut reward_token = reward_token.check(&env.block, deps.api)?; + let reward_token_string = reward_token.to_string(); + ensure!( + !REWARD_TOKENS.has(deps.storage, &reward_token_string), + ContractError::InvalidAsset { + asset: reward_token_string, + } + ); + + ensure!( + reward_token_string != origin_reward_token_string, + ContractError::InvalidAsset { + asset: reward_token_string, + } + ); + + let staking_token_address = config.staking_token.get_raw_address(&deps.as_ref())?; + let staking_token = AssetInfo::cw20(deps.api.addr_validate(staking_token_address.as_str())?); + ensure!( + staking_token != reward_token.asset_info, + ContractError::InvalidAsset { + asset: reward_token.to_string(), + } + ); + + // Set original token as inactive + match REWARD_TOKENS.load(deps.storage, &origin_reward_token_string) { + Ok(mut origin_reward_token) if origin_reward_token.is_active => { + // Need to save current status before setting reward token as inactive + // This is important in case the reward token is allocated token + let state = STATE.load(deps.storage)?; + update_global_index( + &env.block, + &deps.querier, + Milliseconds::from_seconds(env.block.time.seconds()), + env.contract.address.clone(), + &state, + &mut origin_reward_token, + )?; + + origin_reward_token.is_active = false; + REWARD_TOKENS.save( + deps.storage, + &origin_reward_token_string, + &origin_reward_token, + )?; + } + _ => { + return Err(ContractError::InvalidAsset { + asset: origin_reward_token_string, + }) + } + } + + let state = STATE.load(deps.storage)?; + update_global_index( + &env.block, + &deps.querier, + Milliseconds::from_seconds(env.block.time.seconds()), + env.contract.address, + &state, + &mut reward_token, + )?; + + REWARD_TOKENS.save(deps.storage, &reward_token_string, &reward_token)?; + + Ok(Response::new() + .add_attribute("action", "replace_reward_token") + .add_attribute("origin_reward_token", origin_reward_token_string) + .add_attribute("new_reward_token", reward_token.to_string())) +} /// The foundation for this approach is inspired by Anchor's staking implementation: /// https://github.com/Anchor-Protocol/anchor-token-contracts/blob/15c9d6f9753bd1948831f4e1b5d2389d3cf72c93/contracts/gov/src/staking.rs#L15 fn execute_stake_tokens( @@ -265,10 +414,8 @@ fn execute_stake_tokens( token_address: String, amount: Uint128, ) -> Result { - let contract = ADOContract::default(); let config = CONFIG.load(deps.storage)?; - let _mission_contract = contract.get_app_contract(deps.storage)?; let staking_token_address = config.staking_token.get_raw_address(&deps.as_ref())?; ensure!( token_address == staking_token_address, @@ -283,8 +430,9 @@ fn execute_stake_tokens( // Update indexes, important for allocated rewards. update_global_indexes( deps.storage, + &env.block, &deps.querier, - env.block.time.seconds(), + Milliseconds::from_seconds(env.block.time.seconds()), env.contract.address.clone(), None, )?; @@ -304,8 +452,8 @@ fn execute_stake_tokens( amount.multiply_ratio(state.total_share, total_balance) }; - staker.share += share; - state.total_share += share; + staker.share = staker.share.checked_add(share)?; + state.total_share = state.total_share.checked_add(share)?; STATE.save(deps.storage, &state)?; STAKERS.save(deps.storage, &sender, &staker)?; @@ -337,8 +485,9 @@ fn execute_unstake_tokens( // Update indexes, important for allocated rewards. update_global_indexes( deps.storage, + &env.block, &deps.querier, - env.block.time.seconds(), + Milliseconds::from_seconds(env.block.time.seconds()), env.contract.address, None, )?; @@ -367,9 +516,8 @@ fn execute_unstake_tokens( info: staking_token, amount: withdraw_amount, }; - - staker.share -= withdraw_share; - state.total_share -= withdraw_share; + staker.share = staker.share.checked_sub(withdraw_share)?; + state.total_share = state.total_share.checked_sub(withdraw_share)?; STATE.save(deps.storage, &state)?; STAKERS.save(deps.storage, sender, &staker)?; @@ -394,9 +542,10 @@ fn execute_claim_rewards(ctx: ExecuteContext) -> Result // Update indexes, important for allocated rewards. update_global_indexes( deps.storage, + &env.block, &deps.querier, - env.block.time.seconds(), - env.contract.address, + Milliseconds::from_seconds(env.block.time.seconds()), + env.contract.address.clone(), None, )?; update_staker_rewards(deps.storage, sender, &staker)?; @@ -430,6 +579,7 @@ fn execute_claim_rewards(ctx: ExecuteContext) -> Result // Reduce reward balance if is non-allocated token. if let RewardType::NonAllocated { previous_reward_balance, + .. } = &mut token.reward_type { *previous_reward_balance = previous_reward_balance.checked_sub(rewards)?; @@ -442,6 +592,20 @@ fn execute_claim_rewards(ctx: ExecuteContext) -> Result }; msgs.push(asset.transfer_msg(sender)?); } + if !token.is_active { + let reward_balance = token + .asset_info + .query_balance(&deps.querier, &env.contract.address)?; + let reward_balance = Decimal256::from_str(&format!("{0}", reward_balance))?; + let rewards_ceil = staker_reward_info + .index + .mul(Decimal256::from_str(&format!("{0}", staker.share))?) + .ceil(); + // if reward balance token is equal to the rewards, inactive reward token can be removed as it is all distributed + if reward_balance == rewards_ceil { + REWARD_TOKENS.remove(deps.storage, &token_string); + } + } } ensure!(!msgs.is_empty(), ContractError::WithdrawalIsEmpty {}); @@ -456,8 +620,9 @@ fn execute_claim_rewards(ctx: ExecuteContext) -> Result fn update_global_indexes( storage: &mut dyn Storage, + block_info: &BlockInfo, querier: &QuerierWrapper, - current_timestamp: u64, + current_timestamp: Milliseconds, contract_address: Addr, asset_infos: Option>, ) -> Result { @@ -482,6 +647,7 @@ fn update_global_indexes( } Some(mut reward_token) => { update_global_index( + block_info, querier, current_timestamp, contract_address.clone(), @@ -499,8 +665,9 @@ fn update_global_indexes( } fn update_global_index( + block_info: &BlockInfo, querier: &QuerierWrapper, - current_timestamp: u64, + current_timestamp: Milliseconds, contract_address: Addr, state: &State, reward_token: &mut RewardToken, @@ -513,6 +680,7 @@ fn update_global_index( match &reward_token.reward_type { RewardType::NonAllocated { previous_reward_balance, + init_timestamp, } => { update_nonallocated_index( state, @@ -520,18 +688,23 @@ fn update_global_index( reward_token, *previous_reward_balance, contract_address, + current_timestamp, + *init_timestamp, )?; } RewardType::Allocated { allocation_config, allocation_state, + init_timestamp, } => { update_allocated_index( + block_info, state.total_share, reward_token, allocation_config.clone(), allocation_state.clone(), current_timestamp, + *init_timestamp, )?; } } @@ -547,7 +720,12 @@ fn update_nonallocated_index( reward_token: &mut RewardToken, previous_reward_balance: Uint128, contract_address: Addr, + curr_timestamp: Milliseconds, + init_timestamp: Milliseconds, ) -> Result<(), ContractError> { + if curr_timestamp < init_timestamp || !reward_token.is_active { + return Ok(()); + } let reward_balance = reward_token .asset_info .query_balance(querier, contract_address)?; @@ -557,6 +735,7 @@ fn update_nonallocated_index( reward_token.reward_type = RewardType::NonAllocated { previous_reward_balance: reward_balance, + init_timestamp, }; Ok(()) @@ -626,7 +805,6 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { encode_binary(&query_stakers(deps, env, start_after, limit)?) } - QueryMsg::Timestamp {} => encode_binary(&query_timestamp(env)), _ => ADOContract::default().query(deps, env, msg), } } @@ -669,13 +847,14 @@ pub(crate) fn get_pending_rewards( let reward_tokens: Vec = get_reward_tokens(storage)?; let mut pending_rewards = vec![]; let state = STATE.load(storage)?; - let current_timestamp = env.block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(env.block.time.seconds()); for mut token in reward_tokens { let token_string = token.to_string(); let mut staker_reward_info = STAKER_REWARD_INFOS .may_load(storage, (address, &token_string))? .unwrap_or_default(); update_global_index( + &env.block, querier, current_timestamp, env.contract.address.to_owned(), @@ -702,40 +881,7 @@ fn query_stakers( get_stakers(deps, &deps.querier, deps.api, &env, start, limit) } -fn query_timestamp(env: Env) -> u64 { - env.block.time.seconds() -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/mock.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/mock.rs index fb2fbaf..363ac12 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/mock.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/mock.rs @@ -1,27 +1,56 @@ #![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] use crate::contract::{execute, instantiate, query}; -use andromeda_fungible_tokens::cw20_staking::{Cw20HookMsg, InstantiateMsg, QueryMsg}; -use cosmwasm_std::Empty; +use andromeda_fungible_tokens::cw20_staking::{ + AllocationConfig, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, RewardTokenUnchecked, +}; +use andromeda_std::{amp::AndrAddr, common::expiration::Expiry}; +use andromeda_testing::{mock_ado, MockADO, MockContract}; +use cosmwasm_std::{Addr, Empty}; +use cw_asset::AssetInfoUnchecked; use cw_multi_test::{Contract, ContractWrapper}; +pub struct MockCW20Staking(pub Addr); +mock_ado!(MockCW20Staking, ExecuteMsg, QueryMsg); + pub fn mock_andromeda_cw20_staking() -> Box> { let contract = ContractWrapper::new_with_empty(execute, instantiate, query); Box::new(contract) } pub fn mock_cw20_staking_instantiate_msg( - staking_token: String, - kernel_address: Option, + staking_token: impl Into, + kernel_address: impl Into, + owner: Option, ) -> InstantiateMsg { InstantiateMsg { - staking_token, + staking_token: AndrAddr::from_string(staking_token.into()), additional_rewards: None, - kernel_address, + kernel_address: kernel_address.into(), + owner, } } +pub fn mock_cw20_staking_add_reward_tokens( + reward_token: AssetInfoUnchecked, + init_timestamp: Expiry, + allocation_config: Option, +) -> ExecuteMsg { + let reward_token = RewardTokenUnchecked { + asset_info: reward_token, + init_timestamp, + allocation_config, + }; + ExecuteMsg::AddRewardToken { reward_token } +} + +pub fn mock_cw20_staking_update_global_indexes( + asset_infos: Option>, +) -> ExecuteMsg { + ExecuteMsg::UpdateGlobalIndexes { asset_infos } +} + pub fn mock_cw20_stake() -> Cw20HookMsg { Cw20HookMsg::StakeTokens {} } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/mock_querier.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/mock_querier.rs index 7d5d6dd..93c0225 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/mock_querier.rs @@ -8,6 +8,7 @@ use cosmwasm_std::testing::{ mock_env, mock_info, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR, }; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, to_json_binary, Coin, ContractResult, Empty, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, @@ -32,11 +33,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "cw20-staking".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs index 84203ba..db40082 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20-staking/src/testing/tests.rs @@ -1,9 +1,14 @@ use andromeda_std::{ - amp::addresses::AndrAddr, common::expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, - error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT, + amp::addresses::AndrAddr, + common::{ + expiration::{Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}, + Milliseconds, + }, + error::ContractError, + testing::mock_querier::MOCK_KERNEL_CONTRACT, }; use cosmwasm_std::{ - coins, from_json, + coin, coins, from_json, testing::{mock_dependencies, mock_env, mock_info, MOCK_CONTRACT_ADDR}, to_json_binary, Addr, BankMsg, Decimal, Decimal256, DepsMut, Response, Uint128, Uint256, WasmMsg, @@ -22,6 +27,7 @@ use andromeda_fungible_tokens::cw20_staking::{ AllocationConfig, AllocationState, Config, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, RewardToken, RewardTokenUnchecked, RewardType, StakerResponse, State, }; +use andromeda_testing::economics_msg::generate_economics_message; use cw_asset::{AssetInfo, AssetInfoUnchecked}; const MOCK_STAKING_TOKEN: &str = "staking_token"; @@ -39,7 +45,6 @@ fn init( additional_rewards, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; instantiate(deps, mock_env(), info, msg) @@ -48,26 +53,27 @@ fn init( #[test] fn test_instantiate() { let mut deps = mock_dependencies(); - let current_timestamp = mock_env().block.time.seconds(); - + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let res = init( deps.as_mut(), Some(vec![ RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20("incentive_token"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20("allocated_token"), + init_timestamp: Expiry::AtTime(current_timestamp), allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 1, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(1)), cycle_rewards: Uint128::new(100), - cycle_duration: 1, + cycle_duration: Milliseconds::from_seconds(1), reward_increase: None, }), }, @@ -78,7 +84,9 @@ fn test_instantiate() { assert_eq!( Response::new() .add_attribute("method", "instantiate") - .add_attribute("type", "cw20-staking"), + .add_attribute("type", "cw20-staking") + .add_attribute("kernel_address", MOCK_KERNEL_CONTRACT) + .add_attribute("owner", "owner"), res ); @@ -95,8 +103,10 @@ fn test_instantiate() { index: Decimal256::zero(), asset_info: AssetInfo::native("uusd"), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::zero() + previous_reward_balance: Uint128::zero(), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "native:uusd") @@ -108,8 +118,10 @@ fn test_instantiate() { index: Decimal256::zero(), asset_info: AssetInfo::cw20(Addr::unchecked("incentive_token")), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::zero() + previous_reward_balance: Uint128::zero(), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:incentive_token") @@ -121,11 +133,12 @@ fn test_instantiate() { index: Decimal256::zero(), asset_info: AssetInfo::cw20(Addr::unchecked("allocated_token")), reward_type: RewardType::Allocated { + init_timestamp: current_timestamp, + allocation_config: AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 1, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(1)), cycle_rewards: Uint128::new(100), - cycle_duration: 1, + cycle_duration: Milliseconds::from_seconds(1), reward_increase: None, }, allocation_state: AllocationState { @@ -134,6 +147,7 @@ fn test_instantiate() { last_distributed: current_timestamp, } }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:allocated_token") @@ -151,6 +165,7 @@ fn test_instantiate() { #[test] fn test_instantiate_exceed_max() { let mut deps = mock_dependencies(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let mut reward_tokens: Vec = vec![]; @@ -158,6 +173,7 @@ fn test_instantiate_exceed_max() { reward_tokens.push(RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(format!("token{i}")), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }); } @@ -174,12 +190,14 @@ fn test_instantiate_exceed_max() { #[test] fn test_instantiate_staking_token_as_addtional_reward() { let mut deps = mock_dependencies(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let res = init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_STAKING_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }]), ); assert_eq!( @@ -193,17 +211,17 @@ fn test_instantiate_staking_token_as_addtional_reward() { #[test] fn test_instantiate_start_time_in_past() { let mut deps = mock_dependencies(); - let current_timestamp = mock_env().block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let res = init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp.minus_seconds(1)), allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp - 1, - till_timestamp: current_timestamp + 1, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(1)), cycle_rewards: Uint128::new(100), - cycle_duration: 1, + cycle_duration: Milliseconds::from_seconds(1), reward_increase: None, }), }]), @@ -222,17 +240,18 @@ fn test_instantiate_start_time_in_past() { #[test] fn test_instantiate_end_time_in_past() { let mut deps = mock_dependencies(); - let current_timestamp = mock_env().block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let res = init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp), + allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp - 1, + till_timestamp: Expiry::AtTime(current_timestamp.minus_seconds(1)), cycle_rewards: Uint128::new(100), - cycle_duration: 1, + cycle_duration: Milliseconds::from_seconds(1), reward_increase: None, }), }]), @@ -244,17 +263,18 @@ fn test_instantiate_end_time_in_past() { #[test] fn test_instantiate_cycle_duration_zero() { let mut deps = mock_dependencies(); - let current_timestamp = mock_env().block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let res = init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp), + allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 1, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(1)), cycle_rewards: Uint128::new(100), - cycle_duration: 0, + cycle_duration: Milliseconds::zero(), reward_increase: None, }), }]), @@ -266,17 +286,18 @@ fn test_instantiate_cycle_duration_zero() { #[test] fn test_instantiate_invalid_reward_increase() { let mut deps = mock_dependencies(); - let current_timestamp = mock_env().block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let res = init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp), + allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 1, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(1)), cycle_rewards: Uint128::new(100), - cycle_duration: 1, + cycle_duration: Milliseconds::from_seconds(1), reward_increase: Some(Decimal::one()), }), }]), @@ -332,7 +353,8 @@ fn test_stake_unstake_tokens() { .add_attribute("action", "stake_tokens") .add_attribute("sender", "sender") .add_attribute("share", "100") - .add_attribute("amount", "100"), + .add_attribute("amount", "100") + .add_submessage(generate_economics_message(MOCK_STAKING_TOKEN, "Receive")), res ); @@ -370,7 +392,8 @@ fn test_stake_unstake_tokens() { .add_attribute("action", "stake_tokens") .add_attribute("sender", "other_sender") .add_attribute("share", "50") - .add_attribute("amount", "100"), + .add_attribute("amount", "100") + .add_submessage(generate_economics_message(MOCK_STAKING_TOKEN, "Receive")), res ); @@ -422,7 +445,8 @@ fn test_stake_unstake_tokens() { amount: Uint128::new(200) }) .unwrap() - }), + }) + .add_submessage(generate_economics_message("sender", "UnstakeTokens")), res ); @@ -465,7 +489,8 @@ fn test_stake_unstake_tokens() { amount: Uint128::new(100) }) .unwrap() - }), + }) + .add_submessage(generate_economics_message("other_sender", "UnstakeTokens")), res ); @@ -508,17 +533,25 @@ fn test_stake_invalid_token() { #[test] fn test_update_global_indexes() { - let mut deps = mock_dependencies_custom(&coins(40, "uusd")); + let mut deps = mock_dependencies_custom(&[coin(40, "uusd"), coin(40, "uandr")]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![ RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }, + RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uandr"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(1)), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, ]), ) @@ -547,13 +580,15 @@ fn test_update_global_indexes() { let msg = ExecuteMsg::UpdateGlobalIndexes { asset_infos: None }; let info = mock_info("owner", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + let res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); assert_eq!( Response::new() .add_attribute("action", "update_global_indexes") .add_attribute("cw20:incentive_token", "0.2") - .add_attribute("native:uusd", "0.4"), + .add_attribute("native:uandr", "0") + .add_attribute("native:uusd", "0.4") + .add_submessage(generate_economics_message("owner", "UpdateGlobalIndexes")), res ); @@ -562,41 +597,94 @@ fn test_update_global_indexes() { index: Decimal256::from_ratio(Uint256::from(40u128), Uint256::from(100u128)), asset_info: AssetInfo::native("uusd"), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::new(40) + previous_reward_balance: Uint128::new(40), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "native:uusd") .unwrap() ); + assert_eq!( + RewardToken { + index: Decimal256::zero(), + asset_info: AssetInfo::native("uandr"), + reward_type: RewardType::NonAllocated { + previous_reward_balance: Uint128::zero(), + init_timestamp: current_timestamp.plus_seconds(1), + }, + is_active: true + }, + REWARD_TOKENS + .load(deps.as_ref().storage, "native:uandr") + .unwrap() + ); + assert_eq!( RewardToken { index: Decimal256::from_ratio(Uint256::from(20u128), Uint256::from(100u128)), asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_INCENTIVE_TOKEN)), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::new(20) + previous_reward_balance: Uint128::new(20), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:incentive_token") .unwrap() ); + + // Check unallocate updates after init timestamp + let msg = ExecuteMsg::UpdateGlobalIndexes { asset_infos: None }; + let mut new_env = mock_env(); + new_env.block.time = new_env.block.time.plus_seconds(2); + let res = execute(deps.as_mut(), new_env, info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "update_global_indexes") + .add_attribute("cw20:incentive_token", "0.2") + .add_attribute("native:uandr", "0.4") + .add_attribute("native:uusd", "0.4") + .add_submessage(generate_economics_message("owner", "UpdateGlobalIndexes")), + res + ); + + assert_eq!( + RewardToken { + index: Decimal256::from_ratio(Uint256::from(40u128), Uint256::from(100u128)), + asset_info: AssetInfo::native("uandr"), + reward_type: RewardType::NonAllocated { + previous_reward_balance: Uint128::new(40), + init_timestamp: current_timestamp.plus_seconds(1), + }, + is_active: true, + }, + REWARD_TOKENS + .load(deps.as_ref().storage, "native:uandr") + .unwrap() + ); } #[test] fn test_update_global_indexes_selective() { let mut deps = mock_dependencies_custom(&coins(40, "uusd")); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![ RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, ]), ) @@ -632,7 +720,8 @@ fn test_update_global_indexes_selective() { assert_eq!( Response::new() .add_attribute("action", "update_global_indexes") - .add_attribute("native:uusd", "0.4"), + .add_attribute("native:uusd", "0.4") + .add_submessage(generate_economics_message("owner", "UpdateGlobalIndexes")), res ); @@ -641,8 +730,10 @@ fn test_update_global_indexes_selective() { index: Decimal256::from_ratio(Uint256::from(40u128), Uint256::from(100u128)), asset_info: AssetInfo::native("uusd"), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::new(40) + previous_reward_balance: Uint128::new(40), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "native:uusd") @@ -655,7 +746,9 @@ fn test_update_global_indexes_selective() { asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_INCENTIVE_TOKEN)), reward_type: RewardType::NonAllocated { previous_reward_balance: Uint128::zero(), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:incentive_token") @@ -666,16 +759,19 @@ fn test_update_global_indexes_selective() { #[test] fn test_update_global_indexes_invalid_asset() { let mut deps = mock_dependencies_custom(&coins(40, "uusd")); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![ RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, ]), ) @@ -708,16 +804,19 @@ fn test_update_global_indexes_invalid_asset() { #[test] fn test_update_global_indexes_cw20_deposit() { let mut deps = mock_dependencies_custom(&coins(40, "uusd")); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![ RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, ]), ) @@ -755,7 +854,8 @@ fn test_update_global_indexes_cw20_deposit() { assert_eq!( Response::new() .add_attribute("action", "update_global_indexes") - .add_attribute("cw20:incentive_token", "0.2"), + .add_attribute("cw20:incentive_token", "0.2") + .add_submessage(generate_economics_message(MOCK_INCENTIVE_TOKEN, "Receive")), res ); @@ -765,7 +865,9 @@ fn test_update_global_indexes_cw20_deposit() { asset_info: AssetInfo::native("uusd"), reward_type: RewardType::NonAllocated { previous_reward_balance: Uint128::zero(), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "native:uusd") @@ -777,8 +879,10 @@ fn test_update_global_indexes_cw20_deposit() { index: Decimal256::from_ratio(Uint256::from(20u128), Uint256::from(100u128)), asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_INCENTIVE_TOKEN)), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::new(20) + previous_reward_balance: Uint128::new(20), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:incentive_token") @@ -789,11 +893,13 @@ fn test_update_global_indexes_cw20_deposit() { #[test] fn test_claim_rewards() { let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }]), ) .unwrap(); @@ -863,8 +969,10 @@ fn test_claim_rewards() { index: Decimal256::from_ratio(Uint256::from(100u128), Uint256::from(150u128)), asset_info: AssetInfo::native("uusd"), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::new(100) + previous_reward_balance: Uint128::new(100), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "native:uusd") @@ -916,8 +1024,10 @@ fn test_claim_rewards() { index: Decimal256::from_ratio(Uint256::from(100u128), Uint256::from(150u128)), asset_info: AssetInfo::native("uusd"), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::new(34) + previous_reward_balance: Uint128::new(34), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "native:uusd") @@ -930,7 +1040,8 @@ fn test_claim_rewards() { .add_message(BankMsg::Send { to_address: "user1".to_string(), amount: coins(66, "uusd") - }), + }) + .add_submessage(generate_economics_message("user1", "ClaimRewards")), res ); @@ -948,7 +1059,8 @@ fn test_claim_rewards() { .add_message(BankMsg::Send { to_address: "user2".to_string(), amount: coins(33, "uusd") - }), + }) + .add_submessage(generate_economics_message("user2", "ClaimRewards")), res ); @@ -968,8 +1080,10 @@ fn test_claim_rewards() { asset_info: AssetInfo::native("uusd"), reward_type: RewardType::NonAllocated { // Small rounding error, shouldn't really make a difference and is inevitable. - previous_reward_balance: Uint128::new(1) + previous_reward_balance: Uint128::new(1), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "native:uusd") @@ -1010,16 +1124,17 @@ fn test_claim_rewards() { #[test] fn test_claim_rewards_allocated() { let mut deps = mock_dependencies_custom(&[]); - let current_timestamp = mock_env().block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_ALLOCATED_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp), + allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 100, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), cycle_rewards: Uint128::new(100), - cycle_duration: 100, + cycle_duration: Milliseconds::from_seconds(100), reward_increase: None, }), }]), @@ -1048,6 +1163,16 @@ fn test_claim_rewards_allocated() { let info = mock_info(MOCK_STAKING_TOKEN, &[]); let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!( + StakerRewardInfo { + index: Decimal256::zero(), + pending_rewards: Decimal256::zero(), + }, + STAKER_REWARD_INFOS + .load(deps.as_ref().storage, ("user1", "cw20:allocated_token")) + .unwrap() + ); + deps.querier.with_token_balances(&[ ( &MOCK_STAKING_TOKEN.to_string(), @@ -1102,7 +1227,8 @@ fn test_claim_rewards_allocated() { amount: Uint128::new(25) }) .unwrap(), - }), + }) + .add_submessage(generate_economics_message("user1", "ClaimRewards")), res ); @@ -1121,19 +1247,21 @@ fn test_claim_rewards_allocated() { index: Decimal256::from_ratio(Uint256::from(50u128), Uint256::from(200u128)), asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_ALLOCATED_TOKEN)), reward_type: RewardType::Allocated { + init_timestamp: current_timestamp, + allocation_config: AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 100, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), cycle_rewards: Uint128::new(100), - cycle_duration: 100, + cycle_duration: Milliseconds::from_seconds(100), reward_increase: None, }, allocation_state: AllocationState { current_cycle: 0, current_cycle_rewards: Uint128::new(100), - last_distributed: current_timestamp + 50, + last_distributed: current_timestamp.plus_seconds(50), }, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:allocated_token") @@ -1156,7 +1284,186 @@ fn test_claim_rewards_allocated() { amount: Uint128::new(25) }) .unwrap(), + }) + .add_submessage(generate_economics_message("user2", "ClaimRewards")), + res + ); + + assert_eq!( + StakerRewardInfo { + index: Decimal256::percent(25), + pending_rewards: Decimal256::zero(), + }, + STAKER_REWARD_INFOS + .load(deps.as_ref().storage, ("user2", "cw20:allocated_token")) + .unwrap() + ); +} + +#[test] +fn test_claim_rewards_allocated_init_timestamp_in_future() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::cw20(MOCK_ALLOCATED_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(10)), + allocation_config: Some(AllocationConfig { + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(110)), + cycle_rewards: Uint128::new(100), + cycle_duration: Milliseconds::from_seconds(100), + reward_increase: None, }), + }]), + ) + .unwrap(); + + deps.querier.with_token_balances(&[ + ( + &MOCK_STAKING_TOKEN.to_string(), + // 100 is user's deposit. + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100))], + ), + ( + &MOCK_ALLOCATED_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100))], + ), + ]); + + // User 1 stakes tokens. + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "user1".to_string(), + amount: Uint128::new(100), + msg: to_json_binary(&Cw20HookMsg::StakeTokens {}).unwrap(), + }); + + let info = mock_info(MOCK_STAKING_TOKEN, &[]); + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + StakerRewardInfo { + index: Decimal256::zero(), + pending_rewards: Decimal256::zero(), + }, + STAKER_REWARD_INFOS + .load(deps.as_ref().storage, ("user1", "cw20:allocated_token")) + .unwrap() + ); + + deps.querier.with_token_balances(&[ + ( + &MOCK_STAKING_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100 + 100))], + ), + ( + &MOCK_ALLOCATED_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100))], + ), + ]); + + // User 2 stakes 100 tokens. + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "user2".to_string(), + amount: Uint128::new(100), + msg: to_json_binary(&Cw20HookMsg::StakeTokens {}).unwrap(), + }); + + let info = mock_info(MOCK_STAKING_TOKEN, &[]); + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + Staker { + share: Uint128::new(100) + }, + STAKERS.load(deps.as_ref().storage, "user1").unwrap() + ); + assert_eq!( + Staker { + share: Uint128::new(100) + }, + STAKERS.load(deps.as_ref().storage, "user2").unwrap() + ); + + // Speed time up to halfway through cycle. + + let mut env = mock_env(); + env.block.time = env.block.time.plus_seconds(50 + 10); + + // User 1 claims rewards. + let info = mock_info("user1", &[]); + let msg = ExecuteMsg::ClaimRewards {}; + let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "claim_rewards") + .add_message(WasmMsg::Execute { + contract_addr: MOCK_ALLOCATED_TOKEN.to_owned(), + funds: vec![], + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { + recipient: "user1".to_string(), + amount: Uint128::new(25) + }) + .unwrap(), + }) + .add_submessage(generate_economics_message("user1", "ClaimRewards")), + res + ); + + assert_eq!( + StakerRewardInfo { + index: Decimal256::percent(25), + pending_rewards: Decimal256::zero(), + }, + STAKER_REWARD_INFOS + .load(deps.as_ref().storage, ("user1", "cw20:allocated_token")) + .unwrap() + ); + + assert_eq!( + RewardToken { + index: Decimal256::from_ratio(Uint256::from(50u128), Uint256::from(200u128)), + asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_ALLOCATED_TOKEN)), + reward_type: RewardType::Allocated { + init_timestamp: current_timestamp.plus_seconds(10), + allocation_config: AllocationConfig { + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(110)), + cycle_rewards: Uint128::new(100), + cycle_duration: Milliseconds::from_seconds(100), + reward_increase: None, + }, + allocation_state: AllocationState { + current_cycle: 0, + current_cycle_rewards: Uint128::new(100), + last_distributed: current_timestamp.plus_seconds(60), + }, + }, + is_active: true, + }, + REWARD_TOKENS + .load(deps.as_ref().storage, "cw20:allocated_token") + .unwrap() + ); + + // User 2 claims rewards. + let info = mock_info("user2", &[]); + let msg = ExecuteMsg::ClaimRewards {}; + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "claim_rewards") + .add_message(WasmMsg::Execute { + contract_addr: MOCK_ALLOCATED_TOKEN.to_owned(), + funds: vec![], + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { + recipient: "user2".to_string(), + amount: Uint128::new(25) + }) + .unwrap(), + }) + .add_submessage(generate_economics_message("user2", "ClaimRewards")), res ); @@ -1174,25 +1481,28 @@ fn test_claim_rewards_allocated() { #[test] fn test_stake_rewards_update() { let mut deps = mock_dependencies_custom(&coins(40, "uusd")); - let current_timestamp = mock_env().block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![ RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_ALLOCATED_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp), + allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 100, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), cycle_rewards: Uint128::new(100), - cycle_duration: 100, + cycle_duration: Milliseconds::from_seconds(100), reward_increase: None, }), }, @@ -1332,19 +1642,21 @@ fn test_stake_rewards_update() { index: Decimal256::from_ratio(Uint256::from(50u128), Uint256::from(100u128)), asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_ALLOCATED_TOKEN)), reward_type: RewardType::Allocated { + init_timestamp: current_timestamp, + allocation_config: AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 100, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), cycle_rewards: Uint128::new(100), - cycle_duration: 100, + cycle_duration: Milliseconds::from_seconds(100), reward_increase: None, }, allocation_state: AllocationState { current_cycle: 0, current_cycle_rewards: Uint128::new(100), - last_distributed: current_timestamp + 50, + last_distributed: current_timestamp.plus_seconds(50), }, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:allocated_token") @@ -1355,25 +1667,28 @@ fn test_stake_rewards_update() { #[test] fn test_unstake_rewards_update() { let mut deps = mock_dependencies_custom(&coins(40, "uusd")); - let current_timestamp = mock_env().block.time.seconds(); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![ RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_ALLOCATED_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp), + allocation_config: Some(AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 100, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), cycle_rewards: Uint128::new(100), - cycle_duration: 100, + cycle_duration: Milliseconds::from_seconds(100), reward_increase: None, }), }, @@ -1480,19 +1795,21 @@ fn test_unstake_rewards_update() { index: Decimal256::from_ratio(Uint256::from(50u128), Uint256::from(100u128)), asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_ALLOCATED_TOKEN)), reward_type: RewardType::Allocated { + init_timestamp: current_timestamp, + allocation_config: AllocationConfig { - init_timestamp: current_timestamp, - till_timestamp: current_timestamp + 100, + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), cycle_rewards: Uint128::new(100), - cycle_duration: 100, + cycle_duration: Milliseconds::from_seconds(100), reward_increase: None, }, allocation_state: AllocationState { current_cycle: 0, current_cycle_rewards: Uint128::new(100), - last_distributed: current_timestamp + 50, + last_distributed: current_timestamp.plus_seconds(50), }, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:allocated_token") @@ -1503,6 +1820,7 @@ fn test_unstake_rewards_update() { #[test] fn test_add_reward_token() { let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init(deps.as_mut(), None).unwrap(); deps.querier.with_token_balances(&[ @@ -1529,6 +1847,7 @@ fn test_add_reward_token() { reward_token: RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, }; let info = mock_info("owner", &[]); @@ -1538,7 +1857,8 @@ fn test_add_reward_token() { assert_eq!( Response::new() .add_attribute("action", "add_reward_token") - .add_attribute("added_token", "cw20:incentive_token"), + .add_attribute("added_token", "cw20:incentive_token") + .add_submessage(generate_economics_message("owner", "AddRewardToken")), res ); @@ -1547,8 +1867,10 @@ fn test_add_reward_token() { index: Decimal256::zero(), asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_INCENTIVE_TOKEN)), reward_type: RewardType::NonAllocated { - previous_reward_balance: Uint128::zero() + previous_reward_balance: Uint128::zero(), + init_timestamp: current_timestamp, }, + is_active: true, }, REWARD_TOKENS .load(deps.as_ref().storage, "cw20:incentive_token") @@ -1559,11 +1881,13 @@ fn test_add_reward_token() { #[test] fn test_add_reward_token_duplicate() { let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init( deps.as_mut(), Some(vec![RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }]), ) .unwrap(); @@ -1572,6 +1896,7 @@ fn test_add_reward_token_duplicate() { reward_token: RewardTokenUnchecked { asset_info: AssetInfoUnchecked::native("uusd"), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, }; let info = mock_info("owner", &[]); @@ -1588,12 +1913,14 @@ fn test_add_reward_token_duplicate() { #[test] fn test_add_reward_token_staking_token() { let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init(deps.as_mut(), None).unwrap(); let msg = ExecuteMsg::AddRewardToken { reward_token: RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_STAKING_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, }; let info = mock_info("owner", &[]); @@ -1610,12 +1937,14 @@ fn test_add_reward_token_staking_token() { #[test] fn test_add_reward_token_unauthorized() { let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); init(deps.as_mut(), None).unwrap(); let msg = ExecuteMsg::AddRewardToken { reward_token: RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_STAKING_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, }; let info = mock_info("not_owner", &[]); @@ -1627,13 +1956,14 @@ fn test_add_reward_token_unauthorized() { #[test] fn test_add_reward_token_exceeds_max() { let mut deps = mock_dependencies_custom(&[]); - + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); let mut reward_tokens: Vec = vec![]; for i in 0..MAX_REWARD_TOKENS { reward_tokens.push(RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(format!("token{i}")), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }); } @@ -1643,6 +1973,7 @@ fn test_add_reward_token_exceeds_max() { reward_token: RewardTokenUnchecked { asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), }, }; let info = mock_info("owner", &[]); @@ -1656,3 +1987,545 @@ fn test_add_reward_token_exceeds_max() { res.unwrap_err() ); } + +#[test] +fn test_remove_reward_token() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uusd"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }]), + ) + .unwrap(); + + let msg = ExecuteMsg::RemoveRewardToken { + reward_token: "native:uusd".to_string(), + }; + let info = mock_info("owner", &[]); + + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "remove_reward_token") + .add_attribute("number_of_reward_tokens", "0") + .add_attribute("removed_token", "native:uusd") + .add_submessage(generate_economics_message("owner", "RemoveRewardToken")), + res + ); + + let reward_token = REWARD_TOKENS + .load(deps.as_ref().storage, "native:uusd") + .unwrap(); + assert!(!reward_token.is_active); +} + +#[test] +fn test_remove_reward_token_unauthorized() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uusd"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }]), + ) + .unwrap(); + + let msg = ExecuteMsg::RemoveRewardToken { + reward_token: "native:uusd".to_string(), + }; + let info = mock_info("owner1", &[]); + + let res = execute(deps.as_mut(), mock_env(), info, msg); + + assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); +} + +#[test] +fn test_remove_reward_token_invalid_asset() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }]), + ) + .unwrap(); + + let msg = ExecuteMsg::RemoveRewardToken { + reward_token: "native:uusd".to_string(), + }; + let info = mock_info("owner", &[]); + + let res = execute(deps.as_mut(), mock_env(), info, msg); + + assert_eq!( + ContractError::InvalidAsset { + asset: "native:uusd".to_string() + }, + res.unwrap_err() + ); +} + +#[test] +fn test_claim_rewards_after_remove() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + + // Init with additional rewards + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uusd"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }]), + ) + .unwrap(); + + deps.querier.with_token_balances(&[( + &MOCK_STAKING_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100 + 100))], + )]); + + // user1 and user2 stake with 100 tokens separately + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "user1".to_string(), + amount: Uint128::new(100), + msg: to_json_binary(&Cw20HookMsg::StakeTokens {}).unwrap(), + }); + + let info = mock_info(MOCK_STAKING_TOKEN, &[]); + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + deps.querier.with_token_balances(&[( + &MOCK_STAKING_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(200 + 100))], + )]); + + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "user2".to_string(), + amount: Uint128::new(100), + msg: to_json_binary(&Cw20HookMsg::StakeTokens {}).unwrap(), + }); + + let info = mock_info(MOCK_STAKING_TOKEN, &[]); + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + Staker { + share: Uint128::new(100) + }, + STAKERS.load(deps.as_ref().storage, "user1").unwrap() + ); + assert_eq!( + Staker { + share: Uint128::new(50) + }, + STAKERS.load(deps.as_ref().storage, "user2").unwrap() + ); + + let info = mock_info("user1", &[]); + let msg = ExecuteMsg::ClaimRewards {}; + let res = execute(deps.as_mut(), mock_env(), info, msg); + + // No rewards have been given yet. + assert_eq!(ContractError::WithdrawalIsEmpty {}, res.unwrap_err()); + + deps.querier + .base + .update_balance(mock_env().contract.address, coins(100, "uusd")); + + // Update the global index for uusd by depositing 100 uusd + let msg = ExecuteMsg::UpdateGlobalIndexes { + asset_infos: Some(vec![AssetInfoUnchecked::native("uusd")]), + }; + + let info = mock_info("owner", &[]); + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + RewardToken { + index: Decimal256::from_ratio(Uint256::from(100u128), Uint256::from(150u128)), + asset_info: AssetInfo::native("uusd"), + reward_type: RewardType::NonAllocated { + previous_reward_balance: Uint128::new(100), + init_timestamp: current_timestamp, + }, + is_active: true, + }, + REWARD_TOKENS + .load(deps.as_ref().storage, "native:uusd") + .unwrap() + ); + + let info = mock_info("user1", &[]); + let msg = ExecuteMsg::ClaimRewards {}; + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + StakerRewardInfo { + index: Decimal256::from_ratio(Uint256::from(100u128), Uint256::from(150u128)), + pending_rewards: Decimal256::zero(), + }, + STAKER_REWARD_INFOS + .load(deps.as_ref().storage, ("user1", "native:uusd")) + .unwrap() + ); + + assert_eq!( + RewardToken { + index: Decimal256::from_ratio(Uint256::from(100u128), Uint256::from(150u128)), + asset_info: AssetInfo::native("uusd"), + reward_type: RewardType::NonAllocated { + previous_reward_balance: Uint128::new(34), + init_timestamp: current_timestamp, + }, + is_active: true, + }, + REWARD_TOKENS + .load(deps.as_ref().storage, "native:uusd") + .unwrap() + ); + + assert_eq!( + Response::new() + .add_attribute("action", "claim_rewards") + .add_message(BankMsg::Send { + to_address: "user1".to_string(), + amount: coins(66, "uusd") + }) + .add_submessage(generate_economics_message("user1", "ClaimRewards")), + res + ); + + deps.querier + .base + .update_balance(mock_env().contract.address, coins(34, "uusd")); + + let msg = ExecuteMsg::RemoveRewardToken { + reward_token: "native:uusd".to_string(), + }; + let info = mock_info("owner", &[]); + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + let info = mock_info("user2", &[]); + let msg = ExecuteMsg::ClaimRewards {}; + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "claim_rewards") + .add_message(BankMsg::Send { + to_address: "user2".to_string(), + amount: coins(33, "uusd") + }) + .add_submessage(generate_economics_message("user2", "ClaimRewards")), + res + ); + + assert_eq!( + StakerRewardInfo { + index: Decimal256::from_ratio(Uint256::from(100u128), Uint256::from(150u128)), + pending_rewards: Decimal256::zero() + }, + STAKER_REWARD_INFOS + .load(deps.as_ref().storage, ("user2", "native:uusd")) + .unwrap() + ); + + // Last reward is distributed and reward token is removed from the reward token list + assert!(!REWARD_TOKENS.has(deps.as_ref().storage, "native:uusd")); + deps.querier + .base + .update_balance(mock_env().contract.address, coins(1, "uusd")); + + // Verify that the queries return the empty pending rewards. + let msg = QueryMsg::Stakers { + start_after: None, + limit: None, + }; + let res: Vec = + from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + + assert_eq!( + vec![ + StakerResponse { + address: "user1".to_string(), + share: Uint128::new(100), + pending_rewards: vec![], + balance: Uint128::new(200), + }, + StakerResponse { + address: "user2".to_string(), + share: Uint128::new(50), + pending_rewards: vec![], + balance: Uint128::new(100), + }, + ], + res + ); +} + +#[test] +fn test_claim_rewards_allocated_after_remove() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::cw20(MOCK_ALLOCATED_TOKEN), + init_timestamp: Expiry::AtTime(current_timestamp), + allocation_config: Some(AllocationConfig { + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), + cycle_rewards: Uint128::new(100), + cycle_duration: Milliseconds::from_seconds(100), + reward_increase: None, + }), + }]), + ) + .unwrap(); + + deps.querier.with_token_balances(&[ + ( + &MOCK_STAKING_TOKEN.to_string(), + // 100 is user's deposit. + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100))], + ), + ( + &MOCK_ALLOCATED_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100))], + ), + ]); + + // user stake with 100 mock token + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "user".to_string(), + amount: Uint128::new(100), + msg: to_json_binary(&Cw20HookMsg::StakeTokens {}).unwrap(), + }); + + let info = mock_info(MOCK_STAKING_TOKEN, &[]); + let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + deps.querier.with_token_balances(&[ + ( + &MOCK_STAKING_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100 + 100))], + ), + ( + &MOCK_ALLOCATED_TOKEN.to_string(), + &[(&MOCK_CONTRACT_ADDR.to_string(), &Uint128::new(100))], + ), + ]); + + // Speed time up to halfway through cycle. + let mut env = mock_env(); + env.block.time = env.block.time.plus_seconds(50); + + // User claims rewards. + let info = mock_info("user", &[]); + let msg = ExecuteMsg::ClaimRewards {}; + execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + let msg = ExecuteMsg::RemoveRewardToken { + reward_token: format!("cw20:{MOCK_ALLOCATED_TOKEN}"), + }; + + env.block.time = env.block.time.plus_seconds(25); + let info = mock_info("owner", &[]); + execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + env.block.time = env.block.time.plus_seconds(25); + let info = mock_info("user", &[]); + let msg = ExecuteMsg::ClaimRewards {}; + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "claim_rewards") + .add_message(WasmMsg::Execute { + contract_addr: MOCK_ALLOCATED_TOKEN.to_owned(), + funds: vec![], + msg: to_json_binary(&Cw20ExecuteMsg::Transfer { + recipient: "user".to_string(), + amount: Uint128::new(25) + }) + .unwrap(), + }) + .add_submessage(generate_economics_message("user", "ClaimRewards")), + res + ); + + assert_eq!( + StakerRewardInfo { + index: Decimal256::percent(75), + pending_rewards: Decimal256::zero(), + }, + STAKER_REWARD_INFOS + .load(deps.as_ref().storage, ("user", "cw20:allocated_token")) + .unwrap() + ); + + assert_eq!( + RewardToken { + index: Decimal256::from_ratio(Uint256::from(150u128), Uint256::from(200u128)), + asset_info: AssetInfo::cw20(Addr::unchecked(MOCK_ALLOCATED_TOKEN)), + reward_type: RewardType::Allocated { + init_timestamp: current_timestamp, + allocation_config: AllocationConfig { + till_timestamp: Expiry::AtTime(current_timestamp.plus_seconds(100)), + cycle_rewards: Uint128::new(100), + cycle_duration: Milliseconds::from_seconds(100), + reward_increase: None, + }, + allocation_state: AllocationState { + current_cycle: 0, + current_cycle_rewards: Uint128::new(100), + last_distributed: current_timestamp.plus_seconds(75), + }, + }, + is_active: false, + }, + REWARD_TOKENS + .load(deps.as_ref().storage, "cw20:allocated_token") + .unwrap() + ); +} + +#[test] +fn test_replace_reward_token() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uusd"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }]), + ) + .unwrap(); + + let msg = ExecuteMsg::ReplaceRewardToken { + origin_reward_token: "native:uusd".to_string(), + reward_token: RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }, + }; + let info = mock_info("owner", &[]); + + let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_attribute("action", "replace_reward_token") + .add_attribute("origin_reward_token", "native:uusd") + .add_attribute("new_reward_token", format!("cw20:{MOCK_INCENTIVE_TOKEN}")) + .add_submessage(generate_economics_message("owner", "ReplaceRewardToken")), + res + ); + + let reward_token = REWARD_TOKENS + .load(deps.as_ref().storage, "native:uusd") + .unwrap(); + assert!(!reward_token.is_active); + + assert!(REWARD_TOKENS.has( + deps.as_ref().storage, + &format!("cw20:{MOCK_INCENTIVE_TOKEN}") + )); +} +#[test] +fn test_replace_reward_token_unauthorized() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uusd"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }]), + ) + .unwrap(); + + let msg = ExecuteMsg::ReplaceRewardToken { + origin_reward_token: "native:uusd".to_string(), + reward_token: RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }, + }; + let info = mock_info("owner1", &[]); + + let res = execute(deps.as_mut(), mock_env(), info, msg); + + assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); +} + +#[test] +fn test_replace_reward_token_invalid_asset() { + let mut deps = mock_dependencies_custom(&[]); + let current_timestamp = Milliseconds::from_seconds(mock_env().block.time.seconds()); + init( + deps.as_mut(), + Some(vec![RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uusd"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }]), + ) + .unwrap(); + + let msg = ExecuteMsg::ReplaceRewardToken { + origin_reward_token: "native:uusd".to_string(), + reward_token: RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::native("uusd"), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }, + }; + let info = mock_info("owner", &[]); + + let res = execute(deps.as_mut(), mock_env(), info, msg); + + assert_eq!( + ContractError::InvalidAsset { + asset: "native:uusd".to_string() + }, + res.unwrap_err() + ); + + let msg = ExecuteMsg::ReplaceRewardToken { + origin_reward_token: "cw20:uusd".to_string(), + reward_token: RewardTokenUnchecked { + asset_info: AssetInfoUnchecked::cw20(MOCK_INCENTIVE_TOKEN), + allocation_config: None, + init_timestamp: Expiry::AtTime(current_timestamp), + }, + }; + let info = mock_info("owner", &[]); + + let res = execute(deps.as_mut(), mock_env(), info, msg); + + assert_eq!( + ContractError::InvalidAsset { + asset: "cw20:uusd".to_string() + }, + res.unwrap_err() + ); +} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/Cargo.toml b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/Cargo.toml index acfeaf2..9873af4 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/Cargo.toml +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-cw20" -version = "0.2.1" +version = "2.0.4" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -20,16 +20,15 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } cw20 = { workspace = true } cw20-base = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true, features = ["rates"] } andromeda-fungible-tokens = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/README.md b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/README.md new file mode 100644 index 0000000..dff9247 --- /dev/null +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/README.md @@ -0,0 +1,5 @@ +# Overview + +The CW20 ADO is a smart contract to initiate a [standard CW20 token](https://github.com/CosmWasm/cw-plus/blob/main/packages/cw20/README.md). CW20 is a specification for fungible tokens based on CosmWasm. + +[CW20 Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/cw20) diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/andromeda-cw20.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/andromeda-cw20.json deleted file mode 100644 index 7de7372..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/andromeda-cw20.json +++ /dev/null @@ -1,2351 +0,0 @@ -{ - "contract_name": "andromeda-cw20", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "decimals", - "initial_balances", - "kernel_address", - "name", - "symbol" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "initial_balances": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "kernel_address": { - "type": "string" - }, - "marketing": { - "anyOf": [ - { - "$ref": "#/definitions/InstantiateMarketingInfo" - }, - { - "type": "null" - } - ] - }, - "mint": { - "anyOf": [ - { - "$ref": "#/definitions/MinterResponse" - }, - { - "type": "null" - } - ] - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "name": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "symbol": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "InstantiateMarketingInfo": { - "type": "object", - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "logo": { - "anyOf": [ - { - "$ref": "#/definitions/Logo" - }, - { - "type": "null" - } - ] - }, - "marketing": { - "type": [ - "string", - "null" - ] - }, - "project": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "MinterResponse": { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "cap": { - "description": "cap is a hard cap on total supply that can be achieved by minting. Note that this refers to total_supply. If None, there is unlimited cap.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "minter": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"mintable\" extension. If authorized, creates amount new tokens and adds to the recipient balance.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"marketing\" extension. If authorized, updates marketing metadata. Setting None/null for any of these will leave it unchanged. Setting Some(\"\") will clear this field on the contract storage", - "type": "object", - "required": [ - "update_marketing" - ], - "properties": { - "update_marketing": { - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "type": [ - "string", - "null" - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If set as the \"marketing\" role on the contract, upload a new URL, SVG, or PNG for the token", - "type": "object", - "required": [ - "upload_logo" - ], - "properties": { - "upload_logo": { - "$ref": "#/definitions/Logo" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Returns the current balance of the given address, 0 if unset. Return type: BalanceResponse. Returns metadata on the contract - name, decimals, supply, etc. Return type: TokenInfoResponse.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"mintable\" extension. Returns who can mint and the hard cap on maximum tokens after minting. Return type: MinterResponse.", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset. Return type: AllowanceResponse.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension (and \"allowances\") Returns all allowances this owner has approved. Supports pagination. Return type: AllAllowancesResponse.", - "type": "object", - "required": [ - "all_allowances" - ], - "properties": { - "all_allowances": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension Returns all accounts that have balances. Supports pagination. Return type: AllAccountsResponse.", - "type": "object", - "required": [ - "all_accounts" - ], - "properties": { - "all_accounts": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Returns more metadata on the contract to display in the client: - description, logo, project url, etc. Return type: MarketingInfoResponse", - "type": "object", - "required": [ - "marketing_info" - ], - "properties": { - "marketing_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Downloads the mbeded logo data (if stored on chain). Errors if no logo data ftored for this contract. Return type: DownloadLogoResponse.", - "type": "object", - "required": [ - "download_logo" - ], - "properties": { - "download_logo": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "all_accounts": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAccountsResponse", - "type": "object", - "required": [ - "accounts" - ], - "properties": { - "accounts": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "all_allowances": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAllowancesResponse", - "type": "object", - "required": [ - "allowances" - ], - "properties": { - "allowances": { - "type": "array", - "items": { - "$ref": "#/definitions/AllowanceInfo" - } - } - }, - "definitions": { - "AllowanceInfo": { - "type": "object", - "required": [ - "allowance", - "expires", - "spender" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "allowance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "download_logo": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DownloadLogoResponse", - "description": "When we download an embedded logo, we get this response type. We expect a SPA to be able to accept this info and display it.", - "type": "object", - "required": [ - "data", - "mime_type" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "mime_type": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "marketing_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MarketingInfoResponse", - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "logo": { - "description": "A link to the logo, or a comment there is an on-chain logo stored", - "anyOf": [ - { - "$ref": "#/definitions/LogoInfo" - }, - { - "type": "null" - } - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - }, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "LogoInfo": { - "description": "This is used to display logo info, provide a link or inform there is one that can be downloaded from the blockchain itself", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "There is an embedded logo on the chain, make another call to download it.", - "type": "string", - "enum": [ - "embedded" - ] - } - ] - } - } - }, - "minter": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MinterResponse", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "cap": { - "description": "cap is a hard cap on total supply that can be achieved by minting. Note that this refers to total_supply. If None, there is unlimited cap.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "minter": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "token_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/execute.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/execute.json deleted file mode 100644 index 84a11e3..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/execute.json +++ /dev/null @@ -1,984 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Transfer is a base message to move tokens to another account without triggering actions", - "type": "object", - "required": [ - "transfer" - ], - "properties": { - "transfer": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burn is a base message to destroy tokens forever", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Send is a base message to transfer tokens to a contract and trigger an action on the receiving contract.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "contract", - "msg" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Allows spender to access an additional amount tokens from the owner's (env.sender) account. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "increase_allowance" - ], - "properties": { - "increase_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Lowers the spender's access of tokens from the owner's (env.sender) account by amount. If expires is Some(), overwrites current allowance expiration with this one.", - "type": "object", - "required": [ - "decrease_allowance" - ], - "properties": { - "decrease_allowance": { - "type": "object", - "required": [ - "amount", - "spender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Transfers amount tokens from owner -> recipient if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "transfer_from" - ], - "properties": { - "transfer_from": { - "type": "object", - "required": [ - "amount", - "owner", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Sends amount tokens from owner -> contract if `env.sender` has sufficient pre-approval.", - "type": "object", - "required": [ - "send_from" - ], - "properties": { - "send_from": { - "type": "object", - "required": [ - "amount", - "contract", - "msg", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"approval\" extension. Destroys tokens forever", - "type": "object", - "required": [ - "burn_from" - ], - "properties": { - "burn_from": { - "type": "object", - "required": [ - "amount", - "owner" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "owner": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"mintable\" extension. If authorized, creates amount new tokens and adds to the recipient balance.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "amount", - "recipient" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "recipient": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with the \"marketing\" extension. If authorized, updates marketing metadata. Setting None/null for any of these will leave it unchanged. Setting Some(\"\") will clear this field on the contract storage", - "type": "object", - "required": [ - "update_marketing" - ], - "properties": { - "update_marketing": { - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "type": [ - "string", - "null" - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If set as the \"marketing\" role on the contract, upload a new URL, SVG, or PNG for the token", - "type": "object", - "required": [ - "upload_logo" - ], - "properties": { - "upload_logo": { - "$ref": "#/definitions/Logo" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/instantiate.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/instantiate.json deleted file mode 100644 index da8be0a..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/instantiate.json +++ /dev/null @@ -1,242 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "decimals", - "initial_balances", - "kernel_address", - "name", - "symbol" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "initial_balances": { - "type": "array", - "items": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "kernel_address": { - "type": "string" - }, - "marketing": { - "anyOf": [ - { - "$ref": "#/definitions/InstantiateMarketingInfo" - }, - { - "type": "null" - } - ] - }, - "mint": { - "anyOf": [ - { - "$ref": "#/definitions/MinterResponse" - }, - { - "type": "null" - } - ] - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "name": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "symbol": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "EmbeddedLogo": { - "description": "This is used to store the logo on the blockchain in an accepted format. Enforce maximum size of 5KB on all variants.", - "oneOf": [ - { - "description": "Store the Logo as an SVG file. The content must conform to the spec at https://en.wikipedia.org/wiki/Scalable_Vector_Graphics (The contract should do some light-weight sanity-check validation)", - "type": "object", - "required": [ - "svg" - ], - "properties": { - "svg": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - }, - { - "description": "Store the Logo as a PNG file. This will likely only support up to 64x64 or so within the 5KB limit.", - "type": "object", - "required": [ - "png" - ], - "properties": { - "png": { - "$ref": "#/definitions/Binary" - } - }, - "additionalProperties": false - } - ] - }, - "InstantiateMarketingInfo": { - "type": "object", - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "logo": { - "anyOf": [ - { - "$ref": "#/definitions/Logo" - }, - { - "type": "null" - } - ] - }, - "marketing": { - "type": [ - "string", - "null" - ] - }, - "project": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Logo": { - "description": "This is used for uploading logo data, or setting it in InstantiateData", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "Logo content stored on the blockchain. Enforce maximum size of 5KB on all variants", - "type": "object", - "required": [ - "embedded" - ], - "properties": { - "embedded": { - "$ref": "#/definitions/EmbeddedLogo" - } - }, - "additionalProperties": false - } - ] - }, - "MinterResponse": { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "cap": { - "description": "cap is a hard cap on total supply that can be achieved by minting. Note that this refers to total_supply. If None, there is unlimited cap.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "minter": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/query.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/query.json deleted file mode 100644 index 65a6027..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/query.json +++ /dev/null @@ -1,379 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Returns the current balance of the given address, 0 if unset. Return type: BalanceResponse. Returns metadata on the contract - name, decimals, supply, etc. Return type: TokenInfoResponse.", - "type": "object", - "required": [ - "token_info" - ], - "properties": { - "token_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"mintable\" extension. Returns who can mint and the hard cap on maximum tokens after minting. Return type: MinterResponse.", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"allowance\" extension. Returns how much spender can use from owner account, 0 if unset. Return type: AllowanceResponse.", - "type": "object", - "required": [ - "allowance" - ], - "properties": { - "allowance": { - "type": "object", - "required": [ - "owner", - "spender" - ], - "properties": { - "owner": { - "type": "string" - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension (and \"allowances\") Returns all allowances this owner has approved. Supports pagination. Return type: AllAllowancesResponse.", - "type": "object", - "required": [ - "all_allowances" - ], - "properties": { - "all_allowances": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"enumerable\" extension Returns all accounts that have balances. Supports pagination. Return type: AllAccountsResponse.", - "type": "object", - "required": [ - "all_accounts" - ], - "properties": { - "all_accounts": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Returns more metadata on the contract to display in the client: - description, logo, project url, etc. Return type: MarketingInfoResponse", - "type": "object", - "required": [ - "marketing_info" - ], - "properties": { - "marketing_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Only with \"marketing\" extension Downloads the mbeded logo data (if stored on chain). Errors if no logo data ftored for this contract. Return type: DownloadLogoResponse.", - "type": "object", - "required": [ - "download_logo" - ], - "properties": { - "download_logo": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_accounts.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_accounts.json deleted file mode 100644 index cea50fb..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_accounts.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAccountsResponse", - "type": "object", - "required": [ - "accounts" - ], - "properties": { - "accounts": { - "type": "array", - "items": { - "type": "string" - } - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_allowances.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_allowances.json deleted file mode 100644 index 0128722..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_all_allowances.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllAllowancesResponse", - "type": "object", - "required": [ - "allowances" - ], - "properties": { - "allowances": { - "type": "array", - "items": { - "$ref": "#/definitions/AllowanceInfo" - } - } - }, - "definitions": { - "AllowanceInfo": { - "type": "object", - "required": [ - "allowance", - "expires", - "spender" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - }, - "spender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_allowance.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_allowance.json deleted file mode 100644 index dbaf97d..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_allowance.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllowanceResponse", - "type": "object", - "required": [ - "allowance", - "expires" - ], - "properties": { - "allowance": { - "$ref": "#/definitions/Uint128" - }, - "expires": { - "$ref": "#/definitions/Expiration" - } - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_balance.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_download_logo.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_download_logo.json deleted file mode 100644 index c5aa32b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_download_logo.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "DownloadLogoResponse", - "description": "When we download an embedded logo, we get this response type. We expect a SPA to be able to accept this info and display it.", - "type": "object", - "required": [ - "data", - "mime_type" - ], - "properties": { - "data": { - "$ref": "#/definitions/Binary" - }, - "mime_type": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_marketing_info.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_marketing_info.json deleted file mode 100644 index c36ee5f..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_marketing_info.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MarketingInfoResponse", - "type": "object", - "properties": { - "description": { - "description": "A longer description of the token and it's utility. Designed for tooltips or such", - "type": [ - "string", - "null" - ] - }, - "logo": { - "description": "A link to the logo, or a comment there is an on-chain logo stored", - "anyOf": [ - { - "$ref": "#/definitions/LogoInfo" - }, - { - "type": "null" - } - ] - }, - "marketing": { - "description": "The address (if any) who can update this data structure", - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - }, - "project": { - "description": "A URL pointing to the project behind this token.", - "type": [ - "string", - "null" - ] - } - }, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "LogoInfo": { - "description": "This is used to display logo info, provide a link or inform there is one that can be downloaded from the blockchain itself", - "oneOf": [ - { - "description": "A reference to an externally hosted logo. Must be a valid HTTP or HTTPS URL.", - "type": "object", - "required": [ - "url" - ], - "properties": { - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "description": "There is an embedded logo on the chain, make another call to download it.", - "type": "string", - "enum": [ - "embedded" - ] - } - ] - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_minter.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_minter.json deleted file mode 100644 index eaf9718..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_minter.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MinterResponse", - "type": "object", - "required": [ - "minter" - ], - "properties": { - "cap": { - "description": "cap is a hard cap on total supply that can be achieved by minting. Note that this refers to total_supply. If None, there is unlimited cap.", - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "minter": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_operators.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_owner.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissions.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_token_info.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_token_info.json deleted file mode 100644 index 0e84d12..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_token_info.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenInfoResponse", - "type": "object", - "required": [ - "decimals", - "name", - "symbol", - "total_supply" - ], - "properties": { - "decimals": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - }, - "total_supply": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_type.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_version.json b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/contract.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/contract.rs index c1bcffb..eae01a9 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/contract.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/contract.rs @@ -1,26 +1,22 @@ -use andromeda_fungible_tokens::cw20::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use andromeda_fungible_tokens::cw20::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ - ado_base::{ - hooks::AndromedaHook, AndromedaMsg, AndromedaQuery, InstantiateMsg as BaseInstantiateMsg, - }, + ado_base::{AndromedaMsg, AndromedaQuery, InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::Funds, - common::{context::ExecuteContext, encode_binary}, - error::{from_semver, ContractError}, + amp::AndrAddr, + common::{actions::call_action, context::ExecuteContext, encode_binary, Funds}, + error::ContractError, }; use cosmwasm_std::entry_point; use cosmwasm_std::{ - ensure, from_json, to_json_binary, Addr, Api, Binary, CosmosMsg, Deps, DepsMut, Env, - MessageInfo, Response, StdResult, Storage, SubMsg, Uint128, WasmMsg, + from_json, to_json_binary, Addr, Api, Binary, CosmosMsg, Deps, DepsMut, Env, MessageInfo, + Response, StdResult, Storage, SubMsg, Uint128, WasmMsg, }; -use cw2::{get_contract_version, set_contract_version}; use cw20::{Cw20Coin, Cw20ExecuteMsg}; use cw20_base::{ contract::{execute as execute_cw20, instantiate as cw20_instantiate, query as cw20_query}, state::BALANCES, }; -use semver::Version; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-cw20"; @@ -28,34 +24,28 @@ const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - deps: DepsMut, + mut deps: DepsMut, env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; let contract = ADOContract::default(); + let cw20_resp = cw20_instantiate(deps.branch(), env.clone(), info.clone(), msg.clone().into())?; let resp = contract.instantiate( deps.storage, - env.clone(), + env, deps.api, + &deps.querier, info.clone(), BaseInstantiateMsg { - ado_type: "cw20".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, - kernel_address: msg.clone().kernel_address, + kernel_address: msg.kernel_address.clone(), owner: msg.clone().owner, }, )?; - let modules_resp = - contract.register_modules(info.sender.as_str(), deps.storage, msg.clone().modules)?; - - let cw20_resp = cw20_instantiate(deps, env, info, msg.into())?; Ok(resp - .add_submessages(modules_resp.messages) - .add_attributes(modules_resp.attributes) .add_submessages(cw20_resp.messages) .add_attributes(cw20_resp.attributes)) } @@ -77,27 +67,39 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let contract = ADOContract::default(); - if !matches!(msg, ExecuteMsg::UpdateAppContract { .. }) - && !matches!(msg, ExecuteMsg::UpdateOwner { .. }) - { - contract.module_hook::( - &ctx.deps.as_ref(), - AndromedaHook::OnExecute { - sender: ctx.info.sender.to_string(), - payload: encode_binary(&msg)?, - }, - )?; - } - match msg { - ExecuteMsg::Transfer { recipient, amount } => execute_transfer(ctx, recipient, amount), +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + + let _contract = ADOContract::default(); + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + let res = match msg { + ExecuteMsg::Transfer { recipient, amount } => { + execute_transfer(ctx, recipient, amount, action) + } + ExecuteMsg::TransferFrom { + owner, + recipient, + amount, + } => execute_transfer_from(ctx, recipient, owner, amount, action), ExecuteMsg::Burn { amount } => execute_burn(ctx, amount), ExecuteMsg::Send { contract, amount, msg, - } => execute_send(ctx, contract, amount, msg), + } => execute_send(ctx, contract, amount, msg, action), + ExecuteMsg::SendFrom { + owner, + contract, + amount, + msg, + } => execute_send_from(ctx, contract, amount, msg, action, owner), ExecuteMsg::Mint { recipient, amount } => execute_mint(ctx, recipient, amount), _ => { let serialized = encode_binary(&msg)?; @@ -106,50 +108,103 @@ pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result Ok(execute_cw20(ctx.deps, ctx.env, ctx.info, msg.into())?), } } - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } fn execute_transfer( ctx: ExecuteContext, - recipient: String, + recipient: AndrAddr, + amount: Uint128, + action: String, +) -> Result { + handle_transfer(ctx, recipient, None, amount, action, false) +} + +fn execute_transfer_from( + ctx: ExecuteContext, + recipient: AndrAddr, + owner: String, + amount: Uint128, + action: String, +) -> Result { + handle_transfer(ctx, recipient, Some(owner), amount, action, true) +} + +fn handle_transfer( + ctx: ExecuteContext, + recipient: AndrAddr, + owner: Option, amount: Uint128, + action: String, + is_transfer_from: bool, ) -> Result { let ExecuteContext { deps, info, env, .. } = ctx; - let (msgs, events, remainder) = ADOContract::default().on_funds_transfer( - &deps.as_ref(), - info.sender.to_string(), + let transfer_response = ADOContract::default().query_deducted_funds( + deps.as_ref(), + action, Funds::Cw20(Cw20Coin { address: env.contract.address.to_string(), amount, }), - to_json_binary(&ExecuteMsg::Transfer { - amount, - recipient: recipient.clone(), - })?, )?; + match transfer_response { + Some(transfer_response) => { + let remaining_amount = match transfer_response.leftover_funds { + Funds::Native(..) => amount, // Handle the case where remaining amount is native funds + Funds::Cw20(coin) => coin.amount, + }; + + let mut resp = filter_out_cw20_messages( + transfer_response.msgs, + deps.storage, + deps.api, + &info.sender, + )?; + + let recipient = recipient.get_raw_address(&deps.as_ref())?.into_string(); + let cw20_msg = if is_transfer_from { + Cw20ExecuteMsg::TransferFrom { + recipient, + owner: owner.expect("Owner should be provided for TransferFrom"), + amount: remaining_amount, + } + } else { + Cw20ExecuteMsg::Transfer { + recipient, + amount: remaining_amount, + } + }; + + let cw20_resp = execute_cw20(deps, env, info, cw20_msg)?; + resp = resp + .add_submessages(cw20_resp.messages) + .add_attributes(cw20_resp.attributes) + .add_events(transfer_response.events); + Ok(resp) + } + None => { + let recipient = recipient.get_raw_address(&deps.as_ref())?.into_string(); + let cw20_msg = if is_transfer_from { + Cw20ExecuteMsg::TransferFrom { + recipient, + owner: owner.expect("Owner should be provided for TransferFrom"), + amount, + } + } else { + Cw20ExecuteMsg::Transfer { recipient, amount } + }; - let remaining_amount = match remainder { - Funds::Native(..) => amount, //What do we do in the case that the rates returns remaining amount as native funds? - Funds::Cw20(coin) => coin.amount, - }; - - let mut resp = filter_out_cw20_messages(msgs, deps.storage, deps.api, &info.sender)?; - - // Continue with standard cw20 operation - let cw20_resp = execute_cw20( - deps, - env, - info, - Cw20ExecuteMsg::Transfer { - recipient, - amount: remaining_amount, - }, - )?; - resp = resp.add_attributes(cw20_resp.attributes).add_events(events); - Ok(resp) + let cw20_resp = execute_cw20(deps, env, info, cw20_msg)?; + Ok(cw20_resp) + } + } } fn transfer_tokens( @@ -168,7 +223,9 @@ fn transfer_tokens( BALANCES.update( storage, recipient, - |balance: Option| -> StdResult<_> { Ok(balance.unwrap_or_default() + amount) }, + |balance: Option| -> StdResult<_> { + Ok(balance.unwrap_or_default().checked_add(amount)?) + }, )?; Ok(()) } @@ -188,51 +245,104 @@ fn execute_burn(ctx: ExecuteContext, amount: Uint128) -> Result Result { + handle_send(ctx, contract, amount, msg, action, None, false) +} + +fn execute_send_from( + ctx: ExecuteContext, + contract: AndrAddr, + amount: Uint128, + msg: Binary, + action: String, + owner: String, +) -> Result { + handle_send(ctx, contract, amount, msg, action, Some(owner), true) +} + +fn handle_send( + ctx: ExecuteContext, + contract: AndrAddr, + amount: Uint128, + msg: Binary, + action: String, + owner: Option, + is_send_from: bool, ) -> Result { let ExecuteContext { deps, info, env, .. } = ctx; - let (msgs, events, remainder) = ADOContract::default().on_funds_transfer( - &deps.as_ref(), - info.sender.to_string(), + let rates_response = ADOContract::default().query_deducted_funds( + deps.as_ref(), + action, Funds::Cw20(Cw20Coin { address: env.contract.address.to_string(), amount, }), - to_json_binary(&ExecuteMsg::Send { - amount, - contract: contract.clone(), - msg: msg.clone(), - })?, - )?; - - let remaining_amount = match remainder { - Funds::Native(..) => amount, //What do we do in the case that the rates returns remaining amount as native funds? - Funds::Cw20(coin) => coin.amount, - }; - - let mut resp = filter_out_cw20_messages(msgs, deps.storage, deps.api, &info.sender)?; - - let cw20_resp = execute_cw20( - deps, - env, - info, - Cw20ExecuteMsg::Send { - contract, - amount: remaining_amount, - msg, - }, )?; - resp = resp - .add_attributes(cw20_resp.attributes) - .add_events(events) - .add_submessages(cw20_resp.messages); - - Ok(resp) + match rates_response { + Some(rates_response) => { + let remaining_amount = match rates_response.leftover_funds { + Funds::Native(..) => amount, // Handle the case where remaining amount is native funds + Funds::Cw20(coin) => coin.amount, + }; + + let mut resp = filter_out_cw20_messages( + rates_response.msgs, + deps.storage, + deps.api, + &info.sender, + )?; + let contract = contract.get_raw_address(&deps.as_ref())?.to_string(); + let cw20_msg = if is_send_from { + Cw20ExecuteMsg::SendFrom { + contract, + amount: remaining_amount, + msg, + owner: owner.expect("Owner should be provided for SendFrom"), + } + } else { + Cw20ExecuteMsg::Send { + contract, + amount: remaining_amount, + msg, + } + }; + + let cw20_resp = execute_cw20(deps, env, info, cw20_msg)?; + resp = resp + .add_submessages(cw20_resp.messages) + .add_attributes(cw20_resp.attributes) + .add_events(rates_response.events); + + Ok(resp) + } + None => { + let contract = contract.get_raw_address(&deps.as_ref())?.to_string(); + let cw20_msg = if is_send_from { + Cw20ExecuteMsg::SendFrom { + contract, + amount, + msg, + owner: owner.expect("Owner should be provided for SendFrom"), + } + } else { + Cw20ExecuteMsg::Send { + contract, + amount, + msg, + } + }; + + let cw20_resp = execute_cw20(deps, env, info, cw20_msg)?; + Ok(cw20_resp) + } + } } fn execute_mint( @@ -280,36 +390,7 @@ fn filter_out_cw20_messages( #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/mock.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/mock.rs index d577e7d..c545a18 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/mock.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/mock.rs @@ -1,11 +1,138 @@ #![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] - use crate::contract::{execute, instantiate, query}; use andromeda_fungible_tokens::cw20::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use common::ado_base::modules::Module; -use cosmwasm_std::{Binary, Empty, Uint128}; +use andromeda_std::ado_base::rates::Rate; +use andromeda_std::ado_base::rates::RatesMessage; +use andromeda_std::amp::AndrAddr; +use andromeda_testing::mock_contract::ExecuteResult; +use andromeda_testing::MockADO; +use andromeda_testing::MockContract; +use andromeda_testing::{mock::MockApp, mock_ado}; +use cosmwasm_schema::serde::Serialize; +use cosmwasm_std::to_json_binary; +use cosmwasm_std::{Addr, Binary, Empty, Uint128}; +use cw20::BalanceResponse; use cw20::MinterResponse; +use cw_multi_test::Executor; use cw_multi_test::{Contract, ContractWrapper}; +pub struct MockCW20(Addr); +mock_ado!(MockCW20, ExecuteMsg, QueryMsg); + +impl MockCW20 { + #[allow(clippy::too_many_arguments)] + pub fn instantiate( + code_id: u64, + sender: Addr, + app: &mut MockApp, + owner: Option, + name: String, + symbol: String, + decimals: u8, + initial_balances: Vec, + mint: Option, + kernel_address: String, + ) -> MockCW20 { + let msg = mock_cw20_instantiate_msg( + owner, + name, + symbol, + decimals, + initial_balances, + mint, + kernel_address, + ); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "CW20 Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockCW20(addr) + } + + pub fn execute_send( + &self, + app: &mut MockApp, + sender: Addr, + contract: impl Into, + amount: Uint128, + msg: &impl Serialize, + ) -> ExecuteResult { + self.execute( + app, + &mock_cw20_send(contract, amount, to_json_binary(msg).unwrap()), + sender, + &[], + ) + } + + pub fn execute_send_from( + &self, + app: &mut MockApp, + sender: Addr, + contract: impl Into, + amount: Uint128, + owner: String, + msg: &impl Serialize, + ) -> ExecuteResult { + self.execute( + app, + &mock_cw20_send_from(contract, amount, owner, to_json_binary(msg).unwrap()), + sender, + &[], + ) + } + + pub fn execute_transfer_from( + &self, + app: &mut MockApp, + sender: Addr, + recipient: impl Into, + amount: Uint128, + owner: String, + ) -> ExecuteResult { + self.execute( + app, + &mock_cw20_transfer_from(recipient, amount, owner), + sender, + &[], + ) + } + + pub fn execute_increase_allowance( + &self, + app: &mut MockApp, + sender: Addr, + spender: String, + amount: Uint128, + ) -> ExecuteResult { + self.execute( + app, + &mock_cw20_increase_allowance(spender, amount), + sender, + &[], + ) + } + + pub fn execute_add_rate( + &self, + app: &mut MockApp, + sender: Addr, + action: String, + rate: Rate, + ) -> ExecuteResult { + self.execute(app, &mock_set_rate_msg(action, rate), sender, &[]) + } + + pub fn query_balance(&self, app: &MockApp, address: impl Into) -> Uint128 { + self.query::(app, mock_get_cw20_balance(address)) + .balance + } +} pub fn mock_andromeda_cw20() -> Box> { let contract = ContractWrapper::new_with_empty(execute, instantiate, query); @@ -16,14 +143,15 @@ pub fn mock_minter(minter: String, cap: Option) -> MinterResponse { MinterResponse { minter, cap } } +#[allow(clippy::too_many_arguments)] pub fn mock_cw20_instantiate_msg( + owner: Option, name: String, symbol: String, decimals: u8, initial_balances: Vec, mint: Option, - modules: Option>, - kernel_address: Option, + kernel_address: String, ) -> InstantiateMsg { InstantiateMsg { name, @@ -32,23 +160,66 @@ pub fn mock_cw20_instantiate_msg( initial_balances, mint, marketing: None, - modules, kernel_address, + owner, } } -pub fn mock_get_cw20_balance(address: String) -> QueryMsg { - QueryMsg::Balance { address } +pub fn mock_get_cw20_balance(address: impl Into) -> QueryMsg { + QueryMsg::Balance { + address: address.into(), + } +} +pub fn mock_get_version() -> QueryMsg { + QueryMsg::Version {} } -pub fn mock_cw20_send(contract: String, amount: Uint128, msg: Binary) -> ExecuteMsg { +pub fn mock_cw20_send(contract: impl Into, amount: Uint128, msg: Binary) -> ExecuteMsg { ExecuteMsg::Send { - contract, + contract: AndrAddr::from_string(contract.into()), + amount, + msg, + } +} + +pub fn mock_cw20_send_from( + contract: impl Into, + amount: Uint128, + owner: String, + msg: Binary, +) -> ExecuteMsg { + ExecuteMsg::SendFrom { + contract: AndrAddr::from_string(contract.into()), amount, msg, + owner, + } +} + +pub fn mock_cw20_transfer_from( + contract: impl Into, + amount: Uint128, + owner: String, +) -> ExecuteMsg { + ExecuteMsg::TransferFrom { + recipient: AndrAddr::from_string(contract.into()), + amount, + owner, } } -pub fn mock_cw20_transfer(recipient: String, amount: Uint128) -> ExecuteMsg { +pub fn mock_cw20_transfer(recipient: AndrAddr, amount: Uint128) -> ExecuteMsg { ExecuteMsg::Transfer { recipient, amount } } + +pub fn mock_cw20_increase_allowance(spender: String, amount: Uint128) -> ExecuteMsg { + ExecuteMsg::IncreaseAllowance { + spender, + amount, + expires: None, + } +} + +pub fn mock_set_rate_msg(action: String, rate: Rate) -> ExecuteMsg { + ExecuteMsg::Rates(RatesMessage::SetRate { action, rate }) +} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/mock_querier.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/mock_querier.rs index ffe3f13..b47be84 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/mock_querier.rs @@ -1,23 +1,16 @@ use andromeda_fungible_tokens::cw20::QueryMsg as Cw20Query; - -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; + use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; -pub use andromeda_std::testing::mock_querier::{MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT}; use cosmwasm_std::testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage}; use cosmwasm_std::{ - from_json, to_json_binary, BankMsg, Binary, Coin, ContractResult, CosmosMsg, OwnedDeps, - Querier, QuerierResult, QueryRequest, Response, SubMsg, SystemError, SystemResult, Uint128, - WasmQuery, + from_json, to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, + QuerierWrapper, QueryRequest, SystemError, SystemResult, WasmQuery, }; pub const MOCK_CW20_CONTRACT: &str = "mock_cw20_contract"; -pub const MOCK_RATES_CONTRACT: &str = "mock_rates_contract"; -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; pub fn mock_dependencies_custom( contract_balance: &[Coin], @@ -36,11 +29,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "cw20".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -76,10 +70,7 @@ impl WasmMockQuerier { match &request { QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { match contract_addr.as_str() { - // MOCK_TOKEN_CONTRACT => self.handle_token_query(msg), MOCK_CW20_CONTRACT => self.handle_cw20_query(msg), - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } @@ -100,81 +91,6 @@ impl WasmMockQuerier { _ => panic!("Unsupported Query"), } } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - // TODO: IMPLEMENT CW20 - Funds::Cw20(_) => { - let resp = OnFundsTransferResponse::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } } impl WasmMockQuerier { pub fn new(base: MockQuerier) -> Self { diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs index 5a5df6c..3d3a1e8 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-cw20/src/testing/tests.rs @@ -1,32 +1,47 @@ use crate::contract::{execute, instantiate, query}; use crate::testing::mock_querier::mock_dependencies_custom; use andromeda_fungible_tokens::cw20::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use andromeda_std::testing::mock_querier::MOCK_ADDRESS_LIST_CONTRACT; -use andromeda_std::{ - ado_base::Module, amp::addresses::AndrAddr, error::ContractError, - testing::mock_querier::MOCK_KERNEL_CONTRACT, -}; +use andromeda_std::ado_base::permissioning::{LocalPermission, Permission}; +use andromeda_std::ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}; +use andromeda_std::ado_contract::ADOContract; +use andromeda_std::amp::{AndrAddr, Recipient}; +use andromeda_std::common::context::ExecuteContext; + +use andromeda_std::{error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT}; +use andromeda_testing::economics_msg::generate_economics_message; +use cosmwasm_std::{attr, Decimal, Event}; use cosmwasm_std::{ testing::{mock_env, mock_info}, - to_json_binary, Addr, DepsMut, Response, StdError, Uint128, + to_json_binary, Addr, DepsMut, Response, Uint128, }; + use cw20::{Cw20Coin, Cw20ReceiveMsg}; use cw20_base::state::BALANCES; use super::mock_querier::MOCK_CW20_CONTRACT; -fn init(deps: DepsMut, modules: Option>) -> Response { +fn init(deps: DepsMut) -> Response { let msg = InstantiateMsg { name: MOCK_CW20_CONTRACT.into(), symbol: "Symbol".into(), decimals: 6, - initial_balances: vec![Cw20Coin { - amount: 1000u128.into(), - address: "sender".to_string(), - }], + initial_balances: vec![ + Cw20Coin { + amount: 1000u128.into(), + address: "sender".to_string(), + }, + Cw20Coin { + amount: 1u128.into(), + address: "rates_recipient".to_string(), + }, + Cw20Coin { + amount: 1u128.into(), + address: "royalty_recipient".to_string(), + }, + ], mint: None, marketing: None, - modules, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }; @@ -38,7 +53,7 @@ fn init(deps: DepsMut, modules: Option>) -> Response { #[test] fn test_andr_query() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); let msg = QueryMsg::Owner {}; let res = query(deps.as_ref(), mock_env(), msg); @@ -48,21 +63,14 @@ fn test_andr_query() { #[test] fn test_transfer() { - let modules: Vec = vec![Module { - name: Some(MOCK_ADDRESS_LIST_CONTRACT.to_owned()), - address: AndrAddr::from_string(MOCK_ADDRESS_LIST_CONTRACT.to_owned()), - - is_mutable: false, - }]; - let mut deps = mock_dependencies_custom(&[]); - let res = init(deps.as_mut(), Some(modules)); + let res = init(deps.as_mut()); assert_eq!( Response::new() .add_attribute("method", "instantiate") .add_attribute("type", "cw20") - .add_attribute("action", "register_module") - .add_attribute("module_idx", "1"), + .add_attribute("kernel_address", MOCK_KERNEL_CONTRACT) + .add_attribute("owner", "owner"), res ); @@ -74,29 +82,66 @@ fn test_transfer() { ); let msg = ExecuteMsg::Transfer { - recipient: "other".into(), + recipient: AndrAddr::from_string("other"), amount: 100u128.into(), }; - let not_whitelisted_info = mock_info("not_whitelisted", &[]); - let res = execute(deps.as_mut(), mock_env(), not_whitelisted_info, msg.clone()); - assert_eq!( - ContractError::Std(StdError::generic_err( - "Querier contract error: InvalidAddress" - )), - res.unwrap_err() - ); + // Set a royalty of 10% to be paid to royalty_recipient + let rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Deductive, + recipients: vec![Recipient { + address: AndrAddr::from_string("royalty_recipient".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(10), + }), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Transfer", rate) + .unwrap(); + + // The expected events for the royalty + let expected_event = Event::new("royalty").add_attributes(vec![ + attr("deducted", "10cosmos2contract"), + attr("payment", "royalty_recipient<10cosmos2contract"), + ]); + + // Blacklist the sender who otherwise would have been able to call the function successfully + let permission = Permission::Local(LocalPermission::blacklisted(None)); + let actors = vec![AndrAddr::from_string("sender")]; + let action = "Transfer"; + let ctx = ExecuteContext::new(deps.as_mut(), mock_info("owner", &[]), mock_env()); + ADOContract::default() + .execute_set_permission(ctx, actors, action, permission) + .unwrap(); let info = mock_info("sender", &[]); + let err = execute(deps.as_mut(), mock_env(), info.clone(), msg.clone()).unwrap_err(); + + assert_eq!(err, ContractError::Unauthorized {}); + + // Now whitelist the sender, that should allow him to call the function successfully + let permission = Permission::Local(LocalPermission::whitelisted(None)); + let actors = vec![AndrAddr::from_string("sender")]; + let action = "Transfer"; + let ctx = ExecuteContext::new(deps.as_mut(), mock_info("owner", &[]), mock_env()); + ADOContract::default() + .execute_set_permission(ctx, actors, action, permission) + .unwrap(); let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!( Response::new() - // .add_event(Event::new("Royalty")) - // .add_event(Event::new("Tax")) + .add_event(expected_event) .add_attribute("action", "transfer") .add_attribute("from", "sender") .add_attribute("to", "other") - .add_attribute("amount", "100"), + .add_attribute("amount", "90") + .add_submessage(generate_economics_message("sender", "Transfer")), res ); @@ -108,21 +153,21 @@ fn test_transfer() { .unwrap() ); - // Funds given to the receiver. + // Funds given to the receiver. Remove 10 for the royalty assert_eq!( - Uint128::from(100u128), + Uint128::from(100u128 - 10u128), BALANCES .load(deps.as_ref().storage, &Addr::unchecked("other")) .unwrap() ); - // Royalty given to rates_recipient - // assert_eq!( - // Uint128::from(0u128), - // BALANCES - // .load(deps.as_ref().storage, &Addr::unchecked("rates_recipient")) - // .unwrap() - // ); + // Royalty given to royalty_recipient + assert_eq!( + Uint128::from(1u128 + 10u128), + BALANCES + .load(deps.as_ref().storage, &Addr::unchecked("royalty_recipient")) + .unwrap() + ); } #[test] @@ -130,12 +175,14 @@ fn test_send() { let mut deps = mock_dependencies_custom(&[]); let info = mock_info("sender", &[]); - let res = init(deps.as_mut(), None); + let res = init(deps.as_mut()); assert_eq!( Response::new() .add_attribute("method", "instantiate") - .add_attribute("type", "cw20"), + .add_attribute("type", "cw20") + .add_attribute("kernel_address", MOCK_KERNEL_CONTRACT) + .add_attribute("owner", "owner"), res ); @@ -146,13 +193,33 @@ fn test_send() { .unwrap() ); + let rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("rates_recipient".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(10), + }), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Send", rate) + .unwrap(); + let msg = ExecuteMsg::Send { - contract: "contract".into(), + contract: AndrAddr::from_string("contract".to_string()), amount: 100u128.into(), msg: to_json_binary(&"msg").unwrap(), }; let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + let expected_event = Event::new("tax") + .add_attributes(vec![attr("payment", "rates_recipient<10cosmos2contract")]); assert_eq!( Response::new() @@ -168,13 +235,15 @@ fn test_send() { } .into_cosmos_msg("contract") .unwrap(), - ), + ) + .add_event(expected_event) + .add_submessage(generate_economics_message("sender", "Send")), res ); // Funds deducted from the sender (100 for send, 10 for tax). assert_eq!( - Uint128::from(900u128), + Uint128::from(1_000u128 - 100u128 - 10u128), BALANCES .load(deps.as_ref().storage, &Addr::unchecked("sender")) .unwrap() @@ -187,4 +256,12 @@ fn test_send() { .load(deps.as_ref().storage, &Addr::unchecked("contract")) .unwrap() ); + + // The rates recipient started with a balance of 1, and received 10 from the tax + assert_eq!( + Uint128::from(1u128 + 10u128), + BALANCES + .load(deps.as_ref().storage, &Addr::unchecked("rates_recipient")) + .unwrap() + ); } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml index 8d19633..16f4c60 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-lockdrop" -version = "0.2.1" +version = "2.0.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -21,15 +21,16 @@ cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw-asset = { workspace = true } -cw2 = { workspace = true } + cw20 = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true } andromeda-fungible-tokens = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } +andromeda-testing = { workspace = true } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/README.md b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/README.md new file mode 100644 index 0000000..8b400a4 --- /dev/null +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/README.md @@ -0,0 +1,5 @@ +# Overview + +The Lockdrop ADO is another part of the toolkit of allowing a user to set up their own CW20 token. The lockdrop ADO allows users to deposit a native token to be locked for a certain period of time, in exchange for a given CW20 token reward. + +[Lockdrop Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/lockdrop) \ No newline at end of file diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/andromeda-lockdrop.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/andromeda-lockdrop.json deleted file mode 100644 index e817b42..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/andromeda-lockdrop.json +++ /dev/null @@ -1,1630 +0,0 @@ -{ - "contract_name": "andromeda-lockdrop", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "deposit_window", - "incentive_token", - "init_timestamp", - "kernel_address", - "native_denom", - "withdrawal_window" - ], - "properties": { - "deposit_window": { - "description": "Number of seconds for which lockup deposits will be accepted", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "incentive_token": { - "description": "The token being given as incentive.", - "type": "string" - }, - "init_timestamp": { - "description": "The bootsrap contract to be used in the second phase. Timestamp till when deposits can be made", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "native_denom": { - "description": "The native token being deposited.", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "withdrawal_window": { - "description": "Number of seconds for which lockup withdrawals will be allowed", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Function to deposit native fund in the contract in exchange for recieving a proportion of the TOKEN.", - "type": "object", - "required": [ - "deposit_native" - ], - "properties": { - "deposit_native": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Function to withdraw native fund from the lockup position.", - "type": "object", - "required": [ - "withdraw_native" - ], - "properties": { - "withdraw_native": { - "type": "object", - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Facilitates reward claim after claims are enabled.", - "type": "object", - "required": [ - "claim_rewards" - ], - "properties": { - "claim_rewards": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Called by the bootstrap contract when liquidity is added to the TOKEN-NATIVE Pool to enable TOKEN withdrawals by users.", - "type": "object", - "required": [ - "enable_claims" - ], - "properties": { - "enable_claims": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Called by the owner after the phase is over to withdraw all of the NATIVE token to the given recipient, or themselves if not specified.", - "type": "object", - "required": [ - "withdraw_proceeds" - ], - "properties": { - "withdraw_proceeds": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the config information.", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the state information.", - "type": "object", - "required": [ - "state" - ], - "properties": { - "state": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets information for the user with `address`.", - "type": "object", - "required": [ - "user_info" - ], - "properties": { - "user_info": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the withdrawal percent allowed given the timestamp, or the current time if not specified.", - "type": "object", - "required": [ - "withdrawal_percent_allowed" - ], - "properties": { - "withdrawal_percent_allowed": { - "type": "object", - "properties": { - "timestamp": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConfigResponse", - "type": "object", - "required": [ - "deposit_window", - "incentive_token", - "init_timestamp", - "lockdrop_incentives", - "native_denom", - "withdrawal_window" - ], - "properties": { - "deposit_window": { - "description": "Number of seconds for which lockup deposits will be accepted.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "incentive_token": { - "description": "The token being given as incentive.", - "type": "string" - }, - "init_timestamp": { - "description": "Bootstrap Contract address to which tokens can be delegated to for bootstrapping TOKEN-NATIVE Pool. Timestamp till when deposits can be made.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lockdrop_incentives": { - "description": "Total token lockdrop incentives to be distributed among the users.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "native_denom": { - "description": "The native token being deposited.", - "type": "string" - }, - "withdrawal_window": { - "description": "Number of seconds for which lockup withdrawals will be allowed.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "state": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StateResponse", - "type": "object", - "required": [ - "are_claims_allowed", - "total_native_locked" - ], - "properties": { - "are_claims_allowed": { - "description": "Boolean value indicating if the user can withdraw their token rewards or not.", - "type": "boolean" - }, - "total_native_locked": { - "description": "Total NATIVE deposited at the end of Lockdrop window. This value remains unchanged post the lockdrop window.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "user_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "UserInfoResponse", - "type": "object", - "required": [ - "is_lockdrop_claimed", - "total_incentives", - "total_native_locked", - "withdrawal_flag" - ], - "properties": { - "is_lockdrop_claimed": { - "type": "boolean" - }, - "total_incentives": { - "$ref": "#/definitions/Uint128" - }, - "total_native_locked": { - "$ref": "#/definitions/Uint128" - }, - "withdrawal_flag": { - "type": "boolean" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - }, - "withdrawal_percent_allowed": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Decimal", - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/execute.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/execute.json deleted file mode 100644 index 6ba86a5..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/execute.json +++ /dev/null @@ -1,729 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Function to deposit native fund in the contract in exchange for recieving a proportion of the TOKEN.", - "type": "object", - "required": [ - "deposit_native" - ], - "properties": { - "deposit_native": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Function to withdraw native fund from the lockup position.", - "type": "object", - "required": [ - "withdraw_native" - ], - "properties": { - "withdraw_native": { - "type": "object", - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Facilitates reward claim after claims are enabled.", - "type": "object", - "required": [ - "claim_rewards" - ], - "properties": { - "claim_rewards": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Called by the bootstrap contract when liquidity is added to the TOKEN-NATIVE Pool to enable TOKEN withdrawals by users.", - "type": "object", - "required": [ - "enable_claims" - ], - "properties": { - "enable_claims": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Called by the owner after the phase is over to withdraw all of the NATIVE token to the given recipient, or themselves if not specified.", - "type": "object", - "required": [ - "withdraw_proceeds" - ], - "properties": { - "withdraw_proceeds": { - "type": "object", - "properties": { - "recipient": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/instantiate.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/instantiate.json deleted file mode 100644 index 3a4f185..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/instantiate.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "deposit_window", - "incentive_token", - "init_timestamp", - "kernel_address", - "native_denom", - "withdrawal_window" - ], - "properties": { - "deposit_window": { - "description": "Number of seconds for which lockup deposits will be accepted", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "incentive_token": { - "description": "The token being given as incentive.", - "type": "string" - }, - "init_timestamp": { - "description": "The bootsrap contract to be used in the second phase. Timestamp till when deposits can be made", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "native_denom": { - "description": "The native token being deposited.", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "withdrawal_window": { - "description": "Number of seconds for which lockup withdrawals will be allowed", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/query.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/query.json deleted file mode 100644 index a93ff04..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/query.json +++ /dev/null @@ -1,305 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the config information.", - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the state information.", - "type": "object", - "required": [ - "state" - ], - "properties": { - "state": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets information for the user with `address`.", - "type": "object", - "required": [ - "user_info" - ], - "properties": { - "user_info": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the withdrawal percent allowed given the timestamp, or the current time if not specified.", - "type": "object", - "required": [ - "withdrawal_percent_allowed" - ], - "properties": { - "withdrawal_percent_allowed": { - "type": "object", - "properties": { - "timestamp": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_balance.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_config.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_config.json deleted file mode 100644 index 59b99f0..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_config.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConfigResponse", - "type": "object", - "required": [ - "deposit_window", - "incentive_token", - "init_timestamp", - "lockdrop_incentives", - "native_denom", - "withdrawal_window" - ], - "properties": { - "deposit_window": { - "description": "Number of seconds for which lockup deposits will be accepted.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "incentive_token": { - "description": "The token being given as incentive.", - "type": "string" - }, - "init_timestamp": { - "description": "Bootstrap Contract address to which tokens can be delegated to for bootstrapping TOKEN-NATIVE Pool. Timestamp till when deposits can be made.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "lockdrop_incentives": { - "description": "Total token lockdrop incentives to be distributed among the users.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "native_denom": { - "description": "The native token being deposited.", - "type": "string" - }, - "withdrawal_window": { - "description": "Number of seconds for which lockup withdrawals will be allowed.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_operators.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_owner.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissions.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_state.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_state.json deleted file mode 100644 index 3c18a22..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_state.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "StateResponse", - "type": "object", - "required": [ - "are_claims_allowed", - "total_native_locked" - ], - "properties": { - "are_claims_allowed": { - "description": "Boolean value indicating if the user can withdraw their token rewards or not.", - "type": "boolean" - }, - "total_native_locked": { - "description": "Total NATIVE deposited at the end of Lockdrop window. This value remains unchanged post the lockdrop window.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_type.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_user_info.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_user_info.json deleted file mode 100644 index 387aaf4..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_user_info.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "UserInfoResponse", - "type": "object", - "required": [ - "is_lockdrop_claimed", - "total_incentives", - "total_native_locked", - "withdrawal_flag" - ], - "properties": { - "is_lockdrop_claimed": { - "type": "boolean" - }, - "total_incentives": { - "$ref": "#/definitions/Uint128" - }, - "total_native_locked": { - "$ref": "#/definitions/Uint128" - }, - "withdrawal_flag": { - "type": "boolean" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_version.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_withdrawal_percent_allowed.json b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_withdrawal_percent_allowed.json deleted file mode 100644 index 83bac1c..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/schema/raw/response_to_withdrawal_percent_allowed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Decimal", - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs index 6da2c82..be5221f 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/contract.rs @@ -2,29 +2,29 @@ // https://github.com/mars-protocol/mars-periphery/tree/main/contracts/lockdrop use andromeda_fungible_tokens::lockdrop::{ - ConfigResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, StateResponse, + ConfigResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, StateResponse, UserInfoResponse, }; use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, - common::expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, - common::{context::ExecuteContext, encode_binary}, - error::{from_semver, ContractError}, + common::{ + actions::call_action, context::ExecuteContext, encode_binary, + expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, Milliseconds, MillisecondsExpiration, + }, + error::ContractError, }; use cosmwasm_std::{ensure, from_json, Binary, Deps, DepsMut, Env, MessageInfo, Response, Uint128}; use cosmwasm_std::{entry_point, Decimal}; use cw_asset::Asset; use crate::state::{Config, State, CONFIG, STATE, USER_INFO}; -use cw2::{get_contract_version, set_contract_version}; use cw20::Cw20ReceiveMsg; use cw_utils::nonpayable; -use semver::Version; // version info for migration info -const CONTRACT_NAME: &str = "andromeda-lockdrop"; +const CONTRACT_NAME: &str = "crates.io:andromeda-lockdrop"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); //---------------------------------------------------------------------------------------- @@ -38,11 +38,11 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - // CHECK :: init_timestamp needs to be valid ensure!( - msg.init_timestamp >= env.block.time.seconds(), + !msg.init_timestamp + .get_time(&env.block) + .is_in_past(&env.block), ContractError::StartTimeInThePast { current_time: env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO, current_block: env.block.height, @@ -51,15 +51,15 @@ pub fn instantiate( // CHECK :: deposit_window,withdrawal_window need to be valid (withdrawal_window < deposit_window) ensure!( - msg.deposit_window > 0 - && msg.withdrawal_window > 0 + !msg.deposit_window.is_zero() + && !msg.withdrawal_window.is_zero() && msg.withdrawal_window < msg.deposit_window, ContractError::InvalidWindow {} ); let config = Config { // bootstrap_contract_address: msg.bootstrap_contract, - init_timestamp: msg.init_timestamp, + init_timestamp: msg.init_timestamp.get_time(&env.block), deposit_window: msg.deposit_window, withdrawal_window: msg.withdrawal_window, lockdrop_incentives: Uint128::zero(), @@ -74,21 +74,17 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info.clone(), BaseInstantiateMsg { - ado_type: "lockdrop".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; - let mod_resp = - ADOContract::default().register_modules(info.sender.as_str(), deps.storage, msg.modules)?; - Ok(inst_resp - .add_attributes(mod_resp.attributes) - .add_submessages(mod_resp.messages)) + Ok(inst_resp) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -108,65 +104,34 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let contract = ADOContract::default(); - - if !matches!(msg, ExecuteMsg::UpdateAppContract { .. }) - && !matches!(msg, ExecuteMsg::UpdateOwner { .. }) - { - contract.module_hook::( - &ctx.deps.as_ref(), - AndromedaHook::OnExecute { - sender: ctx.info.sender.to_string(), - payload: encode_binary(&msg)?, - }, - )?; - } +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let _contract = ADOContract::default(); + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; - match msg { + let res = match msg { ExecuteMsg::Receive(msg) => receive_cw20(ctx, msg), ExecuteMsg::DepositNative {} => execute_deposit_native(ctx), ExecuteMsg::WithdrawNative { amount } => execute_withdraw_native(ctx, amount), ExecuteMsg::EnableClaims {} => execute_enable_claims(ctx), ExecuteMsg::ClaimRewards {} => execute_claim_rewards(ctx), - ExecuteMsg::WithdrawProceeds { recipient } => execute_withdraw_proceeds(ctx, recipient), - - _ => handle_execute(ctx, msg), - } + // ExecuteMsg::WithdrawProceeds { recipient } => execute_withdraw_proceeds(ctx, recipient), + _ => ADOContract::default().execute(ctx, msg), + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } pub fn receive_cw20( @@ -215,18 +180,21 @@ pub fn execute_increase_incentives( let mut config = CONFIG.load(deps.storage)?; ensure!( - info.sender == config.incentive_token, + info.sender == config.incentive_token.get_raw_address(&deps.as_ref())?, ContractError::InvalidFunds { msg: "Only incentive tokens are valid".to_string(), } ); ensure!( - is_withdraw_open(env.block.time.seconds(), &config), + !config + .init_timestamp + .plus_milliseconds(config.deposit_window) + .is_expired(&env.block), ContractError::TokenAlreadyBeingDistributed {} ); - config.lockdrop_incentives += amount; + config.lockdrop_incentives = config.lockdrop_incentives.checked_add(amount)?; CONFIG.save(deps.storage, &config)?; Ok(Response::new() .add_attribute("action", "incentives_increased") @@ -245,7 +213,7 @@ pub fn execute_deposit_native(ctx: ExecuteContext) -> Result Result SAVE - state.total_native_locked += native_token.amount; + state.total_native_locked = state.total_native_locked.checked_add(native_token.amount)?; STATE.save(deps.storage, &state)?; USER_INFO.save(deps.storage, &depositor_address, &user_info)?; @@ -311,14 +281,15 @@ pub fn execute_withdraw_native( // CHECK :: Lockdrop withdrawal window open ensure!( - is_withdraw_open(env.block.time.seconds(), &config), + is_withdraw_open(Milliseconds::from_nanos(env.block.time.nanos()), &config), ContractError::InvalidWithdrawal { msg: Some("Withdrawals not available".to_string()), } ); // Check :: Amount should be within the allowed withdrawal limit bounds - let max_withdrawal_percent = allowed_withdrawal_percent(env.block.time.seconds(), &config); + // let max_withdrawal_percent = allowed_withdrawal_percent(env.block.time.seconds(), &config); + let max_withdrawal_percent = Decimal::one(); let max_withdrawal_allowed = user_info.total_native_locked * max_withdrawal_percent; let withdraw_amount = withdraw_amount.unwrap_or(max_withdrawal_allowed); ensure!( @@ -331,7 +302,11 @@ pub fn execute_withdraw_native( ); // Update withdrawal flag after the deposit window - if env.block.time.seconds() > config.init_timestamp + config.deposit_window { + if config + .init_timestamp + .plus_milliseconds(config.deposit_window) + .is_expired(&env.block) + { // CHECK :: Max 1 withdrawal allowed ensure!( !user_info.withdrawal_flag, @@ -343,12 +318,12 @@ pub fn execute_withdraw_native( user_info.withdrawal_flag = true; } - user_info.total_native_locked -= withdraw_amount; + user_info.total_native_locked = user_info.total_native_locked.checked_sub(withdraw_amount)?; USER_INFO.save(deps.storage, &withdrawer_address, &user_info)?; // STATE :: UPDATE --> SAVE - state.total_native_locked -= withdraw_amount; + state.total_native_locked = state.total_native_locked.checked_sub(withdraw_amount)?; STATE.save(deps.storage, &state)?; // COSMOS_MSG ::TRANSFER WITHDRAWN native token @@ -390,7 +365,7 @@ pub fn execute_enable_claims(ctx: ExecuteContext) -> Result Result Result, -) -> Result { - let ExecuteContext { - deps, env, info, .. - } = ctx; - nonpayable(&info)?; - - let recipient = recipient.unwrap_or_else(|| info.sender.to_string()); - let config = CONFIG.load(deps.storage)?; - let state = STATE.load(deps.storage)?; - // CHECK :: Only Owner can call this function - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - - // CHECK :: Lockdrop withdrawal window should be closed - let current_timestamp = env.block.time.seconds(); - ensure!( - current_timestamp >= config.init_timestamp && !is_withdraw_open(current_timestamp, &config), - ContractError::InvalidWithdrawal { - msg: Some("Lockdrop withdrawals haven't concluded yet".to_string()), - } - ); - - let native_token = Asset::native(config.native_denom, state.total_native_locked); - - let balance = native_token - .info - .query_balance(&deps.querier, env.contract.address)?; - - ensure!( - balance >= state.total_native_locked, - ContractError::InvalidWithdrawal { - msg: Some("Already withdrew funds".to_string()), - } - ); - - let transfer_msg = native_token.transfer_msg(recipient)?; - - Ok(Response::new() - .add_message(transfer_msg) - .add_attribute("action", "withdraw_proceeds") - .add_attribute("amount", state.total_native_locked) - .add_attribute("timestamp", env.block.time.seconds().to_string())) -} +// fn execute_withdraw_proceeds( +// ctx: ExecuteContext, +// recipient: Option, +// ) -> Result { +// let ExecuteContext { +// deps, env, info, .. +// } = ctx; +// nonpayable(&info)?; + +// let recipient = recipient.unwrap_or_else(|| info.sender.to_string()); +// let config = CONFIG.load(deps.storage)?; +// let state = STATE.load(deps.storage)?; +// // CHECK :: Only Owner can call this function +// ensure!( +// ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, +// ContractError::Unauthorized {} +// ); + +// // CHECK :: Lockdrop withdrawal window should be closed +// let current_timestamp = env.block.time.seconds(); +// ensure!( +// current_timestamp >= config.init_timestamp && is_phase_over(current_timestamp, &config), +// ContractError::InvalidWithdrawal { +// msg: Some("Lockdrop withdrawals haven't concluded yet".to_string()), +// } +// ); + +// let native_token = Asset::native(config.native_denom, state.total_native_locked); + +// let balance = native_token +// .info +// .query_balance(&deps.querier, env.contract.address)?; + +// ensure!( +// balance >= state.total_native_locked, +// ContractError::InvalidWithdrawal { +// msg: Some("Already withdrew funds".to_string()), +// } +// ); + +// let transfer_msg = native_token.transfer_msg(recipient)?; + +// Ok(Response::new() +// .add_message(transfer_msg) +// .add_attribute("action", "withdraw_proceeds") +// .add_attribute("amount", state.total_native_locked) +// .add_attribute("timestamp", env.block.time.seconds().to_string())) +// } //---------------------------------------------------------------------------------------- // Query Functions @@ -560,13 +535,22 @@ pub fn query_user_info( pub fn query_max_withdrawable_percent( deps: Deps, env: Env, - timestamp: Option, + timestamp: Option, ) -> Result { let config = CONFIG.load(deps.storage)?; - Ok(match timestamp { - Some(timestamp) => allowed_withdrawal_percent(timestamp, &config), - None => allowed_withdrawal_percent(env.block.time.seconds(), &config), + Some(timestamp) => { + ensure!( + !timestamp.is_in_past(&env.block), + ContractError::InvalidTimestamp { + msg: "Provided timestamp is in past".to_string() + } + ); + allowed_withdrawal_percent(timestamp, &config) + } + None => { + allowed_withdrawal_percent(Milliseconds::from_nanos(env.block.time.nanos()), &config) + } }) } @@ -575,48 +559,64 @@ pub fn query_max_withdrawable_percent( //---------------------------------------------------------------------------------------- /// @dev Returns true if deposits are allowed -fn is_deposit_open(current_timestamp: u64, config: &Config) -> bool { - let deposits_opened_till = config.init_timestamp + config.deposit_window; +fn is_deposit_open(current_timestamp: MillisecondsExpiration, config: &Config) -> bool { + let deposits_opened_till = config + .init_timestamp + .plus_milliseconds(config.deposit_window); (current_timestamp >= config.init_timestamp) && (deposits_opened_till >= current_timestamp) } /// @dev Returns true if withdrawals are allowed -fn is_withdraw_open(current_timestamp: u64, config: &Config) -> bool { - let withdrawals_opened_till = - config.init_timestamp + config.deposit_window + config.withdrawal_window; - (current_timestamp >= config.init_timestamp) && (withdrawals_opened_till >= current_timestamp) +fn is_withdraw_open(current_timestamp: MillisecondsExpiration, config: &Config) -> bool { + current_timestamp >= config.init_timestamp +} + +fn is_phase_over(current_timestamp: MillisecondsExpiration, config: &Config) -> bool { + let deposits_opened_till = config + .init_timestamp + .plus_milliseconds(config.deposit_window); + // let withdrawals_opened_till = deposits_opened_till + config.withdrawal_window; + deposits_opened_till <= current_timestamp } /// @dev Helper function to calculate maximum % of NATIVE deposited that can be withdrawn /// @params current_timestamp : Current block timestamp /// @params config : Contract configuration -pub fn allowed_withdrawal_percent(current_timestamp: u64, config: &Config) -> Decimal { - let withdrawal_cutoff_init_point = config.init_timestamp + config.deposit_window; +pub fn allowed_withdrawal_percent( + current_timestamp: MillisecondsExpiration, + config: &Config, +) -> Decimal { + let withdrawal_cutoff_init_point = config + .init_timestamp + .plus_milliseconds(config.deposit_window); // Deposit window :: 100% withdrawals allowed if current_timestamp < withdrawal_cutoff_init_point { - return Decimal::from_ratio(100u32, 100u32); + return Decimal::percent(100); } - let withdrawal_cutoff_second_point = - withdrawal_cutoff_init_point + (config.withdrawal_window / 2u64); + let withdrawal_cutoff_second_point = withdrawal_cutoff_init_point + .plus_milliseconds(Milliseconds(config.withdrawal_window.milliseconds() / 2u64)); // Deposit window closed, 1st half of withdrawal window :: 50% withdrawals allowed if current_timestamp <= withdrawal_cutoff_second_point { - return Decimal::from_ratio(50u32, 100u32); + return Decimal::percent(50); } // max withdrawal allowed decreasing linearly from 50% to 0% vs time elapsed - let withdrawal_cutoff_final = withdrawal_cutoff_init_point + config.withdrawal_window; + let withdrawal_cutoff_final = + withdrawal_cutoff_init_point.plus_milliseconds(config.withdrawal_window); // Deposit window closed, 2nd half of withdrawal window :: max withdrawal allowed decreases linearly from 50% to 0% vs time elapsed if current_timestamp < withdrawal_cutoff_final { - let time_left = withdrawal_cutoff_final - current_timestamp; + let time_left = withdrawal_cutoff_final.minus_milliseconds(current_timestamp); Decimal::from_ratio( - 50u64 * time_left, - 100u64 * (withdrawal_cutoff_final - withdrawal_cutoff_second_point), + 50u64 * time_left.milliseconds(), + 100u64 + * (withdrawal_cutoff_final.minus_milliseconds(withdrawal_cutoff_second_point)) + .milliseconds(), ) } // Withdrawals not allowed else { - Decimal::from_ratio(0u32, 100u32) + Decimal::zero() } } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/lib.rs b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/lib.rs index a8c9e47..bcbc58b 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/lib.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/lib.rs @@ -2,3 +2,6 @@ pub mod contract; pub mod state; #[cfg(test)] pub mod testing; + +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/mock.rs b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/mock.rs new file mode 100644 index 0000000..c717b25 --- /dev/null +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/mock.rs @@ -0,0 +1,56 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] + +use crate::contract::{execute, instantiate, query}; +use andromeda_fungible_tokens::lockdrop::{Cw20HookMsg, ExecuteMsg, InstantiateMsg}; +use andromeda_std::{ + amp::AndrAddr, + common::{expiration::Expiry, MillisecondsDuration}, +}; +use cosmwasm_std::{Empty, Uint128}; +use cw_multi_test::{Contract, ContractWrapper}; + +pub fn mock_andromeda_lockdrop() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} + +#[allow(clippy::too_many_arguments)] +pub fn mock_lockdrop_instantiate_msg( + init_timestamp: Expiry, + deposit_window: MillisecondsDuration, + withdrawal_window: MillisecondsDuration, + incentive_token: AndrAddr, + native_denom: String, + owner: Option, + kernel_address: String, +) -> InstantiateMsg { + InstantiateMsg { + init_timestamp, + deposit_window, + withdrawal_window, + native_denom, + incentive_token, + kernel_address, + owner, + } +} + +pub fn mock_deposit_native() -> ExecuteMsg { + ExecuteMsg::DepositNative {} +} + +pub fn mock_enable_claims() -> ExecuteMsg { + ExecuteMsg::EnableClaims {} +} + +pub fn mock_claim_rewards() -> ExecuteMsg { + ExecuteMsg::ClaimRewards {} +} + +pub fn mock_withdraw_native(amount: Option) -> ExecuteMsg { + ExecuteMsg::WithdrawNative { amount } +} + +pub fn mock_cw20_hook_increase_incentives() -> Cw20HookMsg { + Cw20HookMsg::IncreaseIncentives {} +} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/state.rs b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/state.rs index dfc4941..b74942a 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/state.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/state.rs @@ -1,3 +1,7 @@ +use andromeda_std::{ + amp::AndrAddr, + common::{MillisecondsDuration, MillisecondsExpiration}, +}; use cosmwasm_std::{Addr, Uint128}; use cw_storage_plus::{Item, Map}; @@ -17,15 +21,15 @@ pub struct Config { /// Bootstrap Contract address to which incentive tokens can be deposited for bootstrapping TOKEN-NATIVE Pool // pub bootstrap_contract_address: Option, /// Timestamp when Contract will start accepting deposits - pub init_timestamp: u64, + pub init_timestamp: MillisecondsExpiration, /// Deposit Window Length - pub deposit_window: u64, + pub deposit_window: MillisecondsDuration, /// Withdrawal Window Length - pub withdrawal_window: u64, + pub withdrawal_window: MillisecondsDuration, /// Total Token lockdrop incentives to be distributed among the users pub lockdrop_incentives: Uint128, /// The token being given as incentive. - pub incentive_token: String, + pub incentive_token: AndrAddr, /// The native token being deposited. pub native_denom: String, } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/mock_querier.rs b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/mock_querier.rs index 6987b09..fd11206 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/mock_querier.rs @@ -1,23 +1,19 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; + use andromeda_std::testing::mock_querier::MockAndromedaQuerier; +pub use andromeda_std::testing::mock_querier::{ + MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, +}; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, -}; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg, Uint128}; - -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; pub const MOCK_TOKEN_CONTRACT: &str = "token_contract"; - pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; pub const MOCK_TOKENS_FOR_SALE: &[&str] = &[ @@ -47,11 +43,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "lockdrop".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -85,91 +82,17 @@ impl Querier for WasmMockQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) } _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs index 56b8642..96e658d 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-lockdrop/src/testing/tests.rs @@ -1,24 +1,27 @@ +use crate::state::{State, UserInfo, USER_INFO}; +use crate::testing::mock_querier::mock_dependencies_custom; use crate::{ contract::{execute, instantiate, query}, state::{CONFIG, STATE}, }; +use andromeda_fungible_tokens::lockdrop::{ + ConfigResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, StateResponse, + UserInfoResponse, +}; +use andromeda_std::amp::AndrAddr; +use andromeda_std::common::expiration::Expiry; use andromeda_std::{ - common::expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, error::ContractError, + common::{expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, Milliseconds}, + error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT, }; +use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_std::{ coin, coins, from_json, - testing::{mock_env, mock_info, MOCK_CONTRACT_ADDR}, + testing::{mock_env, mock_info}, to_json_binary, Addr, BankMsg, Decimal, DepsMut, Response, Uint128, WasmMsg, }; -use crate::state::{State, UserInfo, USER_INFO}; -use crate::testing::mock_querier::mock_dependencies_custom; -use andromeda_fungible_tokens::lockdrop::{ - ConfigResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, StateResponse, - UserInfoResponse, -}; - use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; const MOCK_INCENTIVE_TOKEN: &str = "mock_incentive_token"; @@ -31,14 +34,13 @@ fn init(deps: DepsMut) -> Result { let msg = InstantiateMsg { // bootstrap_contract: None, - init_timestamp: env.block.time.seconds(), - deposit_window: DEPOSIT_WINDOW, - withdrawal_window: WITHDRAWAL_WINDOW, - incentive_token: MOCK_INCENTIVE_TOKEN.to_owned(), + init_timestamp: Expiry::AtTime(Milliseconds::from_nanos(env.block.time.nanos())), + deposit_window: Milliseconds::from_seconds(DEPOSIT_WINDOW), + withdrawal_window: Milliseconds::from_seconds(WITHDRAWAL_WINDOW), + incentive_token: AndrAddr::from_string(MOCK_INCENTIVE_TOKEN), native_denom: "uusd".to_string(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; instantiate(deps, env, info, msg) @@ -53,7 +55,9 @@ fn test_instantiate() { assert_eq!( Response::new() .add_attribute("method", "instantiate") - .add_attribute("type", "lockdrop"), + .add_attribute("type", "lockdrop") + .add_attribute("kernel_address", MOCK_KERNEL_CONTRACT) + .add_attribute("owner", "owner"), res ); @@ -64,11 +68,11 @@ fn test_instantiate() { assert_eq!( ConfigResponse { // bootstrap_contract_address: None, - init_timestamp: mock_env().block.time.seconds(), - deposit_window: DEPOSIT_WINDOW, - withdrawal_window: WITHDRAWAL_WINDOW, + init_timestamp: Milliseconds::from_nanos(mock_env().block.time.nanos()), + deposit_window: Milliseconds::from_seconds(DEPOSIT_WINDOW), + withdrawal_window: Milliseconds::from_seconds(WITHDRAWAL_WINDOW), lockdrop_incentives: Uint128::zero(), - incentive_token: MOCK_INCENTIVE_TOKEN.to_owned(), + incentive_token: AndrAddr::from_string(MOCK_INCENTIVE_TOKEN), native_denom: "uusd".to_string() }, config_res @@ -95,14 +99,13 @@ fn test_instantiate_init_timestamp_past() { let msg = InstantiateMsg { // bootstrap_contract: None, - init_timestamp: env.block.time.seconds() - 1, - deposit_window: 5, - withdrawal_window: 2, - incentive_token: MOCK_INCENTIVE_TOKEN.to_owned(), + init_timestamp: Expiry::AtTime(Milliseconds::from_seconds(env.block.time.seconds() - 1)), + deposit_window: Milliseconds::from_seconds(5), + withdrawal_window: Milliseconds::from_seconds(2), + incentive_token: AndrAddr::from_string(MOCK_INCENTIVE_TOKEN), native_denom: "uusd".to_string(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let res = instantiate(deps.as_mut(), env.clone(), info, msg); @@ -124,14 +127,13 @@ fn test_instantiate_init_deposit_window_zero() { let msg = InstantiateMsg { // bootstrap_contract: None, - init_timestamp: env.block.time.seconds() + 1, - deposit_window: 0, - withdrawal_window: 2, - incentive_token: MOCK_INCENTIVE_TOKEN.to_owned(), + init_timestamp: Expiry::AtTime(Milliseconds::from_seconds(env.block.time.seconds() + 1)), + deposit_window: Milliseconds::from_seconds(0), + withdrawal_window: Milliseconds::from_seconds(2), + incentive_token: AndrAddr::from_string(MOCK_INCENTIVE_TOKEN), native_denom: "uusd".to_string(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let res = instantiate(deps.as_mut(), env, info, msg); @@ -147,14 +149,13 @@ fn test_instantiate_init_withdrawal_window_zero() { let msg = InstantiateMsg { // bootstrap_contract: None, - init_timestamp: env.block.time.seconds() + 1, - deposit_window: 5, - withdrawal_window: 0, - incentive_token: MOCK_INCENTIVE_TOKEN.to_owned(), + init_timestamp: Expiry::AtTime(Milliseconds::from_seconds(env.block.time.seconds() + 1)), + deposit_window: Milliseconds::from_seconds(5), + withdrawal_window: Milliseconds::from_seconds(0), + incentive_token: AndrAddr::from_string(MOCK_INCENTIVE_TOKEN), native_denom: "uusd".to_string(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let res = instantiate(deps.as_mut(), env, info, msg); @@ -170,14 +171,13 @@ fn test_instantiate_init_deposit_window_less_than_withdrawal_window() { let msg = InstantiateMsg { // bootstrap_contract: None, - init_timestamp: env.block.time.seconds() + 1, - deposit_window: 2, - withdrawal_window: 5, - incentive_token: MOCK_INCENTIVE_TOKEN.to_owned(), + init_timestamp: Expiry::AtTime(Milliseconds::from_seconds(env.block.time.seconds() + 1)), + deposit_window: Milliseconds::from_seconds(2), + withdrawal_window: Milliseconds::from_seconds(5), + incentive_token: AndrAddr::from_string(MOCK_INCENTIVE_TOKEN), native_denom: "uusd".to_string(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let res = instantiate(deps.as_mut(), env, info, msg); @@ -203,7 +203,8 @@ fn test_increase_incentives() { assert_eq!( Response::new() .add_attribute("action", "incentives_increased") - .add_attribute("amount", "100"), + .add_attribute("amount", "100") + .add_submessage(generate_economics_message(MOCK_INCENTIVE_TOKEN, "Receive")), res ); @@ -300,7 +301,8 @@ fn test_deposit_native() { Response::new() .add_attribute("action", "lock_native") .add_attribute("user", "sender") - .add_attribute("ust_deposited", "100"), + .add_attribute("ust_deposited", "100") + .add_submessage(generate_economics_message("sender", "DepositNative")), res ); @@ -417,7 +419,8 @@ fn test_withdraw_native() { }) .add_attribute("action", "withdraw_native") .add_attribute("user", "sender") - .add_attribute("amount", "100"), + .add_attribute("amount", "100") + .add_submessage(generate_economics_message("sender", "WithdrawNative")), res ); @@ -443,270 +446,243 @@ fn test_withdraw_native() { ); } -#[test] -fn test_withdraw_native_withdraw_phase_first_half() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()).unwrap(); - - let msg = ExecuteMsg::DepositNative {}; - let info = mock_info("sender", &coins(100, "uusd")); - - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - let msg = ExecuteMsg::WithdrawNative { - amount: Some(Uint128::new(51)), - }; - - let mut env = mock_env(); - env.block.time = env.block.time.plus_seconds(DEPOSIT_WINDOW + 1); - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg); - - assert_eq!( - ContractError::InvalidWithdrawal { - msg: Some("Amount exceeds max allowed withdrawal limit of 50".to_string()), - }, - res.unwrap_err() - ); - - let msg = ExecuteMsg::WithdrawNative { amount: None }; +// #[test] +// fn test_withdraw_native_withdraw_phase_first_half() { +// let mut deps = mock_dependencies_custom(&[]); +// init(deps.as_mut()).unwrap(); - let res = execute(deps.as_mut(), env, info, msg).unwrap(); +// let msg = ExecuteMsg::DepositNative {}; +// let info = mock_info("sender", &coins(100, "uusd")); - assert_eq!( - Response::new() - .add_message(BankMsg::Send { - to_address: "sender".to_string(), - amount: coins(50, "uusd") - }) - .add_attribute("action", "withdraw_native") - .add_attribute("user", "sender") - // Only half is withdrawable in the first half of the withdrawal period - .add_attribute("amount", "50"), - res - ); +// let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - assert_eq!( - State { - total_native_locked: Uint128::new(50), - total_delegated: Uint128::zero(), - are_claims_allowed: false - }, - STATE.load(deps.as_ref().storage,).unwrap() - ); +// let msg = ExecuteMsg::WithdrawNative { +// amount: Some(Uint128::new(51)), +// }; - assert_eq!( - UserInfo { - total_native_locked: Uint128::new(50), - delegated_incentives: Uint128::zero(), - lockdrop_claimed: false, - withdrawal_flag: true, - }, - USER_INFO - .load(deps.as_ref().storage, &Addr::unchecked("sender")) - .unwrap() - ); -} +// let mut env = mock_env(); +// env.block.time = env.block.time.plus_seconds(DEPOSIT_WINDOW + 1); +// let res = execute(deps.as_mut(), env.clone(), info.clone(), msg); -#[test] -fn test_withdraw_native_withdraw_phase_second_half() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()).unwrap(); +// assert_eq!( +// ContractError::InvalidWithdrawal { +// msg: Some("Amount exceeds max allowed withdrawal limit of 50".to_string()), +// }, +// res.unwrap_err() +// ); - let msg = ExecuteMsg::DepositNative {}; - let info = mock_info("sender", &coins(100, "uusd")); +// let msg = ExecuteMsg::WithdrawNative { amount: None }; - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); +// let res = execute(deps.as_mut(), env, info, msg).unwrap(); - let msg = ExecuteMsg::WithdrawNative { amount: None }; +// assert_eq!( +// Response::new() +// .add_message(BankMsg::Send { +// to_address: "sender".to_string(), +// amount: coins(50, "uusd") +// }) +// .add_attribute("action", "withdraw_native") +// .add_attribute("user", "sender") +// // Only half is withdrawable in the first half of the withdrawal period +// .add_attribute("amount", "50"), +// res +// ); - let mut env = mock_env(); - env.block.time = env - .block - .time - .plus_seconds(DEPOSIT_WINDOW + 3 * WITHDRAWAL_WINDOW / 4); - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); +// assert_eq!( +// State { +// total_native_locked: Uint128::new(50), +// total_delegated: Uint128::zero(), +// are_claims_allowed: false +// }, +// STATE.load(deps.as_ref().storage,).unwrap() +// ); - assert_eq!( - Response::new() - .add_message(BankMsg::Send { - to_address: "sender".to_string(), - amount: coins(25, "uusd") - }) - .add_attribute("action", "withdraw_native") - .add_attribute("user", "sender") - // In second half of withdrawal phase, percent decreases linearly from 50% to 0%. - .add_attribute("amount", "25"), - res - ); +// assert_eq!( +// UserInfo { +// total_native_locked: Uint128::new(50), +// delegated_incentives: Uint128::zero(), +// lockdrop_claimed: false, +// withdrawal_flag: true, +// }, +// USER_INFO +// .load(deps.as_ref().storage, &Addr::unchecked("sender")) +// .unwrap() +// ); +// } - assert_eq!( - State { - total_native_locked: Uint128::new(75), - total_delegated: Uint128::zero(), - are_claims_allowed: false - }, - STATE.load(deps.as_ref().storage).unwrap() - ); +// #[test] +// fn test_withdraw_native_withdraw_phase_second_half() { +// let mut deps = mock_dependencies_custom(&[]); +// init(deps.as_mut()).unwrap(); - assert_eq!( - UserInfo { - total_native_locked: Uint128::new(75), - delegated_incentives: Uint128::zero(), - lockdrop_claimed: false, - withdrawal_flag: true, - }, - USER_INFO - .load(deps.as_ref().storage, &Addr::unchecked("sender")) - .unwrap() - ); +// let msg = ExecuteMsg::DepositNative {}; +// let info = mock_info("sender", &coins(100, "uusd")); - // try to withdraw again - let res = execute(deps.as_mut(), env, info, msg); +// let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - assert_eq!( - ContractError::InvalidWithdrawal { - msg: Some("Max 1 withdrawal allowed".to_string()), - }, - res.unwrap_err() - ); -} +// let msg = ExecuteMsg::WithdrawNative { amount: None }; -#[test] -fn test_withdraw_native_withdrawal_closed() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()).unwrap(); +// let mut env = mock_env(); +// env.block.time = env +// .block +// .time +// .plus_seconds(DEPOSIT_WINDOW + 3 * WITHDRAWAL_WINDOW / 4); +// let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); - let msg = ExecuteMsg::DepositNative {}; - let info = mock_info("sender", &coins(100, "uusd")); +// assert_eq!( +// Response::new() +// .add_message(BankMsg::Send { +// to_address: "sender".to_string(), +// amount: coins(100, "uusd") +// }) +// .add_attribute("action", "withdraw_native") +// .add_attribute("user", "sender") +// // In second half of withdrawal phase, percent decreases linearly from 50% to 0%. +// .add_attribute("amount", "25"), +// res +// ); - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); +// assert_eq!( +// State { +// total_native_locked: Uint128::new(75), +// total_delegated: Uint128::zero(), +// are_claims_allowed: false +// }, +// STATE.load(deps.as_ref().storage).unwrap() +// ); - let msg = ExecuteMsg::WithdrawNative { amount: None }; +// assert_eq!( +// UserInfo { +// total_native_locked: Uint128::new(75), +// delegated_incentives: Uint128::zero(), +// lockdrop_claimed: false, +// withdrawal_flag: true, +// }, +// USER_INFO +// .load(deps.as_ref().storage, &Addr::unchecked("sender")) +// .unwrap() +// ); - let mut env = mock_env(); - env.block.time = env - .block - .time - .plus_seconds(DEPOSIT_WINDOW + WITHDRAWAL_WINDOW + 1); - let res = execute(deps.as_mut(), env, info, msg); +// // try to withdraw again +// let res = execute(deps.as_mut(), env, info, msg); - assert_eq!( - ContractError::InvalidWithdrawal { - msg: Some("Withdrawals not available".to_string()), - }, - res.unwrap_err() - ); -} +// assert_eq!( +// ContractError::InvalidWithdrawal { +// msg: Some("Max 1 withdrawal allowed".to_string()), +// }, +// res.unwrap_err() +// ); +// } -#[test] -fn test_withdraw_proceeds_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()).unwrap(); +// #[test] +// fn test_withdraw_proceeds_unauthorized() { +// let mut deps = mock_dependencies_custom(&[]); +// init(deps.as_mut()).unwrap(); - let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; +// let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; - let info = mock_info("not owner", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); +// let info = mock_info("not owner", &[]); +// let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); -} +// assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); +// } -#[test] -fn test_withdraw_proceeds_phase_not_started() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()).unwrap(); +// #[test] +// fn test_withdraw_proceeds_phase_not_started() { +// let mut deps = mock_dependencies_custom(&[]); +// init(deps.as_mut()).unwrap(); - let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; +// let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; - let info = mock_info("owner", &[]); - let mut env = mock_env(); - env.block.time = env.block.time.minus_seconds(1); - let res = execute(deps.as_mut(), env, info, msg); +// let info = mock_info("owner", &[]); +// let mut env = mock_env(); +// env.block.time = env.block.time.minus_seconds(1); +// let res = execute(deps.as_mut(), env, info, msg); - assert_eq!( - ContractError::InvalidWithdrawal { - msg: Some("Lockdrop withdrawals haven't concluded yet".to_string()), - }, - res.unwrap_err() - ); -} +// assert_eq!( +// ContractError::InvalidWithdrawal { +// msg: Some("Lockdrop withdrawals haven't concluded yet".to_string()), +// }, +// res.unwrap_err() +// ); +// } -#[test] -fn test_withdraw_proceeds_phase_not_ended() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut()).unwrap(); +// #[test] +// fn test_withdraw_proceeds_phase_not_ended() { +// let mut deps = mock_dependencies_custom(&[]); +// init(deps.as_mut()).unwrap(); - let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; +// let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; - let info = mock_info("owner", &[]); - let mut env = mock_env(); - env.block.time = env.block.time.plus_seconds(DEPOSIT_WINDOW); - let res = execute(deps.as_mut(), mock_env(), info, msg); +// let info = mock_info("owner", &[]); +// let mut env = mock_env(); +// env.block.time = env.block.time.plus_seconds(DEPOSIT_WINDOW); +// let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!( - ContractError::InvalidWithdrawal { - msg: Some("Lockdrop withdrawals haven't concluded yet".to_string()), - }, - res.unwrap_err() - ); -} +// assert_eq!( +// ContractError::InvalidWithdrawal { +// msg: Some("Lockdrop withdrawals haven't concluded yet".to_string()), +// }, +// res.unwrap_err() +// ); +// } -#[test] -fn test_withdraw_proceeds() { - // This uusd is to simulate the deposit made prior to withdrawing proceeds. This is needed - // since the mock querier doesn't automatically assign balances. - let amount = 100; - let mut deps = mock_dependencies_custom(&[coin(amount, "uusd")]); - init(deps.as_mut()).unwrap(); +// #[test] +// fn test_withdraw_proceeds() { +// // This uusd is to simulate the deposit made prior to withdrawing proceeds. This is needed +// // since the mock querier doesn't automatically assign balances. +// let amount = 100; +// let mut deps = mock_dependencies_custom(&[coin(amount, "uusd")]); +// init(deps.as_mut()).unwrap(); - let msg = ExecuteMsg::DepositNative {}; - let info = mock_info("sender", &coins(amount, "uusd")); +// let msg = ExecuteMsg::DepositNative {}; +// let info = mock_info("sender", &coins(amount, "uusd")); - let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); +// let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - // Update contract's balance after deposit - deps.querier - .base - .update_balance(MOCK_CONTRACT_ADDR, coins(amount, "uusd")); +// // Update contract's balance after deposit +// deps.querier +// .base +// .update_balance(MOCK_CONTRACT_ADDR, coins(amount, "uusd")); - let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; +// let msg = ExecuteMsg::WithdrawProceeds { recipient: None }; - let info = mock_info("owner", &[]); - let mut env = mock_env(); - env.block.time = env - .block - .time - .plus_seconds(DEPOSIT_WINDOW + WITHDRAWAL_WINDOW + 1); +// let info = mock_info("owner", &[]); +// let mut env = mock_env(); +// env.block.time = env +// .block +// .time +// .plus_seconds(DEPOSIT_WINDOW + WITHDRAWAL_WINDOW + 1); - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); +// let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); - assert_eq!( - Response::new() - .add_message(BankMsg::Send { - to_address: "owner".to_string(), - amount: coins(100, "uusd") - }) - .add_attribute("action", "withdraw_proceeds") - .add_attribute("amount", "100") - .add_attribute("timestamp", env.block.time.seconds().to_string()), - res - ); +// assert_eq!( +// Response::new() +// .add_message(BankMsg::Send { +// to_address: "owner".to_string(), +// amount: coins(100, "uusd") +// }) +// .add_attribute("action", "withdraw_proceeds") +// .add_attribute("amount", "100") +// .add_attribute("timestamp", env.block.time.seconds().to_string()), +// res +// ); - // Remove withdrawn funds. - deps.querier - .base - .update_balance(env.contract.address.clone(), vec![]); +// // Remove withdrawn funds. +// deps.querier +// .base +// .update_balance(env.contract.address.clone(), vec![]); - // try to withdraw again - let res = execute(deps.as_mut(), env, info, msg); +// // try to withdraw again +// let res = execute(deps.as_mut(), env, info, msg); - assert_eq!( - ContractError::InvalidWithdrawal { - msg: Some("Already withdrew funds".to_string()), - }, - res.unwrap_err() - ); -} +// assert_eq!( +// ContractError::InvalidWithdrawal { +// msg: Some("Already withdrew funds".to_string()), +// }, +// res.unwrap_err() +// ); +// } #[test] fn test_enable_claims_no_bootstrap_specified() { @@ -725,7 +701,9 @@ fn test_enable_claims_no_bootstrap_specified() { let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); assert_eq!( - Response::new().add_attribute("action", "enable_claims"), + Response::new() + .add_attribute("action", "enable_claims") + .add_submessage(generate_economics_message("sender", "EnableClaims")), res ); @@ -754,7 +732,7 @@ fn test_enable_claims_no_bootstrap_specified() { // init_timestamp: mock_env().block.time.seconds(), // deposit_window: DEPOSIT_WINDOW, // withdrawal_window: WITHDRAWAL_WINDOW, -// incentive_token: MOCK_INCENTIVE_TOKEN.to_owned(), +// incentive_token: AndrAddr::from_string(MOCK_INCENTIVE_TOKEN), // native_denom: "uusd".to_string(), // }; @@ -805,10 +783,7 @@ fn test_enable_claims_phase_not_ended() { let msg = ExecuteMsg::EnableClaims {}; let mut env = mock_env(); - env.block.time = env - .block - .time - .plus_seconds(DEPOSIT_WINDOW + WITHDRAWAL_WINDOW); + env.block.time = env.block.time.plus_seconds(DEPOSIT_WINDOW - 1); let info = mock_info("sender", &[]); let res = execute(deps.as_mut(), env, info, msg); @@ -876,14 +851,15 @@ fn test_claim_rewards() { .add_attribute("action", "claim_rewards") .add_attribute("amount", "75") .add_message(WasmMsg::Execute { - contract_addr: MOCK_INCENTIVE_TOKEN.to_owned(), + contract_addr: MOCK_INCENTIVE_TOKEN.to_string(), funds: vec![], msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "user1".to_string(), amount: Uint128::new(75) }) .unwrap() - }), + }) + .add_submessage(generate_economics_message("user1", "ClaimRewards")), res ); @@ -914,14 +890,15 @@ fn test_claim_rewards() { .add_attribute("action", "claim_rewards") .add_attribute("amount", "25") .add_message(WasmMsg::Execute { - contract_addr: MOCK_INCENTIVE_TOKEN.to_owned(), + contract_addr: MOCK_INCENTIVE_TOKEN.to_string(), funds: vec![], msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: "user2".to_string(), amount: Uint128::new(25) }) .unwrap() - }), + }) + .add_submessage(generate_economics_message("user2", "ClaimRewards")), res ); @@ -994,9 +971,20 @@ fn test_query_withdrawable_percent() { assert_eq!(Decimal::one(), res); + let msg = QueryMsg::WithdrawalPercentAllowed { + timestamp: Some(Milliseconds::zero()), + }; + let err = query(deps.as_ref(), mock_env(), msg).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidTimestamp { + msg: "Provided timestamp is in past".to_string() + } + ); + let timestamp = mock_env().block.time.plus_seconds(DEPOSIT_WINDOW + 1); let msg = QueryMsg::WithdrawalPercentAllowed { - timestamp: Some(timestamp.seconds()), + timestamp: Some(Milliseconds::from_seconds(timestamp.seconds())), }; let res: Decimal = from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); @@ -1007,7 +995,7 @@ fn test_query_withdrawable_percent() { .time .plus_seconds(DEPOSIT_WINDOW + WITHDRAWAL_WINDOW); let msg = QueryMsg::WithdrawalPercentAllowed { - timestamp: Some(timestamp.seconds()), + timestamp: Some(Milliseconds::from_nanos(timestamp.nanos())), }; let res: Decimal = from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml index df7cab9..167ad54 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml +++ b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-merkle-airdrop" -version = "0.2.1" +version = "2.0.2" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -20,10 +20,8 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } cw20 = { workspace = true } cw-asset = { workspace = true } -semver = { workspace = true } sha2 = "0.10.6" hex = "0.4.3" serde = "1.0.163" @@ -35,4 +33,5 @@ andromeda-fungible-tokens = { workspace = true } cw-multi-test = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } +andromeda-testing = { workspace = true } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/README.md b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/README.md new file mode 100644 index 0000000..526be55 --- /dev/null +++ b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/README.md @@ -0,0 +1,5 @@ +# Overview + +The Merkle-Airdrop ADO is a smart contract that allows projects to launch airdrops using the Merkle-tree (hashing). Uses the same logic of the [base cw20-merkel-airdrop](https://github.com/CosmWasm/cw-tokens/tree/main/contracts/cw20-merkle-airdrop) contract. If you do not know what is a Merkle-airdrop and how it is different from a normal airdrop, please refer to the following [article](https://medium.com/smartz-blog/merkle-airdrop-the-basics-9a0857fcc930). + +[Merkle Airdrop Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/merkle-airdrop) \ No newline at end of file diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/andromeda-merkle-airdrop.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/andromeda-merkle-airdrop.json deleted file mode 100644 index 7483b4f..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/andromeda-merkle-airdrop.json +++ /dev/null @@ -1,1538 +0,0 @@ -{ - "contract_name": "andromeda-merkle-airdrop", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "asset_info", - "kernel_address" - ], - "properties": { - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_String" - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_String": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "register_merkle_root" - ], - "properties": { - "register_merkle_root": { - "type": "object", - "required": [ - "merkle_root" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "merkle_root": { - "description": "MerkleRoot is hex-encoded merkle root.", - "type": "string" - }, - "total_amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claim does not check if contract has enough funds, owner must ensure it.", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "required": [ - "amount", - "proof", - "stage" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "proof": { - "description": "Proof is hex-encoded merkle proof.", - "type": "array", - "items": { - "type": "string" - } - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burn the remaining tokens after expire time (only owner)", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "stage" - ], - "properties": { - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "merkle_root" - ], - "properties": { - "merkle_root": { - "type": "object", - "required": [ - "stage" - ], - "properties": { - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "latest_stage" - ], - "properties": { - "latest_stage": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "object", - "required": [ - "address", - "stage" - ], - "properties": { - "address": { - "type": "string" - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "total_claimed" - ], - "properties": { - "total_claimed": { - "type": "object", - "required": [ - "stage" - ], - "properties": { - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConfigResponse", - "type": "object", - "required": [ - "asset_info" - ], - "properties": { - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - } - } - }, - "is_claimed": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsClaimedResponse", - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "latest_stage": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "LatestStageResponse", - "type": "object", - "required": [ - "latest_stage" - ], - "properties": { - "latest_stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "merkle_root": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MerkleRootResponse", - "type": "object", - "required": [ - "expiration", - "merkle_root", - "stage", - "total_amount" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - }, - "merkle_root": { - "description": "MerkleRoot is hex-encoded merkle root.", - "type": "string" - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "total_amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "total_claimed": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TotalClaimedResponse", - "type": "object", - "required": [ - "total_claimed" - ], - "properties": { - "total_claimed": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/execute.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/execute.json deleted file mode 100644 index 88893e9..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/execute.json +++ /dev/null @@ -1,618 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "register_merkle_root" - ], - "properties": { - "register_merkle_root": { - "type": "object", - "required": [ - "merkle_root" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "merkle_root": { - "description": "MerkleRoot is hex-encoded merkle root.", - "type": "string" - }, - "total_amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Claim does not check if contract has enough funds, owner must ensure it.", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "required": [ - "amount", - "proof", - "stage" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "proof": { - "description": "Proof is hex-encoded merkle proof.", - "type": "array", - "items": { - "type": "string" - } - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burn the remaining tokens after expire time (only owner)", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "stage" - ], - "properties": { - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/instantiate.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/instantiate.json deleted file mode 100644 index cb1c4c1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/instantiate.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "asset_info", - "kernel_address" - ], - "properties": { - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_String" - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AssetInfoBase_for_String": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "type": "string" - } - }, - "additionalProperties": false - } - ] - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/query.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/query.json deleted file mode 100644 index c52a99a..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/query.json +++ /dev/null @@ -1,292 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "merkle_root" - ], - "properties": { - "merkle_root": { - "type": "object", - "required": [ - "stage" - ], - "properties": { - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "latest_stage" - ], - "properties": { - "latest_stage": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "object", - "required": [ - "address", - "stage" - ], - "properties": { - "address": { - "type": "string" - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "total_claimed" - ], - "properties": { - "total_claimed": { - "type": "object", - "required": [ - "stage" - ], - "properties": { - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_balance.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_config.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_config.json deleted file mode 100644 index 40fd2a5..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_config.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ConfigResponse", - "type": "object", - "required": [ - "asset_info" - ], - "properties": { - "asset_info": { - "$ref": "#/definitions/AssetInfoBase_for_Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AssetInfoBase_for_Addr": { - "description": "Represents the type of an fungible asset.\n\nEach **asset info** instance can be one of three variants:\n\n- Native SDK coins. To create an **asset info** instance of this type, provide the denomination. - CW20 tokens. To create an **asset info** instance of this type, provide the contract address.", - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_claimed.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_claimed.json deleted file mode 100644 index 1b1b8b6..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_claimed.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsClaimedResponse", - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_latest_stage.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_latest_stage.json deleted file mode 100644 index 45f8d38..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_latest_stage.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "LatestStageResponse", - "type": "object", - "required": [ - "latest_stage" - ], - "properties": { - "latest_stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_merkle_root.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_merkle_root.json deleted file mode 100644 index ac4a7b8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_merkle_root.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MerkleRootResponse", - "type": "object", - "required": [ - "expiration", - "merkle_root", - "stage", - "total_amount" - ], - "properties": { - "expiration": { - "$ref": "#/definitions/Expiration" - }, - "merkle_root": { - "description": "MerkleRoot is hex-encoded merkle root.", - "type": "string" - }, - "stage": { - "type": "integer", - "format": "uint8", - "minimum": 0.0 - }, - "total_amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_operators.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_owner.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissions.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_total_claimed.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_total_claimed.json deleted file mode 100644 index 356a772..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_total_claimed.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TotalClaimedResponse", - "type": "object", - "required": [ - "total_claimed" - ], - "properties": { - "total_claimed": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_type.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_version.json b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs index 8751c38..94c8f75 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/contract.rs @@ -3,13 +3,9 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, ensure, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Empty, - Env, MessageInfo, Response, StdResult, Uint128, WasmMsg, + attr, ensure, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, Uint128, }; -use cw2::{get_contract_version, set_contract_version}; -use cw20::Cw20ExecuteMsg; -use cw_asset::AssetInfoBase; -use cw_utils::{nonpayable, Expiration}; +use cw_utils::nonpayable; use sha2::Digest; use std::convert::TryInto; @@ -19,53 +15,75 @@ use crate::state::{ }; use andromeda_fungible_tokens::airdrop::{ ConfigResponse, ExecuteMsg, InstantiateMsg, IsClaimedResponse, LatestStageResponse, - MerkleRootResponse, MigrateMsg, QueryMsg, TotalClaimedResponse, + MerkleRootResponse, QueryMsg, TotalClaimedResponse, }; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, + ado_base::{ + permissioning::{LocalPermission, Permission}, + InstantiateMsg as BaseInstantiateMsg, MigrateMsg, + }, ado_contract::ADOContract, - common::{context::ExecuteContext, encode_binary}, - error::{from_semver, ContractError}, + common::{ + actions::call_action, + context::ExecuteContext, + denom::{Asset, SEND_CW20_ACTION}, + encode_binary, + expiration::Expiry, + }, + error::ContractError, }; -use semver::Version; - // Version info, for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-merkle-airdrop"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - deps: DepsMut, + mut deps: DepsMut, env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - let config = Config { - asset_info: msg.asset_info.check(deps.api, None)?, - }; - CONFIG.save(deps.storage, &config)?; - - let stage = 0; - LATEST_STAGE.save(deps.storage, &stage)?; - - let contract = ADOContract::default(); - let resp = contract.instantiate( + let resp = ADOContract::default().instantiate( deps.storage, - env, + env.clone(), deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "merkle-airdrop".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; + // IMPORTANT + // Permission must be set for Cw20 token + // Unless Cw20 is not identified as verified asset + if let Asset::Cw20Token(addr) = msg.asset_info.clone() { + let addr = addr.get_raw_address(&deps.as_ref())?; + ADOContract::default().permission_action(SEND_CW20_ACTION, deps.storage)?; + ADOContract::set_permission( + deps.storage, + SEND_CW20_ACTION, + addr, + Permission::Local(LocalPermission::whitelisted(None)), + )?; + } + + // Validate asset_info + msg.asset_info.get_verified_asset(deps.branch(), env)?; + + let config = Config { + asset_info: msg.asset_info, + }; + + CONFIG.save(deps.storage, &config)?; + + let stage = 0; + LATEST_STAGE.save(deps.storage, &stage)?; + Ok(resp) } @@ -86,8 +104,15 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - match msg { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { ExecuteMsg::RegisterMerkleRoot { merkle_root, expiration, @@ -100,16 +125,22 @@ pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_claim(ctx, stage, amount, proof), ExecuteMsg::Burn { stage } => execute_burn(ctx, stage), _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } pub fn execute_register_merkle_root( ctx: ExecuteContext, merkle_root: String, - expiration: Option, + expiration: Option, total_amount: Option, ) -> Result { - let ExecuteContext { deps, info, .. } = ctx; + let ExecuteContext { + deps, info, env, .. + } = ctx; nonpayable(&info)?; ensure!( @@ -127,8 +158,11 @@ pub fn execute_register_merkle_root( LATEST_STAGE.save(deps.storage, &stage)?; // save expiration - let exp = expiration.unwrap_or(Expiration::Never {}); - STAGE_EXPIRATION.save(deps.storage, stage, &exp)?; + STAGE_EXPIRATION.save( + deps.storage, + stage, + &expiration.map(|e| e.get_time(&env.block)), + )?; // save total airdropped amount let amount = total_amount.unwrap_or_else(Uint128::zero); @@ -154,12 +188,15 @@ pub fn execute_claim( } = ctx; nonpayable(&info)?; - // not expired - let expiration = STAGE_EXPIRATION.load(deps.storage, stage)?; - ensure!( - !expiration.is_expired(&env.block), - ContractError::StageExpired { stage, expiration } - ); + // Ensure that the stage expiration (if it exists) isn't expired + let expiration_milliseconds = STAGE_EXPIRATION.load(deps.storage, stage)?; + if let Some(expiration_milliseconds) = expiration_milliseconds { + let expiration = expiration_milliseconds; + ensure!( + !expiration.is_expired(&env.block), + ContractError::StageExpired { stage, expiration } + ); + }; // verify not claimed ensure!( @@ -196,27 +233,15 @@ pub fn execute_claim( // Update total claimed to reflect let mut claimed_amount = STAGE_AMOUNT_CLAIMED.load(deps.storage, stage)?; - claimed_amount += amount; + claimed_amount = claimed_amount.checked_add(amount)?; STAGE_AMOUNT_CLAIMED.save(deps.storage, stage, &claimed_amount)?; - let transfer_msg: CosmosMsg = match config.asset_info { - AssetInfoBase::Native(denom) => CosmosMsg::Bank(BankMsg::Send { - to_address: info.sender.to_string(), - amount: vec![Coin { amount, denom }], - }), - AssetInfoBase::Cw20(address) => CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address.to_string(), - funds: vec![], - msg: to_json_binary(&Cw20ExecuteMsg::Transfer { - recipient: info.sender.to_string(), - amount, - })?, - }), - _ => CosmosMsg::Custom(Empty {}), - }; + let transfer_msg = config + .asset_info + .transfer(&deps.as_ref(), info.sender.clone(), amount)?; let res = Response::new() - .add_message(transfer_msg) + .add_submessage(transfer_msg) .add_attributes(vec![ attr("action", "claim"), attr("stage", stage.to_string()), @@ -237,10 +262,12 @@ pub fn execute_burn(ctx: ExecuteContext, stage: u8) -> Result Result CosmosMsg::Bank(BankMsg::Burn { - amount: vec![Coin { - amount: balance_to_burn, - denom, - }], - }), - AssetInfoBase::Cw20(address) => CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: address.to_string(), - funds: vec![], - msg: to_json_binary(&Cw20ExecuteMsg::Burn { - amount: balance_to_burn, - })?, - }), - _ => CosmosMsg::Custom(Empty {}), - }; + let burn_msg = config.asset_info.burn(&deps.as_ref(), balance_to_burn)?; // Burn the tokens and response - let res = Response::new().add_message(burn_msg).add_attributes(vec![ - attr("action", "burn"), - attr("stage", stage.to_string()), - attr("address", info.sender), - attr("amount", balance_to_burn), - ]); + let res = Response::new() + .add_submessage(burn_msg) + .add_attributes(vec![ + attr("action", "burn"), + attr("stage", stage.to_string()), + attr("address", info.sender), + attr("amount", balance_to_burn), + ]); Ok(res) } @@ -347,34 +361,5 @@ pub fn query_total_claimed(deps: Deps, stage: u8) -> Result Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/state.rs b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/state.rs index ce8d25d..43701cc 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/state.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/state.rs @@ -1,13 +1,12 @@ +use andromeda_std::common::{denom::Asset, MillisecondsExpiration}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Uint128}; -use cw_asset::AssetInfo; use cw_storage_plus::{Item, Map}; -use cw_utils::Expiration; #[cw_serde] pub struct Config { - pub asset_info: AssetInfo, + pub asset_info: Asset, } pub const CONFIG_KEY: &str = "config"; @@ -17,7 +16,8 @@ pub const LATEST_STAGE_KEY: &str = "stage"; pub const LATEST_STAGE: Item = Item::new(LATEST_STAGE_KEY); pub const STAGE_EXPIRATION_KEY: &str = "stage_exp"; -pub const STAGE_EXPIRATION: Map = Map::new(STAGE_EXPIRATION_KEY); +pub const STAGE_EXPIRATION: Map> = + Map::new(STAGE_EXPIRATION_KEY); pub const STAGE_AMOUNT_KEY: &str = "stage_amount"; pub const STAGE_AMOUNT: Map = Map::new(STAGE_AMOUNT_KEY); diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/mock_querier.rs b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/mock_querier.rs index d2060e4..8af252c 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/mock_querier.rs @@ -6,7 +6,7 @@ use cosmwasm_std::testing::{ }; use cosmwasm_std::{ from_json, to_json_binary, Coin, ContractResult, Empty, OwnedDeps, Querier, QuerierResult, - QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, + QuerierWrapper, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, }; use cw20::{BalanceResponse as Cw20BalanceResponse, Cw20QueryMsg}; use std::collections::HashMap; @@ -28,11 +28,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "cw20-staking".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, diff --git a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/tests.rs b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/tests.rs index cf20fff..8184c81 100644 --- a/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/tests.rs +++ b/andromeda-core/contracts/fungible-tokens/andromeda-merkle-airdrop/src/testing/tests.rs @@ -3,32 +3,36 @@ use andromeda_fungible_tokens::airdrop::{ MerkleRootResponse, QueryMsg, TotalClaimedResponse, }; use andromeda_std::{ - ado_contract::ADOContract, error::ContractError, testing::mock_querier::MOCK_KERNEL_CONTRACT, + ado_contract::ADOContract, + amp::AndrAddr, + common::{denom::Asset, expiration::Expiry, Milliseconds}, + error::ContractError, + testing::mock_querier::{MOCK_CW20_CONTRACT, MOCK_KERNEL_CONTRACT}, }; +use andromeda_testing::economics_msg::generate_economics_message; use cosmwasm_schema::{cw_serde, serde::Deserialize}; use cosmwasm_std::{ - attr, from_json, + attr, coin, from_json, testing::{mock_env, mock_info}, - to_json_binary, Addr, BankMsg, Coin, CosmosMsg, SubMsg, Uint128, WasmMsg, + to_json_binary, BankMsg, Coin, CosmosMsg, SubMsg, Timestamp, Uint128, WasmMsg, }; use cw20::Cw20ExecuteMsg; -use cw_asset::{AssetInfoBase, AssetInfoUnchecked}; -use cw_utils::Expiration; use crate::{ contract::{execute, instantiate, query}, testing::mock_querier::mock_dependencies_custom, }; +const MOCK_NATIVE_DENOM: &str = "uandr"; + #[test] fn proper_instantiation() { let mut deps = mock_dependencies_custom(&[]); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::cw20("anchor0000"), + asset_info: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let env = mock_env(); @@ -44,7 +48,7 @@ fn proper_instantiation() { .is_contract_owner(deps.as_ref().storage, "owner0000") .unwrap()); assert_eq!( - AssetInfoBase::cw20(Addr::unchecked("anchor0000")), + Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), config.asset_info ); @@ -58,10 +62,9 @@ fn register_merkle_root() { let mut deps = mock_dependencies_custom(&[]); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::cw20("anchor0000"), + asset_info: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let env = mock_env(); @@ -123,16 +126,15 @@ struct Encoded { } #[test] -fn claim() { +fn test_claim() { // Run test 1 let mut deps = mock_dependencies_custom(&[]); let test_data: Encoded = from_json(TEST_DATA_1).unwrap(); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::cw20("token0000"), + asset_info: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let env = mock_env(); @@ -159,7 +161,7 @@ fn claim() { let info = mock_info(test_data.account.as_str(), &[]); let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); let expected = SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "token0000".to_string(), + contract_addr: MOCK_CW20_CONTRACT.to_string(), funds: vec![], msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: test_data.account.clone(), @@ -167,7 +169,13 @@ fn claim() { }) .unwrap(), })); - assert_eq!(res.messages, vec![expected]); + assert_eq!( + res.messages, + vec![ + expected, + generate_economics_message(test_data.account.as_str(), "Claim") + ] + ); assert_eq!( res.attributes, @@ -240,7 +248,7 @@ fn claim() { let info = mock_info(test_data.account.as_str(), &[]); let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let expected: SubMsg<_> = SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "token0000".to_string(), + contract_addr: MOCK_CW20_CONTRACT.to_string(), funds: vec![], msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: test_data.account.clone(), @@ -248,7 +256,13 @@ fn claim() { }) .unwrap(), })); - assert_eq!(res.messages, vec![expected]); + assert_eq!( + res.messages, + vec![ + expected, + generate_economics_message(test_data.account.as_str(), "Claim") + ] + ); assert_eq!( res.attributes, @@ -288,15 +302,14 @@ struct MultipleData { } #[test] -fn claim_native() { - let mut deps = mock_dependencies_custom(&[]); +fn test_claim_native() { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); let test_data: Encoded = from_json(TEST_DATA_1).unwrap(); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::native("uusd"), + asset_info: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let env = mock_env(); @@ -325,10 +338,16 @@ fn claim_native() { to_address: test_data.account.clone(), amount: vec![Coin { amount: test_data.amount, - denom: "uusd".to_string(), + denom: MOCK_NATIVE_DENOM.to_string(), }], })); - assert_eq!(res.messages, vec![expected]); + assert_eq!( + res.messages, + vec![ + expected, + generate_economics_message(test_data.account.as_str(), "Claim") + ] + ); assert_eq!( res.attributes, @@ -374,16 +393,15 @@ fn claim_native() { } #[test] -fn multiple_claim() { +fn test_multiple_claim() { // Run test 1 let mut deps = mock_dependencies_custom(&[]); let test_data: MultipleData = from_json(TEST_DATA_1_MULTI).unwrap(); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::cw20("token0000"), + asset_info: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let env = mock_env(); @@ -411,7 +429,7 @@ fn multiple_claim() { let info = mock_info(account.account.as_str(), &[]); let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); let expected = SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "token0000".to_string(), + contract_addr: MOCK_CW20_CONTRACT.to_string(), funds: vec![], msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: account.account.clone(), @@ -419,7 +437,13 @@ fn multiple_claim() { }) .unwrap(), })); - assert_eq!(res.messages, vec![expected]); + assert_eq!( + res.messages, + vec![ + expected, + generate_economics_message(account.account.as_str(), "Claim") + ] + ); assert_eq!( res.attributes, @@ -446,14 +470,13 @@ fn multiple_claim() { // Check expiration. Chain height in tests is 12345 #[test] -fn stage_expires() { +fn test_stage_expires() { let mut deps = mock_dependencies_custom(&[]); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::cw20("anchor0000"), + asset_info: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let env = mock_env(); @@ -465,8 +488,7 @@ fn stage_expires() { let info = mock_info("owner0000", &[]); let msg = ExecuteMsg::RegisterMerkleRoot { merkle_root: "5d4f48f147cb6cb742b376dce5626b2a036f69faec10cd73631c791780e150fc".to_string(), - expiration: Some(Expiration::AtHeight(100)), - + expiration: Some(Expiry::AtTime(Milliseconds::from_nanos(100_000_000))), total_amount: None, }; execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); @@ -483,20 +505,19 @@ fn stage_expires() { res, ContractError::StageExpired { stage: 1, - expiration: Expiration::AtHeight(100) + expiration: Milliseconds::from_nanos(100_000_000) } ) } #[test] -fn cant_burn() { +fn test_cant_burn() { let mut deps = mock_dependencies_custom(&[]); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::cw20("token0000"), + asset_info: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let env = mock_env(); @@ -504,39 +525,37 @@ fn cant_burn() { let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); // can register merkle root - let env = mock_env(); + let mut env = mock_env(); let info = mock_info("owner0000", &[]); let msg = ExecuteMsg::RegisterMerkleRoot { merkle_root: "5d4f48f147cb6cb742b376dce5626b2a036f69faec10cd73631c791780e150fc".to_string(), - expiration: Some(Expiration::AtHeight(12346)), - + expiration: Some(Expiry::AtTime(Milliseconds::from_nanos(100_000_000))), total_amount: Some(Uint128::new(100000)), }; execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); // Can't burn not expired stage let msg = ExecuteMsg::Burn { stage: 1u8 }; - + env.block.time = Timestamp::from_nanos(10_000_000); let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); assert_eq!( res, ContractError::StageNotExpired { stage: 1, - expiration: Expiration::AtHeight(12346) + expiration: Milliseconds::from_nanos(100_000_000) } ) } #[test] -fn can_burn() { +fn test_can_burn() { let mut deps = mock_dependencies_custom(&[]); let test_data: Encoded = from_json(TEST_DATA_1).unwrap(); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::cw20("token0000"), + asset_info: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT)), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let mut env = mock_env(); @@ -546,8 +565,7 @@ fn can_burn() { let info = mock_info("owner0000", &[]); let msg = ExecuteMsg::RegisterMerkleRoot { merkle_root: test_data.root, - expiration: Some(Expiration::AtHeight(12500)), - + expiration: Some(Expiry::AtTime(Milliseconds::from_nanos(100_000_000))), total_amount: Some(Uint128::new(10000)), }; execute(deps.as_mut(), env.clone(), info, msg).unwrap(); @@ -558,11 +576,11 @@ fn can_burn() { stage: 1u8, proof: test_data.proofs, }; - + env.block.time = Timestamp::from_nanos(100_000_000 - 1); let info = mock_info(test_data.account.as_str(), &[]); let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let expected = SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "token0000".to_string(), + contract_addr: MOCK_CW20_CONTRACT.to_string(), funds: vec![], msg: to_json_binary(&Cw20ExecuteMsg::Transfer { recipient: test_data.account.clone(), @@ -570,7 +588,13 @@ fn can_burn() { }) .unwrap(), })); - assert_eq!(res.messages, vec![expected]); + assert_eq!( + res.messages, + vec![ + expected, + generate_economics_message(test_data.account.as_str(), "Claim") + ] + ); assert_eq!( res.attributes, @@ -583,7 +607,7 @@ fn can_burn() { ); // makes the stage expire - env.block.height = 12501; + env.block.time = Timestamp::from_nanos(100_000_000 + 2); // Can burn after expired stage let msg = ExecuteMsg::Burn { stage: 1u8 }; @@ -592,14 +616,17 @@ fn can_burn() { let res = execute(deps.as_mut(), env, info, msg).unwrap(); let expected = SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: "token0000".to_string(), + contract_addr: MOCK_CW20_CONTRACT.to_string(), funds: vec![], msg: to_json_binary(&Cw20ExecuteMsg::Burn { amount: Uint128::new(9900), }) .unwrap(), })); - assert_eq!(res.messages, vec![expected]); + assert_eq!( + res.messages, + vec![expected, generate_economics_message("owner0000", "Burn")] + ); assert_eq!( res.attributes, @@ -613,15 +640,14 @@ fn can_burn() { } #[test] -fn can_burn_native() { - let mut deps = mock_dependencies_custom(&[]); +fn test_can_burn_native() { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); let test_data: Encoded = from_json(TEST_DATA_1).unwrap(); let msg = InstantiateMsg { - asset_info: AssetInfoUnchecked::native("uusd"), + asset_info: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, - modules: None, }; let mut env = mock_env(); @@ -631,8 +657,7 @@ fn can_burn_native() { let info = mock_info("owner0000", &[]); let msg = ExecuteMsg::RegisterMerkleRoot { merkle_root: test_data.root, - expiration: Some(Expiration::AtHeight(12500)), - + expiration: Some(Expiry::AtTime(Milliseconds::from_nanos(100_000_000))), total_amount: Some(Uint128::new(10000)), }; execute(deps.as_mut(), env.clone(), info, msg).unwrap(); @@ -645,10 +670,11 @@ fn can_burn_native() { }; let info = mock_info(test_data.account.as_str(), &[]); + env.block.time = Timestamp::from_nanos(100_000_000 - 1); let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); // makes the stage expire - env.block.height = 12501; + env.block.time = Timestamp::from_nanos(100_000_000 + 1); // Can burn after expired stage let msg = ExecuteMsg::Burn { stage: 1u8 }; @@ -659,10 +685,13 @@ fn can_burn_native() { let expected = SubMsg::new(CosmosMsg::Bank(BankMsg::Burn { amount: vec![Coin { amount: Uint128::new(9900), - denom: "uusd".to_string(), + denom: MOCK_NATIVE_DENOM.to_string(), }], })); - assert_eq!(res.messages, vec![expected]); + assert_eq!( + res.messages, + vec![expected, generate_economics_message("owner0000", "Burn")] + ); assert_eq!( res.attributes, diff --git a/andromeda-core/contracts/modules/andromeda-address-list/Cargo.toml b/andromeda-core/contracts/modules/andromeda-address-list/Cargo.toml index 268af2e..74141e2 100644 --- a/andromeda-core/contracts/modules/andromeda-address-list/Cargo.toml +++ b/andromeda-core/contracts/modules/andromeda-address-list/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-address-list" -version = "0.2.1" +version = "2.0.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -20,15 +20,13 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["module_hooks"] } +andromeda-std = { workspace = true, features = [] } andromeda-modules = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } -andromeda-testing = { workspace = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/modules/andromeda-address-list/README.md b/andromeda-core/contracts/modules/andromeda-address-list/README.md new file mode 100644 index 0000000..2bbb592 --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-address-list/README.md @@ -0,0 +1,7 @@ +# Overview + +The address list ADO is a smart contract that facilitates setting up permissions for ADOs. Instead of setting up the permission on the ADO itself, the owner can reference this ADO instead. + +Permissioning allows ADO owners to give/restrict access to addresses to execute messages on their ADOs. + +**Note**: This ADO is not released yet. Once released, a link to full documentation will be provided. \ No newline at end of file diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/andromeda-address-list.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/andromeda-address-list.json deleted file mode 100644 index ad6c0d7..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/andromeda-address-list.json +++ /dev/null @@ -1,1549 +0,0 @@ -{ - "contract_name": "andromeda-address-list", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "is_inclusive", - "kernel_address" - ], - "properties": { - "is_inclusive": { - "type": "boolean" - }, - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Add an address to the address list", - "type": "object", - "required": [ - "add_address" - ], - "properties": { - "add_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove an address from the address list", - "type": "object", - "required": [ - "remove_address" - ], - "properties": { - "remove_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Add multiple addresses to the address list", - "type": "object", - "required": [ - "add_addresses" - ], - "properties": { - "add_addresses": { - "type": "object", - "required": [ - "addresses" - ], - "properties": { - "addresses": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Query if address is included", - "type": "object", - "required": [ - "includes_address" - ], - "properties": { - "includes_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_inclusive" - ], - "properties": { - "is_inclusive": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "includes_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IncludesAddressResponse", - "type": "object", - "required": [ - "included" - ], - "properties": { - "included": { - "description": "Whether the address is included in the address list", - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_inclusive": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsInclusiveResponse", - "type": "object", - "required": [ - "is_inclusive_response" - ], - "properties": { - "is_inclusive_response": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/execute.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/execute.json deleted file mode 100644 index c236f4c..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/execute.json +++ /dev/null @@ -1,675 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Add an address to the address list", - "type": "object", - "required": [ - "add_address" - ], - "properties": { - "add_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove an address from the address list", - "type": "object", - "required": [ - "remove_address" - ], - "properties": { - "remove_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Add multiple addresses to the address list", - "type": "object", - "required": [ - "add_addresses" - ], - "properties": { - "add_addresses": { - "type": "object", - "required": [ - "addresses" - ], - "properties": { - "addresses": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/instantiate.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/instantiate.json deleted file mode 100644 index 8232bed..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/instantiate.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "is_inclusive", - "kernel_address" - ], - "properties": { - "is_inclusive": { - "type": "boolean" - }, - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/query.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/query.json deleted file mode 100644 index 5c3bfd7..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/query.json +++ /dev/null @@ -1,432 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Query if address is included", - "type": "object", - "required": [ - "includes_address" - ], - "properties": { - "includes_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_inclusive" - ], - "properties": { - "is_inclusive": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_balance.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_includes_address.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_includes_address.json deleted file mode 100644 index 7513106..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_includes_address.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IncludesAddressResponse", - "type": "object", - "required": [ - "included" - ], - "properties": { - "included": { - "description": "Whether the address is included in the address list", - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_inclusive.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_inclusive.json deleted file mode 100644 index 2fef936..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_inclusive.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsInclusiveResponse", - "type": "object", - "required": [ - "is_inclusive_response" - ], - "properties": { - "is_inclusive_response": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_operators.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_owner.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissions.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_type.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_version.json b/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/modules/andromeda-address-list/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-address-list/src/contract.rs b/andromeda-core/contracts/modules/andromeda-address-list/src/contract.rs index 9876fe3..3d01506 100644 --- a/andromeda-core/contracts/modules/andromeda-address-list/src/contract.rs +++ b/andromeda-core/contracts/modules/andromeda-address-list/src/contract.rs @@ -1,22 +1,22 @@ +use andromeda_modules::address_list::{ActorPermissionResponse, IncludesActorResponse}; #[cfg(not(feature = "library"))] -use andromeda_modules::address_list::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; -use andromeda_modules::address_list::{IncludesAddressResponse, IsInclusiveResponse}; +use andromeda_modules::address_list::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, + ado_base::{permissioning::LocalPermission, InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, ado_contract::ADOContract, + amp::AndrAddr, common::{context::ExecuteContext, encode_binary}, - error::{from_semver, ContractError}, + error::ContractError, }; -use cosmwasm_std::{attr, ensure, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError}; -use cosmwasm_std::{entry_point, to_json_binary}; -use cw2::{get_contract_version, set_contract_version}; +use cosmwasm_std::{ + attr, ensure, entry_point, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, +}; use cw_utils::nonpayable; -use semver::Version; -use crate::state::{add_address, includes_address, remove_address, IS_INCLUSIVE}; +use crate::state::{add_actors_permission, includes_actor, PERMISSIONS}; // version info for migration info -const CONTRACT_NAME: &str = "crates.io:andromeda-addresslist"; +const CONTRACT_NAME: &str = "crates.io:andromeda-address-list"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] @@ -26,18 +26,33 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - IS_INCLUSIVE.save(deps.storage, &msg.is_inclusive)?; - + // If the user provided an actor and permission, save them. + if let Some(actor_permission) = msg.actor_permission { + // Permissions of type Limited local permissions aren't allowed in the address list contract + if let LocalPermission::Limited { .. } = actor_permission.permission { + return Err(ContractError::InvalidPermission { + msg: "Limited permission is not supported in address list contract".to_string(), + }); + } + ensure!( + !actor_permission.actors.is_empty(), + ContractError::NoActorsProvided {} + ); + + for actor in actor_permission.actors { + let verified_actor = actor.get_raw_address(&deps.as_ref())?; + add_actors_permission(deps.storage, verified_actor, &actor_permission.permission)?; + } + } let inst_resp = ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "address-list".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -66,148 +81,108 @@ pub fn execute( pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::AddAddress { address } => execute_add_address(ctx, address), - ExecuteMsg::RemoveAddress { address } => execute_remove_address(ctx, address), - ExecuteMsg::AddAddresses { addresses } => execute_add_addresses(ctx, addresses), + ExecuteMsg::PermissionActors { actors, permission } => { + execute_permission_actors(ctx, actors, permission) + } + ExecuteMsg::RemovePermissions { actors } => execute_remove_permissions(ctx, actors), _ => ADOContract::default().execute(ctx, msg), } } -fn execute_add_address(ctx: ExecuteContext, address: String) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - nonpayable(&info)?; - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - add_address(deps.storage, &address)?; - - Ok(Response::new().add_attributes(vec![ - attr("action", "add_address"), - attr("address", address), - ])) -} - -fn execute_remove_address(ctx: ExecuteContext, address: String) -> Result { +fn execute_permission_actors( + ctx: ExecuteContext, + actors: Vec, + permission: LocalPermission, +) -> Result { let ExecuteContext { deps, info, .. } = ctx; nonpayable(&info)?; - ensure!( ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); - - remove_address(deps.storage, &address); - + if let LocalPermission::Limited { .. } = permission { + return Err(ContractError::InvalidPermission { + msg: "Limited permission is not supported in address list contract".to_string(), + }); + } + ensure!(!actors.is_empty(), ContractError::NoActorsProvided {}); + for actor in actors.clone() { + let verified_actor = actor.get_raw_address(&deps.as_ref())?; + add_actors_permission(deps.storage, verified_actor, &permission)?; + } + let actors_str = actors + .iter() + .map(|actor| actor.to_string()) + .collect::>() + .join(", "); Ok(Response::new().add_attributes(vec![ - attr("action", "remove_address"), - attr("address", address), + attr("action", "add_actor_permission"), + attr("actor", actors_str), + attr("permission", permission.to_string()), ])) } -const MAX_ADDRESSES_SIZE: usize = 100; - -fn execute_add_addresses( +fn execute_remove_permissions( ctx: ExecuteContext, - addresses: Vec, + actors: Vec, ) -> Result { let ExecuteContext { deps, info, .. } = ctx; nonpayable(&info)?; - - ensure!( - !addresses.is_empty(), - ContractError::Std(StdError::generic_err("addresses cannot be empty")) - ); - ensure!( - addresses.len() <= MAX_ADDRESSES_SIZE, - ContractError::Std(StdError::generic_err( - "addresses length cannot be more than 100" - )) - ); - ensure!( ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); - - for address in addresses.clone() { - add_address(deps.storage, &address)?; + ensure!(!actors.is_empty(), ContractError::NoActorsProvided {}); + + for actor in actors.clone() { + let verified_actor = actor.get_raw_address(&deps.as_ref())?; + // Ensure that the actor is present in the permissions list + ensure!( + PERMISSIONS.has(deps.storage, &verified_actor), + ContractError::ActorNotFound {} + ); + PERMISSIONS.remove(deps.storage, &verified_actor); } + let actors_str = actors + .iter() + .map(|actor| actor.to_string()) + .collect::>() + .join(", "); Ok(Response::new().add_attributes(vec![ - attr("action", "add_addresses"), - attr("addresses", addresses.join(",")), + attr("action", "remove_actor_permission"), + attr("actor", actors_str), ])) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::AndrHook(msg) => handle_andr_hook(deps, msg), - QueryMsg::IncludesAddress { address } => encode_binary(&query_address(deps, &address)?), - QueryMsg::IsInclusive {} => encode_binary(&handle_is_inclusive(deps)?), + QueryMsg::IncludesActor { actor } => encode_binary(&query_actor(deps, actor)?), + QueryMsg::ActorPermission { actor } => encode_binary(&query_actor_permission(deps, actor)?), _ => ADOContract::default().query(deps, env, msg), } } -fn handle_andr_hook(deps: Deps, msg: AndromedaHook) -> Result { - match msg { - AndromedaHook::OnExecute { sender, .. } => { - let is_included = includes_address(deps.storage, &sender)?; - let is_inclusive = IS_INCLUSIVE.load(deps.storage)?; - if is_included != is_inclusive { - Err(ContractError::Unauthorized {}) - } else { - Ok(to_json_binary(&None::)?) - } - } - _ => Ok(to_json_binary(&None::)?), - } -} - -fn handle_is_inclusive(deps: Deps) -> Result { - let is_inclusive = IS_INCLUSIVE.load(deps.storage)?; - Ok(IsInclusiveResponse { - is_inclusive_response: is_inclusive, +fn query_actor(deps: Deps, actor: Addr) -> Result { + Ok(IncludesActorResponse { + included: includes_actor(deps.storage, &actor)?, }) } -fn query_address(deps: Deps, address: &str) -> Result { - Ok(IncludesAddressResponse { - included: includes_address(deps.storage, address)?, - }) +fn query_actor_permission( + deps: Deps, + actor: Addr, +) -> Result { + let permission = PERMISSIONS.may_load(deps.storage, &actor)?; + if let Some(permission) = permission { + Ok(ActorPermissionResponse { permission }) + } else { + Err(ContractError::ActorNotFound {}) + } } diff --git a/andromeda-core/contracts/modules/andromeda-address-list/src/mock.rs b/andromeda-core/contracts/modules/andromeda-address-list/src/mock.rs index 5f9295d..76ab576 100644 --- a/andromeda-core/contracts/modules/andromeda-address-list/src/mock.rs +++ b/andromeda-core/contracts/modules/andromeda-address-list/src/mock.rs @@ -1,8 +1,11 @@ #![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] use crate::contract::{execute, instantiate, query}; -use andromeda_modules::address_list::{ExecuteMsg, InstantiateMsg, QueryMsg}; -use andromeda_testing::{mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; +use andromeda_modules::address_list::{ActorPermission, ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::{ado_base::permissioning::LocalPermission, amp::AndrAddr}; +use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract, +}; use cosmwasm_std::{Addr, Empty}; use cw_multi_test::{App, Contract, ContractWrapper, Executor}; @@ -14,11 +17,11 @@ impl MockAddressList { code_id: u64, sender: Addr, app: &mut App, - is_inclusive: bool, kernel_address: impl Into, owner: Option, + actor_permission: Option, ) -> MockAddressList { - let msg = mock_address_list_instantiate_msg(is_inclusive, kernel_address, owner); + let msg = mock_address_list_instantiate_msg(kernel_address, owner, actor_permission); let addr = app .instantiate_contract( code_id, @@ -32,17 +35,19 @@ impl MockAddressList { MockAddressList(Addr::unchecked(addr)) } - pub fn execute_add_address( + pub fn execute_actor_permission( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, - address: impl Into, + actors: Vec, + permission: LocalPermission, ) -> ExecuteResult { - self.execute(app, &mock_add_address_msg(address), sender, &[]) - } - - pub fn query_includes_address(&self, app: &App, address: impl Into) -> bool { - self.query::(app, mock_includes_address_msg(address)) + self.execute( + app, + &mock_add_actor_permission_msg(actors, permission), + sender, + &[], + ) } } @@ -52,25 +57,20 @@ pub fn mock_andromeda_address_list() -> Box> { } pub fn mock_address_list_instantiate_msg( - is_inclusive: bool, kernel_address: impl Into, owner: Option, + actor_permission: Option, ) -> InstantiateMsg { InstantiateMsg { - is_inclusive, kernel_address: kernel_address.into(), owner, + actor_permission, } } -pub fn mock_add_address_msg(address: impl Into) -> ExecuteMsg { - ExecuteMsg::AddAddress { - address: address.into(), - } -} - -pub fn mock_includes_address_msg(address: impl Into) -> QueryMsg { - QueryMsg::IncludesAddress { - address: address.into(), - } +pub fn mock_add_actor_permission_msg( + actors: Vec, + permission: LocalPermission, +) -> ExecuteMsg { + ExecuteMsg::PermissionActors { actors, permission } } diff --git a/andromeda-core/contracts/modules/andromeda-address-list/src/state.rs b/andromeda-core/contracts/modules/andromeda-address-list/src/state.rs index d7c7da3..88de853 100644 --- a/andromeda-core/contracts/modules/andromeda-address-list/src/state.rs +++ b/andromeda-core/contracts/modules/andromeda-address-list/src/state.rs @@ -1,21 +1,21 @@ -use cosmwasm_std::{StdResult, Storage}; -use cw_storage_plus::{Item, Map}; +use andromeda_std::ado_base::permissioning::LocalPermission; +use cosmwasm_std::{Addr, StdResult, Storage}; +use cw_storage_plus::Map; -pub const ADDRESS_LIST: Map<&str, bool> = Map::new("addresslist"); -pub const IS_INCLUSIVE: Item = Item::new("is_inclusive"); +/// A mapping of actor to LocalPermission. Contract Permission is not supported in this contract +pub const PERMISSIONS: Map<&Addr, LocalPermission> = Map::new("permissioning"); -/// Add an address to the address list. -pub fn add_address(storage: &mut dyn Storage, addr: &str) -> StdResult<()> { - ADDRESS_LIST.save(storage, addr, &true) +/// Query if a given actor is included in the permissions list. +pub fn includes_actor(storage: &dyn Storage, actor: &Addr) -> StdResult { + Ok(PERMISSIONS.has(storage, actor)) } -/// Remove an address from the address list. Errors if the address is not currently included. -pub fn remove_address(storage: &mut dyn Storage, addr: &str) { - // Check if the address is included in the address list before removing - if ADDRESS_LIST.has(storage, addr) { - ADDRESS_LIST.remove(storage, addr); - }; -} -/// Query if a given address is included in the address list. -pub fn includes_address(storage: &dyn Storage, addr: &str) -> StdResult { - Ok(ADDRESS_LIST.may_load(storage, addr)?.unwrap_or(false)) + +/// Add or update an actor's permission +pub fn add_actors_permission( + storage: &mut dyn Storage, + actor: Addr, + permission: &LocalPermission, +) -> StdResult<()> { + PERMISSIONS.save(storage, &actor, permission)?; + Ok(()) } diff --git a/andromeda-core/contracts/modules/andromeda-address-list/src/testing/mock_querier.rs b/andromeda-core/contracts/modules/andromeda-address-list/src/testing/mock_querier.rs index c6f2ecd..0479281 100644 --- a/andromeda-core/contracts/modules/andromeda-address-list/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/modules/andromeda-address-list/src/testing/mock_querier.rs @@ -1,17 +1,15 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; use andromeda_std::testing::mock_querier::MockAndromedaQuerier; use cosmwasm_std::testing::mock_info; -use cosmwasm_std::Response; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; -pub use andromeda_std::testing::mock_querier::{MOCK_ADDRESS_LIST_CONTRACT, MOCK_KERNEL_CONTRACT}; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -33,11 +31,11 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { - ado_type: "rates".to_string(), - ado_version: "test".to_string(), - operators: None, + ado_type: "address-list".to_string(), + ado_version: "1.0.0".to_string(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -71,35 +69,17 @@ impl Querier for WasmMockQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) } _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/modules/andromeda-address-list/src/testing/tests.rs b/andromeda-core/contracts/modules/andromeda-address-list/src/testing/tests.rs index 372c268..ba26f85 100644 --- a/andromeda-core/contracts/modules/andromeda-address-list/src/testing/tests.rs +++ b/andromeda-core/contracts/modules/andromeda-address-list/src/testing/tests.rs @@ -1,16 +1,16 @@ use crate::contract::{execute, instantiate, query}; -use crate::state::{ADDRESS_LIST, IS_INCLUSIVE}; +use crate::state::PERMISSIONS; use crate::testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}; use andromeda_modules::address_list::{ - ExecuteMsg, IncludesAddressResponse, InstantiateMsg, QueryMsg, + ActorPermission, ActorPermissionResponse, ExecuteMsg, IncludesActorResponse, InstantiateMsg, + QueryMsg, }; -use andromeda_std::ado_base::hooks::AndromedaHook; -use andromeda_std::ado_contract::ADOContract; +use andromeda_std::ado_base::permissioning::LocalPermission; -use andromeda_std::common::encode_binary; +use andromeda_std::amp::AndrAddr; use andromeda_std::error::ContractError; -use cosmwasm_std::{attr, from_json, DepsMut, MessageInfo, StdError}; +use cosmwasm_std::{attr, from_json, Addr, DepsMut, MessageInfo}; use cosmwasm_std::{ testing::{mock_env, mock_info}, Response, @@ -22,9 +22,12 @@ fn init(deps: DepsMut, info: MessageInfo) { mock_env(), info, InstantiateMsg { - is_inclusive: true, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, + actor_permission: Some(ActorPermission { + actors: vec![AndrAddr::from_string("actor")], + permission: LocalPermission::whitelisted(None), + }), }, ) .unwrap(); @@ -38,245 +41,262 @@ fn test_instantiate() { init(deps.as_mut(), info); } +// #[test] +// fn test_instantiate_contract_permission() { +// let mut deps = mock_dependencies_custom(&[]); +// let info = mock_info("creator", &[]); + +// let err = instantiate( +// deps.as_mut(), +// mock_env(), +// info, +// InstantiateMsg { +// kernel_address: MOCK_KERNEL_CONTRACT.to_string(), +// owner: None, +// actor_permission: Some(ActorPermission { +// actor: Addr::unchecked(MOCK_KERNEL_CONTRACT), +// permission: Permission::Whitelisted(None), +// }), +// }, +// ) +// .unwrap_err(); +// assert_eq!( +// err, +// ContractError::InvalidPermission { +// msg: "Contract permissions aren't allowed in the address list contract".to_string() +// } +// ) +// } + #[test] -fn test_add_address() { +fn test_add_remove_actor() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); let operator = "creator"; let info = mock_info(operator, &[]); - let address = "whitelistee"; + let actor = Addr::unchecked("actor"); + let permission = LocalPermission::default(); init(deps.as_mut(), info.clone()); - ADOContract::default() - .execute_update_operators(deps.as_mut(), info.clone(), vec![operator.to_owned()]) - .unwrap(); - - let msg = ExecuteMsg::AddAddress { - address: address.to_string(), + let msg = ExecuteMsg::PermissionActors { + actors: vec![AndrAddr::from_string(actor.clone())], + permission: permission.clone(), }; - //add address for registered operator - - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap(); + let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); let expected = Response::default().add_attributes(vec![ - attr("action", "add_address"), - attr("address", address), + attr("action", "add_actor_permission"), + attr("actor", actor.clone()), + attr("permission", permission.to_string()), ]); assert_eq!(expected, res); - let whitelisted = ADDRESS_LIST.load(deps.as_ref().storage, address).unwrap(); - assert!(whitelisted); + // Check that the actor and permission have been saved. + let new_permission = PERMISSIONS.load(deps.as_ref().storage, &actor).unwrap(); + assert_eq!(new_permission, permission); - let included = ADDRESS_LIST.load(deps.as_ref().storage, "111").unwrap_err(); + // Try with unauthorized address + let unauth_info = mock_info("anyone", &[]); + let res = execute(deps.as_mut(), env.clone(), unauth_info, msg).unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, res); - match included { - cosmwasm_std::StdError::NotFound { .. } => {} - _ => { - panic!(); - } - } + // // Contract permissions aren't allowed to be saved in the address list contract + // let contract_permission = Permission::Whitelisted(None); + // let msg = ExecuteMsg::PermissionActors { + // actor: Addr::unchecked(MOCK_KERNEL_CONTRACT), + // permission: contract_permission, + // }; + // let err = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + // assert_eq!( + // err, + // ContractError::InvalidPermission { + // msg: "Contract permissions aren't allowed in the address list contract".to_string() + // } + // ); + + // Test remove actor + let msg = ExecuteMsg::RemovePermissions { + actors: vec![AndrAddr::from_string(actor.clone())], + }; + let _res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); + let permission = PERMISSIONS.may_load(deps.as_ref().storage, &actor).unwrap(); + assert!(permission.is_none()); - //add address for unregistered operator + // Try with unauthorized address let unauth_info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), env, unauth_info, msg).unwrap_err(); + let res = execute(deps.as_mut(), env.clone(), unauth_info, msg).unwrap_err(); assert_eq!(ContractError::Unauthorized {}, res); + + // Try removing an actor that isn't included in permissions + let random_actor = Addr::unchecked("random_actor"); + let msg = ExecuteMsg::RemovePermissions { + actors: vec![AndrAddr::from_string(random_actor)], + }; + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!(err, ContractError::ActorNotFound {}) } #[test] -fn test_add_addresses() { +fn test_add_remove_multiple_actors() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); let operator = "creator"; let info = mock_info(operator, &[]); - let address = "whitelistee"; - let address_two = "whitlistee2"; + let actors = vec![ + AndrAddr::from_string("actor1"), + AndrAddr::from_string("actor2"), + ]; + let permission = LocalPermission::default(); init(deps.as_mut(), info.clone()); - ADOContract::default() - .execute_update_operators(deps.as_mut(), info.clone(), vec![operator.to_owned()]) - .unwrap(); - - let msg = ExecuteMsg::AddAddresses { addresses: vec![] }; - - //add address for registered operator - - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); - assert_eq!( - res, - ContractError::Std(StdError::generic_err("addresses cannot be empty")) - ); - - let addresses = vec![address.to_string(), address_two.to_string()]; - let msg = ExecuteMsg::AddAddresses { - addresses: addresses.clone(), + let msg = ExecuteMsg::PermissionActors { + actors: actors.clone(), + permission: permission.clone(), }; - //add address for registered operator - - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap(); + let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); let expected = Response::default().add_attributes(vec![ - attr("action", "add_addresses"), - attr("addresses", addresses.join(",")), + attr("action", "add_actor_permission"), + attr("actor", "actor1, actor2"), + attr("permission", permission.to_string()), ]); assert_eq!(expected, res); - let whitelisted = ADDRESS_LIST.load(deps.as_ref().storage, address).unwrap(); - assert!(whitelisted); - let whitelisted = ADDRESS_LIST - .load(deps.as_ref().storage, address_two) + // Check that the actor and permission have been saved. + let new_permission = PERMISSIONS + .load( + deps.as_ref().storage, + &actors[0].get_raw_address(&deps.as_ref()).unwrap(), + ) .unwrap(); - assert!(whitelisted); - - let included = ADDRESS_LIST.load(deps.as_ref().storage, "111").unwrap_err(); - - match included { - cosmwasm_std::StdError::NotFound { .. } => {} - _ => { - panic!(); - } - } + assert_eq!(new_permission, permission); + let new_permission = PERMISSIONS + .load( + deps.as_ref().storage, + &actors[1].get_raw_address(&deps.as_ref()).unwrap(), + ) + .unwrap(); + assert_eq!(new_permission, permission); - //add address for unregistered operator + // Try with unauthorized address let unauth_info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), env, unauth_info, msg).unwrap_err(); + let res = execute(deps.as_mut(), env.clone(), unauth_info, msg).unwrap_err(); assert_eq!(ContractError::Unauthorized {}, res); -} - -#[test] -fn test_remove_address() { - let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - - let operator = "creator"; - let info = mock_info(operator, &[]); - - let address = "whitelistee"; - init(deps.as_mut(), info.clone()); - - //save operator - ADOContract::default() - .execute_update_operators(deps.as_mut(), info.clone(), vec![operator.to_owned()]) - .unwrap(); - - let msg = ExecuteMsg::RemoveAddress { - address: address.to_string(), + // // Contract permissions aren't allowed to be saved in the address list contract + // let contract_permission = Permission::Whitelisted(None); + // let msg = ExecuteMsg::PermissionActors { + // actor: Addr::unchecked(MOCK_KERNEL_CONTRACT), + // permission: contract_permission, + // }; + // let err = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + // assert_eq!( + // err, + // ContractError::InvalidPermission { + // msg: "Contract permissions aren't allowed in the address list contract".to_string() + // } + // ); + + // Test remove actor + let msg = ExecuteMsg::RemovePermissions { + actors: actors.clone(), }; + let _res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); + let permission = PERMISSIONS + .may_load( + deps.as_ref().storage, + &actors[0].get_raw_address(&deps.as_ref()).unwrap(), + ) + .unwrap(); + assert!(permission.is_none()); + let permission = PERMISSIONS + .may_load( + deps.as_ref().storage, + &actors[1].get_raw_address(&deps.as_ref()).unwrap(), + ) + .unwrap(); + assert!(permission.is_none()); - //add address for registered operator - let res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap(); - let expected = Response::default().add_attributes(vec![ - attr("action", "remove_address"), - attr("address", address), - ]); - assert_eq!(expected, res); - - let included_is_err = ADDRESS_LIST.load(deps.as_ref().storage, address).is_err(); - assert!(included_is_err); - - //add address for unregistered operator + // Try with unauthorized address let unauth_info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), env, unauth_info, msg).unwrap_err(); + let res = execute(deps.as_mut(), env.clone(), unauth_info, msg).unwrap_err(); assert_eq!(ContractError::Unauthorized {}, res); -} - -#[test] -fn test_execute_hook_whitelist() { - let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let operator = "creator"; - let info = mock_info(operator, &[]); - - let address = "whitelistee"; - - // Mark it as a whitelist. - IS_INCLUSIVE.save(deps.as_mut().storage, &true).unwrap(); - init(deps.as_mut(), info.clone()); - - let msg = ExecuteMsg::AddAddress { - address: address.to_string(), + // Try removing an actor that isn't included in permissions + let random_actor = Addr::unchecked("random_actor"); + let msg = ExecuteMsg::RemovePermissions { + actors: vec![AndrAddr::from_string(random_actor)], }; - let _res = execute(deps.as_mut(), env, info, msg).unwrap(); - - let msg = QueryMsg::AndrHook(AndromedaHook::OnExecute { - sender: address.to_string(), - payload: encode_binary(&"".to_string()).unwrap(), - }); - - let res: Option = from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - assert_eq!(None, res); - - let msg = QueryMsg::AndrHook(AndromedaHook::OnExecute { - sender: "random".to_string(), - payload: encode_binary(&"".to_string()).unwrap(), - }); - - let res_err: ContractError = query(deps.as_ref(), mock_env(), msg).unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, res_err); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!(err, ContractError::ActorNotFound {}) } #[test] -fn test_execute_hook_blacklist() { +fn test_includes_actor_query() { let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let operator = "creator"; - let info = mock_info(operator, &[]); + let actor = Addr::unchecked("actor"); + let random_actor = Addr::unchecked("random_actor"); - let address = "blacklistee"; - init(deps.as_mut(), info.clone()); + let permission = LocalPermission::default(); - // Mark it as a blacklist. - IS_INCLUSIVE.save(deps.as_mut().storage, &false).unwrap(); - ADOContract::default() - .execute_update_operators(deps.as_mut(), info.clone(), vec![operator.to_owned()]) + PERMISSIONS + .save(deps.as_mut().storage, &actor, &permission) .unwrap(); - let msg = ExecuteMsg::AddAddress { - address: address.to_string(), - }; - let _res = execute(deps.as_mut(), env, info, msg).unwrap(); + let msg = QueryMsg::IncludesActor { actor }; + + let res: IncludesActorResponse = + from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - let msg = QueryMsg::AndrHook(AndromedaHook::OnExecute { - sender: "random".to_string(), - payload: encode_binary(&"".to_string()).unwrap(), - }); + assert_eq!(IncludesActorResponse { included: true }, res); - let res: Option = from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - assert_eq!(None, res); + let msg = QueryMsg::IncludesActor { + actor: random_actor, + }; - let msg = QueryMsg::AndrHook(AndromedaHook::OnExecute { - sender: address.to_string(), - payload: encode_binary(&"".to_string()).unwrap(), - }); + let res: IncludesActorResponse = + from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - let res_err: ContractError = query(deps.as_ref(), mock_env(), msg).unwrap_err(); - assert_eq!(ContractError::Unauthorized {}, res_err); + assert_eq!(IncludesActorResponse { included: false }, res); } #[test] -fn test_andr_get_query() { +fn test_actor_permission_query() { let mut deps = mock_dependencies_custom(&[]); - let address = "whitelistee"; + let actor = Addr::unchecked("actor"); + let random_actor = Addr::unchecked("random_actor"); + + let permission = LocalPermission::default(); - ADDRESS_LIST - .save(deps.as_mut().storage, address, &true) + PERMISSIONS + .save(deps.as_mut().storage, &actor, &permission) .unwrap(); - let msg = QueryMsg::IncludesAddress { - address: address.to_owned(), - }; + let msg = QueryMsg::ActorPermission { actor }; - let res: IncludesAddressResponse = + let res: ActorPermissionResponse = from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - assert_eq!(IncludesAddressResponse { included: true }, res); + assert_eq!( + ActorPermissionResponse { + permission: LocalPermission::default() + }, + res + ); + + // Try querying for an actor that isn't in permissions + let msg = QueryMsg::ActorPermission { + actor: random_actor, + }; + + let err = query(deps.as_ref(), mock_env(), msg).unwrap_err(); + assert_eq!(err, ContractError::ActorNotFound {}); } diff --git a/andromeda-core/contracts/modules/andromeda-date-time/.cargo/config b/andromeda-core/contracts/modules/andromeda-date-time/.cargo/config new file mode 100644 index 0000000..624255c --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" \ No newline at end of file diff --git a/andromeda-core/contracts/modules/andromeda-date-time/Cargo.toml b/andromeda-core/contracts/modules/andromeda-date-time/Cargo.toml new file mode 100644 index 0000000..5baed02 --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "andromeda-date-time" +version = "1.0.1" +edition = "2021" +rust-version = "1.75.0" + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +testing = ["cw-multi-test", "andromeda-testing"] + + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } + +andromeda-std = { workspace = true } +andromeda-modules = { workspace = true } + +chrono = "0.4.38" + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true, optional = true } + +[dev-dependencies] +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/modules/andromeda-date-time/examples/schema.rs b/andromeda-core/contracts/modules/andromeda-date-time/examples/schema.rs new file mode 100644 index 0000000..ce974bc --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/examples/schema.rs @@ -0,0 +1,10 @@ +use andromeda_modules::date_time::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + + } +} diff --git a/andromeda-core/contracts/modules/andromeda-date-time/src/contract.rs b/andromeda-core/contracts/modules/andromeda-date-time/src/contract.rs new file mode 100644 index 0000000..ed31698 --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/src/contract.rs @@ -0,0 +1,126 @@ +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response}; + +use andromeda_modules::date_time::GetDateTimeResponse; +use andromeda_modules::date_time::{ExecuteMsg, InstantiateMsg, QueryMsg, Timezone}; +use andromeda_std::{ + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_contract::ADOContract, + common::{actions::call_action, context::ExecuteContext, encode_binary}, + error::ContractError, +}; +use chrono::{DateTime, Datelike, Timelike, Weekday}; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:andromeda-date-time"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let resp = ADOContract::default().instantiate( + deps.storage, + env, + deps.api, + &deps.querier, + info, + BaseInstantiateMsg { + ado_type: CONTRACT_NAME.to_string(), + ado_version: CONTRACT_VERSION.to_string(), + kernel_address: msg.kernel_address, + owner: msg.owner, + }, + )?; + + Ok(resp) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let ctx = ExecuteContext::new(deps, info, env); + match msg { + ExecuteMsg::AMPReceive(pkt) => { + ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) + } + _ => handle_execute(ctx, msg), + } +} + +#[allow(clippy::match_single_binding)] +fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + let res = match msg { + _ => ADOContract::default().execute(ctx, msg), + }?; + + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::GetDateTime { timezone } => encode_binary(&get_date_time(env, timezone)?), + _ => ADOContract::default().query(deps, env, msg), + } +} + +pub fn get_date_time( + env: Env, + timezone: Option, +) -> Result { + let timestamp = env.block.time.seconds() as i64; + let timezone_i64 = timezone.unwrap_or(Timezone::Utc) as i64; + let offset = timezone_i64.checked_mul(36).unwrap(); + let local_timestamp = timestamp.checked_add(offset).unwrap(); + let local_datetime = DateTime::from_timestamp(local_timestamp, 0).unwrap(); + + let day_of_week = match local_datetime.weekday() { + Weekday::Mon => "Mon", + Weekday::Tue => "Tue", + Weekday::Wed => "Wed", + Weekday::Thu => "Thu", + Weekday::Fri => "Fri", + Weekday::Sat => "Sat", + Weekday::Sun => "Sun", + }; + + let date_time = format!( + "{:04}-{:02}-{:02} {:02}-{:02}-{:02}", + local_datetime.year(), + local_datetime.month(), + local_datetime.day(), + local_datetime.hour(), + local_datetime.minute(), + local_datetime.second(), + ); + + Ok(GetDateTimeResponse { + day_of_week: day_of_week.to_string(), + date_time, + }) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} diff --git a/andromeda-core/contracts/modules/andromeda-date-time/src/lib.rs b/andromeda-core/contracts/modules/andromeda-date-time/src/lib.rs new file mode 100644 index 0000000..b0b35c2 --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/src/lib.rs @@ -0,0 +1,6 @@ +pub mod contract; +#[cfg(test)] +pub mod testing; + +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; diff --git a/andromeda-core/contracts/modules/andromeda-date-time/src/mock.rs b/andromeda-core/contracts/modules/andromeda-date-time/src/mock.rs new file mode 100644 index 0000000..46b6b24 --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/src/mock.rs @@ -0,0 +1,58 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +use crate::contract::{execute, instantiate, query}; +use andromeda_modules::date_time::GetDateTimeResponse; +use andromeda_modules::date_time::{InstantiateMsg, QueryMsg, Timezone}; +use andromeda_testing::mock::MockApp; +use andromeda_testing::{ + mock_ado, + mock_contract::{ExecuteResult, MockADO, MockContract}, +}; +use cosmwasm_std::{Addr, Empty}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; + +pub struct MockDateTime(Addr); +mock_ado!(MockDateTime, ExecuteMsg, QueryMsg); + +impl MockDateTime { + pub fn instantiate( + code_id: u64, + sender: Addr, + app: &mut MockApp, + kernel_address: String, + owner: Option, + ) -> MockDateTime { + let msg = mock_date_time_instantiate_msg(kernel_address, owner); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "Date Time Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockDateTime(Addr::unchecked(addr)) + } + + pub fn query_date_time(&self, app: &mut MockApp, timezone: Timezone) -> GetDateTimeResponse { + let msg = QueryMsg::GetDateTime { timezone }; + let res: GetDateTimeResponse = self.query(app, msg); + res + } +} + +pub fn mock_andromeda_date_time() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} + +pub fn mock_date_time_instantiate_msg( + kernel_address: String, + owner: Option, +) -> InstantiateMsg { + InstantiateMsg { + kernel_address, + owner, + } +} diff --git a/andromeda-core/contracts/modules/andromeda-date-time/src/testing/mock.rs b/andromeda-core/contracts/modules/andromeda-date-time/src/testing/mock.rs new file mode 100644 index 0000000..f51556b --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/src/testing/mock.rs @@ -0,0 +1,39 @@ +use andromeda_modules::date_time::{GetDateTimeResponse, Timezone}; +use andromeda_modules::date_time::{InstantiateMsg, QueryMsg}; +use andromeda_std::{ + error::ContractError, + testing::mock_querier::{mock_dependencies_custom, WasmMockQuerier, MOCK_KERNEL_CONTRACT}, +}; +use cosmwasm_std::{ + from_json, + testing::{mock_env, mock_info, MockApi, MockStorage}, + Deps, MessageInfo, OwnedDeps, +}; + +use crate::contract::{instantiate, query}; + +pub type MockDeps = OwnedDeps; + +pub fn proper_initialization() -> (MockDeps, MessageInfo) { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("creator", &[]); + let msg = InstantiateMsg { + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + }; + let env = mock_env(); + let res = instantiate(deps.as_mut(), env, info.clone(), msg).unwrap(); + assert_eq!(0, res.messages.len()); + (deps, info) +} + +pub fn query_date_time( + deps: Deps, + timezone: Option, +) -> Result { + let res = query(deps, mock_env(), QueryMsg::GetDateTime { timezone }); + match res { + Ok(res) => Ok(from_json(res).unwrap()), + Err(err) => Err(err), + } +} diff --git a/andromeda-core/contracts/modules/andromeda-date-time/src/testing/mod.rs b/andromeda-core/contracts/modules/andromeda-date-time/src/testing/mod.rs new file mode 100644 index 0000000..3bfda28 --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/src/testing/mod.rs @@ -0,0 +1,2 @@ +mod mock; +mod tests; diff --git a/andromeda-core/contracts/modules/andromeda-date-time/src/testing/tests.rs b/andromeda-core/contracts/modules/andromeda-date-time/src/testing/tests.rs new file mode 100644 index 0000000..5fab309 --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-date-time/src/testing/tests.rs @@ -0,0 +1,82 @@ +use super::mock::{proper_initialization, query_date_time}; +use andromeda_modules::date_time::{GetDateTimeResponse, Timezone}; + +#[test] +fn test_instantiation() { + proper_initialization(); +} + +#[test] +fn test_query_date_time() { + let (deps, _) = proper_initialization(); + + // UTC+3 + let query_res = query_date_time(deps.as_ref(), Some(Timezone::UtcPlus3)).unwrap(); + assert_eq!( + query_res, + GetDateTimeResponse { + day_of_week: "Wed".to_string(), + date_time: "2019-10-23 05-23-39".to_string(), + } + ); + + // UTC-9 + let query_res = query_date_time(deps.as_ref(), Some(Timezone::UtcMinus9)).unwrap(); + assert_eq!( + query_res, + GetDateTimeResponse { + day_of_week: "Tue".to_string(), + date_time: "2019-10-22 17-23-39".to_string(), + } + ); + + // UTC-2:30 + let query_res = query_date_time(deps.as_ref(), Some(Timezone::UtcMinus2_30)).unwrap(); + assert_eq!( + query_res, + GetDateTimeResponse { + day_of_week: "Tue".to_string(), + date_time: "2019-10-22 23-53-39".to_string(), + } + ); + + // UTC + let query_res = query_date_time(deps.as_ref(), None).unwrap(); + assert_eq!( + query_res, + GetDateTimeResponse { + day_of_week: "Wed".to_string(), + date_time: "2019-10-23 02-23-39".to_string(), + } + ); + + // UTC+10:30 + let query_res = query_date_time(deps.as_ref(), Some(Timezone::UtcPlus10_30)).unwrap(); + assert_eq!( + query_res, + GetDateTimeResponse { + day_of_week: "Wed".to_string(), + date_time: "2019-10-23 12-53-39".to_string(), + } + ); + + // UTC+12:45 + let query_res = query_date_time(deps.as_ref(), Some(Timezone::UtcPlus12_45)).unwrap(); + assert_eq!( + query_res, + GetDateTimeResponse { + day_of_week: "Wed".to_string(), + date_time: "2019-10-23 15-08-39".to_string(), + } + ); + + // UTC+14 + let query_res = query_date_time(deps.as_ref(), Some(Timezone::UtcPlus14)).unwrap(); + assert_eq!( + query_res, + GetDateTimeResponse { + day_of_week: "Wed".to_string(), + date_time: "2019-10-23 16-23-39".to_string(), + } + ); +} diff --git a/andromeda-core/contracts/modules/andromeda-rates/Cargo.toml b/andromeda-core/contracts/modules/andromeda-rates/Cargo.toml index a99eede..fc0445b 100644 --- a/andromeda-core/contracts/modules/andromeda-rates/Cargo.toml +++ b/andromeda-core/contracts/modules/andromeda-rates/Cargo.toml @@ -1,11 +1,11 @@ -[package] -name = "andromeda-rates" -version = "0.2.1" -edition = "2021" -rust-version = "1.65.0" - -[lib] -crate-type = ["cdylib", "rlib"] +[package] +name = "andromeda-rates" +version = "2.0.3" +edition = "2021" +rust-version = "1.75.0" + +[lib] +crate-type = ["cdylib", "rlib"] [features] # for more explicit tests, cargo test --features=backtraces @@ -18,17 +18,17 @@ testing = ["cw-multi-test"] [dependencies] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } -cw-storage-plus = { workspace = true } -cw-utils = { workspace = true } -cw20 = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } - -andromeda-std = { workspace = true, features = ["module_hooks"] } -andromeda-modules = { workspace = true } - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -cw-multi-test = { workspace = true, optional = true } - -[dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +cw20 = { workspace = true } + + +andromeda-std = { workspace = true } +andromeda-modules = { workspace = true } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } +andromeda-testing = { workspace = true } + +[dev-dependencies] +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/modules/andromeda-rates/README.md b/andromeda-core/contracts/modules/andromeda-rates/README.md new file mode 100644 index 0000000..f1bd66f --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-rates/README.md @@ -0,0 +1,5 @@ +# Overview + +The Rates ADO is a smart contract that can be used to hold rates configurations for other ADOs. Instead of setting up the rate on the ADO itself, the ADO can reference this ADO to extract the rates set up and apply them on the ADO. These rates can be used to add a fee that is paid on a message, whether a tax or royalty. + +**Note**: This ADO is not released yet. Once released, a link to full documentation will be provided. \ No newline at end of file diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/andromeda-rates.json b/andromeda-core/contracts/modules/andromeda-rates/schema/andromeda-rates.json deleted file mode 100644 index 5f7ff7f..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/andromeda-rates.json +++ /dev/null @@ -1,1691 +0,0 @@ -{ - "contract_name": "andromeda-rates", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "rates" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "rates": { - "type": "array", - "items": { - "$ref": "#/definitions/RateInfo" - } - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "PercentRate": { - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "Rate": { - "description": "An enum used to define various types of fees", - "oneOf": [ - { - "description": "A flat rate fee", - "type": "object", - "required": [ - "flat" - ], - "properties": { - "flat": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "description": "A percentage fee", - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/PercentRate" - } - }, - "additionalProperties": false - } - ] - }, - "RateInfo": { - "type": "object", - "required": [ - "is_additive", - "rate", - "recipients" - ], - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "is_additive": { - "type": "boolean" - }, - "rate": { - "$ref": "#/definitions/Rate" - }, - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/Recipient" - } - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "update_rates" - ], - "properties": { - "update_rates": { - "type": "object", - "required": [ - "rates" - ], - "properties": { - "rates": { - "type": "array", - "items": { - "$ref": "#/definitions/RateInfo" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "PercentRate": { - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Rate": { - "description": "An enum used to define various types of fees", - "oneOf": [ - { - "description": "A flat rate fee", - "type": "object", - "required": [ - "flat" - ], - "properties": { - "flat": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "description": "A percentage fee", - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/PercentRate" - } - }, - "additionalProperties": false - } - ] - }, - "RateInfo": { - "type": "object", - "required": [ - "is_additive", - "rate", - "recipients" - ], - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "is_additive": { - "type": "boolean" - }, - "rate": { - "$ref": "#/definitions/Rate" - }, - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/Recipient" - } - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "payments" - ], - "properties": { - "payments": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "payments": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PaymentsResponse", - "type": "object", - "required": [ - "payments" - ], - "properties": { - "payments": { - "type": "array", - "items": { - "$ref": "#/definitions/RateInfo" - } - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "PercentRate": { - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "Rate": { - "description": "An enum used to define various types of fees", - "oneOf": [ - { - "description": "A flat rate fee", - "type": "object", - "required": [ - "flat" - ], - "properties": { - "flat": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "description": "A percentage fee", - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/PercentRate" - } - }, - "additionalProperties": false - } - ] - }, - "RateInfo": { - "type": "object", - "required": [ - "is_additive", - "rate", - "recipients" - ], - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "is_additive": { - "type": "boolean" - }, - "rate": { - "$ref": "#/definitions/Rate" - }, - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/Recipient" - } - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/execute.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/execute.json deleted file mode 100644 index e608be7..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/execute.json +++ /dev/null @@ -1,649 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "update_rates" - ], - "properties": { - "update_rates": { - "type": "object", - "required": [ - "rates" - ], - "properties": { - "rates": { - "type": "array", - "items": { - "$ref": "#/definitions/RateInfo" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "PercentRate": { - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Rate": { - "description": "An enum used to define various types of fees", - "oneOf": [ - { - "description": "A flat rate fee", - "type": "object", - "required": [ - "flat" - ], - "properties": { - "flat": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "description": "A percentage fee", - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/PercentRate" - } - }, - "additionalProperties": false - } - ] - }, - "RateInfo": { - "type": "object", - "required": [ - "is_additive", - "rate", - "recipients" - ], - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "is_additive": { - "type": "boolean" - }, - "rate": { - "$ref": "#/definitions/Rate" - }, - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/Recipient" - } - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/instantiate.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/instantiate.json deleted file mode 100644 index 8f9dec9..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/instantiate.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "rates" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "rates": { - "type": "array", - "items": { - "$ref": "#/definitions/RateInfo" - } - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "PercentRate": { - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "Rate": { - "description": "An enum used to define various types of fees", - "oneOf": [ - { - "description": "A flat rate fee", - "type": "object", - "required": [ - "flat" - ], - "properties": { - "flat": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "description": "A percentage fee", - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/PercentRate" - } - }, - "additionalProperties": false - } - ] - }, - "RateInfo": { - "type": "object", - "required": [ - "is_additive", - "rate", - "recipients" - ], - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "is_additive": { - "type": "boolean" - }, - "rate": { - "$ref": "#/definitions/Rate" - }, - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/Recipient" - } - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/query.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/query.json deleted file mode 100644 index 79882b1..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/query.json +++ /dev/null @@ -1,372 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "payments" - ], - "properties": { - "payments": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_balance.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_operators.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_owner.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_payments.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_payments.json deleted file mode 100644 index 58ac035..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_payments.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PaymentsResponse", - "type": "object", - "required": [ - "payments" - ], - "properties": { - "payments": { - "type": "array", - "items": { - "$ref": "#/definitions/RateInfo" - } - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Decimal": { - "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", - "type": "string" - }, - "PercentRate": { - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/Decimal" - } - }, - "additionalProperties": false - }, - "Rate": { - "description": "An enum used to define various types of fees", - "oneOf": [ - { - "description": "A flat rate fee", - "type": "object", - "required": [ - "flat" - ], - "properties": { - "flat": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "description": "A percentage fee", - "type": "object", - "required": [ - "percent" - ], - "properties": { - "percent": { - "$ref": "#/definitions/PercentRate" - } - }, - "additionalProperties": false - } - ] - }, - "RateInfo": { - "type": "object", - "required": [ - "is_additive", - "rate", - "recipients" - ], - "properties": { - "description": { - "type": [ - "string", - "null" - ] - }, - "is_additive": { - "type": "boolean" - }, - "rate": { - "$ref": "#/definitions/Rate" - }, - "recipients": { - "type": "array", - "items": { - "$ref": "#/definitions/Recipient" - } - } - }, - "additionalProperties": false - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissions.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_type.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_version.json b/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/modules/andromeda-rates/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-rates/src/contract.rs b/andromeda-core/contracts/modules/andromeda-rates/src/contract.rs index b71d1df..0bbdb28 100644 --- a/andromeda-core/contracts/modules/andromeda-rates/src/contract.rs +++ b/andromeda-core/contracts/modules/andromeda-rates/src/contract.rs @@ -1,27 +1,23 @@ #[cfg(not(feature = "library"))] -use crate::state::{Config, CONFIG}; -use andromeda_modules::rates::{ - calculate_fee, ExecuteMsg, InstantiateMsg, MigrateMsg, PaymentAttribute, PaymentsResponse, - QueryMsg, RateInfo, -}; +use crate::state::RATES; +use andromeda_modules::rates::{ExecuteMsg, InstantiateMsg, QueryMsg, RateResponse}; use andromeda_std::{ ado_base::{ - hooks::{AndromedaHook, OnFundsTransferResponse}, - InstantiateMsg as BaseInstantiateMsg, + rates::{calculate_fee, LocalRate, PaymentAttribute, RatesResponse}, + InstantiateMsg as BaseInstantiateMsg, MigrateMsg, }, ado_contract::ADOContract, + amp::Recipient, common::{context::ExecuteContext, deduct_funds, encode_binary, Funds}, - error::{from_semver, ContractError}, + error::ContractError, }; -use cosmwasm_std::entry_point; use cosmwasm_std::{ attr, coin, ensure, Binary, Coin, Deps, DepsMut, Env, Event, MessageInfo, Response, SubMsg, }; -use cw2::{get_contract_version, set_contract_version}; +use cosmwasm_std::{entry_point, from_json}; use cw20::Cw20Coin; use cw_utils::nonpayable; -use semver::Version; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-rates"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -33,19 +29,24 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let config = Config { rates: msg.rates }; - CONFIG.save(deps.storage, &config)?; + let action = msg.action; + let mut rate = msg.rate; + + if rate.recipients.is_empty() { + rate.recipients = vec![Recipient::new(info.sender.clone(), None)]; + }; + + RATES.save(deps.storage, &action, &rate)?; let inst_resp = ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "rates".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -73,14 +74,16 @@ pub fn execute( pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { match msg { - ExecuteMsg::UpdateRates { rates } => execute_update_rates(ctx, rates), + ExecuteMsg::SetRate { action, rate } => execute_set_rate(ctx, action, rate), + ExecuteMsg::RemoveRate { action } => execute_remove_rate(ctx, action), _ => ADOContract::default().execute(ctx, msg), } } -fn execute_update_rates( +fn execute_set_rate( ctx: ExecuteContext, - rates: Vec, + action: String, + mut rate: LocalRate, ) -> Result { let ExecuteContext { deps, info, .. } = ctx; nonpayable(&info)?; @@ -89,78 +92,64 @@ fn execute_update_rates( ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); - let mut config = CONFIG.load(deps.storage)?; - config.rates = rates; - CONFIG.save(deps.storage, &config)?; - - Ok(Response::new().add_attributes(vec![attr("action", "update_rates")])) -} + // Validate the local rate's value + rate.value.validate()?; -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; + // Set the sender as the recipient in case no recipients were provided + if rate.recipients.is_empty() { + rate.recipients = vec![Recipient::new(info.sender, None)]; + }; - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; + RATES.save(deps.storage, &action, &rate)?; - let contract = ADOContract::default(); + Ok(Response::new().add_attributes(vec![attr("action", "set_rate")])) +} - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); +fn execute_remove_rate(ctx: ExecuteContext, action: String) -> Result { + let ExecuteContext { deps, info, .. } = ctx; + nonpayable(&info)?; - // New version has to be newer/greater than the old version ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } + ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} ); + if RATES.has(deps.storage, &action) { + RATES.remove(deps.storage, &action); + Ok(Response::new().add_attributes(vec![attr("action", "remove_rates")])) + } else { + Err(ContractError::ActionNotFound {}) + } +} - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::AndrHook(msg) => handle_andromeda_hook(deps, msg), - QueryMsg::Payments {} => encode_binary(&query_payments(deps)?), + QueryMsg::Rate { action } => encode_binary(&query_rate(deps, action)?), _ => ADOContract::default().query(deps, env, msg), } } -fn handle_andromeda_hook(deps: Deps, msg: AndromedaHook) -> Result { - match msg { - AndromedaHook::OnFundsTransfer { amount, .. } => { - encode_binary(&query_deducted_funds(deps, amount)?) - } - _ => Ok(encode_binary(&None::)?), +fn query_rate(deps: Deps, action: String) -> Result { + let rate = RATES.may_load(deps.storage, &action)?; + match rate { + Some(rate) => Ok(RateResponse { rate }), + None => Err(ContractError::InvalidRate {}), } } -fn query_payments(deps: Deps) -> Result { - let config = CONFIG.load(deps.storage)?; - let rates = config.rates; - - Ok(PaymentsResponse { payments: rates }) -} - //NOTE Currently set as pub for testing pub fn query_deducted_funds( deps: Deps, + payload: Binary, funds: Funds, -) -> Result { - let config = CONFIG.load(deps.storage)?; +) -> Result { + let action: String = from_json(payload)?; + let local_rate = RATES.load(deps.storage, &action)?; let mut msgs: Vec = vec![]; let mut events: Vec = vec![]; let (coin, is_native): (Coin, bool) = match funds { @@ -168,47 +157,47 @@ pub fn query_deducted_funds( Funds::Cw20(cw20_coin) => (coin(cw20_coin.amount.u128(), cw20_coin.address), false), }; let mut leftover_funds = vec![coin.clone()]; - for rate_info in config.rates.iter() { - let event_name = if rate_info.is_additive { - "tax" - } else { - "royalty" - }; - let mut event = Event::new(event_name); - if let Some(desc) = &rate_info.description { - event = event.add_attribute("description", desc); + + let event_name = if local_rate.rate_type.is_additive() { + "tax" + } else { + "royalty" + }; + let mut event = Event::new(event_name); + if let Some(desc) = &local_rate.description { + event = event.add_attribute("description", desc); + } + local_rate.value.validate()?; + let fee = calculate_fee(local_rate.value, &coin)?; + for receiver in local_rate.recipients.iter() { + if !local_rate.rate_type.is_additive() { + deduct_funds(&mut leftover_funds, &fee)?; + event = event.add_attribute("deducted", fee.to_string()); } - let rate = rate_info.rate.validate(&deps.querier)?; - let fee = calculate_fee(rate, &coin)?; - for receiver in rate_info.recipients.iter() { - if !rate_info.is_additive { - deduct_funds(&mut leftover_funds, &fee)?; - event = event.add_attribute("deducted", fee.to_string()); + event = event.add_attribute( + "payment", + PaymentAttribute { + receiver: receiver.get_addr(), + amount: fee.clone(), } - event = event.add_attribute( - "payment", - PaymentAttribute { - receiver: receiver.get_addr(), - amount: fee.clone(), - } - .to_string(), - ); - let msg = if is_native { - receiver.generate_direct_msg(&deps, vec![fee.clone()])? - } else { - receiver.generate_msg_cw20( - &deps, - Cw20Coin { - amount: fee.amount, - address: fee.denom.to_string(), - }, - )? - }; - msgs.push(msg); - } - events.push(event); + .to_string(), + ); + let msg = if is_native { + receiver.generate_direct_msg(&deps, vec![fee.clone()])? + } else { + receiver.generate_msg_cw20( + &deps, + Cw20Coin { + amount: fee.amount, + address: fee.denom.to_string(), + }, + )? + }; + msgs.push(msg); } - Ok(OnFundsTransferResponse { + events.push(event); + + Ok(RatesResponse { msgs, leftover_funds: if is_native { Funds::Native(leftover_funds[0].clone()) diff --git a/andromeda-core/contracts/modules/andromeda-rates/src/mock.rs b/andromeda-core/contracts/modules/andromeda-rates/src/mock.rs index 7281eb2..82d0344 100644 --- a/andromeda-core/contracts/modules/andromeda-rates/src/mock.rs +++ b/andromeda-core/contracts/modules/andromeda-rates/src/mock.rs @@ -1,23 +1,29 @@ #![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] - use crate::contract::{execute, instantiate, query}; -use andromeda_modules::rates::{InstantiateMsg, RateInfo}; -use cosmwasm_std::Empty; +use andromeda_modules::rates::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use andromeda_std::ado_base::rates::LocalRate; +use andromeda_testing::{mock_ado, MockADO, MockContract}; +use cosmwasm_std::{Addr, Empty}; use cw_multi_test::{Contract, ContractWrapper}; +pub struct MockRates(Addr); +mock_ado!(MockRates, ExecuteMsg, QueryMsg); + pub fn mock_andromeda_rates() -> Box> { let contract = ContractWrapper::new_with_empty(execute, instantiate, query); Box::new(contract) } pub fn mock_rates_instantiate_msg( - rates: Vec, + action: String, + rate: LocalRate, kernel_address: impl Into, owner: Option, ) -> InstantiateMsg { InstantiateMsg { - rates, kernel_address: kernel_address.into(), owner, + action, + rate, } } diff --git a/andromeda-core/contracts/modules/andromeda-rates/src/state.rs b/andromeda-core/contracts/modules/andromeda-rates/src/state.rs index a561e9c..16303d3 100644 --- a/andromeda-core/contracts/modules/andromeda-rates/src/state.rs +++ b/andromeda-core/contracts/modules/andromeda-rates/src/state.rs @@ -1,10 +1,5 @@ -use andromeda_modules::rates::RateInfo; -use cosmwasm_schema::cw_serde; -use cw_storage_plus::Item; +use andromeda_std::ado_base::rates::LocalRate; +use cw_storage_plus::Map; -pub const CONFIG: Item = Item::new("config"); - -#[cw_serde] -pub struct Config { - pub rates: Vec, -} +// Mapping of action to LocalRate +pub const RATES: Map<&str, LocalRate> = Map::new("rates"); diff --git a/andromeda-core/contracts/modules/andromeda-rates/src/testing/mock_querier.rs b/andromeda-core/contracts/modules/andromeda-rates/src/testing/mock_querier.rs index 40ca95d..09714db 100644 --- a/andromeda-core/contracts/modules/andromeda-rates/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/modules/andromeda-rates/src/testing/mock_querier.rs @@ -1,25 +1,19 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; + use andromeda_std::testing::mock_querier::MockAndromedaQuerier; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::QuerierWrapper; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, + Coin, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg, Uint128}; -pub use andromeda_std::testing::mock_querier::{ - MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; pub const MOCK_OWNER: &str = "owner"; pub const MOCK_RECIPIENT1: &str = "recipient1"; -pub const MOCK_RECIPIENT2: &str = "recipient2"; +pub const _MOCK_RECIPIENT2: &str = "recipient2"; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -41,11 +35,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "rates".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -79,71 +74,17 @@ impl Querier for WasmMockQuerier { impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } + QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: _, + }) => { + let _ = contract_addr.as_str(); + MockAndromedaQuerier::default().handle_query(&self.base, request) } _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/modules/andromeda-rates/src/testing/mod.rs b/andromeda-core/contracts/modules/andromeda-rates/src/testing/mod.rs index a1e507b..9d75e9e 100644 --- a/andromeda-core/contracts/modules/andromeda-rates/src/testing/mod.rs +++ b/andromeda-core/contracts/modules/andromeda-rates/src/testing/mod.rs @@ -1,2 +1,3 @@ mod mock_querier; +mod test_handler; mod tests; diff --git a/andromeda-core/contracts/modules/andromeda-rates/src/testing/test_handler.rs b/andromeda-core/contracts/modules/andromeda-rates/src/testing/test_handler.rs new file mode 100644 index 0000000..e1905cc --- /dev/null +++ b/andromeda-core/contracts/modules/andromeda-rates/src/testing/test_handler.rs @@ -0,0 +1,109 @@ +use andromeda_std::{ + ado_base::rates::{calculate_fee, LocalRateValue, PercentRate}, + error::ContractError, +}; +use cosmwasm_std::{coin, Coin, Decimal}; + +struct TestHandleLocalCase { + name: &'static str, + fee_rate: LocalRateValue, + payment: Coin, + expected_result: Coin, + expected_error: Option, +} + +#[test] +fn test_handle_local() { + let test_cases = vec![ + TestHandleLocalCase { + name: "Payment is greater than flat rate", + fee_rate: LocalRateValue::Flat(coin(1, "uandr")), + payment: coin(20, "uandr"), + expected_result: coin(1, "uandr"), + expected_error: None, + }, + TestHandleLocalCase { + name: "Payment is less than flat rate", + fee_rate: LocalRateValue::Flat(coin(100, "uandr")), + payment: coin(20, "uandr"), + expected_result: coin(1, "uandr"), + expected_error: Some(ContractError::InsufficientFunds {}), + }, + TestHandleLocalCase { + name: "Payment is equal to flat rate", + fee_rate: LocalRateValue::Flat(coin(100, "uandr")), + payment: coin(100, "uandr"), + expected_result: coin(100, "uandr"), + expected_error: None, + }, + TestHandleLocalCase { + name: "Percent rate without remainder", + fee_rate: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(4), + }), + payment: coin(100, "uandr"), + expected_result: coin(4, "uandr"), + expected_error: None, + }, + TestHandleLocalCase { + name: "Percent rate with small remainder", + fee_rate: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(4), + }), + payment: coin(101, "uandr"), + // If there's a remainder (it's 0.04) it rounds up + expected_result: coin(5, "uandr"), + expected_error: None, + }, + TestHandleLocalCase { + name: "Percent rate with large remainder", + fee_rate: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(7), + }), + payment: coin(114, "uandr"), + // 7.98, should return 8 + expected_result: coin(8, "uandr"), + expected_error: None, + }, + TestHandleLocalCase { + name: "Payment of 1 coin", + fee_rate: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(1), + }), + payment: coin(1, "uandr"), + // The fee takes up the entire payment + expected_result: coin(1, "uandr"), + expected_error: None, + }, + TestHandleLocalCase { + name: "0 percent rate", + fee_rate: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(0), + }), + payment: coin(101, "uandr"), + expected_result: coin(5, "uandr"), + expected_error: Some(ContractError::InvalidRate {}), + }, + TestHandleLocalCase { + name: "101 percent rate", + fee_rate: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(101), + }), + payment: coin(101, "uandr"), + expected_result: coin(5, "uandr"), + expected_error: Some(ContractError::InvalidRate {}), + }, + ]; + + for test in test_cases { + let res = calculate_fee(test.fee_rate, &test.payment); + if let Some(err) = test.expected_error { + assert_eq!(res.unwrap_err(), err, "{}", test.name); + continue; + } + + let response = res.unwrap(); + + assert_eq!(response, test.expected_result, "{}", test.name); + } +} diff --git a/andromeda-core/contracts/modules/andromeda-rates/src/testing/tests.rs b/andromeda-core/contracts/modules/andromeda-rates/src/testing/tests.rs index 4fbab70..8b03922 100644 --- a/andromeda-core/contracts/modules/andromeda-rates/src/testing/tests.rs +++ b/andromeda-core/contracts/modules/andromeda-rates/src/testing/tests.rs @@ -1,18 +1,19 @@ use crate::contract::{execute, instantiate, query, query_deducted_funds}; use crate::testing::mock_querier::{ - mock_dependencies_custom, MOCK_KERNEL_CONTRACT, MOCK_OWNER, MOCK_RECIPIENT1, MOCK_RECIPIENT2, + mock_dependencies_custom, MOCK_KERNEL_CONTRACT, MOCK_OWNER, MOCK_RECIPIENT1, }; -use andromeda_modules::rates::{ExecuteMsg, InstantiateMsg, QueryMsg, RateInfo}; -use andromeda_modules::rates::{PaymentsResponse, Rate}; -use andromeda_std::ado_base::hooks::OnFundsTransferResponse; +use andromeda_modules::rates::{ExecuteMsg, InstantiateMsg, QueryMsg, RateResponse}; + +use andromeda_std::ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, RatesResponse}; +use andromeda_std::amp::AndrAddr; use andromeda_std::common::Funds; use andromeda_std::{amp::recipient::Recipient, common::encode_binary}; -use cosmwasm_std::{attr, Decimal, Event}; +use cosmwasm_std::{attr, Event}; use cosmwasm_std::{ coin, coins, testing::{mock_env, mock_info}, - BankMsg, Coin, CosmosMsg, Response, SubMsg, Uint128, WasmMsg, + BankMsg, CosmosMsg, Response, SubMsg, WasmMsg, }; use cw20::{Cw20Coin, Cw20ExecuteMsg}; @@ -22,38 +23,30 @@ fn test_instantiate_query() { let env = mock_env(); let owner = "owner"; let info = mock_info(owner, &[]); - let rates = vec![ - RateInfo { - rate: Rate::from(Decimal::percent(10)), - is_additive: true, - description: Some("desc1".to_string()), - recipients: vec![Recipient::new("", None)], - }, - RateInfo { - rate: Rate::Flat(Coin { - amount: Uint128::from(10u128), - denom: "uusd".to_string(), - }), - is_additive: false, - description: Some("desc2".to_string()), - recipients: vec![Recipient::new("", None)], - }, - ]; + let action = "deposit".to_string(); + let rate = LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("owner".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(100_u128, "uandr")), + description: None, + }; let msg = InstantiateMsg { - rates: rates.clone(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, + action: action.clone(), + rate: rate.clone(), }; let res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); assert_eq!(0, res.messages.len()); - let payments = query(deps.as_ref(), env, QueryMsg::Payments {}).unwrap(); + let rate_resp = query(deps.as_ref(), env, QueryMsg::Rate { action }).unwrap(); - assert_eq!( - payments, - encode_binary(&PaymentsResponse { payments: rates }).unwrap() - ); + assert_eq!(rate_resp, encode_binary(&RateResponse { rate }).unwrap()); //Why does this test error? //let payments = query(deps.as_ref(), mock_env(), QueryMsg::Payments {}).is_err(); @@ -66,35 +59,30 @@ fn test_andr_receive() { let env = mock_env(); let owner = "owner"; let info = mock_info(owner, &[]); - let rates = vec![ - RateInfo { - rate: Rate::from(Decimal::percent(10)), - is_additive: true, - description: Some("desc1".to_string()), - recipients: vec![Recipient::new("", None)], - }, - RateInfo { - rate: Rate::Flat(Coin { - amount: Uint128::from(10u128), - denom: "uusd".to_string(), - }), - is_additive: false, - description: Some("desc2".to_string()), - recipients: vec![Recipient::new("", None)], - }, - ]; + let action: String = "deposit".to_string(); + let rate = LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("owner".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(100_u128, "uandr")), + description: None, + }; let msg = InstantiateMsg { - rates: rates.clone(), kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, + action: action.clone(), + rate: rate.clone(), }; let _res = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - - let msg = ExecuteMsg::UpdateRates { rates }; + // Update rate + let msg = ExecuteMsg::SetRate { action, rate }; let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::new().add_attributes(vec![attr("action", "update_rates")]), + Response::new().add_attributes(vec![attr("action", "set_rate")]), res ); } @@ -103,57 +91,50 @@ fn test_andr_receive() { fn test_query_deducted_funds_native() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - let info = mock_info(MOCK_OWNER, &[]); - let rates = vec![ - RateInfo { - rate: Rate::Flat(Coin { - amount: Uint128::from(20u128), - denom: "uusd".to_string(), - }), - is_additive: true, - description: Some("desc2".to_string()), - recipients: vec![Recipient::from_string(MOCK_RECIPIENT1)], - }, - RateInfo { - rate: Rate::from(Decimal::percent(10)), - is_additive: false, - description: Some("desc1".to_string()), - recipients: vec![Recipient::from_string(MOCK_RECIPIENT2)], - }, - ]; + let info = mock_info(MOCK_OWNER, &[coin(1000, "uusd")]); + let action: String = "deposit".to_string(); + let payload = encode_binary(&action).unwrap(); + let rate = LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("recipient1".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(20_u128, "uandr")), + description: None, + }; let msg = InstantiateMsg { - rates, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, + action, + rate, }; let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - let res = query_deducted_funds(deps.as_ref(), Funds::Native(coin(100, "uusd"))).unwrap(); + let res = + query_deducted_funds(deps.as_ref(), payload, Funds::Native(coin(100, "uandr"))).unwrap(); let expected_msgs: Vec = vec![ SubMsg::new(CosmosMsg::Bank(BankMsg::Send { to_address: MOCK_RECIPIENT1.into(), - amount: coins(20, "uusd"), - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_RECIPIENT2.into(), - amount: coins(10, "uusd"), + amount: coins(20, "uandr"), })), + // SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + // to_address: MOCK_RECIPIENT2.into(), + // amount: coins(10, "uusd"), + // })), ]; assert_eq!( - OnFundsTransferResponse { + RatesResponse { msgs: expected_msgs, - // Deduct 10% from the percent rate. - // NOTE: test is currently returning 90 instead - leftover_funds: Funds::Native(coin(90, "uusd")), + leftover_funds: Funds::Native(coin(100, "uandr")), events: vec![ - Event::new("tax") - .add_attribute("description", "desc2") - .add_attribute("payment", "recipient1<20uusd"), - Event::new("royalty") - .add_attribute("description", "desc1") - .add_attribute("deducted", "10uusd") - .add_attribute("payment", "recipient2<10uusd"), + Event::new("tax").add_attribute("payment", "recipient1<20uandr"), + // Event::new("royalty") + // .add_attribute("description", "desc1") + // .add_attribute("deducted", "10uusd") + // .add_attribute("payment", "recipient2<10uusd"), ] }, res @@ -167,32 +148,48 @@ fn test_query_deducted_funds_cw20() { let owner = "owner"; let info = mock_info(owner, &[]); let cw20_address = "address"; - let rates = vec![ - RateInfo { - rate: Rate::Flat(Coin { - amount: Uint128::from(20u128), - denom: cw20_address.to_string(), - }), - is_additive: true, - description: Some("desc2".to_string()), - recipients: vec![Recipient::new(MOCK_RECIPIENT1, None)], - }, - RateInfo { - rate: Rate::from(Decimal::percent(10)), - is_additive: false, - description: Some("desc1".to_string()), - recipients: vec![Recipient::new(MOCK_RECIPIENT2, None)], - }, - ]; + + let action: String = "deposit".to_string(); + let payload = encode_binary(&action).unwrap(); + let rate = LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("recipient1".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(20_u128, cw20_address)), + description: None, + }; + + // let rates = vec![ + // RateInfo { + // rate: Rate::Flat(Coin { + // amount: Uint128::from(20u128), + // denom: cw20_address.to_string(), + // }), + // is_additive: true, + // description: Some("desc2".to_string()), + // recipients: vec![Recipient::new(MOCK_RECIPIENT1, None)], + // }, + // RateInfo { + // rate: Rate::from(Decimal::percent(10)), + // is_additive: false, + // description: Some("desc1".to_string()), + // recipients: vec![Recipient::new(MOCK_RECIPIENT2, None)], + // }, + // ]; let msg = InstantiateMsg { - rates, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, + action, + rate, }; let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - let res: OnFundsTransferResponse = query_deducted_funds( + let res: RatesResponse = query_deducted_funds( deps.as_ref(), + payload, Funds::Cw20(Cw20Coin { amount: 100u128.into(), address: "address".into(), @@ -210,32 +207,31 @@ fn test_query_deducted_funds_cw20() { .unwrap(), funds: vec![], }), - SubMsg::new(WasmMsg::Execute { - contract_addr: cw20_address.to_string(), - msg: encode_binary(&Cw20ExecuteMsg::Transfer { - recipient: MOCK_RECIPIENT2.to_string(), - amount: 10u128.into(), - }) - .unwrap(), - funds: vec![], - }), + // SubMsg::new(WasmMsg::Execute { + // contract_addr: cw20_address.to_string(), + // msg: encode_binary(&Cw20ExecuteMsg::Transfer { + // recipient: MOCK_RECIPIENT2.to_string(), + // amount: 10u128.into(), + // }) + // .unwrap(), + // funds: vec![], + // }), ]; assert_eq!( - OnFundsTransferResponse { + RatesResponse { msgs: expected_msgs, - // Deduct 10% from the percent rate. leftover_funds: Funds::Cw20(Cw20Coin { - amount: 90u128.into(), + amount: 100u128.into(), address: cw20_address.to_string() }), events: vec![ Event::new("tax") - .add_attribute("description", "desc2") + // .add_attribute("description", "desc2") .add_attribute("payment", "recipient1<20address"), - Event::new("royalty") - .add_attribute("description", "desc1") - .add_attribute("deducted", "10address") - .add_attribute("payment", "recipient2<10address"), + // Event::new("royalty") + // .add_attribute("description", "desc1") + // .add_attribute("deducted", "10address") + // .add_attribute("payment", "recipient2<10address"), ] }, res diff --git a/andromeda-core/contracts/modules/andromeda-shunting/Cargo.toml b/andromeda-core/contracts/modules/andromeda-shunting/Cargo.toml index 25e59ed..12381a8 100644 --- a/andromeda-core/contracts/modules/andromeda-shunting/Cargo.toml +++ b/andromeda-core/contracts/modules/andromeda-shunting/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-shunting" -version = "0.1.0" +version = "0.2.3" edition = "2021" [lib] @@ -16,10 +16,10 @@ testing = ["cw-multi-test"] [dependencies] cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } -cw-utils = { workspace = true} +cw-utils = { workspace = true } cw2 = { workspace = true } cosmwasm-schema = { workspace = true } -andromeda-std = { workspace = true, features = ["module_hooks"] } +andromeda-std = { workspace = true, features = [] } andromeda-modules = { workspace = true } simple-shunting = "0.1.2" @@ -31,4 +31,4 @@ cw-multi-test = { workspace = true, optional = true } andromeda-testing = { workspace = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/andromeda-shunting.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/andromeda-shunting.json deleted file mode 100644 index 96befc2..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/andromeda-shunting.json +++ /dev/null @@ -1,1366 +0,0 @@ -{ - "contract_name": "andromeda-shunting", - "contract_version": "0.1.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "expressions", - "kernel_address" - ], - "properties": { - "expressions": { - "type": "array", - "items": { - "type": "string" - } - }, - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "update_expressions" - ], - "properties": { - "update_expressions": { - "type": "object", - "required": [ - "expressions" - ], - "properties": { - "expressions": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "evaluate" - ], - "properties": { - "evaluate": { - "type": "object", - "required": [ - "params" - ], - "properties": { - "params": { - "type": "array", - "items": { - "$ref": "#/definitions/EvaluateParam" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "EvaluateParam": { - "oneOf": [ - { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "reference" - ], - "properties": { - "reference": { - "$ref": "#/definitions/EvaluateRefParam" - } - }, - "additionalProperties": false - } - ] - }, - "EvaluateRefParam": { - "type": "object", - "required": [ - "accessor", - "contract", - "msg" - ], - "properties": { - "accessor": { - "type": "string" - }, - "contract": { - "$ref": "#/definitions/Addr" - }, - "msg": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "evaluate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ShuntingResponse", - "type": "object", - "required": [ - "result" - ], - "properties": { - "result": { - "type": "string" - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/execute.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/execute.json deleted file mode 100644 index 6cd375e..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/execute.json +++ /dev/null @@ -1,540 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "update_expressions" - ], - "properties": { - "update_expressions": { - "type": "object", - "required": [ - "expressions" - ], - "properties": { - "expressions": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/instantiate.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/instantiate.json deleted file mode 100644 index c9973e6..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/instantiate.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "expressions", - "kernel_address" - ], - "properties": { - "expressions": { - "type": "array", - "items": { - "type": "string" - } - }, - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/query.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/query.json deleted file mode 100644 index 0dd33f4..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/query.json +++ /dev/null @@ -1,435 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "evaluate" - ], - "properties": { - "evaluate": { - "type": "object", - "required": [ - "params" - ], - "properties": { - "params": { - "type": "array", - "items": { - "$ref": "#/definitions/EvaluateParam" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "EvaluateParam": { - "oneOf": [ - { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "string" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "reference" - ], - "properties": { - "reference": { - "$ref": "#/definitions/EvaluateRefParam" - } - }, - "additionalProperties": false - } - ] - }, - "EvaluateRefParam": { - "type": "object", - "required": [ - "accessor", - "contract", - "msg" - ], - "properties": { - "accessor": { - "type": "string" - }, - "contract": { - "$ref": "#/definitions/Addr" - }, - "msg": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_balance.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_eval_with_params.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_eval_with_params.json deleted file mode 100644 index 9321147..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_eval_with_params.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ShuntingResponse", - "type": "object", - "required": [ - "result" - ], - "properties": { - "result": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_evaluate.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_evaluate.json deleted file mode 100644 index 9321147..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_evaluate.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ShuntingResponse", - "type": "object", - "required": [ - "result" - ], - "properties": { - "result": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_operators.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_owner.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissions.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_type.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_version.json b/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/modules/andromeda-shunting/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/modules/andromeda-shunting/src/contract.rs b/andromeda-core/contracts/modules/andromeda-shunting/src/contract.rs index ccf837a..8f8a13d 100644 --- a/andromeda-core/contracts/modules/andromeda-shunting/src/contract.rs +++ b/andromeda-core/contracts/modules/andromeda-shunting/src/contract.rs @@ -38,11 +38,11 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "shunting".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -156,7 +156,7 @@ fn parse_params(deps: Deps, params: Vec) -> Result, C } .into(); - let raw_result: Value = deps.querier.query::(&query_msg).unwrap(); + let raw_result: Value = deps.querier.query::(&query_msg)?; let json = JSON::from(raw_result); let Value::String(val) = json.get(&accessor).unwrap() else { return Err(ContractError::InvalidExpression { diff --git a/andromeda-core/contracts/modules/andromeda-shunting/src/mock.rs b/andromeda-core/contracts/modules/andromeda-shunting/src/mock.rs index 4fc3c5a..7252d4e 100644 --- a/andromeda-core/contracts/modules/andromeda-shunting/src/mock.rs +++ b/andromeda-core/contracts/modules/andromeda-shunting/src/mock.rs @@ -5,9 +5,10 @@ use andromeda_modules::shunting::{ EvaluateParam, ExecuteMsg, InstantiateMsg, QueryMsg, ShuntingResponse, }; use cosmwasm_std::{Addr, Empty}; -use cw_multi_test::{App, Contract, ContractWrapper}; +use cw_multi_test::{Contract, ContractWrapper}; use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::{MockADO, MockContract}, }; @@ -16,7 +17,7 @@ pub struct MockShunting(Addr); mock_ado!(MockShunting, ExecuteMsg, QueryMsg); impl MockShunting { - pub fn evaluate(&self, app: &App, params: Vec) -> ShuntingResponse { + pub fn evaluate(&self, app: &MockApp, params: Vec) -> ShuntingResponse { let msg = mock_shunting_evaluate(params); let res: ShuntingResponse = self.query(app, msg); res diff --git a/andromeda-core/contracts/modules/andromeda-shunting/src/testing/tests.rs b/andromeda-core/contracts/modules/andromeda-shunting/src/testing/tests.rs index 8a933d3..fae4317 100644 --- a/andromeda-core/contracts/modules/andromeda-shunting/src/testing/tests.rs +++ b/andromeda-core/contracts/modules/andromeda-shunting/src/testing/tests.rs @@ -1,7 +1,5 @@ use crate::contract::{instantiate, query}; -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; use andromeda_modules::shunting::{EvaluateParam, InstantiateMsg, QueryMsg, ShuntingResponse}; use cosmwasm_std::{ diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/Cargo.toml b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/Cargo.toml index 54bddd5..84fc5e3 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/Cargo.toml +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-auction" -version = "0.2.1" +version = "2.0.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,25 +12,24 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] -cosmwasm-std = { workspace = true } +cosmwasm-std = { workspace = true, features = ["cosmwasm_1_1"] } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw721 = { workspace = true } -cw2 = { workspace = true } + cw20 = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true, features = ["rates"] } andromeda-non-fungible-tokens = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } -andromeda-testing = { workspace = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/README.md b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/README.md new file mode 100644 index 0000000..2bc1e1b --- /dev/null +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/README.md @@ -0,0 +1,5 @@ +# Overview + +The Auction ADO is a smart contract that allows performing custom auctions on NFTs. NFTs can be sent to this contract with the required messages to start an auction on it. Once the auction has started, users can place bids on the token until the auction expires. The highest bid will win the auction, sending the funds to the seller and receiving the token in return. + +[Auction Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/auction) \ No newline at end of file diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/andromeda-auction.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/andromeda-auction.json deleted file mode 100644 index c08583c..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/andromeda-auction.json +++ /dev/null @@ -1,2276 +0,0 @@ -{ - "contract_name": "andromeda-auction", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive_nft" - ], - "properties": { - "receive_nft": { - "$ref": "#/definitions/Cw721ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Places a bid on the current auction for the given token_id. The previous largest bid gets automatically sent back to the bidder when they are outbid.", - "type": "object", - "required": [ - "place_bid" - ], - "properties": { - "place_bid": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Transfers the given token to the auction winner's address once the auction is over.", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_auction" - ], - "properties": { - "update_auction": { - "type": "object", - "required": [ - "coin_denom", - "duration", - "start_time", - "token_address", - "token_id" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "duration": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "min_bid": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "start_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - }, - "whitelist": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Addr" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cancel_auction" - ], - "properties": { - "cancel_auction": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw721ReceiveMsg": { - "description": "Cw721ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "msg", - "sender", - "token_id" - ], - "properties": { - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the latest auction state for the given token. This will either be the current auction if there is one in progress or the last completed one.", - "type": "object", - "required": [ - "latest_auction_state" - ], - "properties": { - "latest_auction_state": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the auction state for the given auction id.", - "type": "object", - "required": [ - "auction_state" - ], - "properties": { - "auction_state": { - "type": "object", - "required": [ - "auction_id" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the auction ids for the given token.", - "type": "object", - "required": [ - "auction_ids" - ], - "properties": { - "auction_ids": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets all of the auction infos for a given token address.", - "type": "object", - "required": [ - "auction_infos_for_address" - ], - "properties": { - "auction_infos_for_address": { - "type": "object", - "required": [ - "token_address" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the bids for the given auction id. Start_after starts indexing at 0.", - "type": "object", - "required": [ - "bids" - ], - "properties": { - "bids": { - "type": "object", - "required": [ - "auction_id" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "order_by": { - "anyOf": [ - { - "$ref": "#/definitions/OrderBy" - }, - { - "type": "null" - } - ] - }, - "start_after": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_cancelled" - ], - "properties": { - "is_cancelled": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Returns true only if the auction has been cancelled, the token has been claimed, or the end time has expired", - "type": "object", - "required": [ - "is_closed" - ], - "properties": { - "is_closed": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "OrderBy": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "auction_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionIdsResponse", - "type": "object", - "required": [ - "auction_ids" - ], - "properties": { - "auction_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "auction_infos_for_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionInfo", - "type": "object", - "required": [ - "auction_ids", - "token_address", - "token_id" - ], - "properties": { - "auction_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "auction_state": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionStateResponse", - "type": "object", - "required": [ - "auction_id", - "coin_denom", - "end_time", - "high_bidder_addr", - "high_bidder_amount", - "is_cancelled", - "owner", - "start_time" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - }, - "coin_denom": { - "type": "string" - }, - "end_time": { - "$ref": "#/definitions/Expiration" - }, - "high_bidder_addr": { - "type": "string" - }, - "high_bidder_amount": { - "$ref": "#/definitions/Uint128" - }, - "is_cancelled": { - "type": "boolean" - }, - "min_bid": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "owner": { - "type": "string" - }, - "start_time": { - "$ref": "#/definitions/Expiration" - }, - "whitelist": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Addr" - } - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "bids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BidsResponse", - "type": "object", - "required": [ - "bids" - ], - "properties": { - "bids": { - "type": "array", - "items": { - "$ref": "#/definitions/Bid" - } - } - }, - "additionalProperties": false, - "definitions": { - "Bid": { - "type": "object", - "required": [ - "amount", - "bidder", - "timestamp" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "bidder": { - "type": "string" - }, - "timestamp": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "is_cancelled": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsCancelledResponse", - "type": "object", - "required": [ - "is_cancelled" - ], - "properties": { - "is_cancelled": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_claimed": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsClaimedResponse", - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_closed": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsClosedResponse", - "type": "object", - "required": [ - "is_closed" - ], - "properties": { - "is_closed": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "latest_auction_state": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionStateResponse", - "type": "object", - "required": [ - "auction_id", - "coin_denom", - "end_time", - "high_bidder_addr", - "high_bidder_amount", - "is_cancelled", - "owner", - "start_time" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - }, - "coin_denom": { - "type": "string" - }, - "end_time": { - "$ref": "#/definitions/Expiration" - }, - "high_bidder_addr": { - "type": "string" - }, - "high_bidder_amount": { - "$ref": "#/definitions/Uint128" - }, - "is_cancelled": { - "type": "boolean" - }, - "min_bid": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "owner": { - "type": "string" - }, - "start_time": { - "$ref": "#/definitions/Expiration" - }, - "whitelist": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Addr" - } - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/cw721receive.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/cw721receive.json deleted file mode 100644 index e20b8ea..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/cw721receive.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "cw721receive", - "oneOf": [ - { - "description": "Starts a new auction with the given parameters. The auction info can be modified before it has started but is immutable after that.", - "type": "object", - "required": [ - "start_auction" - ], - "properties": { - "start_auction": { - "type": "object", - "required": [ - "coin_denom", - "duration", - "start_time" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "duration": { - "description": "Duration in milliseconds", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "min_bid": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "start_time": { - "description": "Start time in milliseconds since epoch", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "whitelist": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Addr" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/execute.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/execute.json deleted file mode 100644 index 14a493a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/execute.json +++ /dev/null @@ -1,780 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive_nft" - ], - "properties": { - "receive_nft": { - "$ref": "#/definitions/Cw721ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Places a bid on the current auction for the given token_id. The previous largest bid gets automatically sent back to the bidder when they are outbid.", - "type": "object", - "required": [ - "place_bid" - ], - "properties": { - "place_bid": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Transfers the given token to the auction winner's address once the auction is over.", - "type": "object", - "required": [ - "claim" - ], - "properties": { - "claim": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_auction" - ], - "properties": { - "update_auction": { - "type": "object", - "required": [ - "coin_denom", - "duration", - "start_time", - "token_address", - "token_id" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "duration": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "min_bid": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "start_time": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - }, - "whitelist": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Addr" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cancel_auction" - ], - "properties": { - "cancel_auction": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw721ReceiveMsg": { - "description": "Cw721ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "msg", - "sender", - "token_id" - ], - "properties": { - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/instantiate.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/instantiate.json deleted file mode 100644 index 2173324..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/instantiate.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/query.json deleted file mode 100644 index 2db559d..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/query.json +++ /dev/null @@ -1,638 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the latest auction state for the given token. This will either be the current auction if there is one in progress or the last completed one.", - "type": "object", - "required": [ - "latest_auction_state" - ], - "properties": { - "latest_auction_state": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the auction state for the given auction id.", - "type": "object", - "required": [ - "auction_state" - ], - "properties": { - "auction_state": { - "type": "object", - "required": [ - "auction_id" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the auction ids for the given token.", - "type": "object", - "required": [ - "auction_ids" - ], - "properties": { - "auction_ids": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets all of the auction infos for a given token address.", - "type": "object", - "required": [ - "auction_infos_for_address" - ], - "properties": { - "auction_infos_for_address": { - "type": "object", - "required": [ - "token_address" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the bids for the given auction id. Start_after starts indexing at 0.", - "type": "object", - "required": [ - "bids" - ], - "properties": { - "bids": { - "type": "object", - "required": [ - "auction_id" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "order_by": { - "anyOf": [ - { - "$ref": "#/definitions/OrderBy" - }, - { - "type": "null" - } - ] - }, - "start_after": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_cancelled" - ], - "properties": { - "is_cancelled": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Returns true only if the auction has been cancelled, the token has been claimed, or the end time has expired", - "type": "object", - "required": [ - "is_closed" - ], - "properties": { - "is_closed": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "OrderBy": { - "type": "string", - "enum": [ - "asc", - "desc" - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_ids.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_ids.json deleted file mode 100644 index b3ed62c..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_ids.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionIdsResponse", - "type": "object", - "required": [ - "auction_ids" - ], - "properties": { - "auction_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_infos_for_address.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_infos_for_address.json deleted file mode 100644 index 23f202e..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_infos_for_address.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionInfo", - "type": "object", - "required": [ - "auction_ids", - "token_address", - "token_id" - ], - "properties": { - "auction_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_state.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_state.json deleted file mode 100644 index 20f5c0f..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_auction_state.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionStateResponse", - "type": "object", - "required": [ - "auction_id", - "coin_denom", - "end_time", - "high_bidder_addr", - "high_bidder_amount", - "is_cancelled", - "owner", - "start_time" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - }, - "coin_denom": { - "type": "string" - }, - "end_time": { - "$ref": "#/definitions/Expiration" - }, - "high_bidder_addr": { - "type": "string" - }, - "high_bidder_amount": { - "$ref": "#/definitions/Uint128" - }, - "is_cancelled": { - "type": "boolean" - }, - "min_bid": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "owner": { - "type": "string" - }, - "start_time": { - "$ref": "#/definitions/Expiration" - }, - "whitelist": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Addr" - } - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_balance.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_bids.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_bids.json deleted file mode 100644 index 6c9e374..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_bids.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BidsResponse", - "type": "object", - "required": [ - "bids" - ], - "properties": { - "bids": { - "type": "array", - "items": { - "$ref": "#/definitions/Bid" - } - } - }, - "additionalProperties": false, - "definitions": { - "Bid": { - "type": "object", - "required": [ - "amount", - "bidder", - "timestamp" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "bidder": { - "type": "string" - }, - "timestamp": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_cancelled.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_cancelled.json deleted file mode 100644 index 5126539..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_cancelled.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsCancelledResponse", - "type": "object", - "required": [ - "is_cancelled" - ], - "properties": { - "is_cancelled": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_claimed.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_claimed.json deleted file mode 100644 index 1b1b8b6..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_claimed.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsClaimedResponse", - "type": "object", - "required": [ - "is_claimed" - ], - "properties": { - "is_claimed": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_closed.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_closed.json deleted file mode 100644 index 5f45a2e..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_closed.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsClosedResponse", - "type": "object", - "required": [ - "is_closed" - ], - "properties": { - "is_closed": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_latest_auction_state.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_latest_auction_state.json deleted file mode 100644 index 20f5c0f..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_latest_auction_state.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AuctionStateResponse", - "type": "object", - "required": [ - "auction_id", - "coin_denom", - "end_time", - "high_bidder_addr", - "high_bidder_amount", - "is_cancelled", - "owner", - "start_time" - ], - "properties": { - "auction_id": { - "$ref": "#/definitions/Uint128" - }, - "coin_denom": { - "type": "string" - }, - "end_time": { - "$ref": "#/definitions/Expiration" - }, - "high_bidder_addr": { - "type": "string" - }, - "high_bidder_amount": { - "$ref": "#/definitions/Uint128" - }, - "is_cancelled": { - "type": "boolean" - }, - "min_bid": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "owner": { - "type": "string" - }, - "start_time": { - "$ref": "#/definitions/Expiration" - }, - "whitelist": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Addr" - } - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_operators.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_owner.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_type.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_version.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs index 1a7c4b3..b86566e 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/contract.rs @@ -2,33 +2,41 @@ use crate::state::{ auction_infos, read_auction_infos, read_bids, BIDS, NEXT_AUCTION_ID, TOKEN_AUCTION_STATE, }; use andromeda_non_fungible_tokens::auction::{ - AuctionIdsResponse, AuctionInfo, AuctionStateResponse, Bid, BidsResponse, Cw721HookMsg, - ExecuteMsg, InstantiateMsg, IsCancelledResponse, IsClaimedResponse, IsClosedResponse, - MigrateMsg, QueryMsg, TokenAuctionState, + AuctionIdsResponse, AuctionInfo, AuctionStateResponse, AuthorizedAddressesResponse, Bid, + BidsResponse, Cw20HookMsg, Cw721HookMsg, ExecuteMsg, InstantiateMsg, IsCancelledResponse, + IsClaimedResponse, IsClosedResponse, QueryMsg, TokenAuctionState, }; - use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, - common::Funds, - common::{encode_binary, expiration::expiration_from_milliseconds, OrderBy}, - common::{expiration::MILLISECONDS_TO_NANOSECONDS_RATIO, rates::get_tax_amount}, - error::{from_semver, ContractError}, + ado_base::{ + permissioning::{LocalPermission, Permission}, + InstantiateMsg as BaseInstantiateMsg, MigrateMsg, + }, + amp::{AndrAddr, Recipient}, + common::{ + actions::call_action, + denom::{validate_denom, Asset, SEND_CW20_ACTION}, + encode_binary, + expiration::{expiration_from_milliseconds, get_and_validate_start_time, Expiry}, + Funds, Milliseconds, OrderBy, + }, + error::ContractError, }; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; use cosmwasm_std::{ - attr, coins, ensure, entry_point, from_json, Addr, BankMsg, Binary, BlockInfo, Coin, CosmosMsg, - Deps, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, Response, Storage, SubMsg, - Uint128, WasmMsg, WasmQuery, + attr, coins, ensure, entry_point, from_json, wasm_execute, Addr, BankMsg, Binary, Coin, + CosmosMsg, Deps, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, Response, Storage, + SubMsg, Uint128, WasmMsg, WasmQuery, }; -use cw2::{get_contract_version, set_contract_version}; -use cw721::{Cw721ExecuteMsg, Cw721QueryMsg, Cw721ReceiveMsg, Expiration, OwnerOfResponse}; +use cw20::{Cw20Coin, Cw20ExecuteMsg, Cw20ReceiveMsg}; +use cw721::{Cw721ExecuteMsg, Cw721QueryMsg, Cw721ReceiveMsg, OwnerOfResponse}; use cw_utils::nonpayable; -use semver::Version; -const CONTRACT_NAME: &str = "crates.io:andromeda_auction"; +const CONTRACT_NAME: &str = "crates.io:andromeda-auction"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +const SEND_NFT_ACTION: &str = "SEND_NFT"; + #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, @@ -36,28 +44,49 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; NEXT_AUCTION_ID.save(deps.storage, &Uint128::from(1u128))?; let contract = ADOContract::default(); let resp = contract.instantiate( deps.storage, env, deps.api, - info.clone(), + &deps.querier, + info, BaseInstantiateMsg { - ado_type: "auction".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; - let modules_resp = - contract.register_modules(info.sender.as_str(), deps.storage, msg.modules)?; - Ok(resp - .add_submessages(modules_resp.messages) - .add_attributes(modules_resp.attributes)) + if let Some(authorized_token_addresses) = msg.authorized_token_addresses { + if !authorized_token_addresses.is_empty() { + ADOContract::default().permission_action(SEND_NFT_ACTION, deps.storage)?; + } + + for token_address in authorized_token_addresses { + let addr = token_address.get_raw_address(&deps.as_ref())?; + ADOContract::set_permission( + deps.storage, + SEND_NFT_ACTION, + addr, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + } + if let Some(authorized_cw20_address) = msg.authorized_cw20_address { + let addr = authorized_cw20_address.get_raw_address(&deps.as_ref())?; + ADOContract::default().permission_action(SEND_CW20_ACTION, deps.storage)?; + ADOContract::set_permission( + deps.storage, + SEND_CW20_ACTION, + addr, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + + Ok(resp) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -77,39 +106,41 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let contract = ADOContract::default(); +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); - if !matches!(msg, ExecuteMsg::UpdateAppContract { .. }) - && !matches!(msg, ExecuteMsg::UpdateOwner { .. }) - { - contract.module_hook::( - &ctx.deps.as_ref(), - AndromedaHook::OnExecute { - sender: ctx.info.sender.to_string(), - payload: encode_binary(&msg)?, - }, - )?; - } - match msg { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + let res = match msg { ExecuteMsg::ReceiveNft(msg) => handle_receive_cw721(ctx, msg), + ExecuteMsg::Receive(msg) => handle_receive_cw20(ctx, msg), ExecuteMsg::UpdateAuction { token_id, token_address, start_time, - duration, + end_time, coin_denom, whitelist, min_bid, + min_raise, + recipient, } => execute_update_auction( ctx, token_id, token_address, start_time, - duration, + end_time, coin_denom, whitelist, min_bid, + min_raise, + recipient, ), ExecuteMsg::PlaceBid { token_id, @@ -122,31 +153,100 @@ pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_claim(ctx, token_id, token_address), + } => execute_claim(ctx, token_id, token_address, action), + ExecuteMsg::AuthorizeTokenContract { addr, expiration } => { + execute_authorize_token_contract(ctx.deps, ctx.info, addr, expiration) + } + ExecuteMsg::DeauthorizeTokenContract { addr } => { + execute_deauthorize_token_contract(ctx.deps, ctx.info, addr) + } _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } fn handle_receive_cw721( - ctx: ExecuteContext, + mut ctx: ExecuteContext, msg: Cw721ReceiveMsg, ) -> Result { + ADOContract::default().is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + SEND_NFT_ACTION, + ctx.info.sender.clone(), + )?; match from_json(&msg.msg)? { Cw721HookMsg::StartAuction { start_time, - duration, + end_time, coin_denom, whitelist, min_bid, + min_raise, + recipient, } => execute_start_auction( ctx, msg.sender, msg.token_id, start_time, - duration, + end_time, coin_denom, whitelist, min_bid, + min_raise, + recipient, + ), + } +} + +pub fn handle_receive_cw20( + mut ctx: ExecuteContext, + receive_msg: Cw20ReceiveMsg, +) -> Result { + let is_valid_cw20 = ADOContract::default() + .is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + SEND_CW20_ACTION, + ctx.info.sender.clone(), + ) + .is_ok(); + + ensure!( + is_valid_cw20, + ContractError::InvalidAsset { + asset: ctx.info.sender.into_string() + } + ); + + let ExecuteContext { ref info, .. } = ctx; + nonpayable(info)?; + + let asset_sent = info.sender.clone().into_string(); + let amount_sent = receive_msg.amount; + let sender = receive_msg.sender; + + ensure!( + !amount_sent.is_zero(), + ContractError::InvalidFunds { + msg: "Cannot send a 0 amount".to_string() + } + ); + + match from_json(&receive_msg.msg)? { + Cw20HookMsg::PlaceBid { + token_id, + token_address, + } => execute_place_bid_cw20( + ctx, + token_id, + token_address, + amount_sent, + asset_sent, + &sender, ), } } @@ -156,30 +256,33 @@ fn execute_start_auction( ctx: ExecuteContext, sender: String, token_id: String, - start_time: u64, - duration: u64, - coin_denom: String, + start_time: Option, + end_time: Expiry, + coin_denom: Asset, whitelist: Option>, min_bid: Option, + min_raise: Option, + recipient: Option, ) -> Result { + let ExecuteContext { + mut deps, + info, + env, + .. + } = ctx; + let (coin_denom, uses_cw20) = coin_denom.get_verified_asset(deps.branch(), env.clone())?; ensure!( - start_time > 0 && duration > 0, + !end_time.get_time(&env.block).is_zero(), ContractError::InvalidExpiration {} ); - let ExecuteContext { - deps, info, env, .. - } = ctx; - let start_expiration = expiration_from_milliseconds(start_time)?; - let end_expiration = expiration_from_milliseconds(start_time + duration)?; + // If start time wasn't provided, it will be set as the current_time + let (start_expiration, _current_time) = get_and_validate_start_time(&env, start_time)?; + let end_expiration = expiration_from_milliseconds(end_time.get_time(&env.block))?; - let block_time = block_to_expiration(&env.block, start_expiration).unwrap(); ensure!( - start_expiration.gt(&block_time), - ContractError::StartTimeInThePast { - current_time: env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO, - current_block: env.block.height, - } + end_expiration > start_expiration, + ContractError::StartTimeAfterEndTime {} ); let token_address = info.sender.to_string(); @@ -187,6 +290,19 @@ fn execute_start_auction( let auction_id = get_and_increment_next_auction_id(deps.storage, &token_id, &token_address)?; BIDS.save(deps.storage, auction_id.u128(), &vec![])?; + if let Some(ref whitelist) = whitelist { + ADOContract::default().permission_action(auction_id.to_string(), deps.storage)?; + + for whitelisted_address in whitelist { + ADOContract::set_permission( + deps.storage, + auction_id.to_string(), + whitelisted_address, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + }; + let whitelist_str = format!("{:?}", &whitelist); TOKEN_AUCTION_STATE.save( @@ -198,13 +314,16 @@ fn execute_start_auction( high_bidder_addr: Addr::unchecked(""), high_bidder_amount: Uint128::zero(), coin_denom: coin_denom.clone(), + uses_cw20, auction_id, whitelist, min_bid, + min_raise, owner: sender, token_id, token_address, is_cancelled: false, + recipient, }, )?; Ok(Response::new().add_attributes(vec![ @@ -222,17 +341,41 @@ fn execute_update_auction( ctx: ExecuteContext, token_id: String, token_address: String, - start_time: u64, - duration: u64, - coin_denom: String, + start_time: Option, + end_time: Expiry, + coin_denom: Asset, whitelist: Option>, min_bid: Option, + min_raise: Option, + recipient: Option, ) -> Result { let ExecuteContext { - deps, info, env, .. + mut deps, + info, + env, + .. } = ctx; nonpayable(&info)?; - + let (coin_denom, uses_cw20) = coin_denom.get_verified_asset(deps.branch(), env.clone())?; + + if uses_cw20 { + let valid_cw20_auction = ADOContract::default() + .is_permissioned( + deps.branch(), + env.clone(), + SEND_CW20_ACTION, + coin_denom.clone(), + ) + .is_ok(); + ensure!( + valid_cw20_auction, + ContractError::InvalidFunds { + msg: "Non-permissioned CW20 asset sent".to_string() + } + ); + } else { + validate_denom(deps.as_ref(), coin_denom.clone())?; + } let mut token_auction_state = get_existing_token_auction_state(deps.storage, &token_id, &token_address)?; ensure!( @@ -243,26 +386,45 @@ fn execute_update_auction( !token_auction_state.start_time.is_expired(&env.block), ContractError::AuctionAlreadyStarted {} ); + ensure!( - start_time > 0 && duration > 0, + !end_time.get_time(&env.block).is_zero(), ContractError::InvalidExpiration {} ); - let start_exp = expiration_from_milliseconds(start_time)?; - let end_exp = expiration_from_milliseconds(start_time + duration)?; + // If start time wasn't provided, it will be set as the current_time + let (start_expiration, _current_time) = get_and_validate_start_time(&env, start_time)?; + let end_expiration = expiration_from_milliseconds(end_time.get_time(&env.block))?; + ensure!( - !start_exp.is_expired(&env.block), - ContractError::StartTimeInThePast { - current_time: env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO, - current_block: env.block.height, - } + end_expiration > start_expiration, + ContractError::StartTimeAfterEndTime {} ); - token_auction_state.start_time = start_exp; - token_auction_state.end_time = end_exp; - token_auction_state.whitelist = whitelist.clone(); + if let Some(ref whitelist) = whitelist { + ADOContract::default() + .permission_action(token_auction_state.auction_id.to_string(), deps.storage)?; + + for whitelisted_address in whitelist { + ADOContract::set_permission( + deps.storage, + token_auction_state.auction_id.to_string(), + whitelisted_address, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + }; + + let whitelist_str = format!("{:?}", &whitelist); + + token_auction_state.start_time = start_expiration; + token_auction_state.end_time = end_expiration; token_auction_state.coin_denom = coin_denom.clone(); + token_auction_state.uses_cw20 = uses_cw20; token_auction_state.min_bid = min_bid; + token_auction_state.min_raise = min_raise; + token_auction_state.whitelist = whitelist; + token_auction_state.recipient = recipient; TOKEN_AUCTION_STATE.save( deps.storage, token_auction_state.auction_id.u128(), @@ -270,12 +432,14 @@ fn execute_update_auction( )?; Ok(Response::new().add_attributes(vec![ attr("action", "update_auction"), - attr("start_time", start_time.to_string()), - attr("end_time", end_exp.to_string()), + attr("start_time", start_expiration.to_string()), + attr("end_time", end_expiration.to_string()), attr("coin_denom", coin_denom), + attr("uses_cw20", uses_cw20.to_string()), attr("auction_id", token_auction_state.auction_id.to_string()), - attr("whitelist", format!("{:?}", &whitelist)), + attr("whitelist", format!("{:?}", whitelist_str)), attr("min_bid", format!("{:?}", &min_bid)), + attr("min_raise", format!("{:?}", &min_raise)), ])) } @@ -285,11 +449,21 @@ fn execute_place_bid( token_address: String, ) -> Result { let ExecuteContext { - deps, info, env, .. + mut deps, + info, + env, + .. } = ctx; let mut token_auction_state = get_existing_token_auction_state(deps.storage, &token_id, &token_address)?; + ADOContract::default().is_permissioned( + deps.branch(), + env.clone(), + token_auction_state.auction_id, + info.sender.clone(), + )?; + ensure!( !token_auction_state.is_cancelled, ContractError::AuctionCancelled {} @@ -312,21 +486,22 @@ fn execute_place_bid( ensure!( info.funds.len() == 1, ContractError::InvalidFunds { - msg: "Auctions ensure! exactly one coin to be sent.".to_string(), + msg: "One coin should be sent.".to_string(), } ); - if let Some(ref whitelist) = token_auction_state.whitelist { - ensure!( - whitelist.iter().any(|x| x == info.sender), - ContractError::Unauthorized {} - ); - } ensure!( token_auction_state.high_bidder_addr != info.sender, ContractError::HighestBidderCannotOutBid {} ); + ensure!( + !token_auction_state.uses_cw20, + ContractError::InvalidFunds { + msg: "Native funds were sent to an auction that only accepts cw20".to_string() + } + ); + let payment: &Coin = &info.funds[0]; ensure!( payment.denom == token_auction_state.coin_denom && payment.amount > Uint128::zero(), @@ -352,6 +527,16 @@ fn execute_place_bid( ContractError::BidSmallerThanHighestBid {} ); + // If there's a min_raise, the difference between the new bid and the highest bid should be greater or equal to it. + let min_raise = token_auction_state.min_raise.unwrap_or_default(); + let bid_difference = payment + .amount + .checked_sub(token_auction_state.high_bidder_amount)?; + ensure!( + bid_difference.ge(&min_raise), + ContractError::MinRaiseUnmet {} + ); + let mut messages: Vec = vec![]; // Send back previous bid unless there was no previous bid. if token_auction_state.high_bidder_amount > Uint128::zero() { @@ -374,7 +559,7 @@ fn execute_place_bid( bids_for_auction.push(Bid { bidder: info.sender.to_string(), amount: payment.amount, - timestamp: env.block.time, + timestamp: Milliseconds::from_nanos(env.block.time.nanos()), }); BIDS.save(deps.storage, key, &bids_for_auction)?; Ok(Response::new().add_messages(messages).add_attributes(vec![ @@ -385,6 +570,130 @@ fn execute_place_bid( ])) } +fn execute_place_bid_cw20( + ctx: ExecuteContext, + token_id: String, + token_address: String, + amount_sent: Uint128, + asset_sent: String, + // The user who sent the cw20 + sender: &str, +) -> Result { + let ExecuteContext { mut deps, env, .. } = ctx; + let mut token_auction_state = + get_existing_token_auction_state(deps.storage, &token_id, &token_address)?; + + ADOContract::default().is_permissioned( + deps.branch(), + env.clone(), + token_auction_state.auction_id, + sender, + )?; + + ensure!( + !token_auction_state.is_cancelled, + ContractError::AuctionCancelled {} + ); + + ensure!( + token_auction_state.start_time.is_expired(&env.block), + ContractError::AuctionNotStarted {} + ); + ensure!( + !token_auction_state.end_time.is_expired(&env.block), + ContractError::AuctionEnded {} + ); + + ensure!( + token_auction_state.owner != sender, + ContractError::TokenOwnerCannotBid {} + ); + + let sender_addr = deps.api.addr_validate(sender)?; + + ensure!( + token_auction_state.high_bidder_addr != sender_addr, + ContractError::HighestBidderCannotOutBid {} + ); + + let auction_currency = token_auction_state.clone().coin_denom; + ensure!( + auction_currency == asset_sent, + ContractError::InvalidAsset { asset: asset_sent } + ); + + ensure!( + token_auction_state.uses_cw20, + ContractError::InvalidFunds { + msg: "CW20 funds were sent to an auction that only accepts native funds".to_string() + } + ); + + ensure!( + amount_sent > Uint128::zero(), + ContractError::InvalidFunds { + msg: format!( + "No {} assets are provided to auction", + token_auction_state.coin_denom + ), + } + ); + let min_bid = token_auction_state.min_bid.unwrap_or(Uint128::zero()); + ensure!( + amount_sent >= min_bid, + ContractError::InvalidFunds { + msg: format!( + "Must provide at least {min_bid} {} to bid", + token_auction_state.coin_denom + ) + } + ); + ensure!( + token_auction_state.high_bidder_amount < amount_sent, + ContractError::BidSmallerThanHighestBid {} + ); + + // If there's a min_raise, the difference between the new bid and the highest bid should be greater or equal to it. + let min_raise = token_auction_state.min_raise.unwrap_or_default(); + let bid_difference = amount_sent.checked_sub(token_auction_state.high_bidder_amount)?; + ensure!( + bid_difference.ge(&min_raise), + ContractError::MinRaiseUnmet {} + ); + + let mut cw20_transfer: Vec = vec![]; + // Send back previous bid unless there was no previous bid. + if token_auction_state.high_bidder_amount > Uint128::zero() { + let transfer_msg = Cw20ExecuteMsg::Transfer { + recipient: token_auction_state.high_bidder_addr.to_string(), + amount: token_auction_state.high_bidder_amount, + }; + let wasm_msg = wasm_execute(auction_currency, &transfer_msg, vec![])?; + cw20_transfer.push(wasm_msg); + } + + token_auction_state.high_bidder_addr = sender_addr.clone(); + token_auction_state.high_bidder_amount = amount_sent; + + let key = token_auction_state.auction_id.u128(); + TOKEN_AUCTION_STATE.save(deps.storage, key, &token_auction_state)?; + let mut bids_for_auction = BIDS.load(deps.storage, key)?; + bids_for_auction.push(Bid { + bidder: sender.to_string(), + amount: amount_sent, + timestamp: Milliseconds::from_nanos(env.block.time.nanos()), + }); + BIDS.save(deps.storage, key, &bids_for_auction)?; + Ok(Response::new() + .add_messages(cw20_transfer) + .add_attributes(vec![ + attr("action", "bid"), + attr("token_id", token_id), + attr("bider", sender_addr.to_string()), + attr("amount", amount_sent.to_string()), + ])) +} + fn execute_cancel( ctx: ExecuteContext, token_id: String, @@ -416,13 +725,24 @@ fn execute_cancel( // Refund highest bid, if it exists. if !token_auction_state.high_bidder_amount.is_zero() { - messages.push(CosmosMsg::Bank(BankMsg::Send { - to_address: token_auction_state.high_bidder_addr.to_string(), - amount: coins( - token_auction_state.high_bidder_amount.u128(), - token_auction_state.coin_denom.clone(), - ), - })); + let is_cw20_auction = token_auction_state.uses_cw20; + if is_cw20_auction { + let auction_currency = token_auction_state.clone().coin_denom; + let transfer_msg = Cw20ExecuteMsg::Transfer { + recipient: token_auction_state.high_bidder_addr.clone().into_string(), + amount: token_auction_state.high_bidder_amount, + }; + let wasm_msg = wasm_execute(auction_currency, &transfer_msg, vec![])?; + messages.push(CosmosMsg::Wasm(wasm_msg)) + } else { + messages.push(CosmosMsg::Bank(BankMsg::Send { + to_address: token_auction_state.high_bidder_addr.to_string(), + amount: coins( + token_auction_state.high_bidder_amount.u128(), + token_auction_state.coin_denom.clone(), + ), + })); + } } token_auction_state.is_cancelled = true; @@ -439,11 +759,12 @@ fn execute_claim( ctx: ExecuteContext, token_id: String, token_address: String, + action: String, ) -> Result { let ExecuteContext { deps, info, env, .. } = ctx; - nonpayable(&info)?; + let token_auction_state = get_existing_token_auction_state(deps.storage, &token_id, &token_address)?; ensure!( @@ -485,15 +806,10 @@ fn execute_claim( } // Calculate the funds to be received after tax - let after_tax_payment = purchase_token(deps.as_ref(), &info, token_auction_state.clone())?; + let (after_tax_payment, tax_messages) = + purchase_token(deps.as_ref(), &info, token_auction_state.clone(), action)?; - Ok(Response::new() - .add_submessages(after_tax_payment.1) - // Send funds to the original owner. - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: token_auction_state.owner, - amount: vec![after_tax_payment.0], - })) + let mut resp: Response = Response::new() // Send NFT to auction winner. .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: token_auction_state.token_address.clone(), @@ -503,42 +819,138 @@ fn execute_claim( })?, funds: vec![], })) + // Send tax/royalty messages + .add_submessages(tax_messages) .add_attribute("action", "claim") - .add_attribute("token_id", token_id) - .add_attribute("token_contract", token_auction_state.token_address) + .add_attribute("token_id", token_id.clone()) + .add_attribute("token_contract", token_auction_state.clone().token_address) .add_attribute("recipient", &token_auction_state.high_bidder_addr) .add_attribute("winning_bid_amount", token_auction_state.high_bidder_amount) - .add_attribute("auction_id", token_auction_state.auction_id)) -} + .add_attribute("auction_id", token_auction_state.auction_id); -fn purchase_token( - deps: Deps, - info: &MessageInfo, - state: TokenAuctionState, -) -> Result<(Coin, Vec), ContractError> { - let total_cost = Coin::new(state.high_bidder_amount.u128(), state.coin_denom.clone()); + let recipient = token_auction_state + .recipient + .unwrap_or(Recipient::from_string(token_auction_state.owner)); - let mut total_tax_amount = Uint128::zero(); + match after_tax_payment { + Funds::Native(native_funds) => { + // Send payment to recipient + resp = resp + .add_submessage(recipient.generate_direct_msg(&deps.as_ref(), vec![native_funds])?) + } + Funds::Cw20(cw20_funds) => { + let cw20_msg = recipient.generate_msg_cw20(&deps.as_ref(), cw20_funds)?; + resp = resp.add_submessage(cw20_msg) + } + } + Ok(resp) +} - let (msgs, _events, remainder) = ADOContract::default().on_funds_transfer( - &deps, - info.sender.to_string(), - Funds::Native(total_cost), - encode_binary(&"")?, +fn execute_authorize_token_contract( + deps: DepsMut, + info: MessageInfo, + token_address: AndrAddr, + expiration: Option, +) -> Result { + let contract = ADOContract::default(); + let addr = token_address.get_raw_address(&deps.as_ref())?; + ensure!( + contract.is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + let permission = if let Some(expiration) = expiration { + Permission::Local(LocalPermission::Whitelisted(Some(expiration))) + } else { + Permission::Local(LocalPermission::Whitelisted(None)) + }; + ADOContract::set_permission( + deps.storage, + SEND_NFT_ACTION, + addr.to_string(), + permission.clone(), )?; - let remaining_amount = remainder.try_get_coin()?; + Ok(Response::default().add_attributes(vec![ + attr("action", "authorize_token_contract"), + attr("token_address", addr), + attr("permission", permission.to_string()), + ])) +} - let tax_amount = get_tax_amount(&msgs, state.high_bidder_amount, remaining_amount.amount); +fn execute_deauthorize_token_contract( + deps: DepsMut, + info: MessageInfo, + token_address: AndrAddr, +) -> Result { + let contract = ADOContract::default(); + let addr = token_address.get_raw_address(&deps.as_ref())?; + ensure!( + contract.is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); - // Calculate total tax - total_tax_amount += tax_amount; + ADOContract::remove_permission(deps.storage, SEND_NFT_ACTION, addr.to_string())?; - let after_tax_payment = Coin { - denom: state.coin_denom, - amount: remaining_amount.amount, - }; - Ok((after_tax_payment, msgs)) + Ok(Response::default().add_attributes(vec![ + attr("action", "deauthorize_token_contract"), + attr("token_address", addr), + ])) +} + +fn purchase_token( + deps: Deps, + _info: &MessageInfo, + state: TokenAuctionState, + action: String, +) -> Result<(Funds, Vec), ContractError> { + if !state.uses_cw20 { + let total_cost = Coin::new(state.high_bidder_amount.u128(), state.coin_denom.clone()); + let transfer_response = ADOContract::default().query_deducted_funds( + deps, + action, + Funds::Native(total_cost.clone()), + )?; + match transfer_response { + Some(transfer_response) => { + let remaining_amount = transfer_response.leftover_funds.try_get_coin()?; + let after_tax_payment = Coin { + denom: state.coin_denom, + amount: remaining_amount.amount, + }; + Ok((Funds::Native(after_tax_payment), transfer_response.msgs)) + } + None => { + let after_tax_payment = Coin { + denom: state.coin_denom, + amount: total_cost.amount, + }; + Ok((Funds::Native(after_tax_payment), vec![])) + } + } + } else { + let total_cost = Cw20Coin { + address: state.coin_denom.clone(), + amount: state.high_bidder_amount, + }; + let transfer_response = ADOContract::default().query_deducted_funds( + deps, + action, + Funds::Cw20(total_cost.clone()), + )?; + match transfer_response { + Some(transfer_response) => { + let remaining_amount = transfer_response.leftover_funds.try_get_cw20_coin()?; + Ok((Funds::Cw20(remaining_amount), transfer_response.msgs)) + } + None => { + let after_tax_payment = Cw20Coin { + address: state.coin_denom, + amount: total_cost.amount, + }; + Ok((Funds::Cw20(after_tax_payment), vec![])) + } + } + } } fn get_existing_token_auction_state( @@ -556,14 +968,6 @@ fn get_existing_token_auction_state( Ok(token_auction_state) } -fn block_to_expiration(block: &BlockInfo, model: Expiration) -> Option { - match model { - Expiration::AtTime(_) => Some(Expiration::AtTime(block.time)), - Expiration::AtHeight(_) => Some(Expiration::AtHeight(block.height)), - Expiration::Never {} => None, - } -} - fn get_and_increment_next_auction_id( storage: &mut dyn Storage, token_id: &str, @@ -627,6 +1031,16 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result encode_binary(&query_is_closed(deps, env, token_id, token_address)?), + QueryMsg::AuthorizedAddresses { + start_after, + limit, + order_by, + } => encode_binary(&query_authorized_addresses( + deps, + start_after, + limit, + order_by, + )?), _ => ADOContract::default().query(deps, env, msg), } } @@ -763,36 +1177,22 @@ fn query_owner_of( Ok(res) } +fn query_authorized_addresses( + deps: Deps, + start_after: Option, + limit: Option, + order_by: Option, +) -> Result { + let addresses = ADOContract::default().query_permissioned_actors( + deps, + SEND_NFT_ACTION, + start_after, + limit, + order_by, + )?; + Ok(AuthorizedAddressesResponse { addresses }) +} #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/mock.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/mock.rs index f85f452..5822b4b 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/mock.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/mock.rs @@ -5,14 +5,21 @@ use andromeda_non_fungible_tokens::auction::{ AuctionIdsResponse, AuctionStateResponse, Bid, BidsResponse, Cw721HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, }; -use andromeda_std::ado_base::modules::Module; +use andromeda_std::ado_base::permissioning::{Permission, PermissioningMessage}; +use andromeda_std::ado_base::rates::{Rate, RatesMessage}; use andromeda_std::amp::messages::AMPPkt; +use andromeda_std::amp::AndrAddr; +use andromeda_std::amp::Recipient; +use andromeda_std::common::denom::Asset; +use andromeda_std::common::expiration::Expiry; +use andromeda_testing::mock::MockApp; use andromeda_testing::{ mock_ado, mock_contract::{ExecuteResult, MockADO, MockContract}, }; use cosmwasm_std::{Addr, Coin, Empty, Uint128}; -use cw_multi_test::{App, AppResponse, Contract, ContractWrapper, Executor}; +use cw20::Cw20ReceiveMsg; +use cw_multi_test::{AppResponse, Contract, ContractWrapper, Executor}; pub struct MockAuction(Addr); mock_ado!(MockAuction, ExecuteMsg, QueryMsg); @@ -21,12 +28,12 @@ impl MockAuction { pub fn instantiate( code_id: u64, sender: Addr, - app: &mut App, - modules: Option>, + app: &mut MockApp, + kernel_address: impl Into, owner: Option, ) -> MockAuction { - let msg = mock_auction_instantiate_msg(modules, kernel_address, owner); + let msg = mock_auction_instantiate_msg(kernel_address, owner, None, None); let addr = app .instantiate_contract( code_id, @@ -43,22 +50,26 @@ impl MockAuction { #[allow(clippy::too_many_arguments)] pub fn execute_start_auction( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, - start_time: u64, - duration: u64, - coin_denom: String, + start_time: Option, + end_time: Expiry, + coin_denom: Asset, min_bid: Option, + min_raise: Option, whitelist: Option>, + recipient: Option, ) -> AppResponse { - let msg = mock_start_auction(start_time, duration, coin_denom, min_bid, whitelist); + let msg = mock_start_auction( + start_time, end_time, coin_denom, min_bid, min_raise, whitelist, recipient, + ); app.execute_contract(sender, self.addr().clone(), &msg, &[]) .unwrap() } pub fn execute_place_bid( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, token_id: String, token_address: String, @@ -71,7 +82,7 @@ impl MockAuction { pub fn execute_claim_auction( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, token_id: String, token_address: String, @@ -80,9 +91,42 @@ impl MockAuction { self.execute(app, &msg, sender, &[]) } + pub fn execute_authorize_token_address( + &self, + app: &mut MockApp, + sender: Addr, + token_address: impl Into, + expiration: Option, + ) -> ExecuteResult { + let msg = mock_authorize_token_address(token_address, expiration); + self.execute(app, &msg, sender, &[]) + } + + pub fn execute_add_rate( + &self, + app: &mut MockApp, + sender: Addr, + action: String, + rate: Rate, + ) -> ExecuteResult { + self.execute(app, &mock_set_rate_msg(action, rate), sender, &[]) + } + + pub fn execute_set_permission( + &self, + app: &mut MockApp, + sender: Addr, + actors: Vec, + action: String, + permission: Permission, + ) -> ExecuteResult { + let msg = mock_set_permission(actors, action, permission); + self.execute(app, &msg, sender, &[]) + } + pub fn query_auction_ids( &self, - app: &mut App, + app: &mut MockApp, token_id: String, token_address: String, ) -> Vec { @@ -91,12 +135,16 @@ impl MockAuction { res.auction_ids } - pub fn query_auction_state(&self, app: &mut App, auction_id: Uint128) -> AuctionStateResponse { + pub fn query_auction_state( + &self, + app: &mut MockApp, + auction_id: Uint128, + ) -> AuctionStateResponse { let msg = mock_get_auction_state(auction_id); self.query(app, msg) } - pub fn query_bids(&self, app: &mut App, auction_id: Uint128) -> Vec { + pub fn query_bids(&self, app: &mut MockApp, auction_id: Uint128) -> Vec { let msg = mock_get_bids(auction_id); let res: BidsResponse = self.query(app, msg); res.bids @@ -109,33 +157,94 @@ pub fn mock_andromeda_auction() -> Box> { } pub fn mock_auction_instantiate_msg( - modules: Option>, kernel_address: impl Into, owner: Option, + authorized_token_addresses: Option>, + authorized_cw20_address: Option, ) -> InstantiateMsg { InstantiateMsg { - modules, kernel_address: kernel_address.into(), owner, + authorized_token_addresses, + authorized_cw20_address, } } pub fn mock_start_auction( - start_time: u64, - duration: u64, - coin_denom: String, + start_time: Option, + end_time: Expiry, + coin_denom: Asset, min_bid: Option, + min_raise: Option, whitelist: Option>, + recipient: Option, ) -> Cw721HookMsg { Cw721HookMsg::StartAuction { start_time, - duration, + end_time, coin_denom, min_bid, + min_raise, whitelist, + recipient, } } +pub fn mock_auction_cw20_receive(msg: Cw20ReceiveMsg) -> ExecuteMsg { + ExecuteMsg::Receive(msg) +} + +pub fn mock_authorize_token_address( + token_address: impl Into, + expiration: Option, +) -> ExecuteMsg { + ExecuteMsg::AuthorizeTokenContract { + addr: AndrAddr::from_string(token_address.into()), + expiration, + } +} + +#[allow(clippy::too_many_arguments)] +pub fn mock_update_auction( + token_id: String, + token_address: String, + start_time: Option, + end_time: Expiry, + coin_denom: Asset, + min_bid: Option, + min_raise: Option, + whitelist: Option>, + recipient: Option, +) -> ExecuteMsg { + ExecuteMsg::UpdateAuction { + token_id, + token_address, + start_time, + end_time, + coin_denom, + whitelist, + min_bid, + min_raise, + recipient, + } +} + +pub fn mock_set_rate_msg(action: String, rate: Rate) -> ExecuteMsg { + ExecuteMsg::Rates(RatesMessage::SetRate { action, rate }) +} + +pub fn mock_set_permission( + actors: Vec, + action: String, + permission: Permission, +) -> ExecuteMsg { + ExecuteMsg::Permissioning(PermissioningMessage::SetPermission { + actors, + action, + permission, + }) +} + pub fn mock_get_auction_ids(token_id: String, token_address: String) -> QueryMsg { QueryMsg::AuctionIds { token_id, diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/state.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/state.rs index 90cad1d..3a1ae18 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/state.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/state.rs @@ -105,35 +105,35 @@ pub fn read_auction_infos( #[cfg(test)] mod tests { use super::*; + use andromeda_std::common::Milliseconds; use cosmwasm_std::testing::mock_dependencies; - use cosmwasm_std::Timestamp; fn get_mock_bids() -> Vec { vec![ Bid { bidder: "0".to_string(), amount: Uint128::zero(), - timestamp: Timestamp::from_seconds(0), + timestamp: Milliseconds::from_nanos(0), }, Bid { bidder: "1".to_string(), amount: Uint128::zero(), - timestamp: Timestamp::from_seconds(0), + timestamp: Milliseconds::from_nanos(0), }, Bid { bidder: "2".to_string(), amount: Uint128::zero(), - timestamp: Timestamp::from_seconds(0), + timestamp: Milliseconds::from_nanos(0), }, Bid { bidder: "3".to_string(), amount: Uint128::zero(), - timestamp: Timestamp::from_seconds(0), + timestamp: Milliseconds::from_nanos(0), }, Bid { bidder: "4".to_string(), amount: Uint128::zero(), - timestamp: Timestamp::from_seconds(0), + timestamp: Milliseconds::from_nanos(0), }, ] } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/mock_querier.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/mock_querier.rs index 8368d52..214e8aa 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/mock_querier.rs @@ -1,26 +1,24 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; use andromeda_std::ado_base::InstantiateMsg; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; + use andromeda_std::testing::mock_querier::MockAndromedaQuerier; +use cosmwasm_schema::cw_serde; + +pub use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; use cosmwasm_std::testing::mock_info; +use cosmwasm_std::{coin, BankQuery, QuerierWrapper}; use cosmwasm_std::{ from_json, testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, WasmQuery, }; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg}; -use cw721::{Cw721QueryMsg, OwnerOfResponse, TokensResponse}; -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; +use cw721::{Cw721QueryMsg, OwnerOfResponse, TokensResponse}; pub const MOCK_TOKEN_CONTRACT: &str = "token_contract"; pub const MOCK_UNCLAIMED_TOKEN: &str = "unclaimed_token"; pub const MOCK_TOKEN_ADDR: &str = "token_addr"; -pub const MOCK_RATES_RECIPIENT: &str = "rates_recipient"; pub const MOCK_TOKEN_OWNER: &str = "owner"; pub const MOCK_TOKENS_FOR_SALE: &[&str] = &[ "token1", "token2", "token3", "token4", "token5", "token6", "token7", @@ -49,11 +47,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "crowdfund".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -84,6 +83,26 @@ impl Querier for WasmMockQuerier { } } +// NOTE: It's impossible to construct a non_exhaustive struct from another another crate, so I copied the struct +// https://rust-lang.github.io/rfcs/2008-non-exhaustive.html#functional-record-updates +#[cw_serde( + Serialize, + Deserialize, + Clone, + Debug, + Default, + PartialEq, + Eq, + JsonSchema +)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub struct SupplyResponse { + /// Always returns a Coin with the requested denom. + /// This will be of zero amount if the denom does not exist. + pub amount: Coin, +} + impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { @@ -91,11 +110,28 @@ impl WasmMockQuerier { match contract_addr.as_str() { MOCK_TOKEN_ADDR => self.handle_token_query(msg), MOCK_TOKEN_CONTRACT => self.handle_token_query(msg), - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } + QueryRequest::Bank(bank_query) => match bank_query { + BankQuery::Supply { denom } => { + let response = SupplyResponse { + amount: coin(1_000_000, denom), + }; + + SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) + } + BankQuery::Balance { + address: _, + denom: _, + } => { + panic!("Unsupported Query") + } + BankQuery::AllBalances { address: _ } => { + panic!("Unsupported Query") + } + _ => panic!("Unsupported Query"), + }, _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } @@ -145,88 +181,6 @@ impl WasmMockQuerier { } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_RATES_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_RATES_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - // SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - // to_address: MOCK_TAX_RECIPIENT.to_owned(), - // amount: vec![Coin { - // // Flat tax of 50 - // amount: Uint128::from(50u128), - // denom: coin.denom.clone(), - // }], - // })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs index 4b15abf..c5a41ef 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-auction/src/testing/tests.rs @@ -5,35 +5,61 @@ use crate::{ mock_dependencies_custom, MOCK_TOKEN_ADDR, MOCK_TOKEN_OWNER, MOCK_UNCLAIMED_TOKEN, }, }; + use andromeda_non_fungible_tokens::{ auction::{ - AuctionInfo, AuctionStateResponse, Cw721HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, - TokenAuctionState, + AuctionInfo, AuctionStateResponse, Cw20HookMsg, Cw721HookMsg, ExecuteMsg, InstantiateMsg, + QueryMsg, TokenAuctionState, }, cw721::ExecuteMsg as Cw721ExecuteMsg, }; use andromeda_std::{ - ado_base::modules::Module, - common::{encode_binary, expiration::MILLISECONDS_TO_NANOSECONDS_RATIO}, + ado_base::{ + modules::Module, + rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}, + }, + ado_contract::ADOContract, + amp::AndrAddr, + common::{ + denom::Asset, + encode_binary, + expiration::{Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}, + reply::ReplyId, + Milliseconds, + }, error::ContractError, + os::economics::ExecuteMsg as EconomicsExecuteMsg, testing::mock_querier::MOCK_KERNEL_CONTRACT, }; +use andromeda_std::{amp::Recipient, testing::mock_querier::MOCK_CW20_CONTRACT}; use cosmwasm_std::{ attr, coin, coins, from_json, testing::{mock_dependencies, mock_env, mock_info}, - Addr, BankMsg, CosmosMsg, Deps, DepsMut, Env, Response, Timestamp, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, Deps, DepsMut, Env, Response, SubMsg, + Timestamp, Uint128, WasmMsg, }; +use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; use cw721::Cw721ReceiveMsg; use cw_utils::Expiration; -// const ADDRESS_LIST: &str = "addresslist"; -// const RATES: &str = "rates"; +fn init(deps: DepsMut) -> Response { + let msg = InstantiateMsg { + owner: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + authorized_token_addresses: Some(vec![AndrAddr::from_string(MOCK_TOKEN_ADDR)]), + authorized_cw20_address: None, + }; + + let info = mock_info("owner", &[]); + instantiate(deps, mock_env(), info, msg).unwrap() +} -fn init(deps: DepsMut, modules: Option>) -> Response { +fn init_cw20(deps: DepsMut, _modules: Option>) -> Response { let msg = InstantiateMsg { owner: None, - modules, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + authorized_token_addresses: Some(vec![AndrAddr::from_string(MOCK_TOKEN_ADDR)]), + authorized_cw20_address: Some(AndrAddr::from_string(MOCK_CW20_CONTRACT)), }; let info = mock_info("owner", &[]); @@ -48,41 +74,135 @@ fn query_latest_auction_state_helper(deps: Deps, env: Env) -> AuctionStateRespon from_json(query(deps, env, query_msg).unwrap()).unwrap() } -fn start_auction(deps: DepsMut, whitelist: Option>, min_bid: Option) { +fn current_time() -> u64 { + mock_env().block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO +} + +fn start_auction( + deps: DepsMut, + whitelist: Option>, + min_bid: Option, + min_raise: Option, +) { let hook_msg = Cw721HookMsg::StartAuction { - start_time: 100000, - duration: 100000, - coin_denom: "uusd".to_string(), + start_time: None, + end_time: Expiry::FromNow(Milliseconds(20_000_000)), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist, min_bid, + min_raise, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), msg: encode_binary(&hook_msg).unwrap(), }); - let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(0u64); + let env = mock_env(); + + let info = mock_info(MOCK_TOKEN_ADDR, &[]); + let _res = execute(deps, env, info, msg).unwrap(); +} + +fn start_auction_cw20( + deps: DepsMut, + whitelist: Option>, + min_bid: Option, + min_raise: Option, +) { + let hook_msg = Cw721HookMsg::StartAuction { + start_time: None, + end_time: Expiry::FromNow(Milliseconds(20_000_000)), + coin_denom: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + whitelist, + min_bid, + min_raise, + recipient: None, + }; + let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { + sender: MOCK_TOKEN_OWNER.to_owned(), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + msg: encode_binary(&hook_msg).unwrap(), + }); + let env = mock_env(); let info = mock_info(MOCK_TOKEN_ADDR, &[]); let _res = execute(deps, env, info, msg).unwrap(); } -fn assert_auction_created(deps: Deps, whitelist: Option>, min_bid: Option) { +fn assert_auction_created( + deps: Deps, + whitelist: Option>, + min_bid: Option, + min_raise: Option, +) { + let current_time = mock_env().block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; + let duration = 20_000_000; assert_eq!( TokenAuctionState { - start_time: Expiration::AtTime(Timestamp::from_seconds(100)), - end_time: Expiration::AtTime(Timestamp::from_seconds(200)), + start_time: Expiration::AtTime(Timestamp::from_nanos((current_time + 1) * 1_000_000)), + end_time: Expiration::AtTime(Timestamp::from_nanos( + (current_time + duration) * 1_000_000 + )), high_bidder_addr: Addr::unchecked(""), high_bidder_amount: Uint128::zero(), coin_denom: "uusd".to_string(), + uses_cw20: false, auction_id: 1u128.into(), + owner: MOCK_TOKEN_OWNER.to_string(), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_owned(), + is_cancelled: false, + min_bid, + min_raise, whitelist, + recipient: None + }, + TOKEN_AUCTION_STATE.load(deps.storage, 1u128).unwrap() + ); + + assert_eq!( + AuctionInfo { + auction_ids: vec![Uint128::from(1u128)], + token_address: MOCK_TOKEN_ADDR.to_owned(), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + }, + auction_infos() + .load( + deps.storage, + &(MOCK_UNCLAIMED_TOKEN.to_owned() + MOCK_TOKEN_ADDR) + ) + .unwrap() + ); +} + +fn assert_auction_created_cw20( + deps: Deps, + whitelist: Option>, + min_bid: Option, + min_raise: Option, +) { + let current_time = mock_env().block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; + let duration = 20_000_000; + assert_eq!( + TokenAuctionState { + start_time: Expiration::AtTime(Timestamp::from_nanos((current_time + 1) * 1_000_000)), + end_time: Expiration::AtTime(Timestamp::from_nanos( + (current_time + duration) * 1_000_000 + )), + high_bidder_addr: Addr::unchecked(""), + high_bidder_amount: Uint128::zero(), + coin_denom: MOCK_CW20_CONTRACT.to_string(), + uses_cw20: true, + auction_id: 1u128.into(), owner: MOCK_TOKEN_OWNER.to_string(), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_owned(), is_cancelled: false, min_bid, + min_raise, + whitelist, + recipient: None }, TOKEN_AUCTION_STATE.load(deps.storage, 1u128).unwrap() ); @@ -105,7 +225,14 @@ fn assert_auction_created(deps: Deps, whitelist: Option>, min_bid: Opt #[test] fn test_auction_instantiate() { let mut deps = mock_dependencies(); - let res = init(deps.as_mut(), None); + let res = init(deps.as_mut()); + assert_eq!(0, res.messages.len()); +} + +#[test] +fn test_auction_instantiate_cw20() { + let mut deps = mock_dependencies(); + let res = init_cw20(deps.as_mut(), None); assert_eq!(0, res.messages.len()); } @@ -113,7 +240,7 @@ fn test_auction_instantiate() { fn test_execute_place_bid_non_existing_auction() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_string(), @@ -128,10 +255,10 @@ fn test_execute_place_bid_non_existing_auction() { fn execute_place_bid_auction_not_started() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -149,17 +276,17 @@ fn execute_place_bid_auction_not_started() { fn execute_place_bid_auction_ended() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - env.block.time = Timestamp::from_seconds(300); + env.block.time = env.block.time.plus_days(1); let info = mock_info("sender", &coins(100, "uusd".to_string())); let res = execute(deps.as_mut(), env, info, msg); @@ -170,39 +297,80 @@ fn execute_place_bid_auction_ended() { fn execute_place_bid_token_owner_cannot_bid() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - - env.block.time = Timestamp::from_seconds(150); - + env.block.time = env.block.time.plus_seconds(1); let info = mock_info(MOCK_TOKEN_OWNER, &coins(100, "uusd".to_string())); let res = execute(deps.as_mut(), env, info, msg); assert_eq!(ContractError::TokenOwnerCannotBid {}, res.unwrap_err()); } +#[test] +fn execute_place_bid_min_raise() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + let _res = init(deps.as_mut()); + + start_auction(deps.as_mut(), None, None, Some(Uint128::new(10))); + assert_auction_created(deps.as_ref(), None, None, Some(Uint128::new(10))); + + let msg = ExecuteMsg::PlaceBid { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + + env.block.time = env.block.time.plus_seconds(1); + + let info = mock_info("sender", &coins(100, "uusd".to_string())); + let _res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap(); + + // Difference is less than 10, which is the minimum raise + let info = mock_info("other_sender", &coins(109, "uusd".to_string())); + let err = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap_err(); + assert_eq!(err, ContractError::MinRaiseUnmet {}); + + // Difference is 10, which meets the minimum raise + let info = mock_info("other_sender", &coins(110, "uusd".to_string())); + let _res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap(); + + // Difference exceeds minimum raise + let info = mock_info("other_other_sender", &coins(200, "uusd".to_string())); + let _res = execute(deps.as_mut(), env, info, msg).unwrap(); +} + #[test] fn execute_place_bid_whitelist() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), Some(vec![Addr::unchecked("sender")]), None); - assert_auction_created(deps.as_ref(), Some(vec![Addr::unchecked("sender")]), None); + start_auction( + deps.as_mut(), + Some(vec![Addr::unchecked("sender")]), + None, + None, + ); + assert_auction_created( + deps.as_ref(), + Some(vec![Addr::unchecked("sender")]), + None, + None, + ); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - env.block.time = Timestamp::from_seconds(150); let info = mock_info("not_sender", &coins(100, "uusd".to_string())); + env.block.time = env.block.time.plus_seconds(1); let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); @@ -210,25 +378,68 @@ fn execute_place_bid_whitelist() { let _res = execute(deps.as_mut(), env, info, msg).unwrap(); } +#[test] +fn execute_place_bid_whitelist_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + let _res = init_cw20(deps.as_mut(), None); + + start_auction_cw20( + deps.as_mut(), + Some(vec![Addr::unchecked("sender")]), + None, + None, + ); + assert_auction_created_cw20( + deps.as_ref(), + Some(vec![Addr::unchecked("sender")]), + None, + None, + ); + + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "sender".to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let invalid_asset = "invalid_asset"; + let info = mock_info(invalid_asset, &coins(100, "uusd".to_string())); + env.block.time = env.block.time.plus_seconds(1); + let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); + assert_eq!( + ContractError::InvalidAsset { + asset: invalid_asset.to_string() + }, + res.unwrap_err() + ); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + let _res = execute(deps.as_mut(), env, info, msg).unwrap(); +} + #[test] fn execute_place_bid_highest_bidder_cannot_outbid() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - env.block.time = Timestamp::from_seconds(150); + env.block.time = env.block.time.plus_seconds(1); let info = mock_info("sender", &coins(100, "uusd".to_string())); let _res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap(); - - env.block.time = Timestamp::from_seconds(160); + env.block.time = env.block.time.plus_seconds(2); let info = mock_info("sender", &coins(200, "uusd".to_string())); let res = execute(deps.as_mut(), env, info, msg); assert_eq!( @@ -241,21 +452,21 @@ fn execute_place_bid_highest_bidder_cannot_outbid() { fn execute_place_bid_bid_smaller_than_highest_bid() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - env.block.time = Timestamp::from_seconds(150); + env.block.time = env.block.time.plus_seconds(1); let info = mock_info("sender", &coins(100, "uusd".to_string())); let _res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap(); - env.block.time = Timestamp::from_seconds(160); + env.block.time = env.block.time.plus_seconds(2); let info = mock_info("other", &coins(50, "uusd".to_string())); let res = execute(deps.as_mut(), env, info, msg); assert_eq!(ContractError::BidSmallerThanHighestBid {}, res.unwrap_err()); @@ -265,20 +476,19 @@ fn execute_place_bid_bid_smaller_than_highest_bid() { fn execute_place_bid_invalid_coins_sent() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); - - env.block.time = Timestamp::from_seconds(150); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let error = ContractError::InvalidFunds { - msg: "Auctions ensure! exactly one coin to be sent.".to_string(), + msg: "One coin should be sent.".to_string(), }; let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_string(), token_address: MOCK_TOKEN_ADDR.to_string(), }; + env.block.time = env.block.time.plus_seconds(1); // No coins sent let info = mock_info("sender", &[]); @@ -309,47 +519,62 @@ fn execute_place_bid_invalid_coins_sent() { fn execute_place_bid_multiple_bids() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - - env.block.time = Timestamp::from_seconds(150); - + env.block.time = env.block.time.plus_seconds(1); let info = mock_info("sender", &coins(100, "uusd".to_string())); let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); assert_eq!( - Response::new().add_attributes(vec![ - attr("action", "bid"), - attr("token_id", MOCK_UNCLAIMED_TOKEN), - attr("bider", info.sender), - attr("amount", "100"), - ]), + Response::new() + .add_attributes(vec![ + attr("action", "bid"), + attr("token_id", MOCK_UNCLAIMED_TOKEN), + attr("bider", info.sender), + attr("amount", "100"), + ]) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("sender"), + action: "PlaceBid".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); let mut expected_response = AuctionStateResponse { - start_time: Expiration::AtTime(Timestamp::from_seconds(100)), - end_time: Expiration::AtTime(Timestamp::from_seconds(200)), + start_time: Expiration::AtTime(Timestamp::from_nanos(1571797419880000000)), + end_time: Expiration::AtTime(Timestamp::from_nanos(1571817419879000000)), high_bidder_addr: "sender".to_string(), high_bidder_amount: Uint128::from(100u128), auction_id: Uint128::from(1u128), coin_denom: "uusd".to_string(), - whitelist: None, + uses_cw20: false, is_cancelled: false, min_bid: None, + min_raise: None, + whitelist: None, owner: "owner".to_string(), + recipient: None, }; let res = query_latest_auction_state_helper(deps.as_ref(), env.clone()); assert_eq!(expected_response, res); - env.block.time = Timestamp::from_seconds(160); + env.block.time = env.block.time.plus_seconds(2); let info = mock_info("other", &coins(200, "uusd".to_string())); let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); assert_eq!( @@ -363,7 +588,20 @@ fn execute_place_bid_multiple_bids() { attr("token_id", MOCK_UNCLAIMED_TOKEN), attr("bider", info.sender), attr("amount", "200"), - ]), + ]) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("other"), + action: "PlaceBid".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); @@ -372,7 +610,7 @@ fn execute_place_bid_multiple_bids() { let res = query_latest_auction_state_helper(deps.as_ref(), env.clone()); assert_eq!(expected_response, res); - env.block.time = Timestamp::from_seconds(170); + env.block.time = env.block.time.plus_seconds(3); let info = mock_info("sender", &coins(250, "uusd".to_string())); let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); @@ -387,7 +625,20 @@ fn execute_place_bid_multiple_bids() { attr("token_id", MOCK_UNCLAIMED_TOKEN), attr("bider", info.sender), attr("amount", "250"), - ]), + ]) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("sender"), + action: "PlaceBid".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); @@ -400,18 +651,17 @@ fn execute_place_bid_multiple_bids() { #[test] fn execute_place_bid_auction_cancelled() { let mut deps = mock_dependencies_custom(&[]); - let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let env = mock_env(); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); - assert_auction_created(deps.as_ref(), None, None); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); let msg = ExecuteMsg::CancelAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - env.block.time = Timestamp::from_seconds(150); let info = mock_info(MOCK_TOKEN_OWNER, &[]); let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); @@ -428,38 +678,17 @@ fn execute_place_bid_auction_cancelled() { #[test] fn test_execute_start_auction() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); - - let hook_msg = Cw721HookMsg::StartAuction { - start_time: 100000, - duration: 100000, - coin_denom: "uusd".to_string(), - whitelist: None, - min_bid: None, - }; - let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { - sender: MOCK_TOKEN_OWNER.to_owned(), - token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), - msg: encode_binary(&hook_msg).unwrap(), - }); - let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(0u64); - - let info = mock_info(MOCK_TOKEN_ADDR, &[]); - let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let _res = init(deps.as_mut()); + start_auction(deps.as_mut(), None, None, None); + assert_auction_created(deps.as_ref(), None, None, None); +} - assert_eq!( - res, - Response::new().add_attributes(vec![ - attr("action", "start_auction"), - attr("start_time", "expiration time: 100.000000000"), - attr("end_time", "expiration time: 200.000000000"), - attr("coin_denom", "uusd"), - attr("auction_id", "1"), - attr("whitelist", "None"), - ]), - ); - assert_auction_created(deps.as_ref(), None, None); +#[test] +fn test_execute_start_auction_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let _res = init_cw20(deps.as_mut(), None); + start_auction_cw20(deps.as_mut(), None, None, None); + assert_auction_created_cw20(deps.as_ref(), None, None, None); } // #[test] @@ -467,7 +696,7 @@ fn test_execute_start_auction() { // let mut deps = mock_dependencies_custom(&[]); // let env = mock_env(); // let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { modules: None, kernel_address: None }; +// let msg = InstantiateMsg { kernel_address: None }; // let _res = instantiate(deps.as_mut(), env, &info, msg).unwrap(); // let hook_msg = Cw721HookMsg::StartAuction { @@ -506,7 +735,7 @@ fn test_execute_start_auction() { // let mut deps = mock_dependencies_custom(&[]); // let env = mock_env(); // let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { modules: None, kernel_address: None }; +// let msg = InstantiateMsg { kernel_address: None }; // let _res = instantiate(deps.as_mut(), env, &info, msg).unwrap(); // let hook_msg = Cw721HookMsg::StartAuction { @@ -536,22 +765,23 @@ fn test_execute_start_auction() { #[test] fn execute_start_auction_start_time_in_past() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); let hook_msg = Cw721HookMsg::StartAuction { - start_time: 100000, - duration: 100000, - coin_denom: "uusd".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds(100000))), + end_time: Expiry::AtTime(Milliseconds(100000)), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: None, min_bid: None, + min_raise: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), msg: encode_binary(&hook_msg).unwrap(), }); - let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(150); + let env = mock_env(); let info = mock_info(MOCK_TOKEN_ADDR, &[]); let res = execute(deps.as_mut(), env.clone(), info, msg); @@ -568,40 +798,75 @@ fn execute_start_auction_start_time_in_past() { #[test] fn execute_start_auction_zero_start_time() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); let hook_msg = Cw721HookMsg::StartAuction { - start_time: 0, - duration: 1, - coin_denom: "uusd".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds::zero())), + end_time: Expiry::AtTime(Milliseconds(1)), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: None, min_bid: None, + min_raise: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), msg: encode_binary(&hook_msg).unwrap(), }); - let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(0); let info = mock_info(MOCK_TOKEN_ADDR, &[]); - let res = execute(deps.as_mut(), env, info, msg); + let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::InvalidExpiration {}, res.unwrap_err()); + assert_eq!( + ContractError::StartTimeInThePast { + current_time: 1571797419879, + current_block: 12345 + }, + res.unwrap_err() + ); +} + +#[test] +fn execute_start_auction_start_time_not_provided() { + let mut deps = mock_dependencies_custom(&[]); + let _res = init(deps.as_mut()); + + let hook_msg = Cw721HookMsg::StartAuction { + start_time: None, + end_time: Expiry::AtTime(Milliseconds::from_nanos( + (current_time() + 20_000_000) * 1_000_000, + )), + coin_denom: Asset::NativeToken("uusd".to_string()), + whitelist: None, + min_bid: None, + min_raise: None, + recipient: None, + }; + let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { + sender: MOCK_TOKEN_OWNER.to_owned(), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_TOKEN_ADDR, &[]); + let res = execute(deps.as_mut(), mock_env(), info, msg); + assert!(res.is_ok()) } #[test] fn execute_start_auction_zero_duration() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); let hook_msg = Cw721HookMsg::StartAuction { - start_time: 100, - duration: 0, - coin_denom: "uusd".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds(100))), + end_time: Expiry::AtTime(Milliseconds::zero()), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: None, min_bid: None, + min_raise: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), @@ -622,7 +887,7 @@ fn execute_start_auction_zero_duration() { // let mut deps = mock_dependencies_custom(&[]); // let env = mock_env(); // let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { modules: None, kernel_address: None }; +// let msg = InstantiateMsg { kernel_address: None }; // let _res = instantiate(deps.as_mut(), env, &info, msg).unwrap(); // let hook_msg = Cw721HookMsg::StartAuction { @@ -649,56 +914,31 @@ fn execute_start_auction_zero_duration() { #[test] fn execute_update_auction_zero_start() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::UpdateAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), - start_time: 0, - duration: 1, - coin_denom: "uusd".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds::zero())), + end_time: Expiry::AtTime(Milliseconds(1)), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: None, min_bid: None, + min_raise: None, + recipient: None, }; let mut env = mock_env(); - env.block.height = 0; - env.block.time = Timestamp::from_seconds(0); + env.block.time = env.block.time.minus_days(1); let info = mock_info(MOCK_TOKEN_OWNER, &[]); let res = execute(deps.as_mut(), env, info, msg); - assert_eq!(ContractError::InvalidExpiration {}, res.unwrap_err()); -} - -#[test] -fn execute_update_auction_start_time_in_past() { - let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); - - start_auction(deps.as_mut(), None, None); - - let msg = ExecuteMsg::UpdateAuction { - token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), - token_address: MOCK_TOKEN_ADDR.to_string(), - start_time: 1, - duration: 1, - coin_denom: "uusd".to_string(), - whitelist: None, - min_bid: None, - }; - let mut env = mock_env(); - env.block.height = 150; - env.block.time = Timestamp::from_seconds(10); - - let info = mock_info(MOCK_TOKEN_OWNER, &[]); - let res = execute(deps.as_mut(), env.clone(), info, msg); - assert_eq!( ContractError::StartTimeInThePast { - current_time: env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO, - current_block: env.block.height, + current_time: 1571711019879, + current_block: 12345 }, res.unwrap_err() ); @@ -707,18 +947,20 @@ fn execute_update_auction_start_time_in_past() { #[test] fn execute_update_auction_zero_duration() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::UpdateAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), - start_time: 100000, - duration: 0, - coin_denom: "uusd".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds(100000))), + end_time: Expiry::AtTime(Milliseconds::zero()), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: None, min_bid: None, + min_raise: None, + recipient: None, }; let mut env = mock_env(); env.block.time = Timestamp::from_seconds(0); @@ -732,22 +974,22 @@ fn execute_update_auction_zero_duration() { #[test] fn execute_update_auction_unauthorized() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::UpdateAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), - start_time: 100000, - duration: 100, - coin_denom: "uluna".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds(100000))), + end_time: Expiry::AtTime(Milliseconds(100)), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: Some(vec![Addr::unchecked("user")]), min_bid: None, + min_raise: None, + recipient: None, }; - let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(150); - env.block.height = 0; + let env = mock_env(); let info = mock_info("not_owner", &[]); let res = execute(deps.as_mut(), env, info, msg); @@ -757,24 +999,26 @@ fn execute_update_auction_unauthorized() { #[test] fn execute_update_auction_auction_started() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::UpdateAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), - start_time: 100000, - duration: 100, - coin_denom: "uluna".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds(100000))), + end_time: Expiry::AtTime(Milliseconds(100)), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: Some(vec![Addr::unchecked("user")]), min_bid: None, + min_raise: None, + recipient: None, }; let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(150); - env.block.height = 0; let info = mock_info(MOCK_TOKEN_OWNER, &[]); + env.block.time = env.block.time.plus_days(1); + let res = execute(deps.as_mut(), env, info, msg); assert_eq!(ContractError::AuctionAlreadyStarted {}, res.unwrap_err()); } @@ -782,39 +1026,44 @@ fn execute_update_auction_auction_started() { #[test] fn execute_update_auction() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::UpdateAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), - start_time: 100000, - duration: 100000, - coin_denom: "uluna".to_string(), + start_time: Some(Expiry::AtTime(Milliseconds(1571711019879 + 1))), + end_time: Expiry::AtTime(Milliseconds(1571711019879 + 2)), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: Some(vec![Addr::unchecked("user")]), min_bid: None, + min_raise: None, + recipient: None, }; let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(0); - env.block.height = 0; + + env.block.time = env.block.time.minus_days(1); let info = mock_info(MOCK_TOKEN_OWNER, &[]); let _res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( TokenAuctionState { - start_time: Expiration::AtTime(Timestamp::from_seconds(100)), - end_time: Expiration::AtTime(Timestamp::from_seconds(200)), + start_time: Expiration::AtTime(Timestamp::from_nanos(1571711019880000000)), + end_time: Expiration::AtTime(Timestamp::from_nanos(1571711019881000000)), high_bidder_addr: Addr::unchecked(""), high_bidder_amount: Uint128::zero(), - coin_denom: "uluna".to_string(), + coin_denom: "uusd".to_string(), + uses_cw20: false, auction_id: 1u128.into(), - whitelist: Some(vec![Addr::unchecked("user")]), owner: MOCK_TOKEN_OWNER.to_string(), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_owned(), is_cancelled: false, min_bid: None, + min_raise: None, + whitelist: Some(vec![Addr::unchecked("user")]), + recipient: None, }, TOKEN_AUCTION_STATE .load(deps.as_ref().storage, 1u128) @@ -825,17 +1074,21 @@ fn execute_update_auction() { #[test] fn execute_start_auction_after_previous_finished() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); // There was a previous auction. - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let hook_msg = Cw721HookMsg::StartAuction { - start_time: 300000, - duration: 100000, - coin_denom: "uusd".to_string(), + start_time: None, + end_time: Expiry::AtTime(Milliseconds::from_nanos( + (current_time() + 20_000_000) * 1_000_000, + )), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: None, min_bid: None, + min_raise: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), @@ -843,32 +1096,47 @@ fn execute_start_auction_after_previous_finished() { msg: encode_binary(&hook_msg).unwrap(), }); let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(250); + // Auction ended by that time + env.block.time = env.block.time.plus_hours(1); let info = mock_info(MOCK_TOKEN_ADDR, &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::new().add_attributes(vec![ - attr("action", "start_auction"), - attr("start_time", "expiration time: 300.000000000"), - attr("end_time", "expiration time: 400.000000000"), - attr("coin_denom", "uusd"), - attr("auction_id", "2"), - attr("whitelist", "None"), - ]), + Response::new() + .add_attributes(vec![ + attr("action", "start_auction"), + attr("start_time", "expiration time: 1571801019.880000000"), + attr("end_time", "expiration time: 1571817419.879000000"), + attr("coin_denom", "uusd"), + attr("auction_id", "2"), + attr("whitelist", "None"), + ]) // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_TOKEN_ADDR), + action: "ReceiveNft".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); } -//TODO make execute_claim tests pass + #[test] fn execute_claim_no_bids() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); - env.block.time = Timestamp::from_seconds(250); + // Auction ended by that time + env.block.time = env.block.time.plus_days(1); let msg = ExecuteMsg::Claim { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -882,7 +1150,7 @@ fn execute_claim_no_bids() { .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_TOKEN_ADDR.to_owned(), msg: encode_binary(&Cw721ExecuteMsg::TransferNft { - recipient: MOCK_TOKEN_OWNER.to_owned(), + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), }) .unwrap(), @@ -893,30 +1161,113 @@ fn execute_claim_no_bids() { .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", MOCK_TOKEN_OWNER) .add_attribute("winning_bid_amount", Uint128::zero()) - .add_attribute("auction_id", "1"), + .add_attribute("auction_id", "1") + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("any_user"), + action: "Claim".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); } #[test] -fn execute_claim() { +fn execute_claim_no_bids_cw20() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init_cw20(deps.as_mut(), None); - start_auction(deps.as_mut(), None, None); + start_auction_cw20(deps.as_mut(), None, None, None); - let msg = ExecuteMsg::PlaceBid { + // Auction ended by that time + env.block.time = env.block.time.plus_days(1); + + let msg = ExecuteMsg::Claim { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - env.block.time = Timestamp::from_seconds(150); + let info = mock_info("any_user", &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + assert_eq!( + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_owned(), + msg: encode_binary(&Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + }) + .unwrap(), + funds: vec![], + })) + .add_attribute("action", "claim") + .add_attribute("token_id", MOCK_UNCLAIMED_TOKEN) + .add_attribute("token_contract", MOCK_TOKEN_ADDR) + .add_attribute("recipient", MOCK_TOKEN_OWNER) + .add_attribute("winning_bid_amount", Uint128::zero()) + .add_attribute("auction_id", "1") + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("any_user"), + action: "Claim".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), + res + ); +} + +#[test] +fn execute_claim_with_tax() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + let _res = init(deps.as_mut()); + let tax_recipient = "tax_recipient"; + + let rate: Rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string(tax_recipient.to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(20_u128, "uusd")), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Claim", rate) + .unwrap(); + + start_auction(deps.as_mut(), None, None, None); + + let msg = ExecuteMsg::PlaceBid { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; let info = mock_info("sender", &coins(100, "uusd".to_string())); + env.block.time = env.block.time.plus_seconds(1); + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - env.block.time = Timestamp::from_seconds(250); + // Auction ended by that time + env.block.time = env.block.time.plus_days(1); let msg = ExecuteMsg::Claim { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -926,26 +1277,309 @@ fn execute_claim() { let info = mock_info("any_user", &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); let transfer_nft_msg = Cw721ExecuteMsg::TransferNft { - recipient: "sender".to_string(), + recipient: AndrAddr::from_string("sender".to_string()), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), }; assert_eq!( Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_string(), + msg: encode_binary(&transfer_nft_msg).unwrap(), + funds: vec![], + })) + .add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: tax_recipient.to_owned(), + amount: coins(20, "uusd"), + })) .add_message(CosmosMsg::Bank(BankMsg::Send { to_address: MOCK_TOKEN_OWNER.to_owned(), amount: coins(100, "uusd"), })) + .add_attribute("action", "claim") + .add_attribute("token_id", MOCK_UNCLAIMED_TOKEN) + .add_attribute("token_contract", MOCK_TOKEN_ADDR) + .add_attribute("recipient", "sender") + .add_attribute("winning_bid_amount", Uint128::from(100u128)) + .add_attribute("auction_id", "1") + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("any_user"), + action: "Claim".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), + res + ); +} + +#[test] +fn execute_claim_with_royalty() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + let _res = init(deps.as_mut()); + let royalty_recipient = "royalty_recipient"; + + let rate: Rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Deductive, + recipients: vec![Recipient { + address: AndrAddr::from_string(royalty_recipient.to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(20_u128, "uusd")), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Claim", rate) + .unwrap(); + + start_auction(deps.as_mut(), None, None, None); + + let msg = ExecuteMsg::PlaceBid { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + + let info = mock_info("sender", &coins(100, "uusd".to_string())); + env.block.time = env.block.time.plus_seconds(1); + + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // Auction ended by that time + env.block.time = env.block.time.plus_days(1); + + let msg = ExecuteMsg::Claim { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + + let info = mock_info("any_user", &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let transfer_nft_msg = Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string("sender".to_string()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + }; + assert_eq!( + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_string(), + msg: encode_binary(&transfer_nft_msg).unwrap(), + funds: vec![], + })) + .add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: royalty_recipient.to_owned(), + amount: coins(20, "uusd"), + })) + .add_message(CosmosMsg::Bank(BankMsg::Send { + to_address: MOCK_TOKEN_OWNER.to_owned(), + amount: coins(80, "uusd"), + })) + .add_attribute("action", "claim") + .add_attribute("token_id", MOCK_UNCLAIMED_TOKEN) + .add_attribute("token_contract", MOCK_TOKEN_ADDR) + .add_attribute("recipient", "sender") + .add_attribute("winning_bid_amount", Uint128::from(100u128)) + .add_attribute("auction_id", "1") + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("any_user"), + action: "Claim".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), + res + ); +} + +#[test] +fn execute_claim_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + let _res = init_cw20(deps.as_mut(), None); + + start_auction_cw20(deps.as_mut(), None, None, None); + + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "sender".to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + env.block.time = env.block.time.plus_seconds(1); + + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // Auction ended by that time + env.block.time = env.block.time.plus_days(1); + + let msg = ExecuteMsg::Claim { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + + let info = mock_info("any_user", &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let transfer_nft_msg = Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string("sender".to_string()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + }; + assert_eq!( + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_string(), + msg: encode_binary(&transfer_nft_msg).unwrap(), + funds: vec![], + })) + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_CW20_CONTRACT.to_string(), + msg: encode_binary(&Cw20ExecuteMsg::Transfer { + recipient: MOCK_TOKEN_OWNER.to_owned(), + amount: Uint128::new(100) + }) + .unwrap(), + funds: vec![] + })) + .add_attribute("action", "claim") + .add_attribute("token_id", MOCK_UNCLAIMED_TOKEN) + .add_attribute("token_contract", MOCK_TOKEN_ADDR) + .add_attribute("recipient", "sender") + .add_attribute("winning_bid_amount", Uint128::from(100u128)) + .add_attribute("auction_id", "1") + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("any_user"), + action: "Claim".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), + res + ); +} + +#[test] +fn execute_claim_cw20_with_tax() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + let _res = init_cw20(deps.as_mut(), None); + let tax_recipient = "tax_recipient"; + let rate: Rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string(tax_recipient.to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(20), + }), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Claim", rate) + .unwrap(); + + start_auction_cw20(deps.as_mut(), None, None, None); + + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "sender".to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + env.block.time = env.block.time.plus_seconds(1); + + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + + // Auction ended by that time + env.block.time = env.block.time.plus_days(1); + + let msg = ExecuteMsg::Claim { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + + let info = mock_info("any_user", &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + let transfer_nft_msg = Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string("sender".to_string()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + }; + assert_eq!( + Response::new() .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_TOKEN_ADDR.to_string(), msg: encode_binary(&transfer_nft_msg).unwrap(), funds: vec![], })) + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_CW20_CONTRACT.to_string(), + msg: encode_binary(&Cw20ExecuteMsg::Transfer { + recipient: tax_recipient.to_owned(), + amount: Uint128::new(20) + }) + .unwrap(), + funds: vec![] + })) + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_CW20_CONTRACT.to_string(), + msg: encode_binary(&Cw20ExecuteMsg::Transfer { + recipient: MOCK_TOKEN_OWNER.to_owned(), + amount: Uint128::new(100) + }) + .unwrap(), + funds: vec![] + })) .add_attribute("action", "claim") .add_attribute("token_id", MOCK_UNCLAIMED_TOKEN) .add_attribute("token_contract", MOCK_TOKEN_ADDR) .add_attribute("recipient", "sender") .add_attribute("winning_bid_amount", Uint128::from(100u128)) - .add_attribute("auction_id", "1"), + .add_attribute("auction_id", "1") + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("any_user"), + action: "Claim".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); } @@ -954,18 +1588,18 @@ fn execute_claim() { fn execute_claim_auction_not_ended() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - env.block.time = Timestamp::from_seconds(150); - let info = mock_info("sender", &coins(100, "uusd".to_string())); + env.block.time = env.block.time.plus_seconds(1); + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let msg = ExecuteMsg::Claim { @@ -981,14 +1615,18 @@ fn execute_claim_auction_not_ended() { #[test] fn execute_claim_auction_already_claimed() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); let hook_msg = Cw721HookMsg::StartAuction { - start_time: 100000, - duration: 100000, - coin_denom: "uusd".to_string(), + start_time: None, + end_time: Expiry::AtTime(Milliseconds::from_nanos( + (current_time() + 20_000_000) * 1_000_000, + )), + coin_denom: Asset::NativeToken("uusd".to_string()), whitelist: None, min_bid: None, + min_raise: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), @@ -996,13 +1634,12 @@ fn execute_claim_auction_already_claimed() { msg: encode_binary(&hook_msg).unwrap(), }); let mut env = mock_env(); - env.block.time = Timestamp::from_seconds(0u64); let info = mock_info(MOCK_TOKEN_ADDR, &[]); let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); // Auction is over. - env.block.time = Timestamp::from_seconds(300); + env.block.time = env.block.time.plus_days(1); let msg = ExecuteMsg::Claim { token_id: "claimed_token".to_string(), @@ -1017,32 +1654,94 @@ fn execute_claim_auction_already_claimed() { #[test] fn execute_cancel_no_bids() { let mut deps = mock_dependencies_custom(&[]); - let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let env = mock_env(); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::CancelAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - // Auction start and end are 100 and 200. - env.block.time = Timestamp::from_seconds(150); + let info = mock_info(MOCK_TOKEN_OWNER, &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_owned(), + msg: encode_binary(&Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned() + }) + .unwrap(), + funds: vec![], + })) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("owner"), + action: "CancelAuction".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), + res + ); + + assert!( + TOKEN_AUCTION_STATE + .load(deps.as_ref().storage, 1u128) + .unwrap() + .is_cancelled + ); +} + +#[test] +fn execute_cancel_no_bids_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res = init_cw20(deps.as_mut(), None); + + start_auction_cw20(deps.as_mut(), None, None, None); + + let msg = ExecuteMsg::CancelAuction { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; let info = mock_info(MOCK_TOKEN_OWNER, &[]); let res = execute(deps.as_mut(), env, info, msg).unwrap(); assert_eq!( - Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_ADDR.to_owned(), - msg: encode_binary(&Cw721ExecuteMsg::TransferNft { - recipient: MOCK_TOKEN_OWNER.to_owned(), - token_id: MOCK_UNCLAIMED_TOKEN.to_owned() - }) - .unwrap(), - funds: vec![], - })), + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_owned(), + msg: encode_binary(&Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned() + }) + .unwrap(), + funds: vec![], + })) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("owner"), + action: "CancelAuction".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); @@ -1058,18 +1757,18 @@ fn execute_cancel_no_bids() { fn execute_cancel_with_bids() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - // Auction start and end are 100 and 200. - env.block.time = Timestamp::from_seconds(150); let info = mock_info("bidder", &coins(100, "uusd")); + env.block.time = env.block.time.plus_seconds(1); + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let msg = ExecuteMsg::CancelAuction { @@ -1085,7 +1784,7 @@ fn execute_cancel_with_bids() { .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_TOKEN_ADDR.to_owned(), msg: encode_binary(&Cw721ExecuteMsg::TransferNft { - recipient: MOCK_TOKEN_OWNER.to_owned(), + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), token_id: MOCK_UNCLAIMED_TOKEN.to_owned() }) .unwrap(), @@ -1094,7 +1793,20 @@ fn execute_cancel_with_bids() { .add_message(CosmosMsg::Bank(BankMsg::Send { to_address: "bidder".to_string(), amount: coins(100, "uusd") - })), + })) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("owner"), + action: "CancelAuction".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), res ); @@ -1107,20 +1819,97 @@ fn execute_cancel_with_bids() { } #[test] -fn execute_cancel_not_token_owner() { +fn execute_cancel_with_bids_cw20() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init_cw20(deps.as_mut(), None); - start_auction(deps.as_mut(), None, None); + start_auction_cw20(deps.as_mut(), None, None, None); + + // let msg = ExecuteMsg::PlaceBid { + // token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + // token_address: MOCK_TOKEN_ADDR.to_string(), + // }; + + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "bidder".to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + env.block.time = env.block.time.plus_seconds(1); + + let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let msg = ExecuteMsg::CancelAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - // Auction start and end are 100 and 200. - env.block.time = Timestamp::from_seconds(150); + let info = mock_info(MOCK_TOKEN_OWNER, &[]); + let res = execute(deps.as_mut(), env, info, msg).unwrap(); + + assert_eq!( + Response::new() + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_TOKEN_ADDR.to_owned(), + msg: encode_binary(&Cw721ExecuteMsg::TransferNft { + recipient: AndrAddr::from_string(MOCK_TOKEN_OWNER.to_owned()), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned() + }) + .unwrap(), + funds: vec![], + })) + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: MOCK_CW20_CONTRACT.to_string(), + msg: encode_binary(&Cw20ExecuteMsg::Transfer { + recipient: "bidder".to_owned(), + amount: Uint128::new(100) + }) + .unwrap(), + funds: vec![] + })) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("owner"), + action: "CancelAuction".to_string() + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + )), + res + ); + + assert!( + TOKEN_AUCTION_STATE + .load(deps.as_ref().storage, 1u128) + .unwrap() + .is_cancelled + ); +} + +#[test] +fn execute_cancel_not_token_owner() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let _res = init(deps.as_mut()); + + start_auction(deps.as_mut(), None, None, None); + + let msg = ExecuteMsg::CancelAuction { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; let info = mock_info("anyone", &[]); let res = execute(deps.as_mut(), env, info, msg); @@ -1131,17 +1920,16 @@ fn execute_cancel_not_token_owner() { fn execute_cancel_auction_ended() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, None); + start_auction(deps.as_mut(), None, None, None); let msg = ExecuteMsg::CancelAuction { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - // Auction start and end are 100 and 200. - env.block.time = Timestamp::from_seconds(300); + env.block.time = env.block.time.plus_days(1); let info = mock_info(MOCK_TOKEN_OWNER, &[]); let res = execute(deps.as_mut(), env, info, msg); @@ -1152,18 +1940,17 @@ fn execute_cancel_auction_ended() { fn execute_bid_below_min_price() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut()); - start_auction(deps.as_mut(), None, Some(Uint128::from(100u128))); + start_auction(deps.as_mut(), None, Some(Uint128::from(100u128)), None); let msg = ExecuteMsg::PlaceBid { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - // Auction start and end are 100 and 200. - env.block.time = Timestamp::from_seconds(150); let info = mock_info("bidder", &coins(10, "uusd")); + env.block.time = env.block.time.plus_seconds(1); let res = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap_err(); assert_eq!( diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/Cargo.toml b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/Cargo.toml index 4d87e54..6032110 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/Cargo.toml +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-crowdfund" -version = "0.2.1" +version = "2.0.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -21,15 +21,14 @@ cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw721 = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } +cw20 = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true, features = ["rates"] } andromeda-non-fungible-tokens = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } -andromeda-testing = { workspace = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/README.md b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/README.md new file mode 100644 index 0000000..d7b3342 --- /dev/null +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/README.md @@ -0,0 +1,6 @@ +# Overview + +The Crowdfund ADO is a smart contract that allows users to start a campaign and raise funds for their projects/goal by selling NFTs. +Each campaign can contain multiple tiers for different levels of support. For example you could have a bronze, silver, and gold tier for your crowdfund each having a specified price. All NFTs of the same tier share the same metadata. + +**Note**: This ADO is not released yet. Once released, a link to full documentation will be provided. \ No newline at end of file diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/andromeda-crowdfund.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/andromeda-crowdfund.json deleted file mode 100644 index cc15de6..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/andromeda-crowdfund.json +++ /dev/null @@ -1,2033 +0,0 @@ -{ - "contract_name": "andromeda-crowdfund", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "can_mint_after_sale", - "kernel_address", - "token_address" - ], - "properties": { - "can_mint_after_sale": { - "type": "boolean" - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Mints a new token to be sold in a future sale. Only possible when the sale is not ongoing.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "array", - "items": { - "$ref": "#/definitions/CrowdfundMintMsg" - } - } - }, - "additionalProperties": false - }, - { - "description": "Starts the sale if one is not already ongoing.", - "type": "object", - "required": [ - "start_sale" - ], - "properties": { - "start_sale": { - "type": "object", - "required": [ - "expiration", - "min_tokens_sold", - "price", - "recipient" - ], - "properties": { - "expiration": { - "description": "When the sale ends.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "max_amount_per_wallet": { - "description": "The amount of tokens a wallet can purchase, default is 1.", - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "min_tokens_sold": { - "description": "The minimum amount of tokens sold to go through with the sale.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "price": { - "description": "The price per token.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "recipient": { - "description": "The recipient of the funds if the sale met the minimum sold.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Puchases tokens in an ongoing sale.", - "type": "object", - "required": [ - "purchase" - ], - "properties": { - "purchase": { - "type": "object", - "properties": { - "number_of_tokens": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Purchases the token with the given id.", - "type": "object", - "required": [ - "purchase_by_token_id" - ], - "properties": { - "purchase_by_token_id": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Allow a user to claim their own refund if the minimum number of tokens are not sold.", - "type": "object", - "required": [ - "claim_refund" - ], - "properties": { - "claim_refund": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Ends the ongoing sale by completing `limit` number of operations depending on if the minimum number of tokens was sold.", - "type": "object", - "required": [ - "end_sale" - ], - "properties": { - "end_sale": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CrowdfundMintMsg": { - "type": "object", - "required": [ - "extension", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": [ - "string", - "null" - ] - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "state" - ], - "properties": { - "state": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "available_tokens" - ], - "properties": { - "available_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_token_available" - ], - "properties": { - "is_token_available": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "available_tokens": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "config": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "type": "object", - "required": [ - "can_mint_after_sale", - "token_address" - ], - "properties": { - "can_mint_after_sale": { - "description": "Whether or not the owner can mint additional tokens after the sale has been conducted.", - "type": "boolean" - }, - "token_address": { - "description": "The address of the token contract whose tokens are being sold.", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_token_available": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsTokenAvailableResponse", - "type": "object", - "required": [ - "is_token_available" - ], - "properties": { - "is_token_available": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "state": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "State", - "type": "object", - "required": [ - "amount_sold", - "amount_to_send", - "amount_transferred", - "expiration", - "max_amount_per_wallet", - "min_tokens_sold", - "price", - "recipient" - ], - "properties": { - "amount_sold": { - "description": "Number of tokens sold.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_to_send": { - "description": "The amount of funds to send to recipient if sale successful. This already takes into account the royalties and taxes.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_transferred": { - "description": "Number of tokens transferred to purchasers if sale was successful.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "expiration": { - "description": "The expiration denoting when the sale ends.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "max_amount_per_wallet": { - "description": "The max number of tokens allowed per wallet.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "min_tokens_sold": { - "description": "The minimum number of tokens sold for the sale to go through.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "price": { - "description": "The price of each token.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "recipient": { - "description": "The recipient of the raised funds if the sale is successful.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/execute.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/execute.json deleted file mode 100644 index 62415af..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/execute.json +++ /dev/null @@ -1,852 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Mints a new token to be sold in a future sale. Only possible when the sale is not ongoing.", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "array", - "items": { - "$ref": "#/definitions/CrowdfundMintMsg" - } - } - }, - "additionalProperties": false - }, - { - "description": "Starts the sale if one is not already ongoing.", - "type": "object", - "required": [ - "start_sale" - ], - "properties": { - "start_sale": { - "type": "object", - "required": [ - "expiration", - "min_tokens_sold", - "price", - "recipient" - ], - "properties": { - "expiration": { - "description": "When the sale ends.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "max_amount_per_wallet": { - "description": "The amount of tokens a wallet can purchase, default is 1.", - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "min_tokens_sold": { - "description": "The minimum amount of tokens sold to go through with the sale.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "price": { - "description": "The price per token.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "recipient": { - "description": "The recipient of the funds if the sale met the minimum sold.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Puchases tokens in an ongoing sale.", - "type": "object", - "required": [ - "purchase" - ], - "properties": { - "purchase": { - "type": "object", - "properties": { - "number_of_tokens": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Purchases the token with the given id.", - "type": "object", - "required": [ - "purchase_by_token_id" - ], - "properties": { - "purchase_by_token_id": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Allow a user to claim their own refund if the minimum number of tokens are not sold.", - "type": "object", - "required": [ - "claim_refund" - ], - "properties": { - "claim_refund": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Ends the ongoing sale by completing `limit` number of operations depending on if the minimum number of tokens was sold.", - "type": "object", - "required": [ - "end_sale" - ], - "properties": { - "end_sale": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "CrowdfundMintMsg": { - "type": "object", - "required": [ - "extension", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": [ - "string", - "null" - ] - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/instantiate.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/instantiate.json deleted file mode 100644 index 9a8d203..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/instantiate.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "can_mint_after_sale", - "kernel_address", - "token_address" - ], - "properties": { - "can_mint_after_sale": { - "type": "boolean" - }, - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/query.json deleted file mode 100644 index f3ade56..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/query.json +++ /dev/null @@ -1,473 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "state" - ], - "properties": { - "state": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "config" - ], - "properties": { - "config": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "available_tokens" - ], - "properties": { - "available_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_token_available" - ], - "properties": { - "is_token_available": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_available_tokens.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_available_tokens.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_available_tokens.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_balance.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_config.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_config.json deleted file mode 100644 index ccacf9e..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_config.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Config", - "type": "object", - "required": [ - "can_mint_after_sale", - "token_address" - ], - "properties": { - "can_mint_after_sale": { - "description": "Whether or not the owner can mint additional tokens after the sale has been conducted.", - "type": "boolean" - }, - "token_address": { - "description": "The address of the token contract whose tokens are being sold.", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_token_available.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_token_available.json deleted file mode 100644 index 1c278ec..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_is_token_available.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsTokenAvailableResponse", - "type": "object", - "required": [ - "is_token_available" - ], - "properties": { - "is_token_available": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_operators.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_owner.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_state.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_state.json deleted file mode 100644 index 2bf6a15..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_state.json +++ /dev/null @@ -1,201 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "State", - "type": "object", - "required": [ - "amount_sold", - "amount_to_send", - "amount_transferred", - "expiration", - "max_amount_per_wallet", - "min_tokens_sold", - "price", - "recipient" - ], - "properties": { - "amount_sold": { - "description": "Number of tokens sold.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_to_send": { - "description": "The amount of funds to send to recipient if sale successful. This already takes into account the royalties and taxes.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "amount_transferred": { - "description": "Number of tokens transferred to purchasers if sale was successful.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "expiration": { - "description": "The expiration denoting when the sale ends.", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "max_amount_per_wallet": { - "description": "The max number of tokens allowed per wallet.", - "type": "integer", - "format": "uint32", - "minimum": 0.0 - }, - "min_tokens_sold": { - "description": "The minimum number of tokens sold for the sale to go through.", - "allOf": [ - { - "$ref": "#/definitions/Uint128" - } - ] - }, - "price": { - "description": "The price of each token.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "recipient": { - "description": "The recipient of the raised funds if the sale is successful.", - "allOf": [ - { - "$ref": "#/definitions/Recipient" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Recipient": { - "description": "A simple struct used for inter-contract communication. The struct can be used in two ways:\n\n1. Simply just providing an `AndrAddr` which will treat the communication as a transfer of any related funds 2. Providing an `AndrAddr` and a `Binary` message which will be sent to the contract at the resolved address\n\nThe `Binary` message can be any message that the contract at the resolved address can handle.", - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "ibc_recovery_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "msg": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_type.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_version.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs index 583f963..0e78170 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/contract.rs @@ -1,78 +1,85 @@ -use crate::state::{ - get_available_tokens, Purchase, AVAILABLE_TOKENS, CONFIG, NUMBER_OF_TOKENS_AVAILABLE, - PURCHASES, SALE_CONDUCTED, STATE, -}; -use andromeda_non_fungible_tokens::{ - crowdfund::{ - Config, CrowdfundMintMsg, ExecuteMsg, InstantiateMsg, IsTokenAvailableResponse, MigrateMsg, - QueryMsg, State, - }, - cw721::{ExecuteMsg as Cw721ExecuteMsg, MintMsg, QueryMsg as Cw721QueryMsg}, +use andromeda_non_fungible_tokens::crowdfund::{ + CampaignConfig, CampaignStage, CampaignSummaryResponse, Cw20HookMsg, ExecuteMsg, + InstantiateMsg, PresaleTierOrder, QueryMsg, SimpleTierOrder, Tier, TierMetaData, TierOrder, + TierOrdersResponse, TiersResponse, }; -use andromeda_std::amp::{messages::AMPPkt, recipient::Recipient}; + +use andromeda_non_fungible_tokens::cw721::ExecuteMsg as Cw721ExecuteMsg; +use andromeda_std::ado_base::permissioning::{LocalPermission, Permission}; +use andromeda_std::amp::messages::AMPPkt; +use andromeda_std::amp::{AndrAddr, Recipient}; +use andromeda_std::common::actions::call_action; +use andromeda_std::common::denom::{Asset, SEND_CW20_ACTION}; +use andromeda_std::common::migration::ensure_compatibility; +use andromeda_std::common::{Milliseconds, MillisecondsExpiration, OrderBy}; use andromeda_std::{ado_contract::ADOContract, common::context::ExecuteContext}; use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, - common::{deduct_funds, encode_binary, merge_sub_msgs, rates::get_tax_amount, Funds}, - error::{from_semver, ContractError}, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + common::encode_binary, + error::ContractError, }; -use cw2::{get_contract_version, set_contract_version}; -use semver::Version; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - coins, ensure, has_coins, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, - Order, QuerierWrapper, QueryRequest, Reply, Response, StdError, Storage, SubMsg, Uint128, - WasmMsg, WasmQuery, + coin, ensure, from_json, wasm_execute, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, + MessageInfo, Reply, Response, StdError, Storage, SubMsg, Uint128, Uint64, WasmMsg, +}; + +use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; +use cw_utils::nonpayable; + +use crate::state::{ + add_tier, clear_user_orders, get_and_increase_tier_token_id, get_config, get_current_capital, + get_current_stage, get_duration, get_tier, get_tiers, get_user_orders, is_valid_tiers, + remove_tier, set_config, set_current_capital, set_current_stage, set_duration, set_tier_orders, + set_tiers, update_tier, Duration, }; -use cw721::TokensResponse; -use cw_utils::{nonpayable, Expiration}; -use std::cmp; -const MAX_LIMIT: u32 = 100; -const DEFAULT_LIMIT: u32 = 50; -pub(crate) const MAX_MINT_LIMIT: u32 = 100; const CONTRACT_NAME: &str = "crates.io:andromeda-crowdfund"; const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( - deps: DepsMut, + mut deps: DepsMut, env: Env, info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - CONFIG.save( - deps.storage, - &Config { - token_address: msg.token_address, - can_mint_after_sale: msg.can_mint_after_sale, - }, - )?; - SALE_CONDUCTED.save(deps.storage, &false)?; - NUMBER_OF_TOKENS_AVAILABLE.save(deps.storage, &Uint128::zero())?; let inst_resp = ADOContract::default().instantiate( deps.storage, - env, + env.clone(), deps.api, - info.clone(), + &deps.querier, + info, BaseInstantiateMsg { - ado_type: "crowdfund".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; - let mod_resp = - ADOContract::default().register_modules(info.sender.as_str(), deps.storage, msg.modules)?; - Ok(inst_resp - .add_attributes(mod_resp.attributes) - .add_submessages(mod_resp.messages)) + let campaign_config: CampaignConfig = msg.campaign_config; + let tiers: Vec = msg.tiers.into_iter().collect(); + if let Asset::Cw20Token(addr) = campaign_config.denom.clone() { + let addr = addr.get_raw_address(&deps.as_ref())?; + ADOContract::default().permission_action(SEND_CW20_ACTION, deps.storage)?; + ADOContract::set_permission( + deps.storage, + SEND_CW20_ACTION, + addr, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + + campaign_config.validate(deps.branch(), &env)?; + set_config(deps.storage, campaign_config)?; + + set_tiers(deps.storage, tiers)?; + + Ok(inst_resp) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -86,6 +93,12 @@ pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result Result { + ensure_compatibility(&deps.as_ref(), "1.1.0")?; + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( deps: DepsMut, @@ -103,780 +116,654 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - let contract = ADOContract::default(); +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; - if !matches!(msg, ExecuteMsg::UpdateAppContract { .. }) - && !matches!(msg, ExecuteMsg::UpdateOwner { .. }) - { - contract.module_hook::( - &ctx.deps.as_ref(), - AndromedaHook::OnExecute { - sender: ctx.info.sender.to_string(), - payload: encode_binary(&msg)?, - }, - )?; - } - match msg { - ExecuteMsg::Mint(mint_msgs) => execute_mint(ctx, mint_msgs), - ExecuteMsg::StartSale { - expiration, - price, - min_tokens_sold, - max_amount_per_wallet, - recipient, - } => execute_start_sale( - ctx, - expiration, - price, - min_tokens_sold, - max_amount_per_wallet, - recipient, - ), - ExecuteMsg::Purchase { number_of_tokens } => execute_purchase(ctx, number_of_tokens), - ExecuteMsg::PurchaseByTokenId { token_id } => execute_purchase_by_token_id(ctx, token_id), - ExecuteMsg::ClaimRefund {} => execute_claim_refund(ctx), - ExecuteMsg::EndSale { limit } => execute_end_sale(ctx, limit), + let res = match msg { + ExecuteMsg::AddTier { tier } => execute_add_tier(ctx, tier), + ExecuteMsg::UpdateTier { tier } => execute_update_tier(ctx, tier), + ExecuteMsg::RemoveTier { level } => execute_remove_tier(ctx, level), + ExecuteMsg::StartCampaign { + start_time, + end_time, + presale, + } => execute_start_campaign(ctx, start_time, end_time, presale), + ExecuteMsg::PurchaseTiers { orders } => execute_purchase_tiers(ctx, orders), + ExecuteMsg::Receive(msg) => handle_receive_cw20(ctx, msg), + ExecuteMsg::EndCampaign {} => execute_end_campaign(ctx, false), + ExecuteMsg::DiscardCampaign {} => execute_end_campaign(ctx, true), + ExecuteMsg::Claim {} => execute_claim(ctx), _ => ADOContract::default().execute(ctx, msg), - } + }?; + + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } -fn execute_mint( - ctx: ExecuteContext, - mint_msgs: Vec, -) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; +fn execute_add_tier(ctx: ExecuteContext, tier: Tier) -> Result { + let ExecuteContext { deps, info, .. } = ctx; - ensure!( - mint_msgs.len() <= MAX_MINT_LIMIT as usize, - ContractError::TooManyMintMessages { - limit: MAX_MINT_LIMIT, - } - ); let contract = ADOContract::default(); ensure!( contract.is_contract_owner(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); - // Can only mint when no sale is ongoing. - ensure!( - STATE.may_load(deps.storage)?.is_none(), - ContractError::SaleStarted {} - ); - let sale_conducted = SALE_CONDUCTED.load(deps.storage)?; - let config = CONFIG.load(deps.storage)?; + + tier.validate()?; + + let curr_stage = get_current_stage(deps.storage); ensure!( - config.can_mint_after_sale || !sale_conducted, - ContractError::CannotMintAfterSaleConducted {} + curr_stage == CampaignStage::READY, + ContractError::InvalidCampaignOperation { + operation: "add_tier".to_string(), + stage: curr_stage.to_string() + } ); - let token_contract = config.token_address; - let crowdfund_contract = env.contract.address.to_string(); - let resolved_path = token_contract.get_raw_address(&deps.as_ref())?; + add_tier(deps.storage, &tier)?; - let mut resp = Response::new(); - for mint_msg in mint_msgs { - let mint_resp = mint( - deps.storage, - &crowdfund_contract, - resolved_path.to_string(), - mint_msg, - )?; - resp = resp - .add_attributes(mint_resp.attributes) - .add_submessages(mint_resp.messages); + let mut resp = Response::new() + .add_attribute("action", "add_tier") + .add_attribute("level", tier.level) + .add_attribute("label", tier.label) + .add_attribute("price", tier.price); + + if let Some(limit) = tier.limit { + resp = resp.add_attribute("limit", limit.to_string()); } Ok(resp) } -fn mint( - storage: &mut dyn Storage, - crowdfund_contract: &str, - token_contract: String, - mint_msg: CrowdfundMintMsg, -) -> Result { - let mint_msg: MintMsg = MintMsg { - token_id: mint_msg.token_id, - owner: mint_msg - .owner - .unwrap_or_else(|| crowdfund_contract.to_owned()), - token_uri: mint_msg.token_uri, - extension: mint_msg.extension, - }; - // We allow for owners other than the contract, incase the creator wants to set aside a few - // tokens for some other use, say airdrop, team allocation, etc. Only those which have the - // contract as the owner will be available to sell. - if mint_msg.owner == crowdfund_contract { - // Mark token as available to purchase in next sale. - AVAILABLE_TOKENS.save(storage, &mint_msg.token_id, &true)?; - let current_number = NUMBER_OF_TOKENS_AVAILABLE.load(storage)?; - NUMBER_OF_TOKENS_AVAILABLE.save(storage, &(current_number + Uint128::new(1)))?; +fn execute_update_tier(ctx: ExecuteContext, tier: Tier) -> Result { + let ExecuteContext { deps, info, .. } = ctx; + + let contract = ADOContract::default(); + ensure!( + contract.is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + tier.validate()?; + + let curr_stage = get_current_stage(deps.storage); + ensure!( + curr_stage == CampaignStage::READY, + ContractError::InvalidCampaignOperation { + operation: "update_tier".to_string(), + stage: curr_stage.to_string() + } + ); + + update_tier(deps.storage, &tier)?; + + let mut resp = Response::new() + .add_attribute("action", "update_tier") + .add_attribute("level", tier.level) + .add_attribute("label", tier.label) + .add_attribute("price", tier.price); + + if let Some(limit) = tier.limit { + resp = resp.add_attribute("limit", limit.to_string()); } - Ok(Response::new() - .add_attribute("action", "mint") - .add_message(WasmMsg::Execute { - contract_addr: token_contract, - msg: encode_binary(&Cw721ExecuteMsg::Mint { - token_id: mint_msg.token_id, - owner: mint_msg.owner, - token_uri: mint_msg.token_uri, - extension: mint_msg.extension, - })?, - funds: vec![], - })) + + Ok(resp) } -#[allow(clippy::too_many_arguments)] -fn execute_start_sale( - ctx: ExecuteContext, - expiration: Expiration, - price: Coin, - min_tokens_sold: Uint128, - max_amount_per_wallet: Option, - recipient: Recipient, -) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; - let ado_contract = ADOContract::default(); +fn execute_remove_tier(ctx: ExecuteContext, level: Uint64) -> Result { + let ExecuteContext { deps, info, .. } = ctx; - // Validate recipient - ado_contract.validate_andr_addresses(&deps.as_ref(), vec![recipient.address.clone()])?; + let contract = ADOContract::default(); ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, + contract.is_contract_owner(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); + + let curr_stage = get_current_stage(deps.storage); ensure!( - !matches!(expiration, Expiration::Never {}), - ContractError::ExpirationMustNotBeNever {} - ); - ensure!( - !expiration.is_expired(&env.block), - ContractError::ExpirationInPast {} + curr_stage == CampaignStage::READY, + ContractError::InvalidCampaignOperation { + operation: "remove_tier".to_string(), + stage: curr_stage.to_string() + } ); - SALE_CONDUCTED.save(deps.storage, &true)?; - let state = STATE.may_load(deps.storage)?; - ensure!(state.is_none(), ContractError::SaleStarted {}); - let max_amount_per_wallet = max_amount_per_wallet.unwrap_or(1u32); - - // This is to prevent cloning price. - let price_str = price.to_string(); - STATE.save( - deps.storage, - &State { - expiration, - price, - min_tokens_sold, - max_amount_per_wallet, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient, - }, - )?; - SALE_CONDUCTED.save(deps.storage, &true)?; + remove_tier(deps.storage, level.into())?; - Ok(Response::new() - .add_attribute("action", "start_sale") - .add_attribute("expiration", expiration.to_string()) - .add_attribute("price", price_str) - .add_attribute("min_tokens_sold", min_tokens_sold) - .add_attribute("max_amount_per_wallet", max_amount_per_wallet.to_string())) + let resp = Response::new() + .add_attribute("action", "remove_tier") + .add_attribute("level", level); + + Ok(resp) } -fn execute_purchase_by_token_id( +fn execute_start_campaign( ctx: ExecuteContext, - token_id: String, + start_time: Option, + end_time: MillisecondsExpiration, + presale: Option>, ) -> Result { let ExecuteContext { - mut deps, - info, - env, - .. + deps, info, env, .. } = ctx; - let sender = info.sender.to_string(); - let state = STATE.may_load(deps.storage)?; - // CHECK :: That there is an ongoing sale. - ensure!(state.is_some(), ContractError::NoOngoingSale {}); - - let mut state = state.unwrap(); + // Only owner can start the campaign + let contract = ADOContract::default(); ensure!( - !state.expiration.is_expired(&env.block), - ContractError::NoOngoingSale {} + contract.is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} ); - let mut purchases = PURCHASES - .may_load(deps.storage, &sender)? - .unwrap_or_default(); + // At least one tier should have no limit to start the campaign + ensure!(is_valid_tiers(deps.storage), ContractError::InvalidTiers {}); + // Validate parameters ensure!( - AVAILABLE_TOKENS.has(deps.storage, &token_id), - ContractError::TokenNotAvailable {} + !end_time.is_expired(&env.block) && start_time.unwrap_or(Milliseconds::zero()) < end_time, + ContractError::StartTimeAfterEndTime {} ); - let max_possible = state.max_amount_per_wallet - purchases.len() as u32; + // Campaign can only start on READY stage + let curr_stage = get_current_stage(deps.storage); + ensure!( + curr_stage == CampaignStage::READY, + ContractError::InvalidCampaignOperation { + operation: "start_campaign".to_string(), + stage: curr_stage.to_string() + } + ); - // CHECK :: The user is able to purchase these without going over the limit. - ensure!(max_possible > 0, ContractError::PurchaseLimitReached {}); + // Update tier sold amount and update tier orders based on presale + if let Some(presale) = presale { + let orders = presale.iter().map(|order| order.clone().into()).collect(); + set_tier_orders(deps.storage, orders)?; + } - purchase_tokens( - &mut deps, - vec![token_id.clone()], - &info, - &mut state, - &mut purchases, - )?; + // Set start time and end time + let duration = Duration { + start_time, + end_time, + }; + set_duration(deps.storage, duration)?; - STATE.save(deps.storage, &state)?; - PURCHASES.save(deps.storage, &sender, &purchases)?; + // update stage + set_current_stage(deps.storage, CampaignStage::ONGOING)?; - Ok(Response::new() - .add_attribute("action", "purchase") - .add_attribute("token_id", token_id)) + let mut resp = Response::new() + .add_attribute("action", "start_campaign") + .add_attribute("end_time", end_time); + + if start_time.is_some() { + resp = resp.add_attribute("start_time", start_time.unwrap()); + } + + Ok(resp) } -fn execute_purchase( +fn execute_purchase_tiers( ctx: ExecuteContext, - number_of_tokens: Option, + orders: Vec, ) -> Result { let ExecuteContext { - mut deps, - info, - env, - .. + ref deps, ref info, .. } = ctx; - let sender = info.sender.to_string(); - let state = STATE.may_load(deps.storage)?; - - // CHECK :: That there is an ongoing sale. - ensure!(state.is_some(), ContractError::NoOngoingSale {}); - let mut state = state.unwrap(); + // Ensure campaign accepting coin is received + let campaign_config = get_config(deps.storage)?; ensure!( - !state.expiration.is_expired(&env.block), - ContractError::NoOngoingSale {} + info.funds.len() == 1, + ContractError::InvalidFunds { + msg: format!( + "Only {} is accepted by the campaign.", + campaign_config.denom + ), + } ); - let mut purchases = PURCHASES - .may_load(deps.storage, &sender)? - .unwrap_or_default(); - - let max_possible = state.max_amount_per_wallet - purchases.len() as u32; - - // CHECK :: The user is able to purchase these without going over the limit. - ensure!(max_possible > 0, ContractError::PurchaseLimitReached {}); - - let number_of_tokens_wanted = - number_of_tokens.map_or(max_possible, |n| cmp::min(n, max_possible)); + let payment: &Coin = &info.funds[0]; - // The number of token ids here is equal to min(number_of_tokens_wanted, num_tokens_left). - let token_ids = get_available_tokens(deps.storage, None, Some(number_of_tokens_wanted))?; + let sender = info.sender.to_string(); + let denom = payment.denom.clone(); + let amount = payment.amount; + purchase_tiers(ctx, Asset::NativeToken(denom), amount, sender, orders) +} - let number_of_tokens_purchased = token_ids.len(); +fn handle_receive_cw20( + ctx: ExecuteContext, + cw20_msg: Cw20ReceiveMsg, +) -> Result { + let ExecuteContext { ref info, .. } = ctx; + + let amount = cw20_msg.amount; + let sender = cw20_msg.sender; + let denom = AndrAddr::from_string(info.sender.clone()); + match from_json(&cw20_msg.msg)? { + Cw20HookMsg::PurchaseTiers { orders } => { + purchase_tiers(ctx, Asset::Cw20Token(denom), amount, sender, orders) + } + } +} - let required_payment = - purchase_tokens(&mut deps, token_ids, &info, &mut state, &mut purchases)?; +fn execute_end_campaign( + mut ctx: ExecuteContext, + is_discard: bool, +) -> Result { + nonpayable(&ctx.info)?; - PURCHASES.save(deps.storage, &sender, &purchases)?; - STATE.save(deps.storage, &state)?; + let ExecuteContext { + ref mut deps, + ref info, + ref env, + .. + } = ctx; - // Refund user if they sent more. This can happen near the end of the sale when they weren't - // able to get the amount that they wanted. - let mut funds = info.funds; - deduct_funds(&mut funds, &required_payment)?; + // Only owner can end the campaign + let contract = ADOContract::default(); + ensure!( + contract.is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); - // If any funds were remaining after deduction, send refund. - let resp = if has_coins(&funds, &Coin::new(1, state.price.denom)) { - Response::new().add_message(BankMsg::Send { - to_address: sender, - amount: funds, - }) + // Campaign is finished already successfully + // NOTE: ending failed campaign has no effect and is ignored + let curr_stage = get_current_stage(deps.storage); + let action = if is_discard { + "discard_campaign" } else { - Response::new() + "end_campaign" }; - Ok(resp - .add_attribute("action", "purchase") - .add_attribute( - "number_of_tokens_wanted", - number_of_tokens_wanted.to_string(), - ) - .add_attribute( - "number_of_tokens_purchased", - number_of_tokens_purchased.to_string(), - )) -} - -fn purchase_tokens( - deps: &mut DepsMut, - token_ids: Vec, - info: &MessageInfo, - state: &mut State, - purchases: &mut Vec, -) -> Result { - // CHECK :: There are any tokens left to purchase. - ensure!(!token_ids.is_empty(), ContractError::AllTokensPurchased {}); - - let number_of_tokens_purchased = token_ids.len(); - - // CHECK :: The user has sent enough funds to cover the base fee (without any taxes). - let total_cost = Coin::new( - state.price.amount.u128() * number_of_tokens_purchased as u128, - state.price.denom.clone(), - ); ensure!( - has_coins(&info.funds, &total_cost), - ContractError::InsufficientFunds {} + curr_stage == CampaignStage::ONGOING + || (is_discard && curr_stage != CampaignStage::SUCCESS), + ContractError::InvalidCampaignOperation { + operation: action.to_string(), + stage: curr_stage.to_string() + } ); - let mut total_tax_amount = Uint128::zero(); - - // This is the same for each token, so we only need to do it once. - let (msgs, _events, remainder) = ADOContract::default().on_funds_transfer( - &deps.as_ref(), - info.sender.to_string(), - Funds::Native(state.price.clone()), - encode_binary(&"")?, - )?; + let current_capital = get_current_capital(deps.storage); + let campaign_config = get_config(deps.storage)?; + let duration = get_duration(deps.storage)?; + let soft_cap = campaign_config.soft_cap.unwrap_or(Uint128::one()); + let end_time = duration.end_time; + + // Decide the next stage + let next_stage = match ( + is_discard, + current_capital >= soft_cap, + end_time.is_expired(&env.block), + ) { + // discard the campaign as there are some unexpected issues + (true, _, _) => CampaignStage::FAILED, + // Capital hit the target capital and thus campaign is successful + (false, true, _) => CampaignStage::SUCCESS, + // Capital did hit the target capital and is expired, failed + (false, false, true) => CampaignStage::FAILED, + // Capital did not hit the target capital and campaign is not expired + (false, false, false) => { + if current_capital != Uint128::zero() { + // Need to wait until campaign expires + return Err(ContractError::CampaignNotExpired {}); + } + // No capital is gained and thus it can be paused and restart again + CampaignStage::READY + } + }; - let mut current_number = NUMBER_OF_TOKENS_AVAILABLE.load(deps.storage)?; - for token_id in token_ids { - let remaining_amount = remainder.try_get_coin()?; + set_current_stage(deps.storage, next_stage.clone())?; + + let mut resp = Response::new() + .add_attribute("action", action) + .add_attribute("result", next_stage.to_string()); + if next_stage == CampaignStage::SUCCESS { + let campaign_denom = match campaign_config.denom { + Asset::Cw20Token(ref cw20_token) => Asset::Cw20Token(AndrAddr::from_string( + cw20_token.get_raw_address(&deps.as_ref())?.to_string(), + )), + denom => denom, + }; - let tax_amount = get_tax_amount(&msgs, state.price.amount, remaining_amount.amount); + resp = resp.add_submessage(withdraw_to_recipient( + ctx, + campaign_config.withdrawal_recipient, + current_capital, + campaign_denom, + )?); + } + Ok(resp) +} - let purchase = Purchase { - token_id: token_id.clone(), - tax_amount, - msgs: msgs.clone(), - purchaser: info.sender.to_string(), - }; +fn purchase_tiers( + ctx: ExecuteContext, + denom: Asset, + amount: Uint128, + sender: String, + orders: Vec, +) -> Result { + ensure!(!amount.is_zero(), ContractError::InsufficientFunds {}); - total_tax_amount += tax_amount; + let ExecuteContext { deps, env, .. } = ctx; - state.amount_to_send += remaining_amount.amount; - state.amount_sold += Uint128::new(1); + let campaign_config = get_config(deps.storage)?; + // Ensure campaign accepting coin is received + let campaign_denom = match campaign_config.denom { + Asset::Cw20Token(ref cw20_token) => { + format!("cw20:{}", cw20_token.get_raw_address(&deps.as_ref())?) + } + Asset::NativeToken(ref addr) => format!("native:{}", addr), + }; + ensure!( + denom.to_string() == campaign_denom, + ContractError::InvalidFunds { + msg: format!( + "Only {} is accepted by the campaign.", + campaign_config.denom + ), + } + ); - purchases.push(purchase); + let mut current_capital = get_current_capital(deps.storage); - AVAILABLE_TOKENS.remove(deps.storage, &token_id); - current_number -= Uint128::new(1); - } - NUMBER_OF_TOKENS_AVAILABLE.save(deps.storage, ¤t_number)?; + let current_stage = get_current_stage(deps.storage); - // CHECK :: User has sent enough to cover taxes. - let required_payment = Coin { - denom: state.price.denom.clone(), - amount: state.price.amount * Uint128::from(number_of_tokens_purchased as u128) - + total_tax_amount, - }; + // Tier can be purchased on ONGOING stage ensure!( - has_coins(&info.funds, &required_payment), - ContractError::InsufficientFunds {} + current_stage == CampaignStage::ONGOING, + ContractError::InvalidCampaignOperation { + operation: "purchase_tiers".to_string(), + stage: current_stage.to_string() + } ); - Ok(required_payment) -} -fn execute_claim_refund(ctx: ExecuteContext) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; - nonpayable(&info)?; + let duration = get_duration(deps.storage)?; - let state = STATE.may_load(deps.storage)?; - ensure!(state.is_some(), ContractError::NoOngoingSale {}); - let state = state.unwrap(); + // Need to wait until start_time ensure!( - state.expiration.is_expired(&env.block), - ContractError::SaleNotEnded {} + duration + .start_time + .unwrap_or_default() + .is_expired(&env.block), + ContractError::CampaignNotStarted {} ); + + // Campaign is expired or should be ended due to overfunding ensure!( - state.amount_sold < state.min_tokens_sold, - ContractError::MinSalesExceeded {} + !duration.end_time.is_expired(&env.block) + || campaign_config.hard_cap.unwrap_or(current_capital) > current_capital, + ContractError::CampaignEnded {} ); - let purchases = PURCHASES.may_load(deps.storage, info.sender.as_str())?; - ensure!(purchases.is_some(), ContractError::NoPurchases {}); - let purchases = purchases.unwrap(); - let refund_msg = process_refund(deps.storage, &purchases, &state.price); - let mut resp = Response::new(); - if let Some(refund_msg) = refund_msg { - resp = resp.add_message(refund_msg); + let mut full_orders = Vec::::new(); + + // Measure the total cost for orders + let total_cost = orders.iter().try_fold(Uint128::zero(), |sum, order| { + let tier = get_tier(deps.storage, u64::from(order.level))?; + let new_sum: Result = Ok(sum + tier.price * order.amount); + full_orders.push(TierOrder { + orderer: Addr::unchecked(sender.clone()), + level: order.level, + amount: order.amount, + is_presale: false, + }); + new_sum + })?; + + // Ensure that enough payment is sent for the order + ensure!(total_cost <= amount, ContractError::InsufficientFunds {}); + + // Update order history and sold amount for the tier + set_tier_orders(deps.storage, full_orders)?; + current_capital = current_capital.checked_add(total_cost)?; + + // Update current capital + set_current_capital(deps.storage, current_capital)?; + let mut resp = Response::new() + .add_attribute("action", "purchase_tiers") + .add_attribute("payment", format!("{0}{1}", amount, denom)) + .add_attribute("total_cost", total_cost.to_string()); + + if amount > total_cost { + resp = resp + .add_submessage(transfer_asset_msg(sender, amount - total_cost, denom)?) + .add_attribute("refunded", amount - total_cost); } - Ok(resp.add_attribute("action", "claim_refund")) + Ok(resp) } -fn execute_end_sale(ctx: ExecuteContext, limit: Option) -> Result { - let ExecuteContext { - mut deps, - info, - env, - amp_ctx, - } = ctx; - nonpayable(&info)?; - - let state = STATE.may_load(deps.storage)?; - ensure!(state.is_some(), ContractError::NoOngoingSale {}); - let state = state.unwrap(); - let number_of_tokens_available = NUMBER_OF_TOKENS_AVAILABLE.load(deps.storage)?; - ensure!( - // If all tokens have been sold the sale can be ended too. - state.expiration.is_expired(&env.block) || number_of_tokens_available.is_zero(), - ContractError::SaleNotEnded {} - ); - if state.amount_sold < state.min_tokens_sold { - issue_refunds_and_burn_tokens(&mut deps, env, limit) - } else { - transfer_tokens_and_send_funds( - ExecuteContext { - deps, - info, - env, - amp_ctx, - }, - limit, - ) - } +fn transfer_asset_msg( + to_address: String, + amount: Uint128, + denom: Asset, +) -> Result { + Ok(match denom { + Asset::NativeToken(denom) => SubMsg::new(BankMsg::Send { + to_address, + amount: vec![coin(amount.u128(), denom)], + }), + Asset::Cw20Token(denom) => { + let transfer_msg = Cw20ExecuteMsg::Transfer { + recipient: to_address, + amount, + }; + let wasm_msg = wasm_execute(denom, &transfer_msg, vec![])?; + SubMsg::new(wasm_msg) + } + }) } -fn issue_refunds_and_burn_tokens( - deps: &mut DepsMut, - env: Env, - limit: Option, -) -> Result { - let state = STATE.load(deps.storage)?; - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - ensure!(limit > 0, ContractError::LimitMustNotBeZero {}); - let mut refund_msgs: Vec = vec![]; - // Issue refunds for `limit` number of users. - let purchases: Vec> = PURCHASES - .range(deps.storage, None, None, Order::Ascending) - .take(limit) - .flatten() - .map(|(_v, p)| p) - .collect(); - for purchase_vec in purchases.iter() { - let refund_msg = process_refund(deps.storage, purchase_vec, &state.price); - if let Some(refund_msg) = refund_msg { - refund_msgs.push(refund_msg); +fn withdraw_to_recipient( + ctx: ExecuteContext, + recipient: Recipient, + amount: Uint128, + denom: Asset, +) -> Result { + match denom { + Asset::NativeToken(denom) => { + let kernel_address = + ADOContract::default().get_kernel_address(ctx.deps.as_ref().storage)?; + + let mut pkt = AMPPkt::from_ctx(ctx.amp_ctx, ctx.env.contract.address.to_string()); + let amp_msg = recipient.generate_amp_msg( + &ctx.deps.as_ref(), + Some(vec![coin(amount.u128(), denom.clone())]), + )?; + + pkt = pkt.add_message(amp_msg); + pkt.to_sub_msg(kernel_address, Some(vec![coin(amount.u128(), denom)]), 1) } + denom => transfer_asset_msg( + recipient + .address + .get_raw_address(&ctx.deps.as_ref())? + .to_string(), + amount, + denom, + ), } - - // Burn `limit` number of tokens - let burn_msgs = get_burn_messages(deps, env.contract.address.to_string(), limit)?; - - if burn_msgs.is_empty() && purchases.is_empty() { - // When all tokens have been burned and all purchases have been refunded, the sale is over. - clear_state(deps.storage)?; - } - - Ok(Response::new() - .add_attribute("action", "issue_refunds_and_burn_tokens") - .add_messages(refund_msgs) - .add_messages(burn_msgs)) } -fn transfer_tokens_and_send_funds( - ctx: ExecuteContext, - limit: Option, -) -> Result { - let ExecuteContext { - mut deps, - info, - env, - .. - } = ctx; - let mut state = STATE.load(deps.storage)?; - let mut resp = Response::new(); - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; +fn execute_claim(ctx: ExecuteContext) -> Result { + let ExecuteContext { mut deps, info, .. } = ctx; - ensure!(limit > 0, ContractError::LimitMustNotBeZero {}); - // Send the funds if they haven't been sent yet and if all of the tokens have been transferred. - let mut pkt = match ctx.amp_ctx { - Some(pkt) => pkt, - None => AMPPkt::new(info.sender, env.contract.address.clone(), vec![]), - }; + let curr_stage = get_current_stage(deps.storage); + let mut resp = Response::new().add_attribute("action", "claim"); - if state.amount_transferred == state.amount_sold { - if state.amount_to_send > Uint128::zero() { - let funds = vec![Coin { - denom: state.price.denom.clone(), - amount: state.amount_to_send, - }]; - match state.recipient.msg.clone() { - None => { - resp = resp.add_submessage( - state.recipient.generate_direct_msg(&deps.as_ref(), funds)?, - ); - } - Some(_) => { - let amp_message = state.recipient.clone().generate_amp_msg(Some(funds)); - pkt = pkt.add_message(amp_message); - let kernel_address = ADOContract::default().get_kernel_address(deps.storage)?; - let sub_msg = pkt.to_sub_msg( - kernel_address, - Some(coins( - state.amount_to_send.u128(), - state.price.denom.clone(), - )), - 1, - )?; - resp = resp.add_submessage(sub_msg); - } - } - state.amount_to_send = Uint128::zero(); - STATE.save(deps.storage, &state)?; + let sub_response = match curr_stage { + CampaignStage::SUCCESS => handle_successful_claim(deps.branch(), &info.sender)?, + CampaignStage::FAILED => handle_failed_claim(deps.branch(), &info.sender)?, + _ => { + return Err(ContractError::InvalidCampaignOperation { + operation: "Claim".to_string(), + stage: curr_stage.to_string(), + }) } - // Once all purchased tokens have been transferred, begin burning `limit` number of tokens - // that were not purchased. - let burn_msgs = get_burn_messages(&mut deps, env.contract.address.to_string(), limit)?; - - if burn_msgs.is_empty() { - // When burn messages are empty, we have finished the sale, which is represented by - // having no State. - clear_state(deps.storage)?; - } else { - resp = resp.add_messages(burn_msgs); - } - // If we are here then there are no purchases to process so we can exit. - return Ok(resp.add_attribute("action", "transfer_tokens_and_send_funds")); - } - let mut purchases: Vec = PURCHASES - .range(deps.storage, None, None, Order::Ascending) - .flatten() - // Flatten Vec> into Vec. - .flat_map(|(_v, p)| p) - // Take one extra in order to compare what the next purchaser would be to check if some - // purchases will be left over. - .take(limit + 1) - .collect(); - - let config = CONFIG.load(deps.storage)?; - let mut rate_messages: Vec = vec![]; - let mut transfer_msgs: Vec = vec![]; - - let last_purchaser = if purchases.len() == 1 { - purchases[0].purchaser.clone() - } else { - purchases[purchases.len() - 2].purchaser.clone() }; - // This subtraction is no problem as we will always have at least one purchase. - let subsequent_purchase = &purchases[purchases.len() - 1]; - // If this is false, then there are some purchases that we will need to leave for the next - // round. Otherwise, we are able to process all of the purchases for the last purchaser and we - // can remove their entry from the map entirely. - let remove_last_purchaser = last_purchaser != subsequent_purchase.purchaser; - - let mut number_of_last_purchases_removed = 0; - // If we took an extra element, we remove it. Otherwise limit + 1 was more than was necessary - // so we need to remove all of the purchases from the map. - if limit + 1 == purchases.len() { - // This is an O(1) operation from looking at the source code. - purchases.pop(); - } + resp = resp + .add_attributes(sub_response.attributes) + .add_submessages(sub_response.messages); - // Resolve the token contract address from the VFS - let token_contract_address = config.token_address.get_raw_address(&deps.as_ref())?; - for purchase in purchases.into_iter() { - let purchaser = purchase.purchaser; - let should_remove = purchaser != last_purchaser || remove_last_purchaser; - if should_remove && PURCHASES.has(deps.storage, &purchaser) { - PURCHASES.remove(deps.storage, &purchaser); - } else if purchaser == last_purchaser { - // Keep track of the number of purchases removed from the last purchaser to remove them - // at the end, if not all of them were removed. - number_of_last_purchases_removed += 1; - } - rate_messages.extend(purchase.msgs); - transfer_msgs.push(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: token_contract_address.to_string(), - msg: encode_binary(&Cw721ExecuteMsg::TransferNft { - recipient: purchaser, - token_id: purchase.token_id, - })?, - funds: vec![], - })); - - state.amount_transferred += Uint128::from(1u128); - } - // If the last purchaser wasn't removed, remove the subset of purchases that were processed. - if PURCHASES.has(deps.storage, &last_purchaser) { - let last_purchases = PURCHASES.load(deps.storage, &last_purchaser)?; - PURCHASES.save( - deps.storage, - &last_purchaser, - &last_purchases[number_of_last_purchases_removed..].to_vec(), - )?; - } - STATE.save(deps.storage, &state)?; + clear_user_orders(deps.storage, info.sender)?; - Ok(resp - .add_attribute("action", "transfer_tokens_and_send_funds") - .add_messages(transfer_msgs) - .add_submessages(merge_sub_msgs(rate_messages))) + Ok(resp) } -/// Processes a vector of purchases for the SAME user by merging all funds into a single BankMsg. -/// The given purchaser is then removed from `PURCHASES`. -/// -/// ## Arguments -/// * `storage` - Mutable reference to Storage -/// * `purchase` - Vector of purchases for the same user to issue a refund message for. -/// * `price` - The price of a token -/// -/// Returns an `Option` which is `None` when the amount to refund is zero. -fn process_refund( - storage: &mut dyn Storage, - purchases: &[Purchase], - price: &Coin, -) -> Option { - let purchaser = purchases[0].purchaser.clone(); - // Remove each entry as they get processed. - PURCHASES.remove(storage, &purchaser); - // Reduce a user's purchases into one message. While the tax paid on each item should - // be the same, it is not guaranteed given that the rates module is mutable during the - // sale. - let amount = purchases - .iter() - // This represents the total amount of funds they sent for each purchase. - .map(|p| p.tax_amount + price.amount) - // Adds up all of the purchases. - .reduce(|accum, item| accum + item) - .unwrap_or_else(Uint128::zero); - - if amount > Uint128::zero() { - Some(CosmosMsg::Bank(BankMsg::Send { - to_address: purchaser, - amount: vec![Coin { - denom: price.denom.clone(), - amount, - }], - })) - } else { - None +fn handle_successful_claim(deps: DepsMut, sender: &Addr) -> Result { + let campaign_config = get_config(deps.storage)?; + + let orders = get_user_orders(deps.storage, sender.clone(), None, None, true, None); + ensure!(!orders.is_empty(), ContractError::NoPurchases {}); + + // mint tier token to the owner + let token_address = campaign_config + .token_address + .get_raw_address(&deps.as_ref())?; + + let mut resp = Response::new(); + for order in orders { + let metadata = get_tier(deps.storage, order.level.into())?.metadata; + for _ in 0..order.amount.into() { + let mint_resp = mint( + deps.storage, + token_address.to_string(), + metadata.clone(), + sender.to_string(), + )?; + resp = resp + .add_attributes(mint_resp.attributes) + .add_submessages(mint_resp.messages); + } } + Ok(resp) } -fn get_burn_messages( - deps: &mut DepsMut, - address: String, - limit: usize, -) -> Result, ContractError> { - let config = CONFIG.load(deps.storage)?; - let token_address = config.token_address.get_raw_address(&deps.as_ref())?; - let tokens_to_burn = query_tokens(&deps.querier, token_address.to_string(), address, limit)?; - - tokens_to_burn - .into_iter() - .map(|token_id| { - // Any token that is burnable has been added to this map, and so must be removed. - AVAILABLE_TOKENS.remove(deps.storage, &token_id); - Ok(CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: token_address.to_string(), - funds: vec![], - msg: encode_binary(&Cw721ExecuteMsg::Burn { token_id })?, - })) - }) - .collect() -} +fn handle_failed_claim(deps: DepsMut, sender: &Addr) -> Result { + let campaign_config = get_config(deps.storage)?; + + let orders = get_user_orders(deps.storage, sender.clone(), None, None, false, None); + ensure!(!orders.is_empty(), ContractError::NoPurchases {}); + + // refund + let total_cost = orders.iter().try_fold(Uint128::zero(), |sum, order| { + let tier = get_tier(deps.storage, u64::from(order.level))?; + let new_sum: Result = + Ok(sum.checked_add(tier.price.checked_mul(order.amount)?)?); + new_sum + })?; + let mut resp = Response::new(); + + let campaign_denom = match campaign_config.denom { + Asset::Cw20Token(ref cw20_token) => Asset::Cw20Token(AndrAddr::from_string( + cw20_token.get_raw_address(&deps.as_ref())?.to_string(), + )), + denom => denom, + }; -fn clear_state(storage: &mut dyn Storage) -> Result<(), ContractError> { - STATE.remove(storage); - NUMBER_OF_TOKENS_AVAILABLE.save(storage, &Uint128::zero())?; + let sub_msg = transfer_asset_msg(sender.to_string(), total_cost, campaign_denom)?; + resp = resp.add_submessage(sub_msg); - Ok(()) + Ok(resp) } -fn query_tokens( - querier: &QuerierWrapper, - token_address: String, +fn mint( + storage: &mut dyn Storage, + tier_contract: String, + tier_metadata: TierMetaData, owner: String, - limit: usize, -) -> Result, ContractError> { - let res: TokensResponse = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: token_address, - msg: encode_binary(&Cw721QueryMsg::Tokens { +) -> Result { + let token_id = get_and_increase_tier_token_id(storage)?.to_string(); + + Ok(Response::new().add_message(WasmMsg::Execute { + contract_addr: tier_contract, + msg: encode_binary(&Cw721ExecuteMsg::Mint { + token_id, owner, - start_after: None, - limit: Some(limit as u32), + token_uri: tier_metadata.token_uri, + extension: tier_metadata.extension, })?, - }))?; - Ok(res.tokens) + funds: vec![], + })) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::State {} => encode_binary(&query_state(deps)?), - QueryMsg::Config {} => encode_binary(&query_config(deps)?), - QueryMsg::AvailableTokens { start_after, limit } => { - encode_binary(&query_available_tokens(deps, start_after, limit)?) - } - QueryMsg::IsTokenAvailable { id } => encode_binary(&query_is_token_available(deps, id)), + QueryMsg::CampaignSummary {} => encode_binary(&query_campaign_summary(deps)?), + QueryMsg::TierOrders { + orderer, + start_after, + limit, + order_by, + } => encode_binary(&query_tier_orders( + deps, + orderer, + start_after, + limit, + order_by, + )?), + QueryMsg::Tiers { + start_after, + limit, + order_by, + } => encode_binary(&query_tiers(deps, start_after, limit, order_by)?), _ => ADOContract::default().query(deps, env, msg), } } -fn query_state(deps: Deps) -> Result { - Ok(STATE.load(deps.storage)?) +fn query_campaign_summary(deps: Deps) -> Result { + let current_capital = get_current_capital(deps.storage); + let current_stage = get_current_stage(deps.storage); + let config = get_config(deps.storage)?; + let duration = get_duration(deps.storage)?; + Ok(CampaignSummaryResponse { + title: config.title, + description: config.description, + banner: config.banner, + url: config.url, + token_address: config.token_address, + denom: config.denom, + withdrawal_recipient: config.withdrawal_recipient, + soft_cap: config.soft_cap, + hard_cap: config.hard_cap, + start_time: duration.start_time, + end_time: duration.end_time, + current_stage: current_stage.to_string(), + current_capital: current_capital.into(), + }) } -fn query_config(deps: Deps) -> Result { - Ok(CONFIG.load(deps.storage)?) -} - -fn query_available_tokens( +fn query_tier_orders( deps: Deps, - start_after: Option, + orderer: String, + start_after: Option, limit: Option, -) -> Result, ContractError> { - get_available_tokens(deps.storage, start_after, limit) -} - -fn query_is_token_available(deps: Deps, id: String) -> IsTokenAvailableResponse { - IsTokenAvailableResponse { - is_token_available: AVAILABLE_TOKENS.has(deps.storage, &id), - } -} - -#[cfg_attr(not(feature = "library"), entry_point)] -pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } + order_by: Option, +) -> Result { + let orders = get_user_orders( + deps.storage, + Addr::unchecked(orderer), + start_after, + limit, + true, + order_by, ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + Ok(TierOrdersResponse { orders }) +} +fn query_tiers( + deps: Deps, + start_after: Option, + limit: Option, + order_by: Option, +) -> Result { + let tiers = get_tiers(deps.storage, start_after, limit, order_by)?; + Ok(TiersResponse { tiers }) } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/mock.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/mock.rs index dc13958..3a7f37f 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/mock.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/mock.rs @@ -1,19 +1,18 @@ #![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] use crate::contract::{execute, instantiate, query, reply}; -use andromeda_non_fungible_tokens::{ - crowdfund::{CrowdfundMintMsg, ExecuteMsg, InstantiateMsg, QueryMsg}, - cw721::TokenExtension, +use andromeda_non_fungible_tokens::crowdfund::{ + CampaignConfig, CampaignSummaryResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, + PresaleTierOrder, QueryMsg, SimpleTierOrder, Tier, TierMetaData, }; -use andromeda_std::amp::Recipient; -use andromeda_std::{ado_base::modules::Module, amp::AndrAddr}; +use andromeda_std::common::Milliseconds; use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::{ExecuteResult, MockADO, MockContract}, }; -use cosmwasm_std::{Addr, Coin, Empty, Uint128}; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; -use cw_utils::Expiration; +use cosmwasm_std::{Addr, Coin, Empty, Uint128, Uint64}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; pub struct MockCrowdfund(Addr); mock_ado!(MockCrowdfund, ExecuteMsg, QueryMsg); @@ -23,20 +22,13 @@ impl MockCrowdfund { pub fn instantiate( code_id: u64, sender: Addr, - app: &mut App, - token_address: AndrAddr, - can_mint_after_sale: bool, - modules: Option>, + app: &mut MockApp, + campaign_config: CampaignConfig, + tiers: Vec, kernel_address: impl Into, owner: Option, ) -> MockCrowdfund { - let msg = mock_crowdfund_instantiate_msg( - token_address, - can_mint_after_sale, - modules, - kernel_address, - owner, - ); + let msg = mock_crowdfund_instantiate_msg(campaign_config, tiers, kernel_address, owner); let addr = app .instantiate_contract( code_id, @@ -49,73 +41,62 @@ impl MockCrowdfund { .unwrap(); MockCrowdfund(Addr::unchecked(addr)) } - #[allow(clippy::too_many_arguments)] - pub fn execute_start_sale( + pub fn execute_add_tier( &self, sender: Addr, - app: &mut App, - expiration: Expiration, - price: Coin, - min_tokens_sold: Uint128, - max_amount_per_wallet: Option, - recipient: Recipient, + app: &mut MockApp, + level: Uint64, + label: String, + price: Uint128, + limit: Option, + metadata: TierMetaData, ) -> ExecuteResult { - let msg = mock_start_crowdfund_msg( - expiration, - price, - min_tokens_sold, - max_amount_per_wallet, - recipient, - ); + let msg = mock_add_tier_msg(level, label, price, limit, metadata); self.execute(app, &msg, sender, &[]) } - pub fn execute_end_sale( + pub fn execute_start_campaign( &self, sender: Addr, - app: &mut App, - limit: Option, + app: &mut MockApp, + start_time: Option, + end_time: Milliseconds, + presale: Option>, ) -> ExecuteResult { - let msg = mock_end_crowdfund_msg(limit); + let msg = mock_start_campaign_msg(start_time, end_time, presale); self.execute(app, &msg, sender, &[]) } - pub fn execute_mint( + pub fn execute_purchase( &self, sender: Addr, - app: &mut App, - token_id: String, - extension: TokenExtension, - token_uri: Option, - owner: Option, + app: &mut MockApp, + orders: Vec, + funds: Vec, ) -> ExecuteResult { - let msg = ExecuteMsg::Mint(vec![mock_crowdfund_mint_msg( - token_id, extension, token_uri, owner, - )]); + let msg = mock_purchase_msg(orders); + self.execute(app, &msg, sender, &funds) + } + + pub fn execute_end_campaign(&self, sender: Addr, app: &mut MockApp) -> ExecuteResult { + let msg = mock_end_campaign_msg(); self.execute(app, &msg, sender, &[]) } - pub fn execute_quick_mint( - &self, - sender: Addr, - app: &mut App, - amount: u32, - publisher: String, - ) -> ExecuteResult { - let msg = mock_crowdfund_quick_mint_msg(amount, publisher); + pub fn execute_discard_campaign(&self, sender: Addr, app: &mut MockApp) -> ExecuteResult { + let msg = mock_discard_campaign_msg(); self.execute(app, &msg, sender, &[]) } - pub fn execute_purchase( - &self, - sender: Addr, - app: &mut App, - number_of_tokens: Option, - funds: &[Coin], - ) -> ExecuteResult { - let msg = mock_purchase_msg(number_of_tokens); - self.execute(app, &msg, sender, funds) + pub fn execute_claim(&self, sender: Addr, app: &mut MockApp) -> ExecuteResult { + let msg = mock_claim_msg(); + self.execute(app, &msg, sender, &[]) + } + + pub fn query_campaign_summary(&self, app: &mut MockApp) -> CampaignSummaryResponse { + let msg = QueryMsg::CampaignSummary {}; + self.query(app, msg) } } @@ -125,69 +106,65 @@ pub fn mock_andromeda_crowdfund() -> Box> { } pub fn mock_crowdfund_instantiate_msg( - token_address: AndrAddr, - can_mint_after_sale: bool, - modules: Option>, + campaign_config: CampaignConfig, + tiers: Vec, kernel_address: impl Into, owner: Option, ) -> InstantiateMsg { InstantiateMsg { - token_address, - can_mint_after_sale, - modules, + campaign_config, + tiers, kernel_address: kernel_address.into(), owner, } } -pub fn mock_start_crowdfund_msg( - expiration: Expiration, - price: Coin, - min_tokens_sold: Uint128, - max_amount_per_wallet: Option, - recipient: Recipient, +pub fn mock_add_tier_msg( + level: Uint64, + label: String, + price: Uint128, + limit: Option, + metadata: TierMetaData, ) -> ExecuteMsg { - ExecuteMsg::StartSale { - expiration, - price, - min_tokens_sold, - max_amount_per_wallet, - recipient, + ExecuteMsg::AddTier { + tier: Tier { + level, + label, + price, + limit, + metadata, + }, } } -pub fn mock_end_crowdfund_msg(limit: Option) -> ExecuteMsg { - ExecuteMsg::EndSale { limit } +pub fn mock_start_campaign_msg( + start_time: Option, + end_time: Milliseconds, + presale: Option>, +) -> ExecuteMsg { + ExecuteMsg::StartCampaign { + start_time, + end_time, + presale, + } } -pub fn mock_crowdfund_mint_msg( - token_id: String, - extension: TokenExtension, - token_uri: Option, - owner: Option, -) -> CrowdfundMintMsg { - CrowdfundMintMsg { - token_id, - owner, - token_uri, - extension, - } +pub fn mock_purchase_msg(orders: Vec) -> ExecuteMsg { + ExecuteMsg::PurchaseTiers { orders } } -pub fn mock_crowdfund_quick_mint_msg(amount: u32, publisher: String) -> ExecuteMsg { - let mut mint_msgs: Vec = Vec::new(); - for i in 0..amount { - let extension = TokenExtension { - publisher: publisher.clone(), - }; +pub fn mock_end_campaign_msg() -> ExecuteMsg { + ExecuteMsg::EndCampaign {} +} - let msg = mock_crowdfund_mint_msg(i.to_string(), extension, None, None); - mint_msgs.push(msg); - } +pub fn mock_discard_campaign_msg() -> ExecuteMsg { + ExecuteMsg::DiscardCampaign {} +} - ExecuteMsg::Mint(mint_msgs) +pub fn mock_claim_msg() -> ExecuteMsg { + ExecuteMsg::Claim {} } -pub fn mock_purchase_msg(number_of_tokens: Option) -> ExecuteMsg { - ExecuteMsg::Purchase { number_of_tokens } +pub fn mock_purchase_cw20_msg(orders: Vec) -> Cw20HookMsg { + Cw20HookMsg::PurchaseTiers { orders } } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/state.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/state.rs index a078b2b..e5eb21c 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/state.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/state.rs @@ -1,53 +1,498 @@ -use andromeda_non_fungible_tokens::crowdfund::{Config, State}; -use andromeda_std::error::ContractError; +use andromeda_non_fungible_tokens::crowdfund::{ + CampaignConfig, CampaignStage, SimpleTierOrder, Tier, TierOrder, TierResponseItem, +}; +use andromeda_std::{ + common::{MillisecondsExpiration, OrderBy}, + error::ContractError, +}; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Order, Storage, SubMsg, Uint128}; +use cosmwasm_std::{ensure, Addr, Order, Storage, Uint128, Uint64}; use cw_storage_plus::{Bound, Item, Map}; -/// The config. -pub const CONFIG: Item = Item::new("config"); +#[cw_serde] +pub struct Duration { + /// Time when campaign starts + pub start_time: Option, + /// Time when campaign ends + pub end_time: MillisecondsExpiration, +} +pub const CAMPAIGN_DURATION: Item = Item::new("campaign_duration"); + +pub const CAMPAIGN_CONFIG: Item = Item::new("campaign_config"); -/// The number of tokens available for sale. -pub const NUMBER_OF_TOKENS_AVAILABLE: Item = Item::new("number_of_tokens_available"); +pub const CAMPAIGN_STAGE: Item = Item::new("campaign_stage"); -/// Sale started if and only if STATE.may_load is Some and !duration.is_expired() -pub const STATE: Item = Item::new("state"); +pub const CURRENT_CAPITAL: Item = Item::new("current_capital"); -/// Relates buyer address to vector of purchases. -pub const PURCHASES: Map<&str, Vec> = Map::new("buyers"); +pub const TIERS: Map = Map::new("tiers"); -/// Contains token ids that have not been purchased. -pub const AVAILABLE_TOKENS: Map<&str, bool> = Map::new("available_tokens"); +pub const TIER_SALES: Map = Map::new("tier_sales"); -/// Is set to true when at least one sale has been conducted. This is used to disallow minting if -/// config.can_mint_after_sale is false. -pub const SALE_CONDUCTED: Item = Item::new("sale_conducted"); +pub const TIER_ORDERS: Map<(Addr, u64), OrderInfo> = Map::new("tier_orders"); + +pub const TIER_TOKEN_ID: Item = Item::new("tier_token_id"); #[cw_serde] -pub struct Purchase { - /// The token id being purchased. - pub token_id: String, - /// Amount of tax paid. - pub tax_amount: Uint128, - /// sub messages for sending funds for rates. - pub msgs: Vec, - /// The purchaser of the token. - pub purchaser: String, -} - -const MAX_LIMIT: u32 = 50; -const DEFAULT_LIMIT: u32 = 20; -pub(crate) fn get_available_tokens( +#[derive(Default)] +pub struct OrderInfo { + pub ordered: u128, + pub preordered: u128, +} + +impl OrderInfo { + pub fn amount(self) -> Option { + self.ordered.checked_add(self.preordered) + } +} + +pub(crate) fn set_config( + storage: &mut dyn Storage, + config: CampaignConfig, +) -> Result<(), ContractError> { + CAMPAIGN_CONFIG + .save(storage, &config) + .map_err(ContractError::Std) +} + +pub(crate) fn get_config(storage: &dyn Storage) -> Result { + CAMPAIGN_CONFIG.load(storage).map_err(ContractError::Std) +} + +pub(crate) fn get_duration(storage: &dyn Storage) -> Result { + CAMPAIGN_DURATION.load(storage).map_err(ContractError::Std) +} + +pub(crate) fn set_duration( + storage: &mut dyn Storage, + duration: Duration, +) -> Result<(), ContractError> { + CAMPAIGN_DURATION + .save(storage, &duration) + .map_err(ContractError::Std) +} + +pub(crate) fn get_current_capital(storage: &dyn Storage) -> Uint128 { + CURRENT_CAPITAL.load(storage).unwrap_or_default() +} + +pub(crate) fn set_current_capital( + storage: &mut dyn Storage, + current_capital: Uint128, +) -> Result<(), ContractError> { + CURRENT_CAPITAL + .save(storage, ¤t_capital) + .map_err(ContractError::Std) +} + +/// Only used on the instantiation +pub(crate) fn set_tiers(storage: &mut dyn Storage, tiers: Vec) -> Result<(), ContractError> { + for tier in tiers { + tier.validate()?; + ensure!( + !TIERS.has(storage, tier.level.into()), + ContractError::InvalidTier { + operation: "instantiate".to_string(), + msg: format!("Tier with level {} already defined", tier.level) + } + ); + TIERS.save(storage, tier.level.into(), &tier)?; + } + + Ok(()) +} + +pub(crate) fn get_tier(storage: &mut dyn Storage, level: u64) -> Result { + TIERS + .load(storage, level) + .map_err(|_| ContractError::InvalidTier { + operation: "get_tier".to_string(), + msg: format!("Tier with level {} does not exist", level), + }) +} + +pub(crate) fn add_tier(storage: &mut dyn Storage, tier: &Tier) -> Result<(), ContractError> { + ensure!( + !TIERS.has(storage, tier.level.into()), + ContractError::InvalidTier { + operation: "add".to_string(), + msg: format!("Tier with level {} already exist", tier.level) + } + ); + TIERS.save(storage, tier.level.into(), tier)?; + Ok(()) +} + +pub(crate) fn update_tier(storage: &mut dyn Storage, tier: &Tier) -> Result<(), ContractError> { + ensure!( + TIERS.has(storage, tier.level.into()), + ContractError::InvalidTier { + operation: "update".to_string(), + msg: format!("Tier with level {} does not exist", tier.level), + } + ); + + TIERS.save(storage, tier.level.into(), tier)?; + Ok(()) +} + +pub(crate) fn remove_tier(storage: &mut dyn Storage, level: u64) -> Result<(), ContractError> { + ensure!( + TIERS.has(storage, level), + ContractError::InvalidTier { + operation: "remove".to_string(), + msg: format!("Tier with level {} does not exist", level) + } + ); + + TIERS.remove(storage, level); + Ok(()) +} + +pub(crate) fn set_tier_sales( + storage: &mut dyn Storage, + level: u64, + sold_amount: Uint128, +) -> Result<(), ContractError> { + TIER_SALES.save(storage, level, &sold_amount)?; + Ok(()) +} + +pub(crate) fn get_tiers( storage: &dyn Storage, - start_after: Option, + start_after: Option, limit: Option, -) -> Result, ContractError> { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.as_deref().map(Bound::exclusive); - let tokens: Result, ContractError> = AVAILABLE_TOKENS - .keys(storage, start, None, Order::Ascending) + order_by: Option, +) -> Result, ContractError> { + let limit = limit.unwrap_or(u32::MAX) as usize; + let start = start_after.map(Bound::exclusive); + let order_by = match order_by.unwrap_or(OrderBy::Desc) { + OrderBy::Desc => Order::Descending, + _ => Order::Ascending, + }; + + TIERS + .range(storage, start, None, order_by) .take(limit) - .map(|token| Ok(token?)) + .map(|v| { + let (level, tier) = v?; + let sold_amount = TIER_SALES.load(storage, level)?; + Ok(TierResponseItem { tier, sold_amount }) + }) + .collect() +} + +pub(crate) fn is_valid_tiers(storage: &mut dyn Storage) -> bool { + !TIERS.is_empty(storage) + && TIERS + .range_raw(storage, None, None, Order::Ascending) + .any(|res| res.unwrap().1.limit.is_none()) +} + +pub(crate) fn get_current_stage(storage: &dyn Storage) -> CampaignStage { + CAMPAIGN_STAGE.load(storage).unwrap_or(CampaignStage::READY) +} + +pub(crate) fn set_current_stage( + storage: &mut dyn Storage, + stage: CampaignStage, +) -> Result<(), ContractError> { + CAMPAIGN_STAGE + .save(storage, &stage) + .map_err(ContractError::Std) +} + +pub(crate) fn set_tier_orders( + storage: &mut dyn Storage, + orders: Vec, +) -> Result<(), ContractError> { + for new_order in orders { + let tier = TIERS.load(storage, new_order.level.into()).map_err(|_| { + ContractError::InvalidTier { + operation: "set_tier_orders".to_string(), + msg: format!("Tier with level {} does not exist", new_order.level), + } + })?; + + let mut sold_amount = TIER_SALES + .load(storage, new_order.level.into()) + .unwrap_or_default(); + if let Some(limit) = tier.limit { + sold_amount = sold_amount.checked_add(new_order.amount)?; + ensure!(limit >= sold_amount, ContractError::PurchaseLimitReached {}); + + update_tier(storage, &tier)?; + set_tier_sales(storage, new_order.level.into(), sold_amount)?; + } + + let mut order = TIER_ORDERS + .load(storage, (new_order.orderer.clone(), new_order.level.into())) + .unwrap_or_default(); + + if new_order.is_presale { + order.preordered += new_order.amount.u128(); + } else { + order.ordered += new_order.amount.u128(); + } + + TIER_ORDERS.save( + storage, + (new_order.orderer.clone(), new_order.level.into()), + &order, + )?; + } + Ok(()) +} + +pub(crate) fn get_user_orders( + storage: &dyn Storage, + user: Addr, + start_after: Option, + limit: Option, + include_presale: bool, + order_by: Option, +) -> Vec { + let limit = limit.unwrap_or(u32::MAX) as usize; + let start = start_after.map(Bound::exclusive); + let order_by = match order_by.unwrap_or(OrderBy::Desc) { + OrderBy::Desc => Order::Descending, + _ => Order::Ascending, + }; + + TIER_ORDERS + .prefix(user) + .range(storage, start, None, order_by) + .take(limit) + .map(|v| { + let (level, order_info) = v.unwrap(); + let amount = if include_presale { + order_info.amount().unwrap() + } else { + order_info.ordered + }; + SimpleTierOrder { + level: Uint64::new(level), + amount: Uint128::new(amount), + } + }) + .collect() +} + +pub(crate) fn clear_user_orders( + storage: &mut dyn Storage, + user: Addr, +) -> Result<(), ContractError> { + let levels: Vec = TIER_ORDERS + .prefix(user.clone()) + .range(storage, None, None, Order::Ascending) + .map(|v| v.unwrap().0) .collect(); - tokens + + for level in levels { + TIER_ORDERS.remove(storage, (user.clone(), level)); + } + Ok(()) +} + +pub(crate) fn get_and_increase_tier_token_id( + storage: &mut dyn Storage, +) -> Result { + let tier_token_id = TIER_TOKEN_ID.load(storage).unwrap_or_default(); + let next_tier_token_id = tier_token_id.checked_add(Uint128::one())?; + TIER_TOKEN_ID.save(storage, &next_tier_token_id)?; + Ok(tier_token_id) +} + +#[cfg(test)] +mod tests { + use super::*; + use andromeda_non_fungible_tokens::{crowdfund::TierMetaData, cw721::TokenExtension}; + use cosmwasm_std::testing::MockStorage; + + fn mock_storage() -> MockStorage { + let mut storage = MockStorage::new(); + // Initialize some mock data for testing + let tiers = vec![ + Tier { + level: Uint64::one(), + price: Uint128::new(100), + limit: Some(Uint128::new(1000)), + label: "tier 1".to_string(), + metadata: TierMetaData { + token_uri: None, + extension: TokenExtension { + ..Default::default() + }, + }, + }, + Tier { + level: Uint64::new(2u64), + price: Uint128::new(200), + limit: None, + label: "tier 2".to_string(), + metadata: TierMetaData { + token_uri: None, + extension: TokenExtension { + ..Default::default() + }, + }, + }, + ]; + set_tiers(&mut storage, tiers).unwrap(); + let user1 = Addr::unchecked("user1"); + let orders = vec![ + TierOrder { + orderer: user1.clone(), + level: Uint64::one(), + amount: Uint128::new(50), + is_presale: true, + }, + TierOrder { + orderer: user1.clone(), + level: Uint64::one(), + amount: Uint128::new(50), + is_presale: false, + }, + ]; + set_tier_orders(&mut storage, orders).unwrap(); + storage + } + + pub struct GetUserOrderTestCase { + name: String, + include_presale: bool, + user: Addr, + expected_res: Vec, + } + fn get_tier_sales(storage: &mut dyn Storage, level: u64) -> Uint128 { + TIER_SALES.load(storage, level).unwrap_or_default() + } + + #[test] + fn test_get_user_orders() { + let test_cases = vec![ + GetUserOrderTestCase { + name: "get_user_orders including pesale".to_string(), + include_presale: true, + user: Addr::unchecked("user1"), + expected_res: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(100), + }], + }, + GetUserOrderTestCase { + name: "get_user_orders excluding pesale".to_string(), + include_presale: false, + user: Addr::unchecked("user1"), + expected_res: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(50), + }], + }, + GetUserOrderTestCase { + name: "get_user_orders for non ordered user".to_string(), + include_presale: false, + user: Addr::unchecked("user2"), + expected_res: vec![], + }, + ]; + let storage = mock_storage(); + + for test in test_cases { + let res = get_user_orders( + &storage, + test.user.clone(), + None, + None, + test.include_presale, + None, + ); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + } + } + + pub struct SetOrderTestCase { + name: String, + order: TierOrder, + expected_res: Result<(), ContractError>, + } + + #[test] + fn test_set_tier_orders() { + let test_cases = vec![ + SetOrderTestCase { + name: "set_tier_orders with valid orders".to_string(), + order: TierOrder { + level: Uint64::new(1), + amount: Uint128::new(100), + orderer: Addr::unchecked("user1"), + is_presale: false, + }, + expected_res: Ok(()), + }, + SetOrderTestCase { + name: "set_tier_orders with an order exceeding limit".to_string(), + order: TierOrder { + level: Uint64::new(1), + amount: Uint128::new(1000), + orderer: Addr::unchecked("user2"), + is_presale: false, + }, + expected_res: Err(ContractError::PurchaseLimitReached {}), + }, + SetOrderTestCase { + name: "set_tier_orders with an order for non-existing tier".to_string(), + order: TierOrder { + level: Uint64::new(3), + amount: Uint128::new(50), + orderer: Addr::unchecked("user3"), + is_presale: false, + }, + expected_res: Err(ContractError::InvalidTier { + operation: "set_tier_orders".to_string(), + msg: "Tier with level 3 does not exist".to_string(), + }), + }, + ]; + + for test in test_cases { + let mut storage = mock_storage(); + let level: u64 = test.order.level.into(); + let ordered_amount = test.order.amount; + let orderer = test.order.orderer.clone(); + let prev_sold_amount = get_tier_sales(&mut storage, level); + let prev_order = TIER_ORDERS.load(&storage, (orderer.clone(), level)); + let is_presale = test.order.is_presale; + + let res = set_tier_orders(&mut storage, vec![test.order]); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + + if res.is_ok() { + let sold_amount = get_tier_sales(&mut storage, level); + assert_eq!(sold_amount, prev_sold_amount + ordered_amount); + let order = TIER_ORDERS.load(&storage, (orderer, level)).unwrap(); + let prev_order = prev_order.unwrap(); + if is_presale { + assert_eq!( + order, + OrderInfo { + ordered: prev_order.ordered, + preordered: prev_order.preordered + ordered_amount.u128(), + }, + "Test case: {}", + test.name + ); + } else { + assert_eq!( + order, + OrderInfo { + ordered: prev_order.ordered + ordered_amount.u128(), + preordered: prev_order.preordered, + }, + "Test case: {}", + test.name + ); + } + } + } + } } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/mock_querier.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/mock_querier.rs index 4b10080..03f5ae3 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/mock_querier.rs @@ -1,32 +1,81 @@ -use andromeda_std::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; -use andromeda_std::ado_base::InstantiateMsg; -use andromeda_std::ado_contract::ADOContract; -use andromeda_std::common::Funds; -use andromeda_std::testing::mock_querier::MockAndromedaQuerier; -use cosmwasm_std::testing::mock_info; +use andromeda_non_fungible_tokens::{ + crowdfund::{CampaignConfig, Tier, TierMetaData}, + cw721::TokenExtension, +}; +use andromeda_std::{ + ado_base::InstantiateMsg, + ado_contract::ADOContract, + amp::{AndrAddr, Recipient}, + common::denom::Asset, + testing::mock_querier::{WasmMockQuerier, MOCK_ADO_PUBLISHER, MOCK_KERNEL_CONTRACT}, +}; use cosmwasm_std::{ - from_json, - testing::{mock_env, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, QueryRequest, - SystemError, SystemResult, WasmQuery, + testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage}, + Coin, OwnedDeps, QuerierWrapper, Uint128, Uint64, }; -use cosmwasm_std::{BankMsg, CosmosMsg, Response, SubMsg, Uint128}; -use cw721::{Cw721QueryMsg, TokensResponse}; -pub use andromeda_std::testing::mock_querier::{ - MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, MOCK_RATES_CONTRACT, -}; +pub const MOCK_DEFAULT_OWNER: &str = "owner"; +pub const MOCK_TIER_CONTRACT: &str = "tier_contract"; +pub const MOCK_WITHDRAWAL_ADDRESS: &str = "withdrawal_address"; +pub const MOCK_DEFAULT_LIMIT: u128 = 100000; -pub const MOCK_TOKEN_CONTRACT: &str = "token_contract"; +pub fn mock_campaign_config(denom: Asset) -> CampaignConfig { + CampaignConfig { + title: Some("First Crowdfund".to_string()), + description: Some("Demo campaign for testing".to_string()), + banner: Some("http://".to_string()), + url: Some("http://".to_string()), + denom, + token_address: AndrAddr::from_string(MOCK_TIER_CONTRACT.to_owned()), + withdrawal_recipient: Recipient::from_string(MOCK_WITHDRAWAL_ADDRESS.to_owned()), + soft_cap: None, + hard_cap: None, + } +} -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; -pub const MOCK_TOKENS_FOR_SALE: &[&str] = &[ - "token1", "token2", "token3", "token4", "token5", "token6", "token7", -]; +pub fn mock_campaign_tiers() -> Vec { + vec![ + Tier { + level: Uint64::zero(), + label: "Basic Tier".to_string(), + limit: None, + price: Uint128::new(10u128), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }, + Tier { + level: Uint64::new(1u64), + label: "Tier 1".to_string(), + limit: Some(Uint128::new(MOCK_DEFAULT_LIMIT)), + price: Uint128::new(10u128), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }, + ] +} -pub const MOCK_CONDITIONS_MET_CONTRACT: &str = "conditions_met"; -pub const MOCK_CONDITIONS_NOT_MET_CONTRACT: &str = "conditions_not_met"; +pub fn mock_zero_price_tier(level: Uint64) -> Tier { + Tier { + level, + label: "Invalid Tier".to_string(), + limit: None, + price: Uint128::zero(), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + } +} /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. /// @@ -35,7 +84,7 @@ pub fn mock_dependencies_custom( contract_balance: &[Coin], ) -> OwnedDeps { let custom_querier: WasmMockQuerier = - WasmMockQuerier::new(MockQuerier::new(&[(MOCK_CONTRACT_ADDR, contract_balance)])); + WasmMockQuerier::new(MockQuerier::new(&[(MOCK_TIER_CONTRACT, contract_balance)])); let storage = MockStorage::default(); let mut deps = OwnedDeps { storage, @@ -48,11 +97,11 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "crowdfund".to_string(), ado_version: "test".to_string(), - operators: None, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -60,154 +109,3 @@ pub fn mock_dependencies_custom( .unwrap(); deps } - -pub struct WasmMockQuerier { - pub base: MockQuerier, - pub contract_address: String, - pub tokens_left_to_burn: usize, -} - -impl Querier for WasmMockQuerier { - fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { - // MockQuerier doesn't support Custom, so we ignore it completely here - let request: QueryRequest = match from_json(bin_request) { - Ok(v) => v, - Err(e) => { - return SystemResult::Err(SystemError::InvalidRequest { - error: format!("Parsing query request: {e}"), - request: bin_request.into(), - }) - } - }; - self.handle_query(&request) - } -} - -impl WasmMockQuerier { - pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { - match &request { - QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { - match contract_addr.as_str() { - MOCK_TOKEN_CONTRACT => self.handle_token_query(msg), - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), - MOCK_ADDRESS_LIST_CONTRACT => self.handle_addresslist_query(msg), - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } - } - _ => MockAndromedaQuerier::default().handle_query(&self.base, request), - } - } - - fn handle_token_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - Cw721QueryMsg::Tokens { owner, .. } => { - let res = if owner == MOCK_CONDITIONS_MET_CONTRACT - || owner == MOCK_CONDITIONS_NOT_MET_CONTRACT - { - TokensResponse { - tokens: MOCK_TOKENS_FOR_SALE - [MOCK_TOKENS_FOR_SALE.len() - self.tokens_left_to_burn..] - .iter() - .copied() - .map(String::from) - .collect(), - } - } else { - TokensResponse { - tokens: MOCK_TOKENS_FOR_SALE - .iter() - .copied() - .map(String::from) - .collect(), - } - }; - - SystemResult::Ok(ContractResult::Ok(to_json_binary(&res).unwrap())) - } - - _ => panic!("Unsupported Query"), - } - } - - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - let resp: Response = Response::default(); - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&resp).unwrap(), - )); - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&Some(response)).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - pub fn new(base: MockQuerier) -> Self { - WasmMockQuerier { - base, - contract_address: mock_env().contract.address.to_string(), - tokens_left_to_burn: 2, - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/tests.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/tests.rs index ed02ad8..c40ac5d 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/tests.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-crowdfund/src/testing/tests.rs @@ -1,1711 +1,1564 @@ -use crate::{ - contract::{execute, instantiate, query, MAX_MINT_LIMIT}, - state::{ - Purchase, AVAILABLE_TOKENS, CONFIG, NUMBER_OF_TOKENS_AVAILABLE, PURCHASES, SALE_CONDUCTED, - STATE, - }, - testing::mock_querier::{ - mock_dependencies_custom, MOCK_ADDRESS_LIST_CONTRACT, MOCK_APP_CONTRACT, - MOCK_CONDITIONS_MET_CONTRACT, MOCK_CONDITIONS_NOT_MET_CONTRACT, MOCK_RATES_CONTRACT, - MOCK_ROYALTY_RECIPIENT, MOCK_TAX_RECIPIENT, MOCK_TOKENS_FOR_SALE, MOCK_TOKEN_CONTRACT, - }, -}; use andromeda_non_fungible_tokens::{ crowdfund::{ - Config, CrowdfundMintMsg, ExecuteMsg, InstantiateMsg, IsTokenAvailableResponse, QueryMsg, - State, + CampaignConfig, CampaignStage, ExecuteMsg, InstantiateMsg, SimpleTierOrder, Tier, + TierMetaData, }, cw721::{ExecuteMsg as Cw721ExecuteMsg, TokenExtension}, }; + use andromeda_std::{ - ado_base::modules::Module, - amp::{addresses::AndrAddr, recipient::Recipient}, - common::encode_binary, + common::{reply::ReplyId, MillisecondsExpiration}, error::ContractError, + os::economics::ExecuteMsg as EconomicsExecuteMsg, + testing::mock_querier::{MOCK_ADO_PUBLISHER, MOCK_KERNEL_CONTRACT}, }; use cosmwasm_std::{ - coin, coins, from_json, testing::{mock_env, mock_info}, - Addr, BankMsg, Coin, CosmosMsg, DepsMut, Response, StdError, SubMsg, Uint128, WasmMsg, + to_json_binary, Addr, CosmosMsg, DepsMut, Env, Order, Response, Storage, SubMsg, Uint128, + Uint64, WasmMsg, }; -use cw_utils::Expiration; - -use super::mock_querier::MOCK_KERNEL_CONTRACT; - -const ADDRESS_LIST: &str = "addresslist"; -const RATES: &str = "rates"; -fn get_purchase(token_id: impl Into, purchaser: impl Into) -> Purchase { - Purchase { - token_id: token_id.into(), - purchaser: purchaser.into(), - tax_amount: Uint128::from(50u128), - msgs: get_rates_messages(), - } -} - -fn get_rates_messages() -> Vec { - let coin = coin(100u128, "uusd"); - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom, - }], - })), - ] -} +use crate::{ + contract::{execute, instantiate}, + state::{ + Duration, CAMPAIGN_CONFIG, CAMPAIGN_DURATION, CAMPAIGN_STAGE, CURRENT_CAPITAL, TIERS, + TIER_ORDERS, + }, + testing::mock_querier::{mock_dependencies_custom, mock_zero_price_tier, MOCK_DEFAULT_LIMIT}, +}; -fn get_burn_message(token_id: impl Into) -> CosmosMsg { - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_CONTRACT.to_owned(), - funds: vec![], - msg: encode_binary(&Cw721ExecuteMsg::Burn { - token_id: token_id.into(), - }) - .unwrap(), - }) -} +use super::mock_querier::{mock_campaign_config, mock_campaign_tiers, MOCK_DEFAULT_OWNER}; -fn get_transfer_message(token_id: impl Into, recipient: impl Into) -> CosmosMsg { - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_CONTRACT.to_owned(), - msg: encode_binary(&Cw721ExecuteMsg::TransferNft { - recipient: recipient.into(), - token_id: token_id.into(), - }) - .unwrap(), - funds: vec![], - }) -} - -fn init(deps: DepsMut, modules: Option>) -> Response { +fn init(deps: DepsMut, config: CampaignConfig, tiers: Vec) -> Response { let msg = InstantiateMsg { - token_address: AndrAddr::from_string(MOCK_TOKEN_CONTRACT.to_owned()), + campaign_config: config, + tiers, owner: None, - modules, - can_mint_after_sale: true, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), }; - let info = mock_info("owner", &[]); + let info = mock_info(MOCK_DEFAULT_OWNER, &[]); instantiate(deps, mock_env(), info, msg).unwrap() } -#[test] -fn test_instantiate() { - let mut deps = mock_dependencies_custom(&[]); - - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - - let res = init(deps.as_mut(), Some(modules)); - - assert_eq!( - Response::new() - .add_attribute("method", "instantiate") - .add_attribute("type", "crowdfund") - .add_attribute("action", "register_module") - .add_attribute("module_idx", "1"), - res - ); - - assert_eq!( - Config { - token_address: AndrAddr::from_string(MOCK_TOKEN_CONTRACT.to_owned()), - can_mint_after_sale: true - }, - CONFIG.load(deps.as_mut().storage).unwrap() - ); - - assert!(!SALE_CONDUCTED.load(deps.as_mut().storage).unwrap()); +fn get_campaign_config(storage: &dyn Storage) -> CampaignConfig { + CAMPAIGN_CONFIG.load(storage).unwrap() } -#[test] -fn test_mint_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::Mint(vec![CrowdfundMintMsg { - token_id: "token_id".to_string(), - owner: None, - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }]); - let info = mock_info("not_owner", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); +fn get_tiers(storage: &dyn Storage) -> Vec { + TIERS + .range_raw(storage, None, None, Order::Ascending) + .map(|res| res.unwrap().1) + .collect() } -#[test] -fn test_mint_owner_not_crowdfund() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::Mint(vec![CrowdfundMintMsg { - token_id: "token_id".to_string(), - owner: Some("not_crowdfund".to_string()), - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }]); - let info = mock_info("owner", &[]); - let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - // Since token was minted to owner that is not the contract, it is not available for sale. - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, "token_id")); +fn future_time(env: &Env) -> MillisecondsExpiration { + MillisecondsExpiration::from_seconds(env.block.time.seconds() + 5000) } - -#[test] -fn test_mint_sale_started() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::StartSale { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: Some(5), - recipient: Recipient::from_string("recipient"), - }; - - let info = mock_info("owner", &[]); - let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - let res = mint(deps.as_mut(), "token_id"); - - assert_eq!(ContractError::SaleStarted {}, res.unwrap_err()); +fn past_time() -> MillisecondsExpiration { + MillisecondsExpiration::from_seconds(0) // Past timestamp } - -#[test] -fn test_mint_sale_conducted_cant_mint_after_sale() { - let mut deps = mock_dependencies_custom(&[]); - let msg = InstantiateMsg { - token_address: AndrAddr::from_string(MOCK_TOKEN_CONTRACT.to_owned()), - modules: None, - owner: None, - can_mint_after_sale: false, - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - }; - - let info = mock_info("owner", &[]); - let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); - - SALE_CONDUCTED.save(deps.as_mut().storage, &true).unwrap(); - - let res = mint(deps.as_mut(), "token_id"); - - assert_eq!( - ContractError::CannotMintAfterSaleConducted {}, - res.unwrap_err() - ); +fn set_campaign_stage(store: &mut dyn Storage, stage: &CampaignStage) { + CAMPAIGN_STAGE.save(store, stage).unwrap(); } - -#[test] -fn test_mint_sale_conducted_can_mint_after_sale() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - SALE_CONDUCTED.save(deps.as_mut().storage, &true).unwrap(); - - let _res = mint(deps.as_mut(), "token_id").unwrap(); - - assert!(AVAILABLE_TOKENS.has(deps.as_ref().storage, "token_id")); +fn set_current_capital(store: &mut dyn Storage, current_capital: &Uint128) { + CURRENT_CAPITAL.save(store, current_capital).unwrap(); } -#[test] -fn test_mint_successful() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let res = mint(deps.as_mut(), "token_id").unwrap(); - - let mint_msg = Cw721ExecuteMsg::Mint { - token_id: "token_id".to_string(), - owner: mock_env().contract.address.to_string(), - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }; - - assert_eq!( - Response::new() - .add_attribute("action", "mint") - .add_message(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_CONTRACT.to_owned(), - msg: encode_binary(&mint_msg).unwrap(), - funds: vec![], - }), - res - ); - - assert!(AVAILABLE_TOKENS.has(deps.as_ref().storage, "token_id")); +fn set_campaign_config(store: &mut dyn Storage, config: &CampaignConfig) { + CAMPAIGN_CONFIG.save(store, config).unwrap(); } - -#[test] -fn test_mint_multiple_successful() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let mint_msgs = vec![ - CrowdfundMintMsg { - token_id: "token_id1".to_string(), - owner: None, - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }, - CrowdfundMintMsg { - token_id: "token_id2".to_string(), - owner: None, - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }, - ]; - - let msg = ExecuteMsg::Mint(mint_msgs); - let res = execute(deps.as_mut(), mock_env(), mock_info("owner", &[]), msg).unwrap(); - - assert_eq!( - Response::new() - .add_attribute("action", "mint") - .add_attribute("action", "mint") - .add_message(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_CONTRACT.to_owned(), - msg: encode_binary(&Cw721ExecuteMsg::Mint { - token_id: "token_id1".to_string(), - owner: mock_env().contract.address.to_string(), - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }) - .unwrap(), - funds: vec![], - }) - .add_message(WasmMsg::Execute { - contract_addr: MOCK_TOKEN_CONTRACT.to_owned(), - msg: encode_binary(&Cw721ExecuteMsg::Mint { - token_id: "token_id2".to_string(), - owner: mock_env().contract.address.to_string(), - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }) - .unwrap(), - funds: vec![], - }), - res - ); - - assert!(AVAILABLE_TOKENS.has(deps.as_ref().storage, "token_id1")); - assert!(AVAILABLE_TOKENS.has(deps.as_ref().storage, "token_id2")); - - assert_eq!( - NUMBER_OF_TOKENS_AVAILABLE - .load(deps.as_ref().storage) - .unwrap(), - Uint128::new(2) - ); +fn set_campaign_duration(store: &mut dyn Storage, duration: &Duration) { + CAMPAIGN_DURATION.save(store, duration).unwrap(); } - -#[test] -fn test_mint_multiple_exceeds_limit() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let mint_msg = CrowdfundMintMsg { - token_id: "token_id1".to_string(), - owner: None, - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }; - - let mut mint_msgs: Vec = vec![]; - - for _ in 0..MAX_MINT_LIMIT + 1 { - mint_msgs.push(mint_msg.clone()); +fn set_tiers(storage: &mut dyn Storage, tiers: Vec) { + for tier in tiers { + TIERS.save(storage, tier.level.into(), &tier).unwrap(); } - - let msg = ExecuteMsg::Mint(mint_msgs.clone()); - let res = execute(deps.as_mut(), mock_env(), mock_info("owner", &[]), msg); - - assert_eq!( - ContractError::TooManyMintMessages { - limit: MAX_MINT_LIMIT - }, - res.unwrap_err() - ); -} - -#[test] -fn test_start_sale_no_expiration() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::StartSale { - expiration: Expiration::Never {}, - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: None, - recipient: Recipient::from_string("recipient".to_string()), - }; - - let info = mock_info("owner", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::ExpirationMustNotBeNever {}, res.unwrap_err()); } -#[test] -fn test_start_sale_expiration_in_past() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::StartSale { - expiration: Expiration::AtHeight(mock_env().block.height - 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: None, - recipient: Recipient::from_string("recipient"), - }; - - let info = mock_info("owner", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::ExpirationInPast {}, res.unwrap_err()); -} - -#[test] -fn test_start_sale_unauthorized() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::StartSale { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: None, - recipient: Recipient::from_string("recipient"), - }; - - let info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); +fn get_user_orders( + storage: &dyn Storage, + user: Addr, +) -> Result, ContractError> { + TIER_ORDERS + .prefix(user) + .range(storage, None, None, Order::Ascending) + .map(|res| { + Ok(res.map(|(level, order_info)| SimpleTierOrder { + level: Uint64::new(level), + amount: Uint128::new(order_info.amount().unwrap()), + })?) + }) + .collect() } - -#[test] -fn test_start_sale_max_default() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::StartSale { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: None, - recipient: Recipient::from_string("recipient"), +#[cfg(test)] +mod test { + use andromeda_non_fungible_tokens::crowdfund::{ + Cw20HookMsg, PresaleTierOrder, SimpleTierOrder, TierOrder, }; - - let info = mock_info("owner", &[]); - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg.clone()).unwrap(); - assert_eq!( - Response::new() - .add_attribute("action", "start_sale") - .add_attribute("expiration", "expiration height: 12346") - .add_attribute("price", "100uusd") - .add_attribute("min_tokens_sold", "1") - .add_attribute("max_amount_per_wallet", "1"), - res - ); - - assert_eq!( - State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 1, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }, - STATE.load(deps.as_ref().storage).unwrap() - ); - - assert!(SALE_CONDUCTED.load(deps.as_ref().storage).unwrap()); - - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::SaleStarted {}, res.unwrap_err()); -} - -#[test] -fn test_start_sale_max_modified() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::StartSale { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: Some(5), - recipient: Recipient::from_string("recipient"), + use andromeda_std::{ + amp::{messages::AMPPkt, AndrAddr, Recipient}, + common::{denom::Asset, encode_binary}, + testing::mock_querier::MOCK_CW20_CONTRACT, }; + use cosmwasm_std::{coin, coins, testing::MOCK_CONTRACT_ADDR, wasm_execute, BankMsg, Coin}; + use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; - let info = mock_info("owner", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - assert_eq!( - Response::new() - .add_attribute("action", "start_sale") - .add_attribute("expiration", "expiration height: 12346") - .add_attribute("price", "100uusd") - .add_attribute("min_tokens_sold", "1") - .add_attribute("max_amount_per_wallet", "5"), - res - ); - - assert_eq!( - State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }, - STATE.load(deps.as_ref().storage).unwrap() - ); -} - -#[test] -fn test_purchase_sale_not_started() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, + use crate::{ + state::{get_current_capital, set_current_stage, set_tier_orders, TIER_SALES}, + testing::mock_querier::{MOCK_DEFAULT_OWNER, MOCK_WITHDRAWAL_ADDRESS}, }; - let info = mock_info("sender", &[]); - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg); - assert_eq!(ContractError::NoOngoingSale {}, res.unwrap_err()); + use super::*; - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::NoOngoingSale {}, res.unwrap_err()); -} + const MOCK_NATIVE_DENOM: &str = "uandr"; + const INVA1LID_DENOM: &str = "other"; -#[test] -fn test_purchase_sale_not_ended() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height - 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + struct InstantiateTestCase { + name: String, + config: CampaignConfig, + tiers: Vec, + expected_res: Result, + } + #[test] + fn test_instantiate() { + let test_cases: Vec = vec![ + InstantiateTestCase { + name: "instantiate with native token".to_string(), + config: mock_campaign_config(Asset::NativeToken(MOCK_NATIVE_DENOM.to_string())), + tiers: mock_campaign_tiers(), + expected_res: Ok(Response::new() + .add_attribute("method", "instantiate") + .add_attribute("type", "crowdfund") + .add_attribute("kernel_address", MOCK_KERNEL_CONTRACT) + .add_attribute(MOCK_DEFAULT_OWNER, MOCK_DEFAULT_OWNER)), }, - ) - .unwrap(); - - let info = mock_info("sender", &[]); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg); - assert_eq!(ContractError::NoOngoingSale {}, res.unwrap_err()); - - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::NoOngoingSale {}, res.unwrap_err()); -} - -#[test] -fn test_purchase_no_funds() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + InstantiateTestCase { + name: "instantiate with invalid native token".to_string(), + config: mock_campaign_config(Asset::NativeToken(INVA1LID_DENOM.to_string())), + tiers: mock_campaign_tiers(), + expected_res: Err(ContractError::InvalidAsset { + asset: Asset::NativeToken(INVA1LID_DENOM.to_string()).to_string(), + }), }, - ) - .unwrap(); - - let info = mock_info("sender", &[]); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); - - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); -} - -#[test] -fn test_purchase_wrong_denom() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + InstantiateTestCase { + name: "instantiate with cw20".to_string(), + config: mock_campaign_config(Asset::Cw20Token(AndrAddr::from_string( + MOCK_CW20_CONTRACT.to_string(), + ))), + tiers: mock_campaign_tiers(), + expected_res: Ok(Response::new() + .add_attribute("method", "instantiate") + .add_attribute("type", "crowdfund") + .add_attribute("kernel_address", MOCK_KERNEL_CONTRACT) + .add_attribute(MOCK_DEFAULT_OWNER, MOCK_DEFAULT_OWNER)), }, - ) - .unwrap(); - - let info = mock_info("sender", &coins(100, "uluna")); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); - - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); -} - -#[test] -fn test_purchase_not_enough_for_price() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + InstantiateTestCase { + name: "instantiate with invalid cw20".to_string(), + config: mock_campaign_config(Asset::Cw20Token(AndrAddr::from_string( + "cw20_contract1".to_string(), + ))), + tiers: mock_campaign_tiers(), + expected_res: Err(ContractError::InvalidAsset { + asset: Asset::Cw20Token(AndrAddr::from_string("cw20_contract1".to_string())) + .to_string(), + }), }, - ) - .unwrap(); - - let info = mock_info("sender", &coins(50u128, "uusd")); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); - - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); -} - -#[test] -fn test_purchase_not_enough_for_tax() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - - NUMBER_OF_TOKENS_AVAILABLE - .save(deps.as_mut().storage, &Uint128::new(1)) - .unwrap(); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + InstantiateTestCase { + name: "instantiate with invalid tiers including zero price tier".to_string(), + config: mock_campaign_config(Asset::NativeToken(MOCK_NATIVE_DENOM.to_string())), + tiers: vec![mock_zero_price_tier(Uint64::zero())], + expected_res: Err(ContractError::InvalidTier { + operation: "all".to_string(), + msg: "Price can not be zero".to_string(), + }), }, - ) - .unwrap(); - - let info = mock_info("sender", &coins(100u128, "uusd")); + ]; + + for test in test_cases { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + let info = mock_info(MOCK_DEFAULT_OWNER, &[]); + let msg = InstantiateMsg { + campaign_config: test.config.clone(), + tiers: test.tiers.clone(), + owner: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + }; + let res = instantiate(deps.as_mut(), mock_env(), info, msg); + + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + if res.is_ok() { + assert_eq!( + get_campaign_config(&deps.storage), + test.config, + "Test case: {}", + test.name + ); + let expected_tiers: Vec = test.tiers.into_iter().collect(); + assert_eq!( + get_tiers(deps.as_ref().storage), + expected_tiers, + "Test case: {}", + test.name + ); + } + } + } - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); - - // Reset the state since state does not roll back on failure in tests like it does in prod. - AVAILABLE_TOKENS - .save(deps.as_mut().storage, MOCK_TOKENS_FOR_SALE[0], &true) - .unwrap(); - NUMBER_OF_TOKENS_AVAILABLE - .save(deps.as_mut().storage, &Uint128::new(1)) - .unwrap(); - - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); -} + struct TierTestCase { + name: String, + tier: Tier, + expected_res: Result, + payee: String, + } -#[test] -fn test_purchase_by_token_id_not_available() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + #[test] + fn test_add_tier() { + let valid_tier = Tier { + level: Uint64::new(2u64), + label: "Tier 2".to_string(), + limit: Some(Uint128::new(100)), + price: Uint128::new(100), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, }, - ) - .unwrap(); - - let info = mock_info("sender", &coins(150, "uusd")); - - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[1].to_owned(), - }; - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::TokenNotAvailable {}, res.unwrap_err()); -} - -#[test] -fn test_purchase_by_token_id() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[1]).unwrap(); - - let mut state = State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 1, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }; - - STATE.save(deps.as_mut().storage, &state).unwrap(); - - let info = mock_info("sender", &coins(150, "uusd")); - - // Purchase a token. - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - assert_eq!( - Response::new() - .add_attribute("action", "purchase") - .add_attribute("token_id", MOCK_TOKENS_FOR_SALE[0]), - res - ); - - state.amount_to_send += Uint128::from(90u128); - state.amount_sold += Uint128::from(1u128); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[0])); - assert_eq!( - NUMBER_OF_TOKENS_AVAILABLE - .load(deps.as_ref().storage) - .unwrap(), - Uint128::new(1) - ); - - // Purchase a second one. - let msg = ExecuteMsg::PurchaseByTokenId { - token_id: MOCK_TOKENS_FOR_SALE[1].to_owned(), - }; - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::PurchaseLimitReached {}, res.unwrap_err()); -} - -#[test] -fn test_multiple_purchases() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - - // Mint four tokens. - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[1]).unwrap(); - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[2]).unwrap(); - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[3]).unwrap(); - - // Query available tokens. - let msg = QueryMsg::AvailableTokens { - start_after: None, - limit: None, - }; - let res: Vec = from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - assert_eq!( - vec![ - MOCK_TOKENS_FOR_SALE[0], - MOCK_TOKENS_FOR_SALE[1], - MOCK_TOKENS_FOR_SALE[2], - MOCK_TOKENS_FOR_SALE[3] - ], - res - ); - - // Query if individual token is available - let msg = QueryMsg::IsTokenAvailable { - id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - }; - let res: IsTokenAvailableResponse = - from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - assert!(res.is_token_available); - - // Query if another token is available - let msg = QueryMsg::IsTokenAvailable { - id: MOCK_TOKENS_FOR_SALE[4].to_owned(), - }; - let res: IsTokenAvailableResponse = - from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - let res = res.is_token_available; - - assert!(!res); - - // Purchase 2 tokens - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(2), - }; - - let mut state = State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 3, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }; - STATE.save(deps.as_mut().storage, &state).unwrap(); - - let info = mock_info("sender", &coins(300u128, "uusd")); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_attribute("action", "purchase") - .add_attribute("number_of_tokens_wanted", "2") - .add_attribute("number_of_tokens_purchased", "2"), - res - ); - - state.amount_to_send += Uint128::from(180u128); - state.amount_sold += Uint128::from(2u128); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[0])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[1])); - - assert_eq!( - vec![ - get_purchase(MOCK_TOKENS_FOR_SALE[0], "sender"), - get_purchase(MOCK_TOKENS_FOR_SALE[1], "sender") - ], - PURCHASES.load(deps.as_ref().storage, "sender").unwrap() - ); - - // Purchase max number of tokens. - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - - let info = mock_info("sender", &coins(300u128, "uusd")); - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(BankMsg::Send { - to_address: "sender".to_string(), - // Refund sent back as they only were able to mint one. - amount: coins(150, "uusd") - }) - .add_attribute("action", "purchase") - .add_attribute("number_of_tokens_wanted", "1") - .add_attribute("number_of_tokens_purchased", "1"), - res - ); - - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[2])); - state.amount_to_send += Uint128::from(90u128); - state.amount_sold += Uint128::from(1u128); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - assert_eq!( - vec![ - get_purchase(MOCK_TOKENS_FOR_SALE[0], "sender"), - get_purchase(MOCK_TOKENS_FOR_SALE[1], "sender"), - get_purchase(MOCK_TOKENS_FOR_SALE[2], "sender") - ], - PURCHASES.load(deps.as_ref().storage, "sender").unwrap() - ); - - // Try to purchase an additional token when limit has already been reached. - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::PurchaseLimitReached {}, res.unwrap_err()); - - // User 2 tries to purchase 2 but only 1 is left. - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(2), - }; - - let info = mock_info("user2", &coins(300, "uusd")); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(BankMsg::Send { - to_address: "user2".to_string(), - // Refund sent back as they only were able to mint one. - amount: coins(150, "uusd") - }) - .add_attribute("action", "purchase") - .add_attribute("number_of_tokens_wanted", "2") - .add_attribute("number_of_tokens_purchased", "1"), - res - ); - - assert_eq!( - vec![get_purchase(MOCK_TOKENS_FOR_SALE[3], "user2"),], - PURCHASES.load(deps.as_ref().storage, "user2").unwrap() - ); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[3])); - state.amount_to_send += Uint128::from(90u128); - state.amount_sold += Uint128::from(1u128); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - assert_eq!( - NUMBER_OF_TOKENS_AVAILABLE - .load(deps.as_ref().storage) - .unwrap(), - Uint128::zero() - ); - - // User 2 tries to purchase again. - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - - let info = mock_info("user2", &coins(150, "uusd")); - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::AllTokensPurchased {}, res.unwrap_err()); -} - -#[test] -fn test_purchase_more_than_allowed_per_wallet() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - - // Mint four tokens. - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[0]).unwrap(); - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[1]).unwrap(); - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[2]).unwrap(); - mint(deps.as_mut(), MOCK_TOKENS_FOR_SALE[3]).unwrap(); - - // Try to purchase 4 - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(4), - }; - - let state = State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 3, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }; - STATE.save(deps.as_mut().storage, &state).unwrap(); - - let info = mock_info("sender", &coins(600, "uusd")); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_message(BankMsg::Send { - to_address: "sender".to_string(), - amount: coins(150, "uusd") - }) - .add_attribute("action", "purchase") - // Number got truncated to 3 which is the max possible. - .add_attribute("number_of_tokens_wanted", "3") - .add_attribute("number_of_tokens_purchased", "3"), - res - ); -} - -#[test] -fn test_end_sale_not_expired() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - let state = State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 2, - amount_sold: Uint128::zero(), - amount_to_send: Uint128::zero(), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }; - STATE.save(deps.as_mut().storage, &state).unwrap(); - NUMBER_OF_TOKENS_AVAILABLE - .save(deps.as_mut().storage, &Uint128::new(1)) - .unwrap(); - - let msg = ExecuteMsg::EndSale { limit: None }; - let info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); - assert_eq!(ContractError::SaleNotEnded {}, res.unwrap_err()); -} - -fn mint(deps: DepsMut, token_id: impl Into) -> Result { - let msg = ExecuteMsg::Mint(vec![CrowdfundMintMsg { - token_id: token_id.into(), - owner: None, - token_uri: None, - extension: TokenExtension { - publisher: "publisher".to_string(), - }, - }]); - execute(deps, mock_env(), mock_info("owner", &[]), msg) -} - -#[test] -fn test_integration_conditions_not_met() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - - // Mint all tokens. - for &token_id in MOCK_TOKENS_FOR_SALE { - let _res = mint(deps.as_mut(), token_id).unwrap(); - assert!(AVAILABLE_TOKENS.has(deps.as_ref().storage, token_id)); + }; + let duplicated_tier = Tier { + level: Uint64::new(0u64), + label: "Tier 2".to_string(), + limit: Some(Uint128::new(100)), + price: Uint128::new(100), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }; + + let test_cases: Vec = vec![ + TierTestCase { + name: "standard add_tier".to_string(), + tier: valid_tier.clone(), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Ok(Response::new() + .add_attribute("action", "add_tier") + .add_attribute("level", valid_tier.level.to_string()) + .add_attribute("label", valid_tier.label.clone()) + .add_attribute("price", valid_tier.price.to_string()) + .add_attribute("limit", valid_tier.limit.unwrap().to_string()) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER), + action: "AddTier".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + }, + TierTestCase { + name: "add_tier with unauthorized sender".to_string(), + tier: valid_tier.clone(), + expected_res: Err(ContractError::Unauthorized {}), + payee: "owner1".to_string(), + }, + TierTestCase { + name: "add_tier with zero price tier".to_string(), + tier: mock_zero_price_tier(Uint64::new(2)), + expected_res: Err(ContractError::InvalidTier { + operation: "all".to_string(), + msg: "Price can not be zero".to_string(), + }), + payee: MOCK_DEFAULT_OWNER.to_string(), + }, + TierTestCase { + name: "add_tier with duplicated tier".to_string(), + tier: duplicated_tier, + expected_res: Err(ContractError::InvalidTier { + operation: "add".to_string(), + msg: "Tier with level 0 already exist".to_string(), + }), + payee: MOCK_DEFAULT_OWNER.to_string(), + }, + ]; + for test in test_cases { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + let _ = init( + deps.as_mut(), + mock_campaign_config(Asset::NativeToken(MOCK_NATIVE_DENOM.to_string())), + mock_campaign_tiers(), + ); + + let info = mock_info(&test.payee, &[]); + + let msg = ExecuteMsg::AddTier { + tier: test.tier.clone(), + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + if res.is_ok() { + assert_eq!( + test.tier, + TIERS + .load(deps.as_ref().storage, test.tier.level.into()) + .unwrap(), + "Test case: {}", + test.name + ); + } + } } - assert_eq!( - NUMBER_OF_TOKENS_AVAILABLE - .load(deps.as_ref().storage) - .unwrap(), - Uint128::new(7) - ); - - let msg = ExecuteMsg::StartSale { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(5u128), - max_amount_per_wallet: Some(2), - recipient: Recipient::from_string("recipient"), - }; - - let info = mock_info("owner", &[]); - let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - // Can't mint once sale started. - let res = mint(deps.as_mut(), "token_id"); - assert_eq!(ContractError::SaleStarted {}, res.unwrap_err()); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let info = mock_info("A", &coins(150, "uusd")); - let _res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let info = mock_info("B", &coins(150, "uusd")); - let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let info = mock_info("C", &coins(150, "uusd")); - let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - let state = State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(5u128), - max_amount_per_wallet: 2, - amount_sold: Uint128::from(4u128), - amount_to_send: Uint128::from(360u128), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }; - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - assert_eq!( - vec![ - get_purchase(MOCK_TOKENS_FOR_SALE[0], "A"), - get_purchase(MOCK_TOKENS_FOR_SALE[1], "A") - ], - PURCHASES.load(deps.as_ref().storage, "A").unwrap() - ); - - assert_eq!( - vec![get_purchase(MOCK_TOKENS_FOR_SALE[2], "B"),], - PURCHASES.load(deps.as_ref().storage, "B").unwrap() - ); - - assert_eq!( - vec![get_purchase(MOCK_TOKENS_FOR_SALE[3], "C"),], - PURCHASES.load(deps.as_ref().storage, "C").unwrap() - ); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[0])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[1])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[2])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[3])); - - assert_eq!( - NUMBER_OF_TOKENS_AVAILABLE - .load(deps.as_ref().storage) - .unwrap(), - Uint128::new(3) - ); - - let mut env = mock_env(); - env.block.height += 1; - - // User B claims their own refund. - let msg = ExecuteMsg::ClaimRefund {}; - let info = mock_info("B", &[]); - let res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - assert_eq!( - Response::new() - .add_attribute("action", "claim_refund") - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: "B".to_string(), - amount: coins(150, "uusd"), - })), - res - ); - - assert!(!PURCHASES.has(deps.as_ref().storage, "B")); - - env.contract.address = Addr::unchecked(MOCK_CONDITIONS_NOT_MET_CONTRACT); - deps.querier.tokens_left_to_burn = 7; - let msg = ExecuteMsg::EndSale { limit: None }; - let info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); - let refund_msgs: Vec = vec![ - // All of A's payments grouped into one message. - CosmosMsg::Bank(BankMsg::Send { - to_address: "A".to_string(), - amount: coins(300, "uusd"), - }), - CosmosMsg::Bank(BankMsg::Send { - to_address: "C".to_string(), - amount: coins(150, "uusd"), - }), - ]; - let burn_msgs: Vec = vec![ - get_burn_message(MOCK_TOKENS_FOR_SALE[0]), - get_burn_message(MOCK_TOKENS_FOR_SALE[1]), - get_burn_message(MOCK_TOKENS_FOR_SALE[2]), - get_burn_message(MOCK_TOKENS_FOR_SALE[3]), - // Tokens that were not sold. - get_burn_message(MOCK_TOKENS_FOR_SALE[4]), - get_burn_message(MOCK_TOKENS_FOR_SALE[5]), - get_burn_message(MOCK_TOKENS_FOR_SALE[6]), - ]; - - assert_eq!( - Response::new() - .add_attribute("action", "issue_refunds_and_burn_tokens") - .add_messages(refund_msgs) - .add_messages(burn_msgs), - res - ); - - assert!(!PURCHASES.has(deps.as_ref().storage, "A")); - assert!(!PURCHASES.has(deps.as_ref().storage, "C")); - - // Burned tokens have been removed. - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[4])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[5])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[6])); - - deps.querier.tokens_left_to_burn = 0; - let _res = execute(deps.as_mut(), env, info, msg).unwrap(); - assert!(STATE.may_load(deps.as_mut().storage).unwrap().is_none()); - assert_eq!( - NUMBER_OF_TOKENS_AVAILABLE - .load(deps.as_ref().storage) - .unwrap(), - Uint128::zero() - ); -} - -#[test] -fn test_integration_conditions_met() { - let mut deps = mock_dependencies_custom(&[]); - deps.querier.contract_address = MOCK_CONDITIONS_MET_CONTRACT.to_string(); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - init(deps.as_mut(), Some(modules)); - let mut env = mock_env(); - env.contract.address = Addr::unchecked(MOCK_CONDITIONS_MET_CONTRACT); - - // Mint all tokens. - for &token_id in MOCK_TOKENS_FOR_SALE { - let _res = mint(deps.as_mut(), token_id).unwrap(); - assert!(AVAILABLE_TOKENS.has(deps.as_ref().storage, token_id)); + #[test] + fn test_update_tier() { + let valid_tier = Tier { + level: Uint64::zero(), + label: "Tier 0".to_string(), + limit: Some(Uint128::new(100)), + price: Uint128::new(100), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }; + let non_existing_tier = Tier { + level: Uint64::new(2u64), + label: "Tier 2".to_string(), + limit: Some(Uint128::new(100)), + price: Uint128::new(100), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }; + + let test_cases: Vec = vec![ + TierTestCase { + name: "standard update_tier".to_string(), + tier: valid_tier.clone(), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Ok(Response::new() + .add_attribute("action", "update_tier") + .add_attribute("level", valid_tier.level.to_string()) + .add_attribute("label", valid_tier.label.clone()) + .add_attribute("price", valid_tier.price.to_string()) + .add_attribute("limit", valid_tier.limit.unwrap().to_string()) + // Economics message + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER), + action: "UpdateTier".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + }, + TierTestCase { + name: "update_tier with unauthorized sender".to_string(), + tier: valid_tier.clone(), + expected_res: Err(ContractError::Unauthorized {}), + payee: "owner1".to_string(), + }, + TierTestCase { + name: "update_tier with zero price tier".to_string(), + tier: mock_zero_price_tier(Uint64::zero()), + expected_res: Err(ContractError::InvalidTier { + operation: "all".to_string(), + msg: "Price can not be zero".to_string(), + }), + payee: MOCK_DEFAULT_OWNER.to_string(), + }, + TierTestCase { + name: "update_tier with non existing tier".to_string(), + tier: non_existing_tier, + expected_res: Err(ContractError::InvalidTier { + operation: "update".to_string(), + msg: "Tier with level 2 does not exist".to_string(), + }), + payee: MOCK_DEFAULT_OWNER.to_string(), + }, + ]; + for test in test_cases { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + let _ = init( + deps.as_mut(), + mock_campaign_config(Asset::NativeToken(MOCK_NATIVE_DENOM.to_string())), + mock_campaign_tiers(), + ); + + let info = mock_info(&test.payee, &[]); + + let msg = ExecuteMsg::UpdateTier { + tier: test.tier.clone(), + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + if res.is_ok() { + assert_eq!( + test.tier, + TIERS + .load(deps.as_ref().storage, test.tier.level.into()) + .unwrap(), + "Test case: {}", + test.name + ); + } + } } - let msg = ExecuteMsg::StartSale { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(3u128), - max_amount_per_wallet: Some(2), - recipient: Recipient::from_string("recipient"), - }; - - let info = mock_info("owner", &[]); - let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let info = mock_info("A", &coins(150, "uusd")); - let _res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + #[test] + fn test_remove_tier() { + let valid_tier = Tier { + level: Uint64::zero(), + label: "Tier 0".to_string(), + limit: Some(Uint128::new(100)), + price: Uint128::new(100), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }; + let non_existing_tier = Tier { + level: Uint64::new(2u64), + label: "Tier 2".to_string(), + limit: Some(Uint128::new(100)), + price: Uint128::new(100), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }; + + let test_cases: Vec = vec![ + TierTestCase { + name: "standard remove_tier".to_string(), + tier: valid_tier.clone(), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Ok(Response::new() + .add_attribute("action", "remove_tier") + .add_attribute("level", valid_tier.level.to_string()) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER), + action: "RemoveTier".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + }, + TierTestCase { + name: "remove_tier with unauthorized sender".to_string(), + tier: valid_tier.clone(), + expected_res: Err(ContractError::Unauthorized {}), + payee: "owner1".to_string(), + }, + TierTestCase { + name: "remove_tier with non existing tier level".to_string(), + tier: non_existing_tier, + expected_res: Err(ContractError::InvalidTier { + operation: "remove".to_string(), + msg: "Tier with level 2 does not exist".to_string(), + }), + payee: MOCK_DEFAULT_OWNER.to_string(), + }, + ]; + for test in test_cases { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + let _ = init( + deps.as_mut(), + mock_campaign_config(Asset::NativeToken(MOCK_NATIVE_DENOM.to_string())), + mock_campaign_tiers(), + ); + + let info = mock_info(&test.payee, &[]); + + let msg = ExecuteMsg::RemoveTier { + level: test.tier.level, + }; + + let res = execute(deps.as_mut(), mock_env(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + if res.is_ok() { + assert!( + !TIERS.has(deps.as_ref().storage, test.tier.level.into()), + "Test case: {}", + test.name + ); + } + } + } - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let info = mock_info("B", &coins(150, "uusd")); - let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + struct StartCampaignTestCase { + name: String, + tiers: Vec, + presale: Option>, + start_time: Option, + end_time: MillisecondsExpiration, + expected_res: Result, + payee: String, + } - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let info = mock_info("C", &coins(150, "uusd")); - let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); + #[test] + fn test_start_campaign() { + let mock_orderer = Addr::unchecked("mock_orderer".to_string()); + let valid_presale = vec![PresaleTierOrder { + amount: Uint128::new(100u128), + level: Uint64::new(1u64), + orderer: mock_orderer.clone(), + }]; + + let invalid_presale = vec![PresaleTierOrder { + amount: Uint128::new(100u128), + level: Uint64::new(2u64), + orderer: mock_orderer.clone(), + }]; + + let invalid_tiers = vec![Tier { + level: Uint64::new(1u64), + label: "Tier 1".to_string(), + limit: Some(Uint128::new(1000u128)), + price: Uint128::new(10u128), + metadata: TierMetaData { + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }, + }]; + + let env = mock_env(); + let test_cases: Vec = vec![ + StartCampaignTestCase { + name: "standard start_campaign".to_string(), + tiers: mock_campaign_tiers(), + presale: Some(valid_presale.clone()), + start_time: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() + 100), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Ok(Response::new() + .add_attribute("action", "start_campaign") + .add_attribute( + "end_time", + MillisecondsExpiration::from_seconds(env.block.time.seconds() + 100), + ) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER), + action: "StartCampaign".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + }, + StartCampaignTestCase { + name: "start_campaign with unauthorized sender".to_string(), + tiers: mock_campaign_tiers(), + presale: Some(valid_presale.clone()), + start_time: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() + 100), + payee: "owner1".to_string(), + expected_res: Err(ContractError::Unauthorized {}), + }, + StartCampaignTestCase { + name: "start_campaign with no unlimited tier".to_string(), + tiers: invalid_tiers, + presale: Some(valid_presale.clone()), + start_time: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() + 100), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Err(ContractError::InvalidTiers {}), + }, + StartCampaignTestCase { + name: "start_campaign with invalid presales".to_string(), + tiers: mock_campaign_tiers(), + presale: Some(invalid_presale.clone()), + start_time: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() + 100), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Err(ContractError::InvalidTier { + operation: "set_tier_orders".to_string(), + msg: "Tier with level 2 does not exist".to_string(), + }), + }, + StartCampaignTestCase { + name: "start_campaign with invalid end_time".to_string(), + tiers: mock_campaign_tiers(), + presale: Some(valid_presale.clone()), + start_time: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() - 100), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Err(ContractError::StartTimeAfterEndTime {}), + }, + StartCampaignTestCase { + name: "start_campaign with invalid start_time".to_string(), + tiers: mock_campaign_tiers(), + presale: Some(valid_presale.clone()), + start_time: Some(MillisecondsExpiration::from_seconds( + env.block.time.seconds() + 1000, + )), + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() + 500), + payee: MOCK_DEFAULT_OWNER.to_string(), + expected_res: Err(ContractError::StartTimeAfterEndTime {}), + }, + ]; + for test in test_cases { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + + let _ = init( + deps.as_mut(), + mock_campaign_config(Asset::NativeToken(MOCK_NATIVE_DENOM.to_string())), + test.tiers.clone(), + ); + let info = mock_info(&test.payee, &[]); + + let msg = ExecuteMsg::StartCampaign { + start_time: test.start_time, + end_time: test.end_time, + presale: test.presale.clone(), + }; + + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + + if res.is_ok() { + assert_eq!( + CAMPAIGN_DURATION.load(&deps.storage).unwrap().start_time, + test.start_time + ); + assert_eq!( + CAMPAIGN_DURATION.load(&deps.storage).unwrap().end_time, + test.end_time + ); + assert_eq!( + CAMPAIGN_STAGE.load(&deps.storage).unwrap(), + CampaignStage::ONGOING + ); + for order in &test.presale.unwrap() { + let order_amount: u128 = order.amount.into(); + let order_info = TIER_ORDERS + .load(&deps.storage, (mock_orderer.clone(), order.level.into())) + .unwrap(); + + assert_eq!(order_info.preordered, order_amount); + assert_eq!(order_info.ordered, 0u128); + assert_eq!(order_info.amount().unwrap(), order_amount); + let cur_limit = TIERS.load(&deps.storage, order.level.into()).unwrap().limit; + if cur_limit.is_some() { + assert_eq!( + TIER_SALES + .load(&deps.storage, order.level.into()) + .unwrap() + .u128(), + order_amount + ); + } + } + } else { + assert_eq!( + CAMPAIGN_STAGE + .load(&deps.storage) + .unwrap_or(CampaignStage::READY), + CampaignStage::READY + ); + } + } + } - let msg = ExecuteMsg::Purchase { - number_of_tokens: Some(1), - }; - let info = mock_info("D", &coins(150, "uusd")); - let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - - let mut state = State { - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(3u128), - max_amount_per_wallet: 2, - amount_sold: Uint128::from(5u128), - amount_to_send: Uint128::from(450u128), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), - }; - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - assert_eq!( - vec![ - get_purchase(MOCK_TOKENS_FOR_SALE[0], "A"), - get_purchase(MOCK_TOKENS_FOR_SALE[1], "A") - ], - PURCHASES.load(deps.as_ref().storage, "A").unwrap() - ); - - assert_eq!( - vec![get_purchase(MOCK_TOKENS_FOR_SALE[2], "B"),], - PURCHASES.load(deps.as_ref().storage, "B").unwrap() - ); - assert_eq!( - vec![get_purchase(MOCK_TOKENS_FOR_SALE[3], "C"),], - PURCHASES.load(deps.as_ref().storage, "C").unwrap() - ); - assert_eq!( - vec![get_purchase(MOCK_TOKENS_FOR_SALE[4], "D"),], - PURCHASES.load(deps.as_ref().storage, "D").unwrap() - ); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[0])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[1])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[2])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[3])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[4])); - - env.block.height += 1; - env.contract.address = Addr::unchecked(MOCK_CONDITIONS_MET_CONTRACT); - - let msg = ExecuteMsg::EndSale { limit: Some(1) }; - let info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - - assert_eq!( - Response::new() - .add_attribute("action", "transfer_tokens_and_send_funds") - .add_message(get_transfer_message(MOCK_TOKENS_FOR_SALE[0], "A")) - .add_submessages(get_rates_messages()), - res - ); - - assert_eq!( - vec![get_purchase(MOCK_TOKENS_FOR_SALE[1], "A")], - PURCHASES.load(deps.as_ref().storage, "A").unwrap() - ); - - state.amount_transferred += Uint128::from(1u128); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - let msg = ExecuteMsg::EndSale { limit: Some(2) }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - - assert_eq!( - Response::new() - .add_attribute("action", "transfer_tokens_and_send_funds") - .add_message(get_transfer_message(MOCK_TOKENS_FOR_SALE[1], "A")) - .add_message(get_transfer_message(MOCK_TOKENS_FOR_SALE[2], "B")) - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% for A and B combined - amount: Uint128::from(20u128), - denom: "uusd".to_string(), + struct PurchaseTierTestCase { + name: String, + stage: CampaignStage, + expected_res: Result, + payee: String, + start_time: Option, + end_time: MillisecondsExpiration, + orders: Vec, + initial_cap: Uint128, + funds: Vec, + denom: Asset, + } + #[test] + fn test_execute_purchase_tiers_native() { + // fixed total cost to 100 for valid purchase + let env = mock_env(); + let buyer = "buyer"; + let test_cases: Vec = vec![ + PurchaseTierTestCase { + name: "Standard purchase with valid order using native tokens".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Ok(Response::new() + .add_attribute("action", "purchase_tiers") + .add_attribute("payment", "1000native:uandr") + .add_attribute("total_cost", "100") + .add_attribute("refunded", "900") + .add_message(BankMsg::Send { + to_address: buyer.to_string(), + // Refund sent back as they only were able to mint one. + amount: coins(900, MOCK_NATIVE_DENOM), + }) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(buyer), + action: "PurchaseTiers".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), }], - })) - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Combined tax for both A and B - amount: Uint128::from(100u128), - denom: "uusd".to_string(), + initial_cap: Uint128::new(500), + funds: vec![coin(1000, MOCK_NATIVE_DENOM)], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + }, + PurchaseTierTestCase { + name: "Purchasing more than limit".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::PurchaseLimitReached {}), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(MOCK_DEFAULT_LIMIT + 1), }], - })), - res - ); - - assert!(!PURCHASES.has(deps.as_ref().storage, "A"),); - assert!(!PURCHASES.has(deps.as_ref().storage, "B"),); - assert!(PURCHASES.has(deps.as_ref().storage, "C"),); - assert!(PURCHASES.has(deps.as_ref().storage, "D"),); - - state.amount_transferred += Uint128::from(2u128); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - let msg = ExecuteMsg::EndSale { limit: None }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); - - assert!(!PURCHASES.has(deps.as_ref().storage, "C"),); - assert!(!PURCHASES.has(deps.as_ref().storage, "D"),); - - assert_eq!( - Response::new() - .add_attribute("action", "transfer_tokens_and_send_funds") - .add_message(get_transfer_message(MOCK_TOKENS_FOR_SALE[3], "C")) - .add_message(get_transfer_message(MOCK_TOKENS_FOR_SALE[4], "D")) - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% for C and D combined - amount: Uint128::from(20u128), - denom: "uusd".to_string(), + initial_cap: Uint128::new(500), + funds: vec![coin(10 * MOCK_DEFAULT_LIMIT + 20, MOCK_NATIVE_DENOM)], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + }, + PurchaseTierTestCase { + name: "Purchase with insufficient funds using native tokens".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::InsufficientFunds {}), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(20), }], - })) - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Combined tax for both C and D - amount: Uint128::from(100u128), - denom: "uusd".to_string(), + initial_cap: Uint128::new(500), + funds: vec![coin(10, MOCK_NATIVE_DENOM)], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + }, + PurchaseTierTestCase { + name: "Purchase in wrong campaign stage using native tokens".to_string(), + stage: CampaignStage::READY, + expected_res: Err(ContractError::InvalidCampaignOperation { + operation: "purchase_tiers".to_string(), + stage: "READY".to_string(), + }), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), }], - })), - res - ); - - state.amount_transferred += Uint128::from(2u128); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - let msg = ExecuteMsg::EndSale { limit: None }; - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); - - assert_eq!(3, res.messages.len()); - - // assert_eq!( - // Response::new() - // .add_attribute("action", "transfer_tokens_and_send_funds") - // // Now that all tokens have been transfered, can send the funds to recipient. - // .add_message(CosmosMsg::Bank(BankMsg::Send { - // to_address: "recipient".to_string(), - // amount: coins(450u128, "uusd") - // })) - // // Burn tokens that were not purchased - // .add_message(get_burn_message(MOCK_TOKENS_FOR_SALE[5])) - // .add_message(get_burn_message(MOCK_TOKENS_FOR_SALE[6])), - // res - // ); - - state.amount_to_send = Uint128::zero(); - assert_eq!(state, STATE.load(deps.as_ref().storage).unwrap()); - - // Burned tokens removed. - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[5])); - assert!(!AVAILABLE_TOKENS.has(deps.as_ref().storage, MOCK_TOKENS_FOR_SALE[6])); - - deps.querier.tokens_left_to_burn = 0; - let _res = execute(deps.as_mut(), env, info, msg).unwrap(); - assert!(STATE.may_load(deps.as_mut().storage).unwrap().is_none()); - assert_eq!( - NUMBER_OF_TOKENS_AVAILABLE - .load(deps.as_ref().storage) - .unwrap(), - Uint128::zero() - ); -} - -#[test] -fn test_end_sale_single_purchase() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height - 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::from(1u128), - amount_to_send: Uint128::from(100u128), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + initial_cap: Uint128::new(500), + funds: vec![coin(1000, MOCK_NATIVE_DENOM)], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), }, - ) - .unwrap(); - - PURCHASES - .save( - deps.as_mut().storage, - "A", - &vec![Purchase { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - purchaser: "A".to_string(), - tax_amount: Uint128::zero(), - msgs: vec![], - }], - ) - .unwrap(); - - let msg = ExecuteMsg::EndSale { limit: None }; - let info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_attribute("action", "transfer_tokens_and_send_funds") - // Burn tokens that were not purchased - .add_message(get_transfer_message(MOCK_TOKENS_FOR_SALE[0], "A")), - res - ); -} - -#[test] -fn test_end_sale_all_tokens_sold() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - STATE - .save( - deps.as_mut().storage, - &State { - // Sale has not expired yet. - expiration: Expiration::AtHeight(mock_env().block.height + 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::from(1u128), - amount_to_send: Uint128::from(100u128), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + PurchaseTierTestCase { + name: "Purchase before campaign start using native tokens".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::CampaignNotStarted {}), + payee: buyer.to_string(), + start_time: Some(future_time(&env)), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![coin(1000, MOCK_NATIVE_DENOM)], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), }, - ) - .unwrap(); - - PURCHASES - .save( - deps.as_mut().storage, - "A", - &vec![Purchase { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - purchaser: "A".to_string(), - tax_amount: Uint128::zero(), - msgs: vec![], - }], - ) - .unwrap(); - - NUMBER_OF_TOKENS_AVAILABLE - .save(deps.as_mut().storage, &Uint128::zero()) - .unwrap(); - - let msg = ExecuteMsg::EndSale { limit: None }; - let info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - assert_eq!( - Response::new() - .add_attribute("action", "transfer_tokens_and_send_funds") - // Burn tokens that were not purchased - .add_message(get_transfer_message(MOCK_TOKENS_FOR_SALE[0], "A")), - res - ); -} - -#[test] -fn test_end_sale_limit_zero() { - let mut deps = mock_dependencies_custom(&[]); - init(deps.as_mut(), None); - - STATE - .save( - deps.as_mut().storage, - &State { - expiration: Expiration::AtHeight(mock_env().block.height - 1), - price: coin(100, "uusd"), - min_tokens_sold: Uint128::from(1u128), - max_amount_per_wallet: 5, - amount_sold: Uint128::from(1u128), - amount_to_send: Uint128::from(100u128), - amount_transferred: Uint128::zero(), - recipient: Recipient::from_string("recipient"), + PurchaseTierTestCase { + name: "Purchase after campaign end using native tokens".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::CampaignEnded {}), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: past_time(), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![coin(1000, MOCK_NATIVE_DENOM)], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), }, - ) - .unwrap(); - NUMBER_OF_TOKENS_AVAILABLE - .save(deps.as_mut().storage, &Uint128::new(1)) - .unwrap(); - - PURCHASES - .save( - deps.as_mut().storage, - "A", - &vec![Purchase { - token_id: MOCK_TOKENS_FOR_SALE[0].to_owned(), - purchaser: "A".to_string(), - tax_amount: Uint128::zero(), - msgs: vec![], - }], - ) - .unwrap(); - - let msg = ExecuteMsg::EndSale { limit: Some(0) }; - let info = mock_info("anyone", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!(ContractError::LimitMustNotBeZero {}, res.unwrap_err()); -} - -#[test] -fn test_validate_andr_addresses_regular_address() { - let mut deps = mock_dependencies_custom(&[]); - let msg = InstantiateMsg { - token_address: AndrAddr::from_string("terra1asdf1ssdfadf".to_owned()), - owner: None, - modules: None, - can_mint_after_sale: true, - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - }; - - let info = mock_info("owner", &[]); - let _res = instantiate(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); - - let msg = ExecuteMsg::UpdateAppContract { - address: MOCK_APP_CONTRACT.to_owned(), - }; - - let res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + PurchaseTierTestCase { + name: "Purchase with invalid denomination using native tokens".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::InvalidFunds { + msg: format!("Only native:{MOCK_NATIVE_DENOM} is accepted by the campaign."), + }), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![coin(1000, INVA1LID_DENOM)], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + }, + ]; + for test in test_cases { + let mut deps = mock_dependencies_custom(&test.funds); + let info = mock_info(&test.payee, &test.funds); + + // Mock necessary storage setup + set_campaign_stage(deps.as_mut().storage, &test.stage); + set_current_capital(deps.as_mut().storage, &test.initial_cap); + set_tiers(deps.as_mut().storage, mock_campaign_tiers()); + + let mock_config: CampaignConfig = mock_campaign_config(test.denom); + let duration = Duration { + start_time: test.start_time, + end_time: test.end_time, + }; + set_campaign_config(deps.as_mut().storage, &mock_config); + set_campaign_duration(deps.as_mut().storage, &duration); + let msg = ExecuteMsg::PurchaseTiers { + orders: test.orders.clone(), + }; + + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + + if res.is_ok() { + // Check current capital + let updated_cap = get_current_capital(deps.as_ref().storage); + let expected_cap = test.initial_cap + Uint128::new(100); + assert_eq!(updated_cap, expected_cap, "Test case: {}", test.name); + + // Check tier orders + for order in &test.orders { + let stored_order_info = TIER_ORDERS + .load( + deps.as_ref().storage, + (Addr::unchecked(buyer), order.level.into()), + ) + .unwrap(); + assert_eq!( + stored_order_info.ordered, + order.amount.u128(), + "Test case: {}", + test.name + ); + } + + // Check tier sales + for order in &test.orders { + let sold_amount = TIER_SALES + .load(deps.as_ref().storage, order.level.into()) + .unwrap(); + assert_eq!( + sold_amount.u128(), + order.amount.u128(), + "Test case: {}", + test.name + ); + } + } + } + } - assert_eq!( - Response::new() - .add_attribute("action", "update_app_contract") - .add_attribute("address", MOCK_APP_CONTRACT), - res - ); -} + #[test] + fn test_execute_purchase_tiers_cw20() { + // fixed total cost to 100 for valid purchase + let env = mock_env(); + let buyer = "buyer"; + let valid_denom = Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())); + let test_cases: Vec = vec![ + PurchaseTierTestCase { + name: "Standard purchase with valid order using cw20 token".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Ok(Response::new() + .add_attribute("action", "purchase_tiers") + .add_attribute("payment", "1000cw20:cw20_contract") + .add_attribute("total_cost", "100") + .add_attribute("refunded", "900") + .add_message( + wasm_execute( + MOCK_CW20_CONTRACT.to_string(), + &Cw20ExecuteMsg::Transfer { + recipient: buyer.to_string(), + amount: Uint128::new(900u128), + }, + vec![], + ) + .unwrap(), + ) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_CW20_CONTRACT), + action: "Receive".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![], + denom: valid_denom.clone(), + }, + PurchaseTierTestCase { + name: "Purchase with insufficient funds using cw20 token".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::InsufficientFunds {}), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(200000), + }], + initial_cap: Uint128::new(500), + funds: vec![], + denom: valid_denom.clone(), + }, + PurchaseTierTestCase { + name: "Purchase in wrong campaign stage using cw20 token".to_string(), + stage: CampaignStage::READY, + expected_res: Err(ContractError::InvalidCampaignOperation { + operation: "purchase_tiers".to_string(), + stage: "READY".to_string(), + }), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![], + denom: valid_denom.clone(), + }, + PurchaseTierTestCase { + name: "Purchase before campaign start using cw20 token".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::CampaignNotStarted {}), + payee: buyer.to_string(), + start_time: Some(future_time(&env)), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![], + denom: valid_denom.clone(), + }, + PurchaseTierTestCase { + name: "Purchase after campaign end using cw20 token".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::CampaignEnded {}), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: past_time(), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![], + denom: valid_denom.clone(), + }, + PurchaseTierTestCase { + name: "Purchase with invalid denomination using cw20 token".to_string(), + stage: CampaignStage::ONGOING, + expected_res: Err(ContractError::InvalidFunds { + msg: format!("Only cw20:{MOCK_CW20_CONTRACT} is accepted by the campaign."), + }), + payee: buyer.to_string(), + start_time: Some(past_time()), + end_time: future_time(&env), + orders: vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }], + initial_cap: Uint128::new(500), + funds: vec![], + denom: Asset::Cw20Token(AndrAddr::from_string("cw20_contract124".to_string())), + }, + ]; + + for test in test_cases { + let mut deps = mock_dependencies_custom(&test.funds); + let Asset::Cw20Token(ref cw20) = test.denom else { + todo!(); + }; + let info = mock_info(cw20.as_ref(), &[]); + + // Mock necessary storage setup + set_campaign_stage(deps.as_mut().storage, &test.stage); + set_current_capital(deps.as_mut().storage, &test.initial_cap); + set_tiers(deps.as_mut().storage, mock_campaign_tiers()); + + let mock_config: CampaignConfig = mock_campaign_config(valid_denom.clone()); + set_campaign_config(deps.as_mut().storage, &mock_config); + + let duration = Duration { + start_time: test.start_time, + end_time: test.end_time, + }; + set_campaign_duration(deps.as_mut().storage, &duration); + + let hook_msg = Cw20HookMsg::PurchaseTiers { + orders: test.orders.clone(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: buyer.to_owned(), + amount: Uint128::new(1000u128), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + + if res.is_ok() { + // Check current capital + let updated_cap = get_current_capital(deps.as_ref().storage); + let expected_cap = test.initial_cap + Uint128::new(100); + assert_eq!(updated_cap, expected_cap, "Test case: {}", test.name); + + // Check tier orders + for order in &test.orders { + let stored_order_info = TIER_ORDERS + .load( + deps.as_ref().storage, + (Addr::unchecked(buyer), order.level.into()), + ) + .unwrap(); + assert_eq!( + stored_order_info.ordered, + order.amount.u128(), + "Test case: {}", + test.name + ); + } + + // Check tier sales + for order in &test.orders { + let sold_amount = TIER_SALES + .load(deps.as_ref().storage, order.level.into()) + .unwrap(); + assert_eq!( + sold_amount.u128(), + order.amount.u128(), + "Test case: {}", + test.name + ); + } + } + } + } -#[test] -fn test_addresslist() { - let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(ADDRESS_LIST.to_owned()), - address: AndrAddr::from_string(MOCK_ADDRESS_LIST_CONTRACT.to_owned()), - is_mutable: false, - }]; - let msg = InstantiateMsg { - token_address: AndrAddr::from_string(MOCK_TOKEN_CONTRACT.to_owned()), - modules: Some(modules), - can_mint_after_sale: true, - owner: None, - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - }; + struct EndCampaignTestCase { + name: String, + stage: CampaignStage, + sender: String, + current_capital: Uint128, + soft_cap: Option, + end_time: MillisecondsExpiration, + denom: Asset, + is_discard: bool, + expected_res: Result, + expected_stage: CampaignStage, + } + #[test] + fn test_execute_end_campaign() { + let env = mock_env(); + let deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + let recipient = Recipient::from_string(MOCK_WITHDRAWAL_ADDRESS.to_owned()); + let amp_msg = recipient + .generate_amp_msg(&deps.as_ref(), Some(coins(10000, MOCK_NATIVE_DENOM))) + .unwrap(); + let amp_pkt = AMPPkt::new( + MOCK_CONTRACT_ADDR.to_string(), + MOCK_CONTRACT_ADDR.to_string(), + vec![amp_msg], + ); + let amp_msg = amp_pkt + .to_sub_msg( + MOCK_KERNEL_CONTRACT, + Some(coins(10000, MOCK_NATIVE_DENOM)), + 1, + ) + .unwrap(); + + let test_cases: Vec = vec![ + EndCampaignTestCase { + name: "Successful campaign using native token".to_string(), + stage: CampaignStage::ONGOING, + sender: MOCK_DEFAULT_OWNER.to_string(), + current_capital: Uint128::new(10000u128), + soft_cap: Some(Uint128::new(9000u128)), + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds()), + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + is_discard: false, + expected_res: Ok(Response::new() + .add_attribute("action", "end_campaign") + .add_attribute("result", CampaignStage::SUCCESS.to_string()) + .add_submessage(amp_msg) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER.to_string()), + action: "EndCampaign".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + expected_stage: CampaignStage::SUCCESS, + }, + EndCampaignTestCase { + name: "Successful campaign using cw20".to_string(), + stage: CampaignStage::ONGOING, + sender: MOCK_DEFAULT_OWNER.to_string(), + current_capital: Uint128::new(10000u128), + soft_cap: Some(Uint128::new(9000u128)), + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds()), + denom: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + is_discard: false, + expected_res: Ok(Response::new() + .add_attribute("action", "end_campaign") + .add_attribute("result", CampaignStage::SUCCESS.to_string()) + .add_message( + wasm_execute( + MOCK_CW20_CONTRACT.to_string(), + &Cw20ExecuteMsg::Transfer { + recipient: MOCK_WITHDRAWAL_ADDRESS.to_string(), + amount: Uint128::new(10000u128), + }, + vec![], + ) + .unwrap(), + ) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER.to_string()), + action: "EndCampaign".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + expected_stage: CampaignStage::SUCCESS, + }, + EndCampaignTestCase { + name: "Failed campaign".to_string(), + stage: CampaignStage::ONGOING, + sender: MOCK_DEFAULT_OWNER.to_string(), + current_capital: Uint128::new(10000u128), + soft_cap: Some(Uint128::new(11000u128)), + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds()), + denom: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + is_discard: false, + expected_res: Ok(Response::new() + .add_attribute("action", "end_campaign") + .add_attribute("result", CampaignStage::FAILED.to_string()) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER.to_string()), + action: "EndCampaign".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + expected_stage: CampaignStage::FAILED, + }, + EndCampaignTestCase { + name: "Discard campaign using native token".to_string(), + stage: CampaignStage::ONGOING, + sender: MOCK_DEFAULT_OWNER.to_string(), + current_capital: Uint128::new(10000u128), + soft_cap: Some(Uint128::new(9000u128)), + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds()), + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + is_discard: true, + expected_res: Ok(Response::new() + .add_attribute("action", "discard_campaign") + .add_attribute("result", CampaignStage::FAILED.to_string()) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER.to_string()), + action: "DiscardCampaign".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + expected_stage: CampaignStage::FAILED, + }, + EndCampaignTestCase { + name: "Pause campaign".to_string(), + stage: CampaignStage::ONGOING, + sender: MOCK_DEFAULT_OWNER.to_string(), + current_capital: Uint128::new(0u128), + soft_cap: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() + 1000), + denom: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + is_discard: false, + expected_res: Ok(Response::new() + .add_attribute("action", "end_campaign") + .add_attribute("result", CampaignStage::READY.to_string()) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(MOCK_DEFAULT_OWNER.to_string()), + action: "EndCampaign".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + expected_stage: CampaignStage::READY, + }, + EndCampaignTestCase { + name: "End campaign from unauthorized sender".to_string(), + stage: CampaignStage::ONGOING, + sender: "sender".to_string(), + current_capital: Uint128::new(10000u128), + soft_cap: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds()), + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + is_discard: false, + expected_res: Err(ContractError::Unauthorized {}), + expected_stage: CampaignStage::ONGOING, + }, + EndCampaignTestCase { + name: "End campaign on invalid stage".to_string(), + stage: CampaignStage::READY, + sender: MOCK_DEFAULT_OWNER.to_string(), + current_capital: Uint128::new(10000u128), + soft_cap: None, + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds()), + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + is_discard: false, + expected_res: Err(ContractError::InvalidCampaignOperation { + operation: "end_campaign".to_string(), + stage: CampaignStage::READY.to_string(), + }), + expected_stage: CampaignStage::READY, + }, + EndCampaignTestCase { + name: "End unexpired campaign".to_string(), + stage: CampaignStage::ONGOING, + sender: MOCK_DEFAULT_OWNER.to_string(), + current_capital: Uint128::new(10000u128), + soft_cap: Some(Uint128::new(11000u128)), + end_time: MillisecondsExpiration::from_seconds(env.block.time.seconds() + 100), + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + is_discard: false, + expected_res: Err(ContractError::CampaignNotExpired {}), + expected_stage: CampaignStage::ONGOING, + }, + ]; + for test in test_cases { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + let mut mock_config = mock_campaign_config(test.denom.clone()); + let _ = init(deps.as_mut(), mock_config.clone(), vec![]); + + let info = mock_info(&test.sender, &[]); + set_campaign_stage(deps.as_mut().storage, &test.stage); + set_current_capital(deps.as_mut().storage, &test.current_capital); + + mock_config.soft_cap = test.soft_cap; + let duration = Duration { + start_time: None, + end_time: test.end_time, + }; + + set_campaign_config(deps.as_mut().storage, &mock_config); + set_campaign_duration(deps.as_mut().storage, &duration); + let msg = if test.is_discard { + ExecuteMsg::DiscardCampaign {} + } else { + ExecuteMsg::EndCampaign {} + }; + + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + if res.is_ok() { + assert_eq!( + CAMPAIGN_STAGE + .load(&deps.storage) + .unwrap_or(CampaignStage::SUCCESS), + test.expected_stage, + "Test case: {}", + test.name + ); + } + } + } - let info = mock_info("app_contract", &[]); - let _res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + struct ClaimTestCase { + name: String, + stage: CampaignStage, + orders: Vec, + denom: Asset, + expected_res: Result, + } - // Not whitelisted user - let msg = ExecuteMsg::Purchase { - number_of_tokens: None, - }; - let info = mock_info("not_whitelisted", &[]); - let res = execute(deps.as_mut(), mock_env(), info, msg); - - assert_eq!( - ContractError::Std(StdError::generic_err( - "Querier contract error: InvalidAddress" - )), - res.unwrap_err() - ); + #[test] + fn test_execute_claim() { + let orderer = Addr::unchecked("orderer"); + + let test_cases = vec![ + ClaimTestCase { + name: "Claim when campaign is successful ".to_string(), + stage: CampaignStage::SUCCESS, + orders: vec![ + TierOrder { + is_presale: true, + amount: Uint128::one(), + level: Uint64::one(), + orderer: orderer.clone(), + }, + TierOrder { + is_presale: false, + amount: Uint128::one(), + level: Uint64::one(), + orderer: orderer.clone(), + }, + ], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + expected_res: Ok(Response::new() + .add_attribute("action", "claim") + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "tier_contract".to_string(), + msg: to_json_binary(&Cw721ExecuteMsg::Mint { + token_id: "0".to_string(), + owner: orderer.to_string(), + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }) + .unwrap(), + funds: vec![], + })) + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "tier_contract".to_string(), + msg: to_json_binary(&Cw721ExecuteMsg::Mint { + token_id: "1".to_string(), + owner: orderer.to_string(), + extension: TokenExtension { + publisher: MOCK_ADO_PUBLISHER.to_string(), + }, + token_uri: None, + }) + .unwrap(), + funds: vec![], + })) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: orderer.clone(), + action: "Claim".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + }, + ClaimTestCase { + name: "Claim when native token accepting campaign failed ".to_string(), + stage: CampaignStage::FAILED, + orders: vec![ + TierOrder { + is_presale: true, + amount: Uint128::one(), + level: Uint64::one(), + orderer: orderer.clone(), + }, + TierOrder { + is_presale: false, + amount: Uint128::one(), + level: Uint64::one(), + orderer: orderer.clone(), + }, + ], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + expected_res: Ok(Response::new() + .add_attribute("action", "claim") + .add_message(BankMsg::Send { + to_address: orderer.to_string(), + amount: coins(10, MOCK_NATIVE_DENOM), // only non presale order refunded + }) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: orderer.clone(), + action: "Claim".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + }, + ClaimTestCase { + name: "Claim when cw20 accepting campaign failed ".to_string(), + stage: CampaignStage::FAILED, + orders: vec![ + TierOrder { + is_presale: true, + amount: Uint128::one(), + level: Uint64::one(), + orderer: orderer.clone(), + }, + TierOrder { + is_presale: false, + amount: Uint128::one(), + level: Uint64::one(), + orderer: orderer.clone(), + }, + ], + denom: Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + expected_res: Ok(Response::new() + .add_attribute("action", "claim") + .add_message( + wasm_execute( + MOCK_CW20_CONTRACT.to_string(), + &Cw20ExecuteMsg::Transfer { + recipient: orderer.to_string(), + amount: Uint128::new(10u128), + }, + vec![], + ) + .unwrap(), + ) + .add_submessage(SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: orderer.clone(), + action: "Claim".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ))), + }, + ClaimTestCase { + name: "Claim without purchasing in successful campaign".to_string(), + stage: CampaignStage::SUCCESS, + orders: vec![], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + expected_res: Err(ContractError::NoPurchases {}), + }, + ClaimTestCase { + name: "Claim without purchasing in failed campaign".to_string(), + stage: CampaignStage::FAILED, + orders: vec![], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + expected_res: Err(ContractError::NoPurchases {}), + }, + ClaimTestCase { + name: "Claim on invalid stage".to_string(), + stage: CampaignStage::READY, + orders: vec![], + denom: Asset::NativeToken(MOCK_NATIVE_DENOM.to_string()), + expected_res: Err(ContractError::InvalidCampaignOperation { + operation: "Claim".to_string(), + stage: CampaignStage::READY.to_string(), + }), + }, + ]; + for test in test_cases { + let mut deps = mock_dependencies_custom(&[coin(100000, MOCK_NATIVE_DENOM)]); + let env = mock_env(); + let mock_config: CampaignConfig = mock_campaign_config(test.denom.clone()); + set_campaign_config(deps.as_mut().storage, &mock_config); + set_current_stage(deps.as_mut().storage, test.stage).unwrap(); + set_tiers(deps.as_mut().storage, mock_campaign_tiers()); + set_tier_orders(deps.as_mut().storage, test.orders).unwrap(); + let msg = ExecuteMsg::Claim {}; + + let info = mock_info(orderer.as_ref(), &[]); + + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!(res, test.expected_res, "Test case: {}", test.name); + if res.is_ok() { + // processed orders should be cleared + let orders = get_user_orders(deps.as_ref().storage, orderer.clone()).unwrap(); + assert!(orders.is_empty(), "Test case: {}", test.name); + } + } + } } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/Cargo.toml b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/Cargo.toml index 0257e55..1800e61 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/Cargo.toml +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "andromeda-cw721" -version = "0.2.1" +version = "2.0.4" authors = ["Connor Barr "] edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" exclude = [ # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. @@ -21,7 +21,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] cosmwasm-std = { workspace = true } @@ -29,12 +29,11 @@ cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw721-base = { workspace = true } cw721 = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } + andromeda-non-fungible-tokens = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true, features = ["rates"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } -andromeda-testing = { workspace = true } +andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/README.md b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/README.md new file mode 100644 index 0000000..09f97c2 --- /dev/null +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/README.md @@ -0,0 +1,5 @@ +# Overview + +The CW721 ADO is a smart contract to allow users to launch their own custom NFT projects. In addition to the standard CW721 messages, we have added some custom logic to further extend the utility and function of the contract. + +[CW721 Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/cw721) \ No newline at end of file diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/andromeda-cw721.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/andromeda-cw721.json deleted file mode 100644 index 9218b97..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/andromeda-cw721.json +++ /dev/null @@ -1,4159 +0,0 @@ -{ - "contract_name": "andromeda-cw721", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "minter", - "name", - "symbol" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "minter": { - "description": "The minter is the only one who can create new NFTs. This is designed for a base NFT that is controlled by an external program or contract. You will likely replace this with custom logic in custom NFTs", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "name": { - "description": "Name of the NFT contract", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "symbol": { - "description": "Symbol of the NFT contract", - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Mints a token", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "extension", - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Transfers ownership of a token", - "type": "object", - "required": [ - "transfer_nft" - ], - "properties": { - "transfer_nft": { - "type": "object", - "required": [ - "recipient", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Sends a token to another contract", - "type": "object", - "required": [ - "send_nft" - ], - "properties": { - "send_nft": { - "type": "object", - "required": [ - "contract", - "msg", - "token_id" - ], - "properties": { - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted Approval", - "type": "object", - "required": [ - "revoke" - ], - "properties": { - "revoke": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approves an address for all tokens owned by the sender", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burns a token, removing all data related to it. The ID of the token is still reserved.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Archives a token, causing it to be immutable but readable", - "type": "object", - "required": [ - "archive" - ], - "properties": { - "archive": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Assigns a `TransferAgreement` for a token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "agreement": { - "anyOf": [ - { - "$ref": "#/definitions/TransferAgreement" - }, - { - "type": "null" - } - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Mint multiple tokens at a time", - "type": "object", - "required": [ - "batch_mint" - ], - "properties": { - "batch_mint": { - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "array", - "items": { - "$ref": "#/definitions/MintMsg" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "ExecuteMsg": { - "oneOf": [ - { - "description": "Mints a token", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "extension", - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Transfers ownership of a token", - "type": "object", - "required": [ - "transfer_nft" - ], - "properties": { - "transfer_nft": { - "type": "object", - "required": [ - "recipient", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Sends a token to another contract", - "type": "object", - "required": [ - "send_nft" - ], - "properties": { - "send_nft": { - "type": "object", - "required": [ - "contract", - "msg", - "token_id" - ], - "properties": { - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted Approval", - "type": "object", - "required": [ - "revoke" - ], - "properties": { - "revoke": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approves an address for all tokens owned by the sender", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burns a token, removing all data related to it. The ID of the token is still reserved.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Archives a token, causing it to be immutable but readable", - "type": "object", - "required": [ - "archive" - ], - "properties": { - "archive": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Assigns a `TransferAgreement` for a token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "agreement": { - "anyOf": [ - { - "$ref": "#/definitions/TransferAgreement" - }, - { - "type": "null" - } - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Mint multiple tokens at a time", - "type": "object", - "required": [ - "batch_mint" - ], - "properties": { - "batch_mint": { - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "array", - "items": { - "$ref": "#/definitions/MintMsg" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "MintMsg": { - "type": "object", - "required": [ - "extension", - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "TransferAgreement": { - "description": "A struct used to represent an agreed transfer of a token. The `purchaser` may use the `Transfer` message for this token as long as funds are provided equalling the `amount` defined in the agreement.", - "type": "object", - "required": [ - "amount", - "purchaser" - ], - "properties": { - "amount": { - "description": "The amount required for the purchaser to transfer ownership of the token", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "purchaser": { - "description": "The address of the purchaser", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Owner of the given token by ID", - "type": "object", - "required": [ - "owner_of" - ], - "properties": { - "owner_of": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approvals for a given address (paginated)", - "type": "object", - "required": [ - "all_operators" - ], - "properties": { - "all_operators": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Amount of tokens minted by the contract", - "type": "object", - "required": [ - "num_tokens" - ], - "properties": { - "num_tokens": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token", - "type": "object", - "required": [ - "nft_info" - ], - "properties": { - "nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token and any approvals assigned to it", - "type": "object", - "required": [ - "all_nft_info" - ], - "properties": { - "all_nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract owned by a given address (paginated)", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract (paginated)", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If the token is archived", - "type": "object", - "required": [ - "is_archived" - ], - "properties": { - "is_archived": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The transfer agreement for the token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The current config of the contract", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/QueryMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Return approvals that a token has Return type: `ApprovalsResponse`", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "QueryMsg": { - "oneOf": [ - { - "description": "Owner of the given token by ID", - "type": "object", - "required": [ - "owner_of" - ], - "properties": { - "owner_of": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approvals for a given address (paginated)", - "type": "object", - "required": [ - "all_operators" - ], - "properties": { - "all_operators": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Amount of tokens minted by the contract", - "type": "object", - "required": [ - "num_tokens" - ], - "properties": { - "num_tokens": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token", - "type": "object", - "required": [ - "nft_info" - ], - "properties": { - "nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token and any approvals assigned to it", - "type": "object", - "required": [ - "all_nft_info" - ], - "properties": { - "all_nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract owned by a given address (paginated)", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract (paginated)", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If the token is archived", - "type": "object", - "required": [ - "is_archived" - ], - "properties": { - "is_archived": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The transfer agreement for the token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The current config of the contract", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/QueryMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Return approvals that a token has Return type: `ApprovalsResponse`", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "all_nft_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllNftInfoResponse_for_TokenExtension", - "type": "object", - "required": [ - "access", - "info" - ], - "properties": { - "access": { - "description": "Who can transfer the token", - "allOf": [ - { - "$ref": "#/definitions/OwnerOfResponse" - } - ] - }, - "info": { - "description": "Data on the token itself,", - "allOf": [ - { - "$ref": "#/definitions/NftInfoResponse_for_TokenExtension" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "NftInfoResponse_for_TokenExtension": { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "OwnerOfResponse": { - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "all_operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "all_tokens": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_after` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "approval": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalResponse", - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "$ref": "#/definitions/Approval" - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "approvals": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalsResponse", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "contract_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractInfoResponse", - "type": "object", - "required": [ - "name", - "symbol" - ], - "properties": { - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - } - }, - "additionalProperties": false - }, - "extension": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenExtension", - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "is_archived": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsArchivedResponse", - "type": "object", - "required": [ - "is_archived" - ], - "properties": { - "is_archived": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "minter": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MinterResponse", - "description": "Shows who can mint these tokens", - "type": "object", - "properties": { - "minter": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "nft_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NftInfoResponse_for_TokenExtension", - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - } - } - }, - "num_tokens": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NumTokensResponse", - "type": "object", - "required": [ - "count" - ], - "properties": { - "count": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner_of": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OwnerOfResponse", - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "tokens": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_after` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "transfer_agreement": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_TransferAgreement", - "anyOf": [ - { - "$ref": "#/definitions/TransferAgreement" - }, - { - "type": "null" - } - ], - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "TransferAgreement": { - "description": "A struct used to represent an agreed transfer of a token. The `purchaser` may use the `Transfer` message for this token as long as funds are provided equalling the `amount` defined in the agreement.", - "type": "object", - "required": [ - "amount", - "purchaser" - ], - "properties": { - "amount": { - "description": "The amount required for the purchaser to transfer ownership of the token", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "purchaser": { - "description": "The address of the purchaser", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/execute.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/execute.json deleted file mode 100644 index b6b7442..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/execute.json +++ /dev/null @@ -1,1577 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Mints a token", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "extension", - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Transfers ownership of a token", - "type": "object", - "required": [ - "transfer_nft" - ], - "properties": { - "transfer_nft": { - "type": "object", - "required": [ - "recipient", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Sends a token to another contract", - "type": "object", - "required": [ - "send_nft" - ], - "properties": { - "send_nft": { - "type": "object", - "required": [ - "contract", - "msg", - "token_id" - ], - "properties": { - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted Approval", - "type": "object", - "required": [ - "revoke" - ], - "properties": { - "revoke": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approves an address for all tokens owned by the sender", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burns a token, removing all data related to it. The ID of the token is still reserved.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Archives a token, causing it to be immutable but readable", - "type": "object", - "required": [ - "archive" - ], - "properties": { - "archive": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Assigns a `TransferAgreement` for a token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "agreement": { - "anyOf": [ - { - "$ref": "#/definitions/TransferAgreement" - }, - { - "type": "null" - } - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Mint multiple tokens at a time", - "type": "object", - "required": [ - "batch_mint" - ], - "properties": { - "batch_mint": { - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "array", - "items": { - "$ref": "#/definitions/MintMsg" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "ExecuteMsg": { - "oneOf": [ - { - "description": "Mints a token", - "type": "object", - "required": [ - "mint" - ], - "properties": { - "mint": { - "type": "object", - "required": [ - "extension", - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Transfers ownership of a token", - "type": "object", - "required": [ - "transfer_nft" - ], - "properties": { - "transfer_nft": { - "type": "object", - "required": [ - "recipient", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Sends a token to another contract", - "type": "object", - "required": [ - "send_nft" - ], - "properties": { - "send_nft": { - "type": "object", - "required": [ - "contract", - "msg", - "token_id" - ], - "properties": { - "contract": { - "type": "string" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Allows operator to transfer / send the token from the owner's account. If expiration is set, then this allowance has a time/height limit", - "type": "object", - "required": [ - "approve" - ], - "properties": { - "approve": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted Approval", - "type": "object", - "required": [ - "revoke" - ], - "properties": { - "revoke": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approves an address for all tokens owned by the sender", - "type": "object", - "required": [ - "approve_all" - ], - "properties": { - "approve_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "expires": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Remove previously granted ApproveAll permission", - "type": "object", - "required": [ - "revoke_all" - ], - "properties": { - "revoke_all": { - "type": "object", - "required": [ - "operator" - ], - "properties": { - "operator": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Burns a token, removing all data related to it. The ID of the token is still reserved.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Archives a token, causing it to be immutable but readable", - "type": "object", - "required": [ - "archive" - ], - "properties": { - "archive": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Assigns a `TransferAgreement` for a token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "agreement": { - "anyOf": [ - { - "$ref": "#/definitions/TransferAgreement" - }, - { - "type": "null" - } - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Mint multiple tokens at a time", - "type": "object", - "required": [ - "batch_mint" - ], - "properties": { - "batch_mint": { - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "array", - "items": { - "$ref": "#/definitions/MintMsg" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/ExecuteMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "MintMsg": { - "type": "object", - "required": [ - "extension", - "owner", - "token_id" - ], - "properties": { - "extension": { - "description": "Any custom extension used by this contract", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "owner": { - "description": "The owner of the newly minter NFT", - "type": "string" - }, - "token_id": { - "description": "Unique ID of the NFT", - "type": "string" - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "TransferAgreement": { - "description": "A struct used to represent an agreed transfer of a token. The `purchaser` may use the `Transfer` message for this token as long as funds are provided equalling the `amount` defined in the agreement.", - "type": "object", - "required": [ - "amount", - "purchaser" - ], - "properties": { - "amount": { - "description": "The amount required for the purchaser to transfer ownership of the token", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "purchaser": { - "description": "The address of the purchaser", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/instantiate.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/instantiate.json deleted file mode 100644 index 859b5d3..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/instantiate.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address", - "minter", - "name", - "symbol" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "minter": { - "description": "The minter is the only one who can create new NFTs. This is designed for a base NFT that is controlled by an external program or contract. You will likely replace this with custom logic in custom NFTs", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "name": { - "description": "Name of the NFT contract", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - }, - "symbol": { - "description": "Symbol of the NFT contract", - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/query.json deleted file mode 100644 index ae1c0b2..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/query.json +++ /dev/null @@ -1,1330 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Owner of the given token by ID", - "type": "object", - "required": [ - "owner_of" - ], - "properties": { - "owner_of": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approvals for a given address (paginated)", - "type": "object", - "required": [ - "all_operators" - ], - "properties": { - "all_operators": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Amount of tokens minted by the contract", - "type": "object", - "required": [ - "num_tokens" - ], - "properties": { - "num_tokens": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token", - "type": "object", - "required": [ - "nft_info" - ], - "properties": { - "nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token and any approvals assigned to it", - "type": "object", - "required": [ - "all_nft_info" - ], - "properties": { - "all_nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract owned by a given address (paginated)", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract (paginated)", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If the token is archived", - "type": "object", - "required": [ - "is_archived" - ], - "properties": { - "is_archived": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The transfer agreement for the token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The current config of the contract", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/QueryMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Return approvals that a token has Return type: `ApprovalsResponse`", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "QueryMsg": { - "oneOf": [ - { - "description": "Owner of the given token by ID", - "type": "object", - "required": [ - "owner_of" - ], - "properties": { - "owner_of": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Approvals for a given address (paginated)", - "type": "object", - "required": [ - "all_operators" - ], - "properties": { - "all_operators": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Amount of tokens minted by the contract", - "type": "object", - "required": [ - "num_tokens" - ], - "properties": { - "num_tokens": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token", - "type": "object", - "required": [ - "nft_info" - ], - "properties": { - "nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The data of a token and any approvals assigned to it", - "type": "object", - "required": [ - "all_nft_info" - ], - "properties": { - "all_nft_info": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract owned by a given address (paginated)", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "owner": { - "type": "string" - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "All tokens minted by the contract (paginated)", - "type": "object", - "required": [ - "all_tokens" - ], - "properties": { - "all_tokens": { - "type": "object", - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "If the token is archived", - "type": "object", - "required": [ - "is_archived" - ], - "properties": { - "is_archived": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The transfer agreement for the token", - "type": "object", - "required": [ - "transfer_agreement" - ], - "properties": { - "transfer_agreement": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "The current config of the contract", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "$ref": "#/definitions/QueryMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "minter" - ], - "properties": { - "minter": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "type": "object", - "required": [ - "spender", - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "spender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Return approvals that a token has Return type: `ApprovalsResponse`", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "object", - "required": [ - "token_id" - ], - "properties": { - "include_expired": { - "type": [ - "boolean", - "null" - ] - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_nft_info.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_nft_info.json deleted file mode 100644 index eb93cea..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_nft_info.json +++ /dev/null @@ -1,170 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AllNftInfoResponse_for_TokenExtension", - "type": "object", - "required": [ - "access", - "info" - ], - "properties": { - "access": { - "description": "Who can transfer the token", - "allOf": [ - { - "$ref": "#/definitions/OwnerOfResponse" - } - ] - }, - "info": { - "description": "Data on the token itself,", - "allOf": [ - { - "$ref": "#/definitions/NftInfoResponse_for_TokenExtension" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "NftInfoResponse_for_TokenExtension": { - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "OwnerOfResponse": { - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_operators.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_operators.json deleted file mode 100644 index 533a096..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_operators.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_tokens.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_tokens.json deleted file mode 100644 index 4728d37..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_all_tokens.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_after` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approval.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approval.json deleted file mode 100644 index b29eab5..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approval.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalResponse", - "type": "object", - "required": [ - "approval" - ], - "properties": { - "approval": { - "$ref": "#/definitions/Approval" - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approvals.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approvals.json deleted file mode 100644 index 7cdac00..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_approvals.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ApprovalsResponse", - "type": "object", - "required": [ - "approvals" - ], - "properties": { - "approvals": { - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_balance.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_contract_info.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_contract_info.json deleted file mode 100644 index 4a805a8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_contract_info.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractInfoResponse", - "type": "object", - "required": [ - "name", - "symbol" - ], - "properties": { - "name": { - "type": "string" - }, - "symbol": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_extension.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_extension.json deleted file mode 100644 index 06d3666..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_extension.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokenExtension", - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_get.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_get.json deleted file mode 100644 index a2e5afd..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_get.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_Binary", - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_archived.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_archived.json deleted file mode 100644 index 2dfa3cd..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_archived.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsArchivedResponse", - "type": "object", - "required": [ - "is_archived" - ], - "properties": { - "is_archived": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_minter.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_minter.json deleted file mode 100644 index e79df37..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_minter.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "MinterResponse", - "description": "Shows who can mint these tokens", - "type": "object", - "properties": { - "minter": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_nft_info.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_nft_info.json deleted file mode 100644 index c4ba909..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_nft_info.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NftInfoResponse_for_TokenExtension", - "type": "object", - "required": [ - "extension" - ], - "properties": { - "extension": { - "description": "You can add any custom metadata here when you extend cw721-base", - "allOf": [ - { - "$ref": "#/definitions/TokenExtension" - } - ] - }, - "token_uri": { - "description": "Universal resource identifier for this NFT Should point to a JSON file that conforms to the ERC721 Metadata JSON Schema", - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "TokenExtension": { - "description": "https://docs.opensea.io/docs/metadata-standards Replicates OpenSea Metadata Standards", - "type": "object", - "required": [ - "publisher" - ], - "properties": { - "publisher": { - "description": "The original publisher of the token", - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_num_tokens.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_num_tokens.json deleted file mode 100644 index aff5850..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_num_tokens.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "NumTokensResponse", - "type": "object", - "required": [ - "count" - ], - "properties": { - "count": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_operators.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner_of.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner_of.json deleted file mode 100644 index abb9006..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_owner_of.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OwnerOfResponse", - "type": "object", - "required": [ - "approvals", - "owner" - ], - "properties": { - "approvals": { - "description": "If set this address is approved to transfer/send the token as well", - "type": "array", - "items": { - "$ref": "#/definitions/Approval" - } - }, - "owner": { - "description": "Owner of the token", - "type": "string" - } - }, - "additionalProperties": false, - "definitions": { - "Approval": { - "type": "object", - "required": [ - "expires", - "spender" - ], - "properties": { - "expires": { - "description": "When the Approval expires (maybe Expiration::never)", - "allOf": [ - { - "$ref": "#/definitions/Expiration" - } - ] - }, - "spender": { - "description": "Account that can transfer/send the token", - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_tokens.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_tokens.json deleted file mode 100644 index 4728d37..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_tokens.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TokensResponse", - "type": "object", - "required": [ - "tokens" - ], - "properties": { - "tokens": { - "description": "Contains all token_ids in lexicographical ordering If there are more than `limit`, use `start_after` in future queries to achieve pagination.", - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_transfer_agreement.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_transfer_agreement.json deleted file mode 100644 index 851a11f..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_transfer_agreement.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_TransferAgreement", - "anyOf": [ - { - "$ref": "#/definitions/TransferAgreement" - }, - { - "type": "null" - } - ], - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "TransferAgreement": { - "description": "A struct used to represent an agreed transfer of a token. The `purchaser` may use the `Transfer` message for this token as long as funds are provided equalling the `amount` defined in the agreement.", - "type": "object", - "required": [ - "amount", - "purchaser" - ], - "properties": { - "amount": { - "description": "The amount required for the purchaser to transfer ownership of the token", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - }, - "purchaser": { - "description": "The address of the purchaser", - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_type.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_version.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs index 97da17c..fa4885e 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/contract.rs @@ -1,33 +1,26 @@ #[cfg(not(feature = "imported"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, ensure, from_json, has_coins, to_json_binary, Api, BankMsg, Binary, Coin, CosmosMsg, - Deps, DepsMut, Empty, Env, MessageInfo, QuerierWrapper, Response, SubMsg, Uint128, + attr, ensure, from_json, has_coins, to_json_binary, Addr, Api, BankMsg, Binary, Coin, + CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, QuerierWrapper, Response, SubMsg, Uint128, }; -use crate::state::{ - is_archived, ANDR_MINTER, ARCHIVED, BATCH_MINT_ACTION, MINT_ACTION, TRANSFER_AGREEMENTS, -}; +use crate::state::{is_archived, ANDR_MINTER, ARCHIVED, TRANSFER_AGREEMENTS}; use andromeda_non_fungible_tokens::cw721::{ - ExecuteMsg, InstantiateMsg, MigrateMsg, MintMsg, QueryMsg, TokenExtension, TransferAgreement, + ExecuteMsg, InstantiateMsg, MintMsg, QueryMsg, TokenExtension, TransferAgreement, }; +use andromeda_std::common::rates::get_tax_amount; use andromeda_std::{ ado_base::{AndromedaMsg, AndromedaQuery}, - ado_contract::{ - permissioning::{is_context_permissioned, is_context_permissioned_strict}, - ADOContract, - }, - common::context::ExecuteContext, + ado_contract::{permissioning::is_context_permissioned_strict, ADOContract}, + amp::AndrAddr, + common::{actions::call_action, context::ExecuteContext}, }; -use cw2::{get_contract_version, set_contract_version}; -use semver::Version; use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, - common::encode_binary, - common::rates::get_tax_amount, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, common::Funds, - error::{from_semver, ContractError}, + error::ContractError, }; use cw721::{ContractInfoResponse, Cw721Execute}; use cw721_base::{state::TokenInfo, Cw721Contract, ExecuteMsg as Cw721ExecuteMsg}; @@ -43,8 +36,6 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - let contract_info = ContractInfoResponse { name: msg.name, symbol: msg.symbol, @@ -63,22 +54,17 @@ pub fn instantiate( deps.storage, env, deps.api, + &deps.querier, info.clone(), BaseInstantiateMsg { - ado_type: "cw721".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; - let modules_resp = - contract.register_modules(info.sender.as_str(), deps.storage, msg.modules)?; - Ok(resp - .add_submessages(modules_resp.messages) - .add_attributes(modules_resp.attributes) - .add_attributes(vec![attr("minter", msg.minter)])) + Ok(resp.add_attributes(vec![attr("minter", msg.minter)])) } #[cfg_attr(not(feature = "imported"), entry_point)] @@ -100,32 +86,16 @@ pub fn execute( } } -fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { +fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { let contract = ADOContract::default(); - ensure!( - is_context_permissioned( - ctx.deps.storage, - &ctx.info, - &ctx.env, - &ctx.amp_ctx, - msg.as_ref() - )?, - ContractError::Unauthorized {} - ); - - let payee = if let Some(amp_ctx) = ctx.amp_ctx.clone() { - ctx.deps - .api - .addr_validate(amp_ctx.ctx.get_origin().as_str())? - } else { - ctx.info.sender.clone() - }; - - let fee_msg = ADOContract::default().pay_fee( - ctx.deps.storage, - &ctx.deps.querier, - msg.as_ref().to_string(), - payee, + let action = msg.as_ref().to_string(); + + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), )?; if let ExecuteMsg::Approve { token_id, .. } = &msg { @@ -141,12 +111,12 @@ fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result execute_mint(ctx, token_id, token_uri, owner, extension), - ExecuteMsg::BatchMint { tokens } => execute_batch_mint(ctx, tokens), + } => execute_mint(ctx, token_id, token_uri, owner, extension, action), + ExecuteMsg::BatchMint { tokens } => execute_batch_mint(ctx, tokens, action), ExecuteMsg::TransferNft { recipient, token_id, - } => execute_transfer(ctx, recipient, token_id), + } => execute_transfer(ctx, recipient, token_id, &action), ExecuteMsg::TransferAgreement { token_id, agreement, @@ -167,7 +137,10 @@ fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result, owner: String, extension: TokenExtension, + action: String, ) -> Result { let minter = ANDR_MINTER .load(ctx.deps.storage)? @@ -191,11 +165,11 @@ fn execute_mint( ensure!( ctx.contains_sender(minter.as_str()) | is_context_permissioned_strict( - ctx.deps.storage, + ctx.deps.branch(), &ctx.info, &ctx.env, &ctx.amp_ctx, - MINT_ACTION + action )?, ContractError::Unauthorized {} ); @@ -236,6 +210,7 @@ fn mint( fn execute_batch_mint( mut ctx: ExecuteContext, tokens_to_mint: Vec, + action: String, ) -> Result { let mut resp = Response::default(); let minter = ANDR_MINTER @@ -244,11 +219,11 @@ fn execute_batch_mint( ensure!( ctx.contains_sender(minter.as_str()) | is_context_permissioned_strict( - ctx.deps.storage, + ctx.deps.branch(), &ctx.info, &ctx.env, &ctx.amp_ctx, - BATCH_MINT_ACTION + action )?, ContractError::Unauthorized {} ); @@ -275,32 +250,18 @@ fn execute_batch_mint( } fn execute_transfer( - env: ExecuteContext, - recipient: String, + ctx: ExecuteContext, + recipient: AndrAddr, token_id: String, + action: &str, ) -> Result { let ExecuteContext { deps, info, env, .. - } = env; + } = ctx; let base_contract = ADOContract::default(); - let responses = base_contract.module_hook::( - &deps.as_ref(), - AndromedaHook::OnTokenTransfer { - token_id: token_id.clone(), - sender: info.sender.to_string(), - recipient: recipient.clone(), - }, - )?; // Reduce all responses into one. - let mut resp = responses - .into_iter() - .reduce(|resp, r| { - resp.add_submessages(r.messages) - .add_events(r.events) - .add_attributes(r.attributes) - }) - .unwrap_or_else(Response::new); - + let mut resp = Response::new(); + let recipient_address = recipient.get_raw_address(&deps.as_ref())?.into_string(); let contract = AndrCW721Contract::default(); let mut token = contract.tokens.load(deps.storage, &token_id)?; ensure!( @@ -312,35 +273,52 @@ fn execute_transfer( &TRANSFER_AGREEMENTS.may_load(deps.storage, &token_id)? { let agreement_amount = get_transfer_agreement_amount(deps.api, &deps.querier, agreement)?; - let (mut msgs, events, remainder) = base_contract.on_funds_transfer( - &deps.as_ref(), - info.sender.to_string(), + let transfer_response = base_contract.query_deducted_funds( + deps.as_ref(), + action, Funds::Native(agreement_amount.clone()), - encode_binary(&ExecuteMsg::TransferNft { - token_id: token_id.clone(), - recipient: recipient.clone(), - })?, )?; - let remaining_amount = remainder.try_get_coin()?; - let tax_amount = get_tax_amount(&msgs, agreement_amount.amount, remaining_amount.amount); - msgs.push(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: token.owner.to_string(), - amount: vec![remaining_amount], - }))); - resp = resp.add_submessages(msgs).add_events(events); - tax_amount + + match transfer_response { + Some(mut transfer_response) => { + let remaining_amount = transfer_response.leftover_funds.try_get_coin()?; + let tax_amount = get_tax_amount( + &transfer_response.msgs, + agreement_amount.amount, + remaining_amount.amount, + ); + transfer_response + .msgs + .push(SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: token.owner.to_string(), + amount: vec![remaining_amount], + }))); + resp = resp.add_submessages(transfer_response.msgs); + tax_amount + } + None => { + let remaining_amount = Funds::Native(agreement_amount).try_get_coin()?; + let tax_amount = Uint128::zero(); + let msg = SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: token.owner.to_string(), + amount: vec![remaining_amount], + })); + resp = resp.add_submessage(msg); + tax_amount + } + } } else { Uint128::zero() }; check_can_send(deps.as_ref(), env, info, &token_id, &token, tax_amount)?; - token.owner = deps.api.addr_validate(&recipient)?; + token.owner = deps.api.addr_validate(&recipient_address)?; token.approvals.clear(); TRANSFER_AGREEMENTS.remove(deps.storage, &token_id); contract.tokens.save(deps.storage, &token_id, &token)?; Ok(resp .add_attribute("action", "transfer") - .add_attribute("recipient", recipient)) + .add_attribute("recipient", recipient_address)) } fn get_transfer_agreement_amount( @@ -410,11 +388,11 @@ fn check_can_send( } fn execute_update_transfer_agreement( - env: ExecuteContext, + ctx: ExecuteContext, token_id: String, agreement: Option, ) -> Result { - let ExecuteContext { deps, info, .. } = env; + let ExecuteContext { deps, info, .. } = ctx; let contract = AndrCW721Contract::default(); let token = contract.tokens.load(deps.storage, &token_id)?; ensure!(token.owner == info.sender, ContractError::Unauthorized {}); @@ -438,8 +416,8 @@ fn execute_update_transfer_agreement( Ok(Response::default()) } -fn execute_archive(env: ExecuteContext, token_id: String) -> Result { - let ExecuteContext { deps, info, .. } = env; +fn execute_archive(ctx: ExecuteContext, token_id: String) -> Result { + let ExecuteContext { deps, info, .. } = ctx; ensure!( !is_archived(deps.storage, &token_id)?.is_archived, ContractError::TokenIsArchived {} @@ -455,8 +433,8 @@ fn execute_archive(env: ExecuteContext, token_id: String) -> Result Result { - let ExecuteContext { deps, info, .. } = env; +fn execute_burn(ctx: ExecuteContext, token_id: String) -> Result { + let ExecuteContext { deps, info, .. } = ctx; let contract = AndrCW721Contract::default(); let token = contract.tokens.load(deps.storage, &token_id)?; ensure!(token.owner == info.sender, ContractError::Unauthorized {}); @@ -481,7 +459,7 @@ fn execute_burn(env: ExecuteContext, token_id: String) -> Result Result { let ExecuteContext { @@ -489,6 +467,7 @@ fn execute_send_nft( } = ctx; let contract = AndrCW721Contract::default(); TRANSFER_AGREEMENTS.remove(deps.storage, &token_id); + let contract_addr = contract_addr.get_raw_address(&deps.as_ref())?.into_string(); Ok(contract.send_nft(deps, env, info, contract_addr, token_id, msg)?) } @@ -520,41 +499,12 @@ pub fn query_transfer_agreement( Ok(TRANSFER_AGREEMENTS.may_load(deps.storage, &token_id)?) } -pub fn query_minter(deps: Deps) -> Result { - let minter = ANDR_MINTER.load(deps.storage)?.get_raw_address(&deps)?; - Ok(minter.to_string()) +pub fn query_minter(deps: Deps) -> Result { + let minter = ANDR_MINTER.load(deps.storage)?; + minter.get_raw_address(&deps) } #[cfg_attr(not(feature = "imported"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/mock.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/mock.rs index e4190d1..323d11b 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/mock.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/mock.rs @@ -4,15 +4,16 @@ use crate::contract::{execute, instantiate, query}; use andromeda_non_fungible_tokens::cw721::{ ExecuteMsg, InstantiateMsg, MintMsg, QueryMsg, TokenExtension, TransferAgreement, }; -use andromeda_std::{ado_base::modules::Module, amp::addresses::AndrAddr}; +use andromeda_std::amp::addresses::AndrAddr; use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::{ExecuteResult, MockADO, MockContract}, }; use cosmwasm_schema::serde::Serialize; use cosmwasm_std::{to_json_binary, Addr, Binary, Coin, Empty}; use cw721::OwnerOfResponse; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; pub struct MockCW721(Addr); mock_ado!(MockCW721, ExecuteMsg, QueryMsg); @@ -22,11 +23,10 @@ impl MockCW721 { pub fn instantiate( code_id: u64, sender: Addr, - app: &mut App, + app: &mut MockApp, name: impl Into, symbol: impl Into, minter: impl Into, - modules: Option>, kernel_address: impl Into, owner: Option, ) -> MockCW721 { @@ -34,7 +34,6 @@ impl MockCW721 { name.into(), symbol.into(), minter.into(), - modules, kernel_address.into(), owner, ); @@ -53,7 +52,7 @@ impl MockCW721 { pub fn execute_quick_mint( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, amount: u32, owner: impl Into, @@ -64,25 +63,25 @@ impl MockCW721 { pub fn execute_send_nft( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, contract: impl Into, token_id: impl Into, msg: &impl Serialize, ) -> ExecuteResult { let msg = mock_send_nft( - contract.into(), + AndrAddr::from_string(contract.into()), token_id.into(), to_json_binary(msg).unwrap(), ); self.execute(app, &msg, sender, &[]) } - pub fn query_minter(&self, app: &App) -> Addr { + pub fn query_minter(&self, app: &MockApp) -> Addr { self.query::(app, mock_cw721_minter_query()) } - pub fn query_owner_of(&self, app: &App, token_id: impl Into) -> Addr { + pub fn query_owner_of(&self, app: &MockApp, token_id: impl Into) -> Addr { Addr::unchecked( self.query::(app, mock_cw721_owner_of(token_id.into(), None)) .owner, @@ -90,6 +89,10 @@ impl MockCW721 { } } +pub fn mock_cw721_minter_query() -> QueryMsg { + QueryMsg::Minter {} +} + pub fn mock_andromeda_cw721() -> Box> { let contract = ContractWrapper::new_with_empty(execute, instantiate, query); Box::new(contract) @@ -99,7 +102,6 @@ pub fn mock_cw721_instantiate_msg( name: String, symbol: String, minter: impl Into, - modules: Option>, kernel_address: String, owner: Option, ) -> InstantiateMsg { @@ -107,7 +109,6 @@ pub fn mock_cw721_instantiate_msg( name, symbol, minter: AndrAddr::from_string(minter.into()), - modules, kernel_address, owner, } @@ -120,10 +121,6 @@ pub fn mock_cw721_owner_of(token_id: String, include_expired: Option) -> Q } } -pub fn mock_cw721_minter_query() -> QueryMsg { - QueryMsg::Minter {} -} - pub fn mock_mint_msg( token_id: String, extension: TokenExtension, @@ -152,7 +149,7 @@ pub fn mock_quick_mint_msg(amount: u32, owner: String) -> ExecuteMsg { ExecuteMsg::BatchMint { tokens: mint_msgs } } -pub fn mock_send_nft(contract: String, token_id: String, msg: Binary) -> ExecuteMsg { +pub fn mock_send_nft(contract: AndrAddr, token_id: String, msg: Binary) -> ExecuteMsg { ExecuteMsg::SendNft { contract, token_id, @@ -160,7 +157,7 @@ pub fn mock_send_nft(contract: String, token_id: String, msg: Binary) -> Execute } } -pub fn mock_transfer_nft(recipient: String, token_id: String) -> ExecuteMsg { +pub fn mock_transfer_nft(recipient: AndrAddr, token_id: String) -> ExecuteMsg { ExecuteMsg::TransferNft { recipient, token_id, diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/state.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/state.rs index c05c482..d8f3da4 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/state.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/state.rs @@ -7,9 +7,6 @@ pub const ANDR_MINTER: Item = Item::new("minter"); pub const TRANSFER_AGREEMENTS: Map<&str, TransferAgreement> = Map::new("transfer_agreements"); pub const ARCHIVED: Map<&str, bool> = Map::new("archived_tokens"); -pub const MINT_ACTION: &str = "can_mint"; -pub const BATCH_MINT_ACTION: &str = "can_batch_mint"; - pub fn is_archived( storage: &dyn Storage, token_id: &str, diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs index cce060a..17b5761 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-cw721/src/testing/mod.rs @@ -1,36 +1,32 @@ -use cosmwasm_std::{ - attr, coin, coins, from_json, - testing::{mock_env, mock_info}, - Addr, Coin, DepsMut, Env, Response, StdError, Uint128, -}; - -use andromeda_std::error::ContractError; -use andromeda_std::{ado_base::modules::Module, testing::mock_querier::FAKE_VFS_PATH}; -use andromeda_std::{ado_contract::ADOContract, amp::addresses::AndrAddr}; - use crate::{contract::*, state::TRANSFER_AGREEMENTS}; use andromeda_non_fungible_tokens::cw721::{ ExecuteMsg, InstantiateMsg, IsArchivedResponse, MintMsg, QueryMsg, TokenExtension, TransferAgreement, }; -use andromeda_std::testing::mock_querier::{ - mock_dependencies_custom, MOCK_ADDRESS_LIST_CONTRACT, MOCK_KERNEL_CONTRACT, +use andromeda_std::error::ContractError; +use andromeda_std::testing::mock_querier::FAKE_VFS_PATH; +use andromeda_std::testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL_CONTRACT}; +use andromeda_std::{ado_contract::ADOContract, amp::addresses::AndrAddr}; +use cosmwasm_std::{ + attr, coin, from_json, + testing::{mock_env, mock_info}, + Addr, Coin, DepsMut, Env, Response, StdError, Uint128, }; use cw721::{AllNftInfoResponse, OwnerOfResponse}; const MINTER: &str = "minter"; const SYMBOL: &str = "TT"; const NAME: &str = "TestToken"; -const ADDRESS_LIST: &str = "addresslist"; +const _ADDRESS_LIST: &str = "addresslist"; // const RATES: &str = "rates"; -fn init_setup(deps: DepsMut, env: Env, modules: Option>) { +fn init_setup(deps: DepsMut, env: Env) { let info = mock_info(MINTER, &[]); let inst_msg = InstantiateMsg { name: NAME.to_string(), symbol: SYMBOL.to_string(), minter: AndrAddr::from_string(MINTER.to_string()), - modules, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }; @@ -55,7 +51,7 @@ fn test_transfer_nft() { let creator = String::from("creator"); let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - init_setup(deps.as_mut(), env.clone(), None); + init_setup(deps.as_mut(), env.clone()); mint_token( deps.as_mut(), env.clone(), @@ -67,7 +63,7 @@ fn test_transfer_nft() { ); let transfer_msg = ExecuteMsg::TransferNft { - recipient: Addr::unchecked("recipient").to_string(), + recipient: AndrAddr::from_string(Addr::unchecked("recipient").to_string()), token_id: token_id.clone(), }; @@ -124,7 +120,7 @@ fn test_agreed_transfer_nft() { amount: Uint128::from(100u64), }; let purchaser = "purchaser"; - init_setup(deps.as_mut(), env.clone(), None); + init_setup(deps.as_mut(), env.clone()); mint_token( deps.as_mut(), env.clone(), @@ -149,7 +145,7 @@ fn test_agreed_transfer_nft() { .unwrap(); let transfer_msg = ExecuteMsg::TransferNft { - recipient: Addr::unchecked("recipient").to_string(), + recipient: AndrAddr::from_string(Addr::unchecked("recipient").to_string()), token_id: token_id.clone(), }; @@ -188,7 +184,7 @@ fn test_agreed_transfer_nft_wildcard() { amount: Uint128::from(100u64), }; let purchaser = "*"; - init_setup(deps.as_mut(), env.clone(), None); + init_setup(deps.as_mut(), env.clone()); mint_token( deps.as_mut(), env.clone(), @@ -211,7 +207,7 @@ fn test_agreed_transfer_nft_wildcard() { // Transfer the nft let transfer_msg = ExecuteMsg::TransferNft { - recipient: Addr::unchecked("recipient").to_string(), + recipient: AndrAddr::from_string(Addr::unchecked("recipient").to_string()), token_id: token_id.clone(), }; @@ -233,7 +229,7 @@ fn test_archive() { let creator = String::from("creator"); let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - init_setup(deps.as_mut(), env.clone(), None); + init_setup(deps.as_mut(), env.clone()); mint_token( deps.as_mut(), env.clone(), @@ -269,7 +265,7 @@ fn test_burn() { let creator = String::from("creator"); let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - init_setup(deps.as_mut(), env.clone(), None); + init_setup(deps.as_mut(), env.clone()); mint_token( deps.as_mut(), env.clone(), @@ -332,7 +328,7 @@ fn test_archived_check() { let valid_info = mock_info(creator.as_str(), &[]); let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - init_setup(deps.as_mut(), env.clone(), None); + init_setup(deps.as_mut(), env.clone()); mint_token( deps.as_mut(), env.clone(), @@ -370,7 +366,7 @@ fn test_transfer_agreement() { denom: "uluna".to_string(), }, }; - init_setup(deps.as_mut(), env.clone(), None); + init_setup(deps.as_mut(), env.clone()); mint_token( deps.as_mut(), env.clone(), @@ -402,104 +398,118 @@ fn test_transfer_agreement() { assert_eq!(resp, Some(agreement)) } -#[test] -fn test_modules() { - let modules: Vec = vec![ - // Module::new(RATES, MOCK_RATES_CONTRACT, false), - Module::new(ADDRESS_LIST, MOCK_ADDRESS_LIST_CONTRACT, false), - ]; - - let mut deps = mock_dependencies_custom(&coins(100, "uusd")); - - let token_id = String::from("testtoken"); - let creator = String::from("creator"); - let env = mock_env(); - let _agreement = TransferAgreement { - purchaser: String::from("purchaser"), - amount: Coin { - amount: Uint128::from(100u64), - denom: "uusd".to_string(), - }, - }; - init_setup(deps.as_mut(), env.clone(), Some(modules)); - mint_token( - deps.as_mut(), - env, - token_id, - creator.clone(), - TokenExtension { publisher: creator }, - ); - - // let msg = ExecuteMsg::TransferAgreement { - // token_id: token_id.clone(), - // agreement: Some(agreement), - // }; - - // let not_whitelisted_info = mock_info("not_whitelisted", &[]); - // let res = execute(deps.as_mut(), mock_env(), not_whitelisted_info, msg.clone()); - // assert_eq!( - // ContractError::Std(StdError::generic_err( - // "Querier contract error: InvalidAddress" - // )), - // res.unwrap_err() - // ); - - // let info = mock_info("creator", &[]); - // let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); - - // let msg = ExecuteMsg::TransferNft { - // token_id: token_id.clone(), - // recipient: "purchaser".into(), - // }; - - // // Tax not added by sender, remember that the contract holds 100 uusd which is enough to cover - // // the taxes in this case. - // let purchaser = mock_info("purchaser", &coins(100, "uusd")); - // let res = execute(deps.as_mut(), mock_env(), purchaser, msg.clone()); - // assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); - - // // Add 10 for tax. - // let purchaser = mock_info("purchaser", &coins(100 + 10, "uusd")); - // let res = execute(deps.as_mut(), mock_env(), purchaser, msg).unwrap(); - - // let sub_msgs: Vec = vec![ - // // For royalty. - // bank_sub_msg(MOCK_RATES_RECIPIENT, vec![coin(10, "uusd")]), - // // For tax. - // bank_sub_msg(MOCK_RATES_RECIPIENT, vec![coin(10, "uusd")]), - // bank_sub_msg(&creator, vec![coin(80, "uusd")]), - // ]; - - // assert_eq!( - // Response::new() - // .add_attribute("action", "transfer") - // .add_attribute("recipient", "purchaser") - // .add_submessages(sub_msgs) - // .add_event(Event::new("Royalty")) - // .add_event(Event::new("Tax")), - // res - // ); - - // // Test the hook. - // let msg = QueryMsg::AndrHook(AndromedaHook::OnFundsTransfer { - // sender: "sender".to_string(), - // payload: to_json_binary(&token_id).unwrap(), - // amount: Funds::Native(coin(100, "uusd")), - // }); - - // let res: OnFundsTransferResponse = - // from_json(&query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); - - // let expected_response = OnFundsTransferResponse { - // msgs: vec![ - // bank_sub_msg(MOCK_RATES_RECIPIENT, vec![coin(10, "uusd")]), - // bank_sub_msg(MOCK_RATES_RECIPIENT, vec![coin(10, "uusd")]), - // ], - // leftover_funds: Funds::Native(coin(90, "uusd")), - // events: vec![Event::new("Royalty"), Event::new("Tax")], - // }; - // assert_eq!(expected_response, res); -} +// #[test] +// fn test_modules() { +// let mut deps = mock_dependencies_custom(&coins(100, "uusd")); + +// let token_id = String::from("testtoken"); +// let creator = String::from("creator"); +// let env = mock_env(); +// let agreement = TransferAgreement { +// purchaser: String::from("purchaser"), +// amount: Coin { +// amount: Uint128::from(100u64), +// denom: "uusd".to_string(), +// }, +// }; +// init_setup(deps.as_mut(), env.clone()); +// mint_token( +// deps.as_mut(), +// env, +// token_id.clone(), +// creator.clone(), +// TokenExtension { +// publisher: creator.clone(), +// }, +// ); + +// let rate = Rate::Local(LocalRate { +// rate_type: LocalRateType::Deductive, +// recipients: vec![Recipient { +// address: AndrAddr::from_string("mrc".to_string()), +// msg: None, +// ibc_recovery_address: None, +// }], +// value: LocalRateValue::Flat(coin(10_u128, "uusd")), +// description: None, +// }); + +// // Set rates +// ADOContract::default() +// .set_rates(deps.as_mut().storage, "cw721", rate) +// .unwrap(); + +// let msg = ExecuteMsg::TransferAgreement { +// token_id: token_id.clone(), +// agreement: Some(agreement), +// }; + +// //TODO when address list is implemented +// // let not_whitelisted_info = mock_info("not_whitelisted", &[]); +// // let res = execute(deps.as_mut(), mock_env(), not_whitelisted_info, msg.clone()); +// // assert_eq!( +// // ContractError::Std(StdError::generic_err( +// // "Querier contract error: InvalidAddress" +// // )), +// // res.unwrap_err() +// // ); + +// let info = mock_info("creator", &[]); +// let _res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); + +// let msg = ExecuteMsg::TransferNft { +// token_id: token_id.clone(), +// recipient: "purchaser".into(), +// }; + +// // Tax not added by sender, remember that the contract holds 100 uusd which is enough to cover +// // the taxes in this case. +// let purchaser = mock_info("purchaser", &coins(100, "uusd")); +// let res = execute(deps.as_mut(), mock_env(), purchaser, msg.clone()); +// assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); + +// // Add 10 for tax. +// let purchaser = mock_info("purchaser", &coins(100 + 10, "uusd")); +// let res = execute(deps.as_mut(), mock_env(), purchaser, msg).unwrap(); + +// let sub_msgs: Vec = vec![ +// // For royalty. +// // bank_sub_msg("MOCK_RATES_RECIPIENT", vec![coin(10, "uusd")]), +// // For tax. +// bank_sub_msg("mrc", vec![coin(10, "uusd")]), +// bank_sub_msg(&creator, vec![coin(80, "uusd")]), +// ]; + +// assert_eq!( +// Response::new() +// .add_attribute("action", "transfer") +// .add_attribute("recipient", "purchaser") +// .add_submessages(sub_msgs) +// .add_event(Event::new("Royalty")) +// .add_event(Event::new("Tax")), +// res +// ); + +// // Test the hook. +// let msg = QueryMsg::AndrHook(AndromedaHook::OnFundsTransfer { +// sender: "sender".to_string(), +// payload: to_json_binary(&token_id).unwrap(), +// amount: Funds::Native(coin(100, "uusd")), +// }); + +// let res: RatesResponse = +// from_json(query(deps.as_ref(), mock_env(), msg).unwrap()).unwrap(); + +// let expected_response = RatesResponse { +// msgs: vec![ +// bank_sub_msg("MOCK_RATES_RECIPIENT", vec![coin(10, "uusd")]), +// bank_sub_msg("MOCK_RATES_RECIPIENT", vec![coin(10, "uusd")]), +// ], +// leftover_funds: Funds::Native(coin(90, "uusd")), +// events: vec![Event::new("Royalty"), Event::new("Tax")], +// }; +// assert_eq!(expected_response, res); +// } // TODO: IMPLEMENT // #[test] @@ -560,7 +570,7 @@ fn test_update_app_contract_invalid_minter() { name: NAME.to_string(), symbol: SYMBOL.to_string(), minter: AndrAddr::from_string(FAKE_VFS_PATH), - modules: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: Some("owner".to_string()), }; @@ -588,7 +598,7 @@ fn test_batch_mint() { name: NAME.to_string(), symbol: SYMBOL.to_string(), minter: AndrAddr::from_string(MINTER), - modules: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }; diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/Cargo.toml b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/Cargo.toml index abcda09..cc3422f 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/Cargo.toml +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-marketplace" -version = "0.2.1" +version = "2.1.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" [lib] crate-type = ["cdylib", "rlib"] @@ -12,7 +12,7 @@ crate-type = ["cdylib", "rlib"] backtraces = ["cosmwasm-std/backtraces"] # use library feature to disable all instantiate/execute/query exports library = [] -testing = ["cw-multi-test"] +testing = ["cw-multi-test", "andromeda-testing"] [dependencies] @@ -21,15 +21,14 @@ cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = { workspace = true } cw721 = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } +cw20 = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true, features = ["rates"] } andromeda-non-fungible-tokens = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } -andromeda-testing = { workspace = true } +andromeda-testing = { workspace = true, optional = true } [dev-dependencies] -andromeda-app = { version = "0.1.0", path = "../../../packages/andromeda-app" } +andromeda-app = { workspace = true } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/README.md b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/README.md new file mode 100644 index 0000000..b8803eb --- /dev/null +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/README.md @@ -0,0 +1,10 @@ +# Overview + +The Marketplace ADO is a smart contract that allows you to sell your NFTs in a marketplace. The seller sends their NFT to the Marketplace ADO and attaches the sale options such as the price and funds used to purchase the NFT. Once the NFT is sent, the sale will start at the time specified by the seller. + +Purchasing the NFT can be customized to work with one of the following options: + +- CW20 +- Native + +[Marketplace Full Documentation](https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/marketplace) \ No newline at end of file diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/andromeda-marketplace.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/andromeda-marketplace.json deleted file mode 100644 index 47ea3b3..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/andromeda-marketplace.json +++ /dev/null @@ -1,1820 +0,0 @@ -{ - "contract_name": "andromeda-marketplace", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive_nft" - ], - "properties": { - "receive_nft": { - "$ref": "#/definitions/Cw721ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Transfers NFT to buyer and sends funds to seller", - "type": "object", - "required": [ - "buy" - ], - "properties": { - "buy": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Updates the sale's price, demomination, and whitelist", - "type": "object", - "required": [ - "update_sale" - ], - "properties": { - "update_sale": { - "type": "object", - "required": [ - "coin_denom", - "price", - "token_address", - "token_id" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "price": { - "$ref": "#/definitions/Uint128" - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cancel_sale" - ], - "properties": { - "cancel_sale": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw721ReceiveMsg": { - "description": "Cw721ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "msg", - "sender", - "token_id" - ], - "properties": { - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the latest sale state for the given token. This will either be the current sale if there is one in progress or the last completed one.", - "type": "object", - "required": [ - "latest_sale_state" - ], - "properties": { - "latest_sale_state": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the sale state for the given sale id.", - "type": "object", - "required": [ - "sale_state" - ], - "properties": { - "sale_state": { - "type": "object", - "required": [ - "sale_id" - ], - "properties": { - "sale_id": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the sale ids for the given token.", - "type": "object", - "required": [ - "sale_ids" - ], - "properties": { - "sale_ids": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets all of the sale infos for a given token address.", - "type": "object", - "required": [ - "sale_infos_for_address" - ], - "properties": { - "sale_infos_for_address": { - "type": "object", - "required": [ - "token_address" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "andr_hook": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "block_height_upon_creation": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - "is_operator": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "kernel_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "latest_sale_state": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleStateResponse", - "type": "object", - "required": [ - "coin_denom", - "price", - "sale_id", - "status" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "price": { - "$ref": "#/definitions/Uint128" - }, - "sale_id": { - "$ref": "#/definitions/Uint128" - }, - "status": { - "$ref": "#/definitions/Status" - } - }, - "additionalProperties": false, - "definitions": { - "Status": { - "type": "string", - "enum": [ - "open", - "expired", - "executed", - "cancelled" - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "module": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "module_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "operators": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "original_publisher": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false - }, - "owner": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false - }, - "permissioned_actions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "permissions": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } - }, - "sale_ids": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleIdsResponse", - "type": "object", - "required": [ - "sale_ids" - ], - "properties": { - "sale_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "sale_infos_for_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_SaleInfo", - "type": "array", - "items": { - "$ref": "#/definitions/SaleInfo" - }, - "definitions": { - "SaleInfo": { - "type": "object", - "required": [ - "sale_ids", - "token_address", - "token_id" - ], - "properties": { - "sale_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "sale_state": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleStateResponse", - "type": "object", - "required": [ - "coin_denom", - "price", - "sale_id", - "status" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "price": { - "$ref": "#/definitions/Uint128" - }, - "sale_id": { - "$ref": "#/definitions/Uint128" - }, - "status": { - "$ref": "#/definitions/Status" - } - }, - "additionalProperties": false, - "definitions": { - "Status": { - "type": "string", - "enum": [ - "open", - "expired", - "executed", - "cancelled" - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - }, - "version": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/cw721receive.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/cw721receive.json deleted file mode 100644 index a63c600..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/cw721receive.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "cw721receive", - "oneOf": [ - { - "description": "Starts a new sale with the given parameters. The sale info can be modified before it has started but is immutable after that.", - "type": "object", - "required": [ - "start_sale" - ], - "properties": { - "start_sale": { - "type": "object", - "required": [ - "coin_denom", - "price" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "duration": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "price": { - "$ref": "#/definitions/Uint128" - }, - "start_time": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/execute.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/execute.json deleted file mode 100644 index 5c8014a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/execute.json +++ /dev/null @@ -1,724 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "receive_nft" - ], - "properties": { - "receive_nft": { - "$ref": "#/definitions/Cw721ReceiveMsg" - } - }, - "additionalProperties": false - }, - { - "description": "Transfers NFT to buyer and sends funds to seller", - "type": "object", - "required": [ - "buy" - ], - "properties": { - "buy": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Updates the sale's price, demomination, and whitelist", - "type": "object", - "required": [ - "update_sale" - ], - "properties": { - "update_sale": { - "type": "object", - "required": [ - "coin_denom", - "price", - "token_address", - "token_id" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "price": { - "$ref": "#/definitions/Uint128" - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cancel_sale" - ], - "properties": { - "cancel_sale": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_owner" - ], - "properties": { - "update_owner": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_operators" - ], - "properties": { - "update_operators": { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_app_contract" - ], - "properties": { - "update_app_contract": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "set_permission" - ], - "properties": { - "set_permission": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_permission" - ], - "properties": { - "remove_permission": { - "type": "object", - "required": [ - "action", - "actor" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permission_action" - ], - "properties": { - "permission_action": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_module" - ], - "properties": { - "register_module": { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "deregister_module" - ], - "properties": { - "deregister_module": { - "type": "object", - "required": [ - "module_idx" - ], - "properties": { - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "alter_module" - ], - "properties": { - "alter_module": { - "type": "object", - "required": [ - "module", - "module_idx" - ], - "properties": { - "module": { - "$ref": "#/definitions/Module" - }, - "module_idx": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw721ReceiveMsg": { - "description": "Cw721ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "msg", - "sender", - "token_id" - ], - "properties": { - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/instantiate.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/instantiate.json deleted file mode 100644 index 2173324..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/instantiate.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "modules": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/Module" - } - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Module": { - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/query.json deleted file mode 100644 index cdb3839..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/query.json +++ /dev/null @@ -1,507 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Gets the latest sale state for the given token. This will either be the current sale if there is one in progress or the last completed one.", - "type": "object", - "required": [ - "latest_sale_state" - ], - "properties": { - "latest_sale_state": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the sale state for the given sale id.", - "type": "object", - "required": [ - "sale_state" - ], - "properties": { - "sale_state": { - "type": "object", - "required": [ - "sale_id" - ], - "properties": { - "sale_id": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets the sale ids for the given token.", - "type": "object", - "required": [ - "sale_ids" - ], - "properties": { - "sale_ids": { - "type": "object", - "required": [ - "token_address", - "token_id" - ], - "properties": { - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Gets all of the sale infos for a given token address.", - "type": "object", - "required": [ - "sale_infos_for_address" - ], - "properties": { - "sale_infos_for_address": { - "type": "object", - "required": [ - "token_address" - ], - "properties": { - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - }, - "token_address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissions" - ], - "properties": { - "permissions": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "type": "string" - }, - "limit": { - "type": [ - "integer", - "null" - ], - "format": "uint32", - "minimum": 0.0 - }, - "start_after": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "permissioned_actions" - ], - "properties": { - "permissioned_actions": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "andr_hook" - ], - "properties": { - "andr_hook": { - "$ref": "#/definitions/AndromedaHook" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "AndromedaHook": { - "oneOf": [ - { - "type": "object", - "required": [ - "on_execute" - ], - "properties": { - "on_execute": { - "type": "object", - "required": [ - "payload", - "sender" - ], - "properties": { - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_funds_transfer" - ], - "properties": { - "on_funds_transfer": { - "type": "object", - "required": [ - "amount", - "payload", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Funds" - }, - "payload": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "on_token_transfer" - ], - "properties": { - "on_token_transfer": { - "type": "object", - "required": [ - "recipient", - "sender", - "token_id" - ], - "properties": { - "recipient": { - "type": "string" - }, - "sender": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Cw20Coin": { - "type": "object", - "required": [ - "address", - "amount" - ], - "properties": { - "address": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false - }, - "Funds": { - "oneOf": [ - { - "type": "object", - "required": [ - "native" - ], - "properties": { - "native": { - "$ref": "#/definitions/Coin" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "cw20" - ], - "properties": { - "cw20": { - "$ref": "#/definitions/Cw20Coin" - } - }, - "additionalProperties": false - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_hook.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_hook.json deleted file mode 100644 index a46573a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_hook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Binary", - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_balance.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_balance.json deleted file mode 100644 index 4e3b16a..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_balance.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "description": "Always returns a Coin with the requested denom. This may be of 0 amount if no such funds.", - "allOf": [ - { - "$ref": "#/definitions/Coin" - } - ] - } - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_block_height_upon_creation.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_block_height_upon_creation.json deleted file mode 100644 index 0ef1730..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_block_height_upon_creation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockHeightResponse", - "type": "object", - "required": [ - "block_height" - ], - "properties": { - "block_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_is_operator.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_is_operator.json deleted file mode 100644 index 9f750c8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_is_operator.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "IsOperatorResponse", - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_kernel_address.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_kernel_address.json deleted file mode 100644 index dc0e342..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_kernel_address.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "KernelAddressResponse", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_latest_sale_state.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_latest_sale_state.json deleted file mode 100644 index f21c2dd..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_latest_sale_state.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleStateResponse", - "type": "object", - "required": [ - "coin_denom", - "price", - "sale_id", - "status" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "price": { - "$ref": "#/definitions/Uint128" - }, - "sale_id": { - "$ref": "#/definitions/Uint128" - }, - "status": { - "$ref": "#/definitions/Status" - } - }, - "additionalProperties": false, - "definitions": { - "Status": { - "type": "string", - "enum": [ - "open", - "expired", - "executed", - "cancelled" - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module.json deleted file mode 100644 index cecb73e..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Module", - "description": "A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated", - "type": "object", - "required": [ - "address", - "is_mutable" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "is_mutable": { - "type": "boolean" - }, - "name": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false, - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module_ids.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module_ids.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_module_ids.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_operators.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_operators.json deleted file mode 100644 index c812b4b..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_operators.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "OperatorsResponse", - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_original_publisher.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_original_publisher.json deleted file mode 100644 index 2269741..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_original_publisher.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PublisherResponse", - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_owner.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_owner.json deleted file mode 100644 index cd196f7..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_owner.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ContractOwnerResponse", - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissioned_actions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissioned_actions.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissioned_actions.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissions.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissions.json deleted file mode 100644 index 7b918d8..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_permissions.json +++ /dev/null @@ -1,165 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PermissionInfo", - "type": "array", - "items": { - "$ref": "#/definitions/PermissionInfo" - }, - "definitions": { - "Expiration": { - "description": "Expiration represents a point in time when some event happens. It can compare with a BlockInfo and will return is_expired() == true once the condition is hit (and for every block in the future)", - "oneOf": [ - { - "description": "AtHeight will expire when `env.block.height` >= height", - "type": "object", - "required": [ - "at_height" - ], - "properties": { - "at_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - }, - { - "description": "AtTime will expire when `env.block.time` >= time", - "type": "object", - "required": [ - "at_time" - ], - "properties": { - "at_time": { - "$ref": "#/definitions/Timestamp" - } - }, - "additionalProperties": false - }, - { - "description": "Never will never expire. Used to express the empty variant", - "type": "object", - "required": [ - "never" - ], - "properties": { - "never": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "Permission": { - "description": "An enum to represent a user's permission for an action\n\n- **Blacklisted** - The user cannot perform the action until after the provided expiration - **Limited** - The user can perform the action while uses are remaining and before the provided expiration **for a permissioned action** - **Whitelisted** - The user can perform the action until the provided expiration **for a permissioned action**\n\nExpiration defaults to `Never` if not provided", - "oneOf": [ - { - "type": "object", - "required": [ - "blacklisted" - ], - "properties": { - "blacklisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "limited" - ], - "properties": { - "limited": { - "type": "object", - "required": [ - "uses" - ], - "properties": { - "expiration": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - }, - "uses": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "whitelisted" - ], - "properties": { - "whitelisted": { - "anyOf": [ - { - "$ref": "#/definitions/Expiration" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - ] - }, - "PermissionInfo": { - "type": "object", - "required": [ - "action", - "actor", - "permission" - ], - "properties": { - "action": { - "type": "string" - }, - "actor": { - "type": "string" - }, - "permission": { - "$ref": "#/definitions/Permission" - } - }, - "additionalProperties": false - }, - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_ids.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_ids.json deleted file mode 100644 index d601608..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_ids.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleIdsResponse", - "type": "object", - "required": [ - "sale_ids" - ], - "properties": { - "sale_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_infos_for_address.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_infos_for_address.json deleted file mode 100644 index b8409bf..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_infos_for_address.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_SaleInfo", - "type": "array", - "items": { - "$ref": "#/definitions/SaleInfo" - }, - "definitions": { - "SaleInfo": { - "type": "object", - "required": [ - "sale_ids", - "token_address", - "token_id" - ], - "properties": { - "sale_ids": { - "type": "array", - "items": { - "$ref": "#/definitions/Uint128" - } - }, - "token_address": { - "type": "string" - }, - "token_id": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_state.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_state.json deleted file mode 100644 index f21c2dd..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_sale_state.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "SaleStateResponse", - "type": "object", - "required": [ - "coin_denom", - "price", - "sale_id", - "status" - ], - "properties": { - "coin_denom": { - "type": "string" - }, - "price": { - "$ref": "#/definitions/Uint128" - }, - "sale_id": { - "$ref": "#/definitions/Uint128" - }, - "status": { - "$ref": "#/definitions/Status" - } - }, - "additionalProperties": false, - "definitions": { - "Status": { - "type": "string", - "enum": [ - "open", - "expired", - "executed", - "cancelled" - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_type.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_type.json deleted file mode 100644 index 27e96a9..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_type.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "TypeResponse", - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_version.json b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_version.json deleted file mode 100644 index 4a16f10..0000000 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/schema/raw/response_to_version.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VersionResponse", - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs index 4766b2a..509ead7 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/contract.rs @@ -1,32 +1,39 @@ use crate::state::{ read_sale_infos, sale_infos, SaleInfo, TokenSaleState, NEXT_SALE_ID, TOKEN_SALE_STATE, }; +use std::vec; use andromeda_non_fungible_tokens::marketplace::{ - Cw721HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, SaleIdsResponse, + Cw20HookMsg, Cw721HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, SaleIdsResponse, SaleStateResponse, Status, }; -use andromeda_std::ado_contract::ADOContract; - -use andromeda_std::common::context::ExecuteContext; -use andromeda_std::common::expiration::{ - expiration_from_milliseconds, MILLISECONDS_TO_NANOSECONDS_RATIO, -}; use andromeda_std::{ - ado_base::{hooks::AndromedaHook, InstantiateMsg as BaseInstantiateMsg}, - common::{encode_binary, rates::get_tax_amount, Funds}, - error::{from_semver, ContractError}, + ado_base::{ + permissioning::{LocalPermission, Permission}, + InstantiateMsg as BaseInstantiateMsg, MigrateMsg, + }, + ado_contract::ADOContract, + amp::Recipient, + common::{ + actions::call_action, + context::ExecuteContext, + denom::{Asset, SEND_CW20_ACTION, SEND_NFT_ACTION}, + encode_binary, + expiration::{expiration_from_milliseconds, get_and_validate_start_time, Expiry}, + rates::{get_tax_amount, get_tax_amount_cw20}, + Funds, Milliseconds, MillisecondsDuration, + }, + error::ContractError, }; -use cw2::{get_contract_version, set_contract_version}; + +use cw20::{Cw20Coin, Cw20ReceiveMsg}; use cw721::{Cw721ExecuteMsg, Cw721QueryMsg, Cw721ReceiveMsg, OwnerOfResponse}; -use semver::Version; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - attr, ensure, from_json, has_coins, BankMsg, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, - MessageInfo, QuerierWrapper, QueryRequest, Response, Storage, SubMsg, Uint128, WasmMsg, - WasmQuery, + attr, coin, ensure, from_json, Addr, Binary, Coin, CosmosMsg, Deps, DepsMut, Env, MessageInfo, + QuerierWrapper, QueryRequest, Response, Storage, SubMsg, Uint128, WasmMsg, WasmQuery, }; use cw_utils::{nonpayable, Expiration}; @@ -41,27 +48,49 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; NEXT_SALE_ID.save(deps.storage, &Uint128::from(1u128))?; let inst_resp = ADOContract::default().instantiate( deps.storage, env, deps.api, - info.clone(), + &deps.querier, + info, BaseInstantiateMsg { - ado_type: "marketplace".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, )?; - let mod_resp = - ADOContract::default().register_modules(info.sender.as_str(), deps.storage, msg.modules)?; - Ok(inst_resp - .add_attributes(mod_resp.attributes) - .add_submessages(mod_resp.messages)) + if let Some(authorized_token_addresses) = msg.authorized_token_addresses { + if !authorized_token_addresses.is_empty() { + ADOContract::default().permission_action(SEND_NFT_ACTION, deps.storage)?; + } + + for token_address in authorized_token_addresses { + let addr = token_address.get_raw_address(&deps.as_ref())?; + ADOContract::set_permission( + deps.storage, + SEND_NFT_ACTION, + addr, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + } + + if let Some(authorized_cw20_address) = msg.authorized_cw20_address { + ADOContract::default().permission_action(SEND_CW20_ACTION, deps.storage)?; + let addr = authorized_cw20_address.get_raw_address(&deps.as_ref())?; + ADOContract::set_permission( + deps.storage, + SEND_CW20_ACTION, + addr, + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + } + + Ok(inst_resp) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -71,20 +100,6 @@ pub fn execute( info: MessageInfo, msg: ExecuteMsg, ) -> Result { - let contract = ADOContract::default(); - - if !matches!(msg, ExecuteMsg::UpdateAppContract { .. }) - && !matches!(msg, ExecuteMsg::UpdateOwner { .. }) - { - contract.module_hook::( - &deps.as_ref(), - AndromedaHook::OnExecute { - sender: info.sender.to_string(), - payload: encode_binary(&msg)?, - }, - )?; - } - let ctx = ExecuteContext::new(deps, info, env); match msg { @@ -95,34 +110,52 @@ pub fn execute( } } -pub fn handle_execute(ctx: ExecuteContext, msg: ExecuteMsg) -> Result { - match msg { +pub fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + let res = match msg { ExecuteMsg::ReceiveNft(msg) => handle_receive_cw721(ctx, msg), + ExecuteMsg::Receive(msg) => handle_receive_cw20(ctx, msg), ExecuteMsg::UpdateSale { token_id, token_address, coin_denom, price, - } => execute_update_sale(ctx, token_id, token_address, price, coin_denom), + recipient, + } => execute_update_sale(ctx, token_id, token_address, price, coin_denom, recipient), ExecuteMsg::Buy { token_id, token_address, - } => execute_buy(ctx, token_id, token_address), + } => execute_buy(ctx, token_id, token_address, action), ExecuteMsg::CancelSale { token_id, token_address, } => execute_cancel(ctx, token_id, token_address), _ => ADOContract::default().execute(ctx, msg), - } + }?; + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) } fn handle_receive_cw721( - ctx: ExecuteContext, + mut ctx: ExecuteContext, msg: Cw721ReceiveMsg, ) -> Result { - let ExecuteContext { - deps, info, env, .. - } = ctx; + ADOContract::default().is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + SEND_NFT_ACTION, + ctx.info.sender.clone(), + )?; match from_json(&msg.msg)? { Cw721HookMsg::StartSale { @@ -130,61 +163,97 @@ fn handle_receive_cw721( coin_denom, start_time, duration, + recipient, } => execute_start_sale( - deps, - env, + ctx.deps, + ctx.env, msg.sender, msg.token_id, - info.sender.to_string(), + ctx.info.sender.to_string(), price, - coin_denom, start_time, + coin_denom, duration, + recipient, + ), + } +} + +pub fn handle_receive_cw20( + mut ctx: ExecuteContext, + receive_msg: Cw20ReceiveMsg, +) -> Result { + ADOContract::default().is_permissioned( + ctx.deps.branch(), + ctx.env.clone(), + SEND_CW20_ACTION, + ctx.info.sender.clone(), + )?; + let ExecuteContext { ref info, .. } = ctx; + nonpayable(info)?; + + let asset_sent = info.sender.clone(); + let amount_sent = receive_msg.amount; + let sender = receive_msg.sender; + + ensure!( + !amount_sent.is_zero(), + ContractError::InvalidFunds { + msg: "Cannot send a 0 amount".to_string() + } + ); + + match from_json(&receive_msg.msg)? { + Cw20HookMsg::Buy { + token_id, + token_address, + } => execute_buy_cw20( + ctx, + token_id, + token_address, + amount_sent, + asset_sent, + &sender, + "Buy".to_string(), ), } } #[allow(clippy::too_many_arguments)] fn execute_start_sale( - deps: DepsMut, + mut deps: DepsMut, env: Env, sender: String, token_id: String, token_address: String, price: Uint128, - coin_denom: String, - start_time: Option, - duration: Option, + start_time: Option, + coin_denom: Asset, + duration: Option, + recipient: Option, ) -> Result { + let (coin_denom, uses_cw20) = coin_denom.get_verified_asset(deps.branch(), env.clone())?; + // Price can't be zero ensure!(price > Uint128::zero(), ContractError::InvalidZeroAmount {}); - let current_time = env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; + // If start time wasn't provided, it will be set as the current_time - let start_expiration = if let Some(start_time) = start_time { - expiration_from_milliseconds(start_time)? - } else { - expiration_from_milliseconds(current_time)? - }; + let (start_expiration, _current_time) = get_and_validate_start_time(&env, start_time.clone())?; - // If no duration is provided, the exipration will be set as Never let end_expiration = if let Some(duration) = duration { - expiration_from_milliseconds(start_time.unwrap_or(current_time) + duration)? + ensure!(!duration.is_zero(), ContractError::InvalidExpiration {}); + expiration_from_milliseconds( + start_time + // If start time isn't provided, it is set one second in advance from the current time + .unwrap_or(Expiry::FromNow(Milliseconds::from_seconds(1))) + .get_time(&env.block) + .plus_milliseconds(duration), + )? } else { + // If no duration is provided, the exipration will be set as Never Expiration::Never {} }; - // To guard against misleading start times - // Subtracting one second from the current block because the unit tests fail otherwise. The current time slightly differed from the block time. - let recent_past_timestamp = env.block.time.minus_seconds(1); - let recent_past_expiration = expiration_from_milliseconds(recent_past_timestamp.seconds())?; - ensure!( - start_expiration.gt(&recent_past_expiration), - ContractError::StartTimeInThePast { - current_time: env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO, - current_block: env.block.height, - } - ); - let sale_id = get_and_increment_next_sale_id(deps.storage, &token_id, &token_address)?; TOKEN_SALE_STATE.save( @@ -200,6 +269,8 @@ fn execute_start_sale( status: Status::Open, start_time: start_expiration, end_time: end_expiration, + uses_cw20, + recipient, }, )?; Ok(Response::new().add_attributes(vec![ @@ -212,6 +283,7 @@ fn execute_start_sale( attr("token_address", token_address), attr("start_time", start_expiration.to_string()), attr("end_time", end_expiration.to_string()), + attr("uses_cw20", uses_cw20.to_string()), ])) } @@ -221,16 +293,22 @@ fn execute_update_sale( token_id: String, token_address: String, price: Uint128, - coin_denom: String, + coin_denom: Asset, + recipient: Option, ) -> Result { - let ExecuteContext { deps, info, .. } = ctx; - + let ExecuteContext { + mut deps, + env, + info, + .. + } = ctx; + let (coin_denom, uses_cw20) = coin_denom.get_verified_asset(deps.branch(), env)?; nonpayable(&info)?; let mut token_sale_state = get_existing_token_sale_state(deps.storage, &token_id, &token_address)?; - // Only token owner is authorized to update the sale + // Only token owner is authorized to update the sale ensure!( info.sender == token_sale_state.owner, ContractError::Unauthorized {} @@ -241,6 +319,8 @@ fn execute_update_sale( token_sale_state.price = price; token_sale_state.coin_denom = coin_denom.clone(); + token_sale_state.uses_cw20 = uses_cw20; + token_sale_state.recipient = recipient; TOKEN_SALE_STATE.save( deps.storage, token_sale_state.sale_id.u128(), @@ -250,6 +330,7 @@ fn execute_update_sale( attr("action", "update_sale"), attr("coin_denom", coin_denom), attr("price", price), + attr("uses_cw20", uses_cw20.to_string()), attr("sale_id", token_sale_state.sale_id.to_string()), attr("token_id", token_id), attr("token_address", token_address), @@ -260,12 +341,10 @@ fn execute_buy( ctx: ExecuteContext, token_id: String, token_address: String, + action: String, ) -> Result { let ExecuteContext { - mut deps, - info, - env, - .. + deps, info, env, .. } = ctx; let mut token_sale_state = @@ -302,7 +381,7 @@ fn execute_buy( ensure!( info.funds.len() == 1, ContractError::InvalidFunds { - msg: "Sales ensure! exactly one coin to be sent.".to_string(), + msg: "One coin should be sent.".to_string(), } ); @@ -320,6 +399,12 @@ fn execute_buy( ); let coin_denom = token_sale_state.coin_denom.clone(); + ensure!( + !token_sale_state.uses_cw20, + ContractError::InvalidFunds { + msg: "Native funds were sent to a sale that only accepts cw20".to_string() + } + ); let payment: &Coin = &info.funds[0]; // Make sure funds are equal to the price and in the correct denomination @@ -329,9 +414,13 @@ fn execute_buy( msg: format!("No {coin_denom} assets are provided to sale"), } ); + + let price = token_sale_state.price; ensure!( - payment.amount >= token_sale_state.price, - ContractError::InsufficientFunds {} + payment.amount >= price, + ContractError::InvalidFunds { + msg: format!("The funds sent don't match the price {price}"), + } ); // Change sale status from Open to Executed @@ -340,15 +429,17 @@ fn execute_buy( TOKEN_SALE_STATE.save(deps.storage, key, &token_sale_state)?; // Calculate the funds to be received after tax - let after_tax_payment = purchase_token(&mut deps, &info, token_sale_state.clone())?; + let (after_tax_payment, tax_messages) = purchase_token( + deps.as_ref(), + &info, + None, + token_sale_state.clone(), + action.clone(), + )?; - Ok(Response::new() - .add_submessages(after_tax_payment.1) - // Send funds to the original owner. - .add_message(CosmosMsg::Bank(BankMsg::Send { - to_address: token_sale_state.owner, - amount: vec![after_tax_payment.0], - })) + let mut resp = Response::new() + // Send tax/royalty messages + .add_submessages(tax_messages) // Send NFT to buyer. .add_message(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: token_sale_state.token_address.clone(), @@ -362,7 +453,163 @@ fn execute_buy( .add_attribute("token_id", token_id) .add_attribute("token_contract", token_sale_state.token_address) .add_attribute("recipient", info.sender.to_string()) - .add_attribute("sale_id", token_sale_state.sale_id)) + .add_attribute("sale_id", token_sale_state.sale_id); + // Marketplace recipient's funds + let sale_recipient_funds = after_tax_payment.try_get_coin()?; + + // It could be zero if the royalties are 100% of the sale price + if !sale_recipient_funds.amount.is_zero() { + // Get sale recipient's address + let recipient = token_sale_state + .recipient + .unwrap_or(Recipient::from_string(token_sale_state.owner)); + + // Send payment to recipient + resp = resp.add_submessage( + recipient.generate_direct_msg(&deps.as_ref(), vec![sale_recipient_funds])?, + ) + } + Ok(resp) +} + +fn execute_buy_cw20( + ctx: ExecuteContext, + token_id: String, + token_address: String, + amount_sent: Uint128, + asset_sent: Addr, + // The user who sent the cw20 + sender: &str, + action: String, +) -> Result { + let ExecuteContext { + mut deps, + info, + env, + .. + } = ctx; + + let mut token_sale_state = + get_existing_token_sale_state(deps.storage, &token_id, &token_address)?; + + let key = token_sale_state.sale_id.u128(); + + match token_sale_state.status { + Status::Open => { + // Make sure the end time isn't expired, if it is we'll return an error and change the Status to expired in case if it's set as Open or Pending + ensure!( + !token_sale_state.end_time.is_expired(&env.block), + ContractError::SaleExpired {} + ); + + // If start time hasn't expired, it means that the sale hasn't started yet. + ensure!( + token_sale_state.start_time.is_expired(&env.block), + ContractError::SaleNotOpen {} + ); + } + Status::Expired => return Err(ContractError::SaleExpired {}), + Status::Executed => return Err(ContractError::SaleExecuted {}), + Status::Cancelled => return Err(ContractError::SaleCancelled {}), + } + + // The owner can't buy his own NFT + ensure!( + token_sale_state.owner != sender, + ContractError::TokenOwnerCannotBuy {} + ); + + let token_owner = query_owner_of( + deps.querier, + token_sale_state.token_address.clone(), + token_id.clone(), + )? + .owner; + ensure!( + // If this is false then the token is no longer held by the contract so the token has been + // claimed. + token_owner == env.contract.address, + ContractError::SaleAlreadyConducted {} + ); + + let is_cw20_sale = token_sale_state.uses_cw20; + ensure!( + is_cw20_sale, + ContractError::InvalidFunds { + msg: "CW20 funds were sent to a sale that only accepts native funds".to_string() + } + ); + + let sale_currency = token_sale_state.coin_denom.clone(); + let valid_cw20_sale = ADOContract::default() + .is_permissioned(deps.branch(), env, SEND_CW20_ACTION, sale_currency.clone()) + .is_ok(); + ensure!( + valid_cw20_sale, + ContractError::InvalidAsset { + asset: asset_sent.to_string() + } + ); + + let payment: &Coin = &coin(amount_sent.u128(), asset_sent.to_string()); + + // Make sure funds are equal to the price and in the correct denomination + ensure!( + payment.denom == sale_currency, + ContractError::InvalidFunds { + msg: format!("No {sale_currency} assets are provided to sale"), + } + ); + + // Change sale status from Open to Executed + token_sale_state.status = Status::Executed; + + TOKEN_SALE_STATE.save(deps.storage, key, &token_sale_state)?; + + // Calculate the funds to be received after tax + let (after_tax_payment, tax_messages) = purchase_token( + deps.as_ref(), + &info, + Some(amount_sent), + token_sale_state.clone(), + action, + )?; + + let mut resp: Response = Response::new() + // Send tax/royalty messages + .add_submessages(tax_messages) + // Send NFT to buyer. + .add_message(CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: token_sale_state.token_address.clone(), + msg: encode_binary(&Cw721ExecuteMsg::TransferNft { + recipient: sender.to_string(), + token_id: token_id.clone(), + })?, + funds: vec![], + })) + .add_attribute("action", "buy") + .add_attribute("token_id", token_id) + .add_attribute("token_contract", token_sale_state.token_address) + .add_attribute("recipient", sender.to_string()) + .add_attribute("sale_id", token_sale_state.sale_id); + + match after_tax_payment { + Funds::Cw20(cw20_after_tax_payment) => { + if !cw20_after_tax_payment.amount.is_zero() { + // Get sale recipient's address + let recipient = token_sale_state + .recipient + .unwrap_or(Recipient::from_string(token_sale_state.owner)); + // Send payment to recipient + resp = resp.add_submessage( + recipient.generate_msg_cw20(&deps.as_ref(), cw20_after_tax_payment)?, + ); + } + } + Funds::Native(_) => {} + } + + Ok(resp) } fn execute_cancel( @@ -414,42 +661,100 @@ fn execute_cancel( } fn purchase_token( - deps: &mut DepsMut, + deps: Deps, info: &MessageInfo, + amount_sent: Option, state: TokenSaleState, -) -> Result<(Coin, Vec), ContractError> { - let total_cost = Coin::new(state.price.u128(), state.coin_denom.clone()); - - let mut total_tax_amount = Uint128::zero(); - - let (msgs, _events, remainder) = ADOContract::default().on_funds_transfer( - &deps.as_ref(), - info.sender.to_string(), - Funds::Native(total_cost), - encode_binary(&"")?, - )?; - - let remaining_amount = remainder.try_get_coin()?; - - let tax_amount = get_tax_amount(&msgs, state.price, remaining_amount.amount); - - // Calculate total tax - total_tax_amount += tax_amount; - - let required_payment = Coin { - denom: state.coin_denom.clone(), - amount: state.price + total_tax_amount, - }; - ensure!( - has_coins(&info.funds, &required_payment), - ContractError::InsufficientFunds {} - ); - - let after_tax_payment = Coin { - denom: state.coin_denom, - amount: remaining_amount.amount, - }; - Ok((after_tax_payment, msgs)) + action: String, +) -> Result<(Funds, Vec), ContractError> { + // Handle cw20 case + if let Some(amount_sent) = amount_sent { + let total_cost = Cw20Coin { + address: state.coin_denom.clone(), + amount: state.price, + }; + let rates_response = ADOContract::default().query_deducted_funds( + deps, + action.clone(), + Funds::Cw20(total_cost), + )?; + match rates_response { + Some(rates_response) => { + let remaining_amount = rates_response.leftover_funds.try_get_cw20_coin()?; + let tax_amount = + get_tax_amount_cw20(&rates_response.msgs, state.price, remaining_amount.amount); + let total_required_payment = state.price.checked_add(tax_amount)?; + + // Check that enough funds were sent to cover the required payment + ensure!( + amount_sent.eq(&total_required_payment), + ContractError::InvalidFunds { + msg: format!( + "Invalid funds provided, expected: {}, received: {}", + total_required_payment, amount_sent + ) + } + ); + let after_tax_payment = Cw20Coin { + address: state.clone().coin_denom, + amount: remaining_amount.amount, + }; + Ok((Funds::Cw20(after_tax_payment), rates_response.msgs)) + } + // No rates response means that there's no tax + None => { + let payment = Cw20Coin { + address: state.coin_denom, + amount: state.price, + }; + + Ok((Funds::Cw20(payment), vec![])) + } + } + // Handle native funds case + } else { + let total_cost = Coin::new(state.price.u128(), state.coin_denom.clone()); + let rates_response = ADOContract::default().query_deducted_funds( + deps, + action, + Funds::Native(total_cost.clone()), + )?; + match rates_response { + Some(rates_response) => { + let remaining_amount = rates_response.leftover_funds.try_get_coin()?; + let tax_amount = + get_tax_amount(&rates_response.msgs, state.price, remaining_amount.amount); + + let total_required_payment = state.price.checked_add(tax_amount)?; + + // Check that enough funds were sent to cover the required payment + let amount_sent = info.funds[0].amount.u128(); + ensure!( + amount_sent.eq(&total_required_payment.u128()), + ContractError::InvalidFunds { + msg: format!( + "Invalid funds provided, expected: {}, received: {}", + total_required_payment, amount_sent + ) + } + ); + + let after_tax_payment = Coin { + denom: state.clone().coin_denom, + amount: remaining_amount.amount, + }; + + Ok((Funds::Native(after_tax_payment), rates_response.msgs)) + } + None => { + let payment = Coin { + denom: state.coin_denom, + amount: state.price, + }; + Ok((Funds::Native(payment), vec![])) + } + } + } } fn get_existing_token_sale_state( @@ -574,472 +879,5 @@ fn query_owner_of( #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } - -// #[cfg(test)] -// mod tests { -// use super::*; -// use crate::mock_querier::{ -// mock_dependencies_custom, MOCK_RATES_CONTRACT, MOCK_TOKEN_ADDR, MOCK_TOKEN_OWNER, -// MOCK_UNCLAIMED_TOKEN, -// }; -// use crate::state::SaleInfo; -// use andromeda_non_fungible_tokens::marketplace::{Cw721HookMsg, ExecuteMsg, InstantiateMsg}; - -// use common::ado_base::modules::{Module, RATES}; -// use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; -// use cosmwasm_std::{coin, coins}; - -// fn start_sale(deps: DepsMut) { -// let hook_msg = Cw721HookMsg::StartSale { -// coin_denom: "uusd".to_string(), -// price: Uint128::new(100), -// }; -// let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { -// sender: MOCK_TOKEN_OWNER.to_owned(), -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// msg: encode_binary(&hook_msg).unwrap(), -// }); -// let env = mock_env(); - -// let info = mock_info(MOCK_TOKEN_ADDR, &[]); -// let _res = execute(deps, env, info, msg).unwrap(); -// } - -// fn assert_sale_created(deps: Deps) { -// assert_eq!( -// TokenSaleState { -// coin_denom: "uusd".to_string(), -// sale_id: 1u128.into(), -// owner: MOCK_TOKEN_OWNER.to_string(), -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_owned(), -// status: Status::Open, -// price: Uint128::new(100) -// }, -// TOKEN_SALE_STATE.load(deps.storage, 1u128).unwrap() -// ); - -// assert_eq!( -// SaleInfo { -// sale_ids: vec![Uint128::from(1u128)], -// token_address: MOCK_TOKEN_ADDR.to_owned(), -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// }, -// sale_infos() -// .load( -// deps.storage, -// &(MOCK_UNCLAIMED_TOKEN.to_owned() + MOCK_TOKEN_ADDR) -// ) -// .unwrap() -// ); -// } - -// #[test] -// fn test_sale_instantiate() { -// let owner = "creator"; -// let mut deps = mock_dependencies(); -// let env = mock_env(); -// let info = mock_info(owner, &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let res = instantiate(deps.as_mut(), env, info, msg).unwrap(); -// assert_eq!(0, res.messages.len()); -// } - -// #[test] -// fn test_execute_buy_non_existing_sale() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info(MOCK_TOKEN_OWNER, &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_string(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; -// let info = mock_info("buyer", &coins(100, "uusd")); -// let res = execute(deps.as_mut(), env, info, msg); -// assert_eq!(ContractError::SaleDoesNotExist {}, res.unwrap_err()); -// } - -// #[test] -// fn execute_buy_sale_not_open_already_bought() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info(MOCK_TOKEN_OWNER, &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// let info = mock_info("sender", &coins(100, "uusd".to_string())); -// let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// let info = mock_info("sender", &coins(100, "uusd".to_string())); -// let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); -// assert_eq!(err, ContractError::SaleNotOpen {}) -// } - -// #[test] -// fn execute_buy_sale_not_open_cancelled() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info(MOCK_TOKEN_OWNER, &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::CancelSale { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// let info = mock_info(MOCK_TOKEN_OWNER, &[]); -// let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; -// let info = mock_info("sender", &coins(100, "uusd".to_string())); -// let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); -// assert_eq!(err, ContractError::SaleNotOpen {}) -// } - -// #[test] -// fn execute_buy_token_owner_cannot_buy() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// let info = mock_info(MOCK_TOKEN_OWNER, &coins(100, "uusd".to_string())); -// let res = execute(deps.as_mut(), env, info, msg); -// assert_eq!(ContractError::TokenOwnerCannotBuy {}, res.unwrap_err()); -// } - -// // #[test] -// // fn execute_buy_whitelist() { -// // let mut deps = mock_dependencies_custom(&[]); -// // let env = mock_env(); -// // let info = mock_info("owner", &[]); -// // let msg = InstantiateMsg { -// // let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// // start_sale(deps.as_mut(), Some(vec![Addr::unchecked("sender")])); -// // assert_sale_created(deps.as_ref(), Some(vec![Addr::unchecked("sender")])); - -// // let msg = ExecuteMsg::Buy { -// // token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// // token_address: MOCK_TOKEN_ADDR.to_string(), -// // }; - -// // let info = mock_info("not_sender", &coins(100, "uusd".to_string())); -// // let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); -// // assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); - -// // let info = mock_info("sender", &coins(100, "uusd".to_string())); -// // let _res = execute(deps.as_mut(), env, info, msg).unwrap(); -// // } - -// #[test] -// fn execute_buy_invalid_coins_sent() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let error = ContractError::InvalidFunds { -// msg: "Sales ensure! exactly one coin to be sent.".to_string(), -// }; -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_string(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// // No coins sent -// let info = mock_info("sender", &[]); -// let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); -// assert_eq!(error, res.unwrap_err()); - -// // Multiple coins sent -// let info = mock_info("sender", &[coin(100, "uusd"), coin(100, "uluna")]); -// let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); -// assert_eq!(error, res.unwrap_err()); - -// // Invalid denom sent -// let info = mock_info("sender", &[coin(100, "uluna")]); -// let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); -// assert_eq!( -// ContractError::InvalidFunds { -// msg: "No uusd assets are provided to sale".to_string(), -// }, -// res.unwrap_err() -// ); - -// // Correct denom but empty -// let info = mock_info("sender", &[coin(0, "uusd")]); -// let res = execute(deps.as_mut(), env, info, msg); -// assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); -// } - -// #[test] -// fn execute_buy_works() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// let info = mock_info("someone", &coins(100, "uusd".to_string())); -// let _res = execute(deps.as_mut(), env, info, msg).unwrap(); -// } - -// #[test] -// fn execute_update_sale_unauthorized() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::UpdateSale { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// price: Uint128::new(11), -// coin_denom: "juno".to_string(), -// }; - -// let info = mock_info("someone", &[]); -// let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); -// assert_eq!(err, ContractError::Unauthorized {}) -// } - -// #[test] -// fn execute_update_sale_invalid_price() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env.clone(), info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::UpdateSale { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// price: Uint128::zero(), -// coin_denom: "juno".to_string(), -// }; - -// let info = mock_info("owner", &[]); -// let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); -// assert_eq!(err, ContractError::InvalidZeroAmount {}) -// } - -// #[test] -// fn execute_start_sale_invalid_price() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let msg = InstantiateMsg { -// modules: None, -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - -// let hook_msg = Cw721HookMsg::StartSale { -// coin_denom: "uusd".to_string(), -// price: Uint128::zero(), -// }; -// let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { -// sender: MOCK_TOKEN_OWNER.to_owned(), -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// msg: encode_binary(&hook_msg).unwrap(), -// }); -// let env = mock_env(); - -// let info = mock_info(MOCK_TOKEN_ADDR, &[]); -// let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); -// assert_eq!(err, ContractError::InvalidZeroAmount {}) -// } - -// #[test] -// fn execute_buy_with_tax_and_royalty_insufficient_funds() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let modules = vec![Module { -// module_name: Some(RATES.to_owned()), -// address: MOCK_RATES_CONTRACT.to_owned(), - -// is_mutable: false, -// }]; -// let msg = InstantiateMsg { -// modules: Some(modules), -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// let info = mock_info("someone", &coins(100, "uusd".to_string())); -// let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); -// assert_eq!(err, ContractError::InsufficientFunds {}) -// } - -// #[test] -// fn execute_buy_with_tax_and_royalty_works() { -// let mut deps = mock_dependencies_custom(&[]); -// let env = mock_env(); -// let info = mock_info("owner", &[]); -// let modules = vec![Module { -// module_name: Some(RATES.to_owned()), -// address: MOCK_RATES_CONTRACT.to_owned(), - -// is_mutable: false, -// }]; -// let msg = InstantiateMsg { -// modules: Some(modules), -// kernel_address: None, -// }; -// let _res = instantiate(deps.as_mut(), env, info, msg).unwrap(); - -// start_sale(deps.as_mut()); -// assert_sale_created(deps.as_ref()); - -// let msg = ExecuteMsg::Buy { -// token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), -// token_address: MOCK_TOKEN_ADDR.to_string(), -// }; - -// let info = mock_info("someone", &coins(150, "uusd".to_string())); -// let res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); -// let expected: Vec> = vec![ -// SubMsg::new(CosmosMsg::Bank(BankMsg::Send { -// to_address: "royalty_recipient".to_string(), -// amount: vec![coin(10, "uusd")], -// })), -// SubMsg::new(CosmosMsg::Bank(BankMsg::Send { -// to_address: "tax_recipient".to_string(), -// amount: vec![coin(50, "uusd")], -// })), -// SubMsg::new(CosmosMsg::Bank(BankMsg::Send { -// to_address: "owner".to_string(), -// amount: vec![coin(90, "uusd")], -// })), -// SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { -// contract_addr: MOCK_TOKEN_ADDR.to_string(), -// msg: encode_binary(&Cw721ExecuteMsg::TransferNft { -// recipient: info.sender.to_string(), -// token_id: MOCK_UNCLAIMED_TOKEN.to_string(), -// }) -// .unwrap(), -// funds: vec![], -// })), -// ]; -// assert_eq!(res.messages, expected) -// } -// } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/mock.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/mock.rs index a42db99..02601e7 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/mock.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/mock.rs @@ -1,14 +1,27 @@ -#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +#![cfg(all(not(target_arch = "wasm32"), feature = "testing", feature = "rates"))] use crate::contract::{execute, instantiate, query}; use andromeda_non_fungible_tokens::marketplace::{ Cw721HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg, }; -use andromeda_std::ado_base::modules::Module; +use andromeda_std::ado_base::permissioning::Permission; +use andromeda_std::ado_base::permissioning::PermissioningMessage; +use andromeda_std::ado_base::rates::Rate; +use andromeda_std::ado_base::rates::RatesMessage; +use andromeda_std::ado_base::rates::RatesQueryMessage; +use andromeda_std::ado_base::version::VersionResponse; use andromeda_std::amp::messages::AMPPkt; -use andromeda_testing::{mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; + +use andromeda_std::amp::AndrAddr; +use andromeda_std::amp::Recipient; +use andromeda_std::common::denom::Asset; +use andromeda_std::common::expiration::Expiry; +use andromeda_std::common::MillisecondsDuration; +use andromeda_testing::{ + mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract, +}; use cosmwasm_std::{Addr, Empty, Uint128}; -use cw_multi_test::{App, Contract, ContractWrapper, Executor}; +use cw_multi_test::{Contract, ContractWrapper, Executor}; pub struct MockMarketplace(Addr); mock_ado!(MockMarketplace, ExecuteMsg, QueryMsg); @@ -17,12 +30,18 @@ impl MockMarketplace { pub fn instantiate( code_id: u64, sender: Addr, - app: &mut App, + app: &mut MockApp, kernel_address: impl Into, - modules: Option>, owner: Option, + authorized_cw20_address: Option, + authorized_token_addresses: Option>, ) -> MockMarketplace { - let msg = mock_marketplace_instantiate_msg(kernel_address.into(), modules, owner); + let msg = mock_marketplace_instantiate_msg( + kernel_address.into(), + owner, + authorized_cw20_address, + authorized_token_addresses, + ); let addr = app .instantiate_contract( code_id, @@ -38,13 +57,58 @@ impl MockMarketplace { pub fn execute_buy_token( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, token_address: impl Into, token_id: impl Into, ) -> ExecuteResult { self.execute(app, &mock_buy_token(token_address, token_id), sender, &[]) } + + pub fn execute_set_rate( + &self, + app: &mut MockApp, + sender: Addr, + action: impl Into, + rate: Rate, + ) -> ExecuteResult { + self.execute(app, &mock_set_rates(action, rate), sender, &[]) + } + + #[allow(clippy::too_many_arguments)] + pub fn execute_update_sale( + &self, + app: &mut MockApp, + sender: Addr, + token_address: impl Into, + token_id: impl Into, + coin_denom: Asset, + price: Uint128, + recipient: Option, + ) -> ExecuteResult { + self.execute( + app, + &mock_update_sale( + token_id.into(), + token_address.into(), + coin_denom, + price, + recipient, + ), + sender, + &[], + ) + } + + pub fn query_rates(&self, app: &mut MockApp, action: String) -> Option { + let msg = mock_get_rates(action); + self.query(app, msg) + } + + pub fn query_version(&self, app: &mut MockApp) -> VersionResponse { + let msg = mock_get_version(); + self.query(app, msg) + } } pub fn mock_andromeda_marketplace() -> Box> { @@ -54,22 +118,45 @@ pub fn mock_andromeda_marketplace() -> Box> { pub fn mock_marketplace_instantiate_msg( kernel_address: String, - modules: Option>, owner: Option, + authorized_cw20_address: Option, ) -> InstantiateMsg { InstantiateMsg { - modules, kernel_address, owner, + authorized_cw20_address, } } -pub fn mock_start_sale(price: Uint128, coin_denom: impl Into) -> Cw721HookMsg { +pub fn mock_start_sale( + price: Uint128, + coin_denom: Asset, + duration: Option, + start_time: Option, + recipient: Option, +) -> Cw721HookMsg { Cw721HookMsg::StartSale { price, - coin_denom: coin_denom.into(), - start_time: None, - duration: None, + coin_denom, + start_time, + duration, + recipient, + } +} + +pub fn mock_update_sale( + token_id: String, + token_address: String, + coin_denom: Asset, + price: Uint128, + recipient: Option, +) -> ExecuteMsg { + ExecuteMsg::UpdateSale { + token_id, + token_address, + price, + coin_denom, + recipient, } } @@ -80,6 +167,37 @@ pub fn mock_buy_token(token_address: impl Into, token_id: impl Into, rate: Rate) -> ExecuteMsg { + ExecuteMsg::Rates(RatesMessage::SetRate { + action: action.into(), + rate, + }) +} + +pub fn mock_set_permissions( + actor: AndrAddr, + action: impl Into, + permission: Permission, +) -> ExecuteMsg { + ExecuteMsg::Permissioning(PermissioningMessage::SetPermission { + actor, + action: action.into(), + permission, + }) +} + pub fn mock_receive_packet(packet: AMPPkt) -> ExecuteMsg { ExecuteMsg::AMPReceive(packet) } + +pub fn mock_get_rates(action: String) -> QueryMsg { + QueryMsg::Rates { action } +} + +pub fn mock_get_all_rates() -> QueryMsg { + QueryMsg::AllRates {} +} + +pub fn mock_get_version() -> QueryMsg { + QueryMsg::Version {} +} diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/state.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/state.rs index 48165a3..4c8b7de 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/state.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/state.rs @@ -1,5 +1,5 @@ use andromeda_non_fungible_tokens::marketplace::{SaleStateResponse, Status}; -use andromeda_std::error::ContractError; +use andromeda_std::{amp::Recipient, error::ContractError}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{Order, Storage, SubMsg, Uint128}; @@ -20,6 +20,8 @@ pub struct TokenSaleState { pub status: Status, pub start_time: Expiration, pub end_time: Expiration, + pub uses_cw20: bool, + pub recipient: Option, } #[cw_serde] @@ -59,6 +61,9 @@ impl From for SaleStateResponse { sale_id: token_sale_state.sale_id, status: token_sale_state.status, price: token_sale_state.price, + start_time: token_sale_state.start_time, + end_time: token_sale_state.end_time, + recipient: token_sale_state.recipient, } } } diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/mock_querier.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/mock_querier.rs index 18a4424..644b0cc 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/mock_querier.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/mock_querier.rs @@ -1,29 +1,23 @@ use andromeda_app::app::QueryMsg as AppQueryMsg; +use andromeda_std::ado_contract::ADOContract; + use andromeda_std::testing::mock_querier::MockAndromedaQuerier; pub use andromeda_std::testing::mock_querier::{MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT}; -use andromeda_std::{ - ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}, - ado_contract::ADOContract, - common::Funds, -}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - from_json, + coin, from_json, testing::{mock_env, mock_info, MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, BankMsg, Binary, Coin, ContractResult, CosmosMsg, OwnedDeps, Querier, - QuerierResult, QueryRequest, Response, SubMsg, SystemError, SystemResult, Uint128, WasmQuery, + to_json_binary, BankQuery, Binary, Coin, ContractResult, OwnedDeps, Querier, QuerierResult, + QuerierWrapper, QueryRequest, SystemError, SystemResult, WasmQuery, }; use cw721::{Cw721QueryMsg, OwnerOfResponse}; -pub const MOCK_ADDRESSLIST_CONTRACT: &str = "addresslist_contract"; - pub const MOCK_TOKEN_ADDR: &str = "token0001"; +pub const MOCK_CW721_ADDR: &str = "cw721_contract"; pub const MOCK_TOKEN_OWNER: &str = "owner"; pub const MOCK_UNCLAIMED_TOKEN: &str = "unclaimed_token"; -pub const MOCK_TAX_RECIPIENT: &str = "tax_recipient"; -pub const MOCK_ROYALTY_RECIPIENT: &str = "royalty_recipient"; -pub const MOCK_RATES_CONTRACT: &str = "rates_contract"; -pub const RATES: &str = "rates"; +pub const _RATES: &str = "rates"; use andromeda_std::ado_base::InstantiateMsg; /// Alternative to `cosmwasm_std::testing::mock_dependencies` that allows us to respond to custom queries. @@ -46,11 +40,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &QuerierWrapper::new(&deps.querier), mock_info("sender", &[]), InstantiateMsg { ado_type: "crowdfund".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -81,18 +76,59 @@ impl Querier for WasmMockQuerier { } } +#[cw_serde( + Serialize, + Deserialize, + Clone, + Debug, + Default, + PartialEq, + Eq, + JsonSchema +)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub struct SupplyResponse { + /// Always returns a Coin with the requested denom. + /// This will be of zero amount if the denom does not exist. + pub amount: Coin, +} + impl WasmMockQuerier { pub fn handle_query(&self, request: &QueryRequest) -> QuerierResult { match &request { QueryRequest::Wasm(WasmQuery::Smart { contract_addr, msg }) => { match contract_addr.as_str() { MOCK_TOKEN_ADDR => self.handle_token_query(msg), - MOCK_RATES_CONTRACT => self.handle_rates_query(msg), MOCK_APP_CONTRACT => self.handle_app_query(msg), - MOCK_ADDRESSLIST_CONTRACT => self.handle_addresslist_query(msg), _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } + QueryRequest::Bank(bank_query) => match bank_query { + BankQuery::Supply { denom } => { + let response = SupplyResponse { + amount: coin(1_000_000, denom), + }; + + SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) + } + BankQuery::Balance { + address: _, + denom: _, + } => { + panic!("Unsupported Query") + } + BankQuery::AllBalances { address: _ } => { + panic!("Unsupported Query") + } + // BankQuery::DenomMetadata { denom: _ } => { + // panic!("Unsupported Query") + // } + // BankQuery::AllDenomMetadata { pagination: _ } => { + // panic!("Unsupported Query") + // } + _ => panic!("Unsupported Query"), + }, _ => MockAndromedaQuerier::default().handle_query(&self.base, request), } } @@ -129,77 +165,6 @@ impl WasmMockQuerier { } } - fn handle_rates_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnFundsTransfer { - sender: _, - payload: _, - amount, - } => { - let (new_funds, msgs): (Funds, Vec) = match amount { - Funds::Native(ref coin) => ( - Funds::Native(Coin { - // Deduct royalty of 10%. - amount: coin.amount.multiply_ratio(90u128, 100u128), - denom: coin.denom.clone(), - }), - vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_ROYALTY_RECIPIENT.to_owned(), - amount: vec![Coin { - // Royalty of 10% - amount: coin.amount.multiply_ratio(10u128, 100u128), - denom: coin.denom.clone(), - }], - })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: MOCK_TAX_RECIPIENT.to_owned(), - amount: vec![Coin { - // Flat tax of 50 - amount: Uint128::from(50u128), - denom: coin.denom.clone(), - }], - })), - ], - ), - Funds::Cw20(_) => { - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )) - } - }; - let response = OnFundsTransferResponse { - msgs, - events: vec![], - leftover_funds: new_funds, - }; - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&None::).unwrap(), - )), - }, - } - } - - fn handle_addresslist_query(&self, msg: &Binary) -> QuerierResult { - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook_msg) => match hook_msg { - AndromedaHook::OnExecute { sender, payload: _ } => { - let whitelisted_addresses = ["sender"]; - let response: Response = Response::default(); - if whitelisted_addresses.contains(&sender.as_str()) { - SystemResult::Ok(ContractResult::Ok(to_json_binary(&response).unwrap())) - } else { - SystemResult::Ok(ContractResult::Err("InvalidAddress".to_string())) - } - } - _ => SystemResult::Ok(ContractResult::Err("UnsupportedOperation".to_string())), - }, - } - } - pub fn new(base: MockQuerier) -> Self { WasmMockQuerier { base, diff --git a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs index 0a86587..e809d72 100644 --- a/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs +++ b/andromeda-core/contracts/non-fungible-tokens/andromeda-marketplace/src/testing/tests.rs @@ -1,20 +1,30 @@ +use std::vec; + use andromeda_non_fungible_tokens::marketplace::{ - Cw721HookMsg, ExecuteMsg, InstantiateMsg, Status, + Cw20HookMsg, Cw721HookMsg, ExecuteMsg, InstantiateMsg, Status, }; use andromeda_std::{ - ado_base::modules::Module, - amp::addresses::AndrAddr, + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}, + ado_contract::ADOContract, + amp::{AndrAddr, Recipient}, common::{ + denom::Asset, encode_binary, - expiration::{expiration_from_milliseconds, MILLISECONDS_TO_NANOSECONDS_RATIO}, + expiration::{expiration_from_milliseconds, Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}, + reply::ReplyId, + Milliseconds, }, error::ContractError, + os::economics::ExecuteMsg as EconomicsExecuteMsg, + testing::mock_querier::MOCK_CW20_CONTRACT, }; use cosmwasm_std::{ coin, coins, testing::{mock_env, mock_info}, - BankMsg, CosmosMsg, Deps, DepsMut, Env, Response, SubMsg, Uint128, WasmMsg, + to_json_binary, Addr, BankMsg, CosmosMsg, Decimal, Deps, DepsMut, Env, Response, SubMsg, + Uint128, WasmMsg, }; +use cw20::Cw20ReceiveMsg; use cw721::{Cw721ExecuteMsg, Cw721ReceiveMsg}; use cw_utils::Expiration; @@ -23,17 +33,18 @@ use crate::{ contract::{execute, instantiate}, state::{sale_infos, SaleInfo, TokenSaleState, TOKEN_SALE_STATE}, testing::mock_querier::{ - mock_dependencies_custom, MOCK_RATES_CONTRACT, MOCK_TOKEN_ADDR, MOCK_TOKEN_OWNER, - MOCK_UNCLAIMED_TOKEN, RATES, + mock_dependencies_custom, MOCK_CW721_ADDR, MOCK_TOKEN_ADDR, MOCK_TOKEN_OWNER, + MOCK_UNCLAIMED_TOKEN, }, }; -fn start_sale(deps: DepsMut) { +fn start_sale(deps: DepsMut, coin_denom: Asset) { let hook_msg = Cw721HookMsg::StartSale { - coin_denom: "uusd".to_string(), + coin_denom, price: Uint128::new(100), start_time: None, duration: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), @@ -46,14 +57,15 @@ fn start_sale(deps: DepsMut) { let _res = execute(deps, env, info, msg).unwrap(); } -fn start_sale_future_start(deps: DepsMut, env: Env) { +fn start_sale_future_start(deps: DepsMut, env: Env, coin_denom: Asset) { let current_time = env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; let hook_msg = Cw721HookMsg::StartSale { - coin_denom: "uusd".to_string(), + coin_denom, price: Uint128::new(100), // Add one to the current time to have it set in the future - start_time: Some(current_time + 1), + start_time: Some(Expiry::AtTime(Milliseconds(current_time + 1))), duration: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), @@ -69,12 +81,13 @@ fn start_sale_future_start(deps: DepsMut, env: Env) { fn start_sale_future_start_with_duration(deps: DepsMut, env: Env) { let current_time = env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; let hook_msg = Cw721HookMsg::StartSale { - coin_denom: "uusd".to_string(), + coin_denom: Asset::NativeToken("uusd".to_string()), price: Uint128::new(100), // Add one to the current time to have it set in the future - start_time: Some(current_time + 1), + start_time: Some(Expiry::AtTime(Milliseconds(current_time + 1))), // Add duration, the end time's expiration will be current time + duration - duration: Some(1), + duration: Some(Milliseconds(1)), + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), @@ -87,23 +100,29 @@ fn start_sale_future_start_with_duration(deps: DepsMut, env: Env) { let _res = execute(deps, env, info, msg).unwrap(); } -fn init(deps: DepsMut, modules: Option>) -> Response { +fn init( + deps: DepsMut, + authorized_cw20_address: Option, + authorized_token_addresses: Option>, +) -> Response { let msg = InstantiateMsg { owner: None, - modules, kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + authorized_cw20_address, + authorized_token_addresses, }; let info = mock_info("owner", &[]); instantiate(deps, mock_env(), info, msg).unwrap() } -fn assert_sale_created(deps: Deps, env: Env) { +fn assert_sale_created(deps: Deps, env: Env, coin_denom: String, uses_cw20: bool) { let current_time = env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; - let start_time_expiration = expiration_from_milliseconds(current_time).unwrap(); + let start_time_expiration = + expiration_from_milliseconds(Milliseconds(current_time + 1)).unwrap(); assert_eq!( TokenSaleState { - coin_denom: "uusd".to_string(), + coin_denom, sale_id: 1u128.into(), owner: MOCK_TOKEN_OWNER.to_string(), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -112,7 +131,9 @@ fn assert_sale_created(deps: Deps, env: Env) { price: Uint128::new(100), // start sale function has start_time set as None, so it defaults to the current time start_time: start_time_expiration, - end_time: Expiration::Never {} + end_time: Expiration::Never {}, + uses_cw20, + recipient: None, }, TOKEN_SALE_STATE.load(deps.storage, 1u128).unwrap() ); @@ -132,13 +153,14 @@ fn assert_sale_created(deps: Deps, env: Env) { ); } -fn assert_sale_created_future_start(deps: Deps, env: Env) { +fn assert_sale_created_future_start(deps: Deps, env: Env, coin_denom: String, uses_cw20: bool) { let current_time = env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; // Add one to the current time to have it set in the future - let start_time_expiration = expiration_from_milliseconds(current_time + 1).unwrap(); + let start_time_expiration = + expiration_from_milliseconds(Milliseconds(current_time + 1)).unwrap(); assert_eq!( TokenSaleState { - coin_denom: "uusd".to_string(), + coin_denom, sale_id: 1u128.into(), owner: MOCK_TOKEN_OWNER.to_string(), token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -146,7 +168,9 @@ fn assert_sale_created_future_start(deps: Deps, env: Env) { status: Status::Open, price: Uint128::new(100), start_time: start_time_expiration, - end_time: Expiration::Never {} + end_time: Expiration::Never {}, + uses_cw20, + recipient: None, }, TOKEN_SALE_STATE.load(deps.storage, 1u128).unwrap() ); @@ -169,24 +193,120 @@ fn assert_sale_created_future_start(deps: Deps, env: Env) { #[test] fn test_sale_instantiate() { let mut deps = mock_dependencies_custom(&[]); - let res = init(deps.as_mut(), None); + let res = init(deps.as_mut(), None, None); assert_eq!(0, res.messages.len()); } #[test] fn test_sale_instantiate_future_start() { let mut deps = mock_dependencies_custom(&[]); - let res = init(deps.as_mut(), None); + let res = init(deps.as_mut(), None, None); assert_eq!(0, res.messages.len()); - start_sale_future_start(deps.as_mut(), mock_env()); - assert_sale_created_future_start(deps.as_ref(), mock_env()); + start_sale_future_start( + deps.as_mut(), + mock_env(), + Asset::NativeToken("uusd".to_string()), + ); + assert_sale_created_future_start(deps.as_ref(), mock_env(), "uusd".to_string(), false); +} + +#[test] +fn test_authorized_cw721() { + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let res = init( + deps.as_mut(), + None, + Some(vec![AndrAddr::from_string(MOCK_CW721_ADDR.to_string())]), + ); + assert_eq!(0, res.messages.len()); + + let current_time = env.block.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO; + let hook_msg = Cw721HookMsg::StartSale { + coin_denom: Asset::NativeToken("uusd".to_string()), + price: Uint128::new(100), + // Add one to the current time to have it set in the future + start_time: Some(Expiry::AtTime(Milliseconds(current_time + 1))), + duration: None, + recipient: None, + }; + let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { + sender: MOCK_TOKEN_OWNER.to_owned(), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + msg: encode_binary(&hook_msg).unwrap(), + }); + let env = mock_env(); + + let info = mock_info(MOCK_TOKEN_ADDR, &[]); + let err = execute(deps.as_mut(), env.clone(), info, msg.clone()).unwrap_err(); + assert_eq!(ContractError::Unauthorized {}, err); + + // Now let's set mock cw721 addr as the message sender + let info = mock_info(MOCK_CW721_ADDR, &[]); + let _res = execute(deps.as_mut(), env, info, msg).unwrap(); + + // Add one to the current time to have it set in the future + let start_time_expiration = + expiration_from_milliseconds(Milliseconds(current_time + 1)).unwrap(); + assert_eq!( + TokenSaleState { + coin_denom: "uusd".to_string(), + sale_id: 1u128.into(), + owner: MOCK_TOKEN_OWNER.to_string(), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_CW721_ADDR.to_owned(), + status: Status::Open, + price: Uint128::new(100), + start_time: start_time_expiration, + end_time: Expiration::Never {}, + uses_cw20: false, + recipient: None, + }, + TOKEN_SALE_STATE.load(deps.as_ref().storage, 1u128).unwrap() + ); + assert_eq!( + SaleInfo { + sale_ids: vec![Uint128::from(1u128)], + token_address: MOCK_CW721_ADDR.to_owned(), + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + }, + sale_infos() + .load( + deps.as_ref().storage, + &(MOCK_UNCLAIMED_TOKEN.to_owned() + MOCK_CW721_ADDR) + ) + .unwrap() + ); +} + +#[test] +fn test_sale_instantiate_future_start_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let res = init( + deps.as_mut(), + Some(AndrAddr::from_string(MOCK_CW20_CONTRACT)), + None, + ); + assert_eq!(0, res.messages.len()); + + start_sale_future_start( + deps.as_mut(), + mock_env(), + Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + ); + assert_sale_created_future_start( + deps.as_ref(), + mock_env(), + MOCK_CW20_CONTRACT.to_string(), + true, + ); } #[test] fn test_execute_buy_non_existing_sale() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); let env = mock_env(); let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_string(), @@ -200,11 +320,11 @@ fn test_execute_buy_non_existing_sale() { #[test] fn test_execute_buy_sale_not_open_already_bought() { let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let _res = init(deps.as_mut(), None); + let mut env = mock_env(); + let _res = init(deps.as_mut(), None, None); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), env.clone()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), env.clone(), "uusd".to_string(), false); let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -212,6 +332,8 @@ fn test_execute_buy_sale_not_open_already_bought() { }; let info = mock_info("sender", &coins(100, "uusd".to_string())); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); let _res = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let msg = ExecuteMsg::Buy { @@ -229,10 +351,10 @@ fn test_execute_buy_sale_not_open_cancelled() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), env.clone()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), env.clone(), "uusd".to_string(), false); let msg = ExecuteMsg::CancelSale { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -254,35 +376,79 @@ fn test_execute_buy_sale_not_open_cancelled() { #[test] fn test_execute_buy_token_owner_cannot_buy() { let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); + let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), env.clone()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), env.clone(), "uusd".to_string(), false); let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); let info = mock_info(MOCK_TOKEN_OWNER, &coins(100, "uusd".to_string())); let res = execute(deps.as_mut(), env, info, msg); assert_eq!(ContractError::TokenOwnerCannotBuy {}, res.unwrap_err()); } +#[test] +fn test_execute_buy_token_owner_cannot_buy_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + + let _res = init( + deps.as_mut(), + Some(AndrAddr::from_string(MOCK_CW20_CONTRACT)), + None, + ); + + let uses_cw20 = true; + start_sale( + deps.as_mut(), + Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + ); + assert_sale_created( + deps.as_ref(), + env.clone(), + MOCK_CW20_CONTRACT.to_string(), + uses_cw20, + ); + + let hook_msg = Cw20HookMsg::Buy { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: MOCK_TOKEN_OWNER.to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); + + let res = execute(deps.as_mut(), env, info, msg); + assert_eq!(ContractError::TokenOwnerCannotBuy {}, res.unwrap_err()); +} + #[test] fn test_execute_buy_invalid_coins_sent() { let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); + let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), env.clone()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), env.clone(), "uusd".to_string(), false); let error = ContractError::InvalidFunds { - msg: "Sales ensure! exactly one coin to be sent.".to_string(), + msg: "One coin should be sent.".to_string(), }; let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_string(), @@ -291,6 +457,8 @@ fn test_execute_buy_invalid_coins_sent() { // No coins sent let info = mock_info("sender", &[]); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); let res = execute(deps.as_mut(), env.clone(), info, msg.clone()); assert_eq!(error, res.unwrap_err()); @@ -311,19 +479,85 @@ fn test_execute_buy_invalid_coins_sent() { // Correct denom but empty let info = mock_info("sender", &[coin(0, "uusd")]); + let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert!(matches!(res, ContractError::InvalidFunds { .. })); +} + +#[test] +fn test_execute_buy_invalid_coins_sent_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + + let _res = init( + deps.as_mut(), + Some(AndrAddr::from_string(MOCK_CW20_CONTRACT)), + None, + ); + + let uses_cw20 = true; + start_sale( + deps.as_mut(), + Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + ); + assert_sale_created( + deps.as_ref(), + env.clone(), + MOCK_CW20_CONTRACT.to_string(), + uses_cw20, + ); + + let hook_msg = Cw20HookMsg::Buy { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + // No coins sent + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "buyer".to_string(), + amount: Uint128::zero(), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); + let res = execute(deps.as_mut(), env.clone(), info, msg); + assert_eq!( + ContractError::InvalidFunds { + msg: "Cannot send a 0 amount".to_string(), + }, + res.unwrap_err() + ); + + let hook_msg = Cw20HookMsg::Buy { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "buyer".to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + // Invalid denom sent + let info = mock_info("invalid_cw20", &[]); + let res = execute(deps.as_mut(), env, info, msg); - assert_eq!(ContractError::InsufficientFunds {}, res.unwrap_err()); + assert_eq!(ContractError::Unauthorized {}, res.unwrap_err()); } #[test] fn test_execute_buy_works() { let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); + let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init( + deps.as_mut(), + Some(AndrAddr::from_string(MOCK_CW20_CONTRACT)), + None, + ); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), env.clone()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), env.clone(), "uusd".to_string(), false); let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -331,6 +565,47 @@ fn test_execute_buy_works() { }; let info = mock_info("someone", &coins(100, "uusd".to_string())); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); + let _res = execute(deps.as_mut(), env, info, msg).unwrap(); +} + +#[test] +fn test_execute_buy_works_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let mut env = mock_env(); + + let _res = init( + deps.as_mut(), + Some(AndrAddr::from_string(MOCK_CW20_CONTRACT)), + None, + ); + + let uses_cw20 = true; + start_sale( + deps.as_mut(), + Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + ); + assert_sale_created( + deps.as_ref(), + env.clone(), + MOCK_CW20_CONTRACT.to_string(), + uses_cw20, + ); + + let hook_msg = Cw20HookMsg::Buy { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "someone".to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); let _res = execute(deps.as_mut(), env, info, msg).unwrap(); } @@ -339,10 +614,14 @@ fn test_execute_buy_future_start() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); - start_sale_future_start(deps.as_mut(), mock_env()); - assert_sale_created_future_start(deps.as_ref(), mock_env()); + start_sale_future_start( + deps.as_mut(), + mock_env(), + Asset::NativeToken("uusd".to_string()), + ); + assert_sale_created_future_start(deps.as_ref(), mock_env(), "uusd".to_string(), false); let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), @@ -360,7 +639,7 @@ fn test_execute_buy_sale_expired() { let mut deps = mock_dependencies_custom(&[]); let mut env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); start_sale_future_start_with_duration(deps.as_mut(), mock_env()); @@ -382,16 +661,17 @@ fn test_execute_update_sale_unauthorized() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), env.clone()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), env.clone(), "uusd".to_string(), false); let msg = ExecuteMsg::UpdateSale { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), price: Uint128::new(11), - coin_denom: "juno".to_string(), + coin_denom: Asset::NativeToken("juno".to_string()), + recipient: None, }; let info = mock_info("someone", &[]); @@ -404,16 +684,17 @@ fn test_execute_update_sale_invalid_price() { let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), env.clone()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), env.clone(), "uusd".to_string(), false); let msg = ExecuteMsg::UpdateSale { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), price: Uint128::zero(), - coin_denom: "juno".to_string(), + coin_denom: Asset::NativeToken("juno".to_string()), + recipient: None, }; let info = mock_info("owner", &[]); @@ -424,13 +705,14 @@ fn test_execute_update_sale_invalid_price() { #[test] fn test_execute_start_sale_invalid_price() { let mut deps = mock_dependencies_custom(&[]); - let _res = init(deps.as_mut(), None); + let _res = init(deps.as_mut(), None, None); let hook_msg = Cw721HookMsg::StartSale { - coin_denom: "uusd".to_string(), + coin_denom: Asset::NativeToken("uusd".to_string()), price: Uint128::zero(), start_time: None, duration: None, + recipient: None, }; let msg = ExecuteMsg::ReceiveNft(Cw721ReceiveMsg { sender: MOCK_TOKEN_OWNER.to_owned(), @@ -447,59 +729,182 @@ fn test_execute_start_sale_invalid_price() { #[test] fn test_execute_buy_with_tax_and_royalty_insufficient_funds() { let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - let _res = init(deps.as_mut(), Some(modules)); + let _res = init(deps.as_mut(), None, None); + + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), mock_env(), "uusd".to_string(), false); + + let rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("tax_recipient".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(50), + }), + description: None, + }); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), mock_env()); + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Buy", rate) + .unwrap(); let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; - + let mut env = mock_env(); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); let info = mock_info("someone", &coins(100, "uusd".to_string())); - let err = execute(deps.as_mut(), mock_env(), info, msg).unwrap_err(); - assert_eq!(err, ContractError::InsufficientFunds {}) + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidFunds { + msg: "Invalid funds provided, expected: 150, received: 100".to_string() + } + ); } +#[test] +fn test_execute_buy_with_tax_and_royalty_insufficient_funds_cw20() { + let mut deps = mock_dependencies_custom(&[]); + let _res = init( + deps.as_mut(), + Some(AndrAddr::from_string(MOCK_CW20_CONTRACT)), + None, + ); + + let uses_cw20 = true; + start_sale( + deps.as_mut(), + Asset::Cw20Token(AndrAddr::from_string(MOCK_CW20_CONTRACT.to_string())), + ); + assert_sale_created( + deps.as_ref(), + mock_env(), + MOCK_CW20_CONTRACT.to_string(), + uses_cw20, + ); + + let rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("tax_recipient".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(50), + }), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Buy", rate) + .unwrap(); + + let hook_msg = Cw20HookMsg::Buy { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let msg = ExecuteMsg::Receive(Cw20ReceiveMsg { + sender: "someone".to_string(), + amount: Uint128::new(100), + msg: encode_binary(&hook_msg).unwrap(), + }); + + let info = mock_info(MOCK_CW20_CONTRACT, &[]); + + let mut env = mock_env(); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidFunds { + msg: "Invalid funds provided, expected: 150, received: 100".to_string() + } + ); +} + +#[test] +fn execute_buy_with_tax_and_royalty_too_many_funds() { + let mut deps = mock_dependencies_custom(&[]); + let _res = init(deps.as_mut(), None, None); + + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), mock_env(), "uusd".to_string(), false); + + let msg = ExecuteMsg::Buy { + token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), + token_address: MOCK_TOKEN_ADDR.to_string(), + }; + let mut env = mock_env(); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); + + let info = mock_info("someone", &[coin(200, "uusd"), coin(100, "uandr")]); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert!(matches!(err, ContractError::InvalidFunds { .. })); +} + +// TODO having both tax and royalty is currently unsupported #[test] fn test_execute_buy_with_tax_and_royalty_works() { let mut deps = mock_dependencies_custom(&[]); - let modules = vec![Module { - name: Some(RATES.to_owned()), - address: AndrAddr::from_string(MOCK_RATES_CONTRACT.to_owned()), - is_mutable: false, - }]; - let _res = init(deps.as_mut(), Some(modules)); + let _res = init(deps.as_mut(), None, None); - start_sale(deps.as_mut()); - assert_sale_created(deps.as_ref(), mock_env()); + start_sale(deps.as_mut(), Asset::NativeToken("uusd".to_string())); + assert_sale_created(deps.as_ref(), mock_env(), "uusd".to_string(), false); let msg = ExecuteMsg::Buy { token_id: MOCK_UNCLAIMED_TOKEN.to_owned(), token_address: MOCK_TOKEN_ADDR.to_string(), }; + let rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("tax_recipient".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(50), + }), + description: None, + }); + + // Set rates + ADOContract::default() + .set_rates(deps.as_mut().storage, "Buy", rate) + .unwrap(); + let info = mock_info("someone", &coins(150, "uusd".to_string())); - let res = execute(deps.as_mut(), mock_env(), info.clone(), msg).unwrap(); + let mut env = mock_env(); + // Add one second so that the start_time expires + env.block.time = env.block.time.plus_seconds(1); + + let res = execute(deps.as_mut(), env, info.clone(), msg).unwrap(); let expected: Vec> = vec![ - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: "royalty_recipient".to_string(), - amount: vec![coin(10, "uusd")], - })), + // SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + // to_address: "royalty_recipient".to_string(), + // amount: vec![coin(10, "uusd")], + // })), + + // SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + // to_address: "owner".to_string(), + // amount: vec![coin(90, "uusd")], + // })), SubMsg::new(CosmosMsg::Bank(BankMsg::Send { to_address: "tax_recipient".to_string(), amount: vec![coin(50, "uusd")], })), - SubMsg::new(CosmosMsg::Bank(BankMsg::Send { - to_address: "owner".to_string(), - amount: vec![coin(90, "uusd")], - })), SubMsg::new(CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: MOCK_TOKEN_ADDR.to_string(), msg: encode_binary(&Cw721ExecuteMsg::TransferNft { @@ -509,6 +914,22 @@ fn test_execute_buy_with_tax_and_royalty_works() { .unwrap(), funds: vec![], })), + SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: "owner".to_string(), + amount: vec![coin(100, "uusd")], + })), + SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked("someone"), + action: "Buy".to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ), ]; assert_eq!(res.messages, expected) } diff --git a/andromeda-core/contracts/os/andromeda-adodb/Cargo.toml b/andromeda-core/contracts/os/andromeda-adodb/Cargo.toml index 7b6de9a..a989b25 100644 --- a/andromeda-core/contracts/os/andromeda-adodb/Cargo.toml +++ b/andromeda-core/contracts/os/andromeda-adodb/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "andromeda-adodb" -version = "0.2.1" +version = "1.1.2" authors = ["Connor Barr "] edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" exclude = [ # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. @@ -25,13 +25,9 @@ testing = ["cw-multi-test"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw2 = { workspace = true } andromeda-std = { workspace = true } semver = { workspace = true } cw-asset = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } - -[dev-dependencies] -# andromeda-testing = { version = "0.1.0", path = "../../../packages/andromeda-testing" } diff --git a/andromeda-core/contracts/os/andromeda-adodb/README.md b/andromeda-core/contracts/os/andromeda-adodb/README.md index a883785..bfb3537 100644 --- a/andromeda-core/contracts/os/andromeda-adodb/README.md +++ b/andromeda-core/contracts/os/andromeda-adodb/README.md @@ -1,3 +1,5 @@ -# Andromeda Factory +# Overview +The Database ADO (ADODB) is a smart contract that is primarily used to store code Ids for Andromeda ADOs. These code Ids are used to instantiate these ADOs in Andromeda Apps. The code Ids are stored within a key value pair where the key is the ADO type and the value is the ADO code Id. +The ADODB is also responsible for managing the economic engine of the Andromeda ecosystem, allowing ADO publishers to set custom fees to be paid when interacting with one of their published ADOs. These fees can be set as native or a CW20 token. -A repository containing the NFT contract for Andromeda Protocol on Terra. This contract's primary purpose is to initialise and register ADO collections. Registration is done by a mapping between the ADO collection's symbol and the contract address for the given ADO collection. Documentation can be found [here](https://app.gitbook.com/@andromedaprotocol/s/andromeda/contracts/andromeda-factory). +[ADODB Full Documentation](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/andromeda-factory) \ No newline at end of file diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/andromeda-adodb.json b/andromeda-core/contracts/os/andromeda-adodb/schema/andromeda-adodb.json deleted file mode 100644 index 0d87615..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/andromeda-adodb.json +++ /dev/null @@ -1,495 +0,0 @@ -{ - "contract_name": "andromeda-adodb", - "contract_version": "0.2.1", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "publish" - ], - "properties": { - "publish": { - "type": "object", - "required": [ - "ado_type", - "code_id", - "version" - ], - "properties": { - "action_fees": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/ActionFee" - } - }, - "ado_type": { - "type": "string" - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "publisher": { - "type": [ - "string", - "null" - ] - }, - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_action_fees" - ], - "properties": { - "update_action_fees": { - "type": "object", - "required": [ - "action_fees", - "ado_type" - ], - "properties": { - "action_fees": { - "type": "array", - "items": { - "$ref": "#/definitions/ActionFee" - } - }, - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_action_fees" - ], - "properties": { - "remove_action_fees": { - "type": "object", - "required": [ - "actions", - "ado_type" - ], - "properties": { - "actions": { - "type": "array", - "items": { - "type": "string" - } - }, - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_publisher" - ], - "properties": { - "update_publisher": { - "type": "object", - "required": [ - "ado_type", - "publisher" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "publisher": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "ActionFee": { - "type": "object", - "required": [ - "action", - "amount", - "asset" - ], - "properties": { - "action": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - }, - "asset": { - "type": "string" - }, - "receiver": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "code_id" - ], - "properties": { - "code_id": { - "type": "object", - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "object", - "required": [ - "code_id" - ], - "properties": { - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "all_ado_types" - ], - "properties": { - "all_ado_types": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ado_metadata" - ], - "properties": { - "ado_metadata": { - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "action_fee" - ], - "properties": { - "action_fee": { - "type": "object", - "required": [ - "action", - "ado_type" - ], - "properties": { - "action": { - "type": "string" - }, - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "action_fee_by_code_id" - ], - "properties": { - "action_fee_by_code_id": { - "type": "object", - "required": [ - "action", - "code_id" - ], - "properties": { - "action": { - "type": "string" - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "migrate": null, - "sudo": null, - "responses": { - "a_d_o_metadata": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ADOMetadata", - "anyOf": [ - { - "$ref": "#/definitions/ADOMetadata" - }, - { - "type": "null" - } - ], - "definitions": { - "ADOMetadata": { - "type": "object", - "required": [ - "latest_version", - "publisher" - ], - "properties": { - "latest_version": { - "type": "string" - }, - "publisher": { - "type": "string" - } - }, - "additionalProperties": false - } - } - }, - "a_d_o_type": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_String", - "type": [ - "string", - "null" - ] - }, - "action_fee": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ActionFee", - "anyOf": [ - { - "$ref": "#/definitions/ActionFee" - }, - { - "type": "null" - } - ], - "definitions": { - "ActionFee": { - "type": "object", - "required": [ - "action", - "amount", - "asset" - ], - "properties": { - "action": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - }, - "asset": { - "type": "string" - }, - "receiver": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "action_fee_by_code_id": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ActionFee", - "anyOf": [ - { - "$ref": "#/definitions/ActionFee" - }, - { - "type": "null" - } - ], - "definitions": { - "ActionFee": { - "type": "object", - "required": [ - "action", - "amount", - "asset" - ], - "properties": { - "action": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - }, - "asset": { - "type": "string" - }, - "receiver": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "all_a_d_o_types": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "code_id": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "uint64", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/execute.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/execute.json deleted file mode 100644 index 01a0399..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/execute.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "publish" - ], - "properties": { - "publish": { - "type": "object", - "required": [ - "ado_type", - "code_id", - "version" - ], - "properties": { - "action_fees": { - "type": [ - "array", - "null" - ], - "items": { - "$ref": "#/definitions/ActionFee" - } - }, - "ado_type": { - "type": "string" - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "publisher": { - "type": [ - "string", - "null" - ] - }, - "version": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_action_fees" - ], - "properties": { - "update_action_fees": { - "type": "object", - "required": [ - "action_fees", - "ado_type" - ], - "properties": { - "action_fees": { - "type": "array", - "items": { - "$ref": "#/definitions/ActionFee" - } - }, - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "remove_action_fees" - ], - "properties": { - "remove_action_fees": { - "type": "object", - "required": [ - "actions", - "ado_type" - ], - "properties": { - "actions": { - "type": "array", - "items": { - "type": "string" - } - }, - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "update_publisher" - ], - "properties": { - "update_publisher": { - "type": "object", - "required": [ - "ado_type", - "publisher" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "publisher": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "ActionFee": { - "type": "object", - "required": [ - "action", - "amount", - "asset" - ], - "properties": { - "action": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - }, - "asset": { - "type": "string" - }, - "receiver": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/instantiate.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/instantiate.json deleted file mode 100644 index 7727d50..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/instantiate.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/query.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/query.json deleted file mode 100644 index fc3ca4c..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/query.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "code_id" - ], - "properties": { - "code_id": { - "type": "object", - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "object", - "required": [ - "code_id" - ], - "properties": { - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "all_ado_types" - ], - "properties": { - "all_ado_types": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "ado_metadata" - ], - "properties": { - "ado_metadata": { - "type": "object", - "required": [ - "ado_type" - ], - "properties": { - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "action_fee" - ], - "properties": { - "action_fee": { - "type": "object", - "required": [ - "action", - "ado_type" - ], - "properties": { - "action": { - "type": "string" - }, - "ado_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "action_fee_by_code_id" - ], - "properties": { - "action_fee_by_code_id": { - "type": "object", - "required": [ - "action", - "code_id" - ], - "properties": { - "action": { - "type": "string" - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_metadata.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_metadata.json deleted file mode 100644 index 44d1820..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_metadata.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ADOMetadata", - "anyOf": [ - { - "$ref": "#/definitions/ADOMetadata" - }, - { - "type": "null" - } - ], - "definitions": { - "ADOMetadata": { - "type": "object", - "required": [ - "latest_version", - "publisher" - ], - "properties": { - "latest_version": { - "type": "string" - }, - "publisher": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_type.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_type.json deleted file mode 100644 index f4c601d..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_a_d_o_type.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_String", - "type": [ - "string", - "null" - ] -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee.json deleted file mode 100644 index cfb585a..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ActionFee", - "anyOf": [ - { - "$ref": "#/definitions/ActionFee" - }, - { - "type": "null" - } - ], - "definitions": { - "ActionFee": { - "type": "object", - "required": [ - "action", - "amount", - "asset" - ], - "properties": { - "action": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - }, - "asset": { - "type": "string" - }, - "receiver": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee_by_code_id.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee_by_code_id.json deleted file mode 100644 index cfb585a..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_action_fee_by_code_id.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ActionFee", - "anyOf": [ - { - "$ref": "#/definitions/ActionFee" - }, - { - "type": "null" - } - ], - "definitions": { - "ActionFee": { - "type": "object", - "required": [ - "action", - "amount", - "asset" - ], - "properties": { - "action": { - "type": "string" - }, - "amount": { - "$ref": "#/definitions/Uint128" - }, - "asset": { - "type": "string" - }, - "receiver": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_all_a_d_o_types.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_all_a_d_o_types.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_all_a_d_o_types.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_andr_query.json deleted file mode 100644 index 7b729a7..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "uint64", - "type": "integer", - "format": "uint64", - "minimum": 0.0 -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_code_id.json b/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_code_id.json deleted file mode 100644 index 7b729a7..0000000 --- a/andromeda-core/contracts/os/andromeda-adodb/schema/raw/response_to_code_id.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "uint64", - "type": "integer", - "format": "uint64", - "minimum": 0.0 -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/src/contract.rs b/andromeda-core/contracts/os/andromeda-adodb/src/contract.rs index b231ee4..dac8fba 100644 --- a/andromeda-core/contracts/os/andromeda-adodb/src/contract.rs +++ b/andromeda-core/contracts/os/andromeda-adodb/src/contract.rs @@ -1,21 +1,12 @@ -use crate::state::{ - read_code_id, read_latest_code_id, store_code_id, ACTION_FEES, ADO_TYPE, CODE_ID, - LATEST_VERSION, PUBLISHER, -}; -use andromeda_std::ado_base::InstantiateMsg as BaseInstantiateMsg; +use crate::{execute, query}; +use andromeda_std::ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}; use andromeda_std::ado_contract::ADOContract; use andromeda_std::common::encode_binary; -use andromeda_std::error::{from_semver, ContractError}; -use andromeda_std::os::adodb::{ - ADOMetadata, ADOVersion, ActionFee, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, -}; +use andromeda_std::error::ContractError; +use andromeda_std::os::adodb::{ADOVersion, ExecuteMsg, InstantiateMsg, QueryMsg}; use cosmwasm_std::{ - attr, ensure, entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Order, Reply, Response, - StdError, StdResult, Storage, + entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, }; -use cw2::{get_contract_version, set_contract_version}; -use cw_storage_plus::Bound; -use semver::Version; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-adodb"; @@ -28,16 +19,15 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "adodb".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -69,7 +59,7 @@ pub fn execute( action_fees, version, publisher, - } => publish( + } => execute::publish( deps, env, info, @@ -79,331 +69,72 @@ pub fn execute( action_fees, publisher, ), + ExecuteMsg::Unpublish { ado_type, version } => { + execute::unpublish(deps, env, info, ado_type, version) + } ExecuteMsg::UpdateActionFees { action_fees, ado_type, } => { - execute_update_action_fees(deps, info, &ADOVersion::from_string(ado_type), action_fees) + execute::update_action_fees(deps, info, &ADOVersion::from_string(ado_type), action_fees) } ExecuteMsg::RemoveActionFees { ado_type, actions } => { - execute_remove_actions(deps, info, &ADOVersion::from_string(ado_type), actions) + execute::remove_actions(deps, info, &ADOVersion::from_string(ado_type), actions) } ExecuteMsg::UpdatePublisher { ado_type, publisher, - } => execute_update_publisher(deps, info, &ADOVersion::from_string(ado_type), publisher), - } -} - -pub fn update_action_fees( - storage: &mut dyn Storage, - ado_version: &ADOVersion, - fees: Vec, -) -> Result<(), ContractError> { - for action_fee in fees { - ACTION_FEES.save( - storage, - &(ado_version.clone().into_string(), action_fee.clone().action), - &action_fee.clone(), - )?; - } - - Ok(()) -} - -#[allow(clippy::too_many_arguments)] -pub fn publish( - deps: DepsMut, - _env: Env, - info: MessageInfo, - code_id: u64, - ado_type: String, - version: String, - action_fees: Option>, - publisher: Option, -) -> Result { - ensure!( - ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let current_ado_version = LATEST_VERSION.may_load(deps.storage, &ado_type)?; - if let Some(ado_version) = current_ado_version { - let new_version = semver::Version::parse(&version).unwrap(); - let current_version = semver::Version::parse(&ado_version.0).unwrap(); - ensure!( - new_version > current_version, - ContractError::InvalidADOVersion { - msg: Some("Version must be newer than the current version".to_string()) - } - ); - } - - //TODO: Get Code ID info with cosmwasm 1.2 - - let version = ADOVersion::from_type(ado_type).with_version(version); - ensure!( - version.validate(), - ContractError::InvalidADOVersion { msg: None } - ); - - // Ensure version is not already published - let curr_code_id = read_code_id(deps.storage, &version); - ensure!( - curr_code_id.is_err(), - ContractError::InvalidADOVersion { - msg: Some(String::from("Version already published")) - } - ); - - store_code_id(deps.storage, &version, code_id)?; - PUBLISHER.save( - deps.storage, - version.as_str(), - &publisher.clone().unwrap_or(info.sender.to_string()), - )?; - - if let Some(fees) = action_fees { - update_action_fees(deps.storage, &version, fees)?; - } - - Ok(Response::default().add_attributes(vec![ - attr("action", "publish_ado"), - attr("ado_type", version.into_string()), - attr("code_id", code_id.to_string()), - attr("publisher", publisher.unwrap_or(info.sender.to_string())), - ])) -} - -fn execute_update_action_fees( - deps: DepsMut, - info: MessageInfo, - ado_version: &ADOVersion, - action_fees: Vec, -) -> Result { - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let ado_type_exists = read_code_id(deps.storage, ado_version); - ensure!( - ado_type_exists.is_ok(), - ContractError::InvalidADOVersion { - msg: Some("ADO type does not exist".to_string()) - } - ); - - update_action_fees(deps.storage, ado_version, action_fees)?; - - Ok(Response::default().add_attributes(vec![ - attr("action", "update_action_fees"), - attr("ado_type", ado_version.clone().into_string()), - ])) -} - -fn execute_remove_actions( - deps: DepsMut, - info: MessageInfo, - ado_version: &ADOVersion, - actions: Vec, -) -> Result { - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - let ado_type_exists = read_code_id(deps.storage, ado_version); - ensure!( - ado_type_exists.is_ok(), - ContractError::InvalidADOVersion { - msg: Some("ADO type does not exist".to_string()) + } => execute::update_publisher(deps, info, &ADOVersion::from_string(ado_type), publisher), + // Base message + ExecuteMsg::Ownership(ownership_message) => { + ADOContract::default().execute_ownership(deps, env, info, ownership_message) } - ); - - let mut res = Response::default().add_attributes(vec![ - attr("action", "remove_actions"), - attr("ado_type", ado_version.clone().into_string()), - ]); - - for action in actions { - ACTION_FEES.remove( - deps.storage, - &(ado_version.clone().into_string(), action.clone()), - ); - res = res.add_attribute("action_fee_removed", action); } - - Ok(res) -} - -fn execute_update_publisher( - deps: DepsMut, - info: MessageInfo, - ado_version: &ADOVersion, - publisher: String, -) -> Result { - ensure!( - ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, - ContractError::Unauthorized {} - ); - - let ado_type_exists = read_code_id(deps.storage, ado_version); - ensure!( - ado_type_exists.is_ok(), - ContractError::InvalidADOVersion { - msg: Some("ADO type does not exist".to_string()) - } - ); - - PUBLISHER.save(deps.storage, ado_version.as_str(), &publisher)?; - - Ok(Response::default().add_attributes(vec![ - attr("action", "update_publisher"), - attr("ado_type", ado_version.clone().into_string()), - attr("publisher", publisher), - ])) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { - QueryMsg::CodeId { key } => encode_binary(&query_code_id(deps, key)?), - QueryMsg::ADOType { code_id } => encode_binary(&query_ado_type(deps, code_id)?), + QueryMsg::CodeId { key } => encode_binary(&query::code_id(deps, key)?), + // QueryMsg::UnpublishedCodeIds {} => encode_binary(&query::unpublished_code_ids(deps)?), + QueryMsg::IsUnpublishedCodeId { code_id } => { + encode_binary(&query::is_unpublished_code_id(deps, code_id)?) + } + QueryMsg::ADOType { code_id } => encode_binary(&query::ado_type(deps, code_id)?), QueryMsg::AllADOTypes { start_after, limit } => { - encode_binary(&query_all_ado_types(deps.storage, start_after, limit)?) + encode_binary(&query::all_ado_types(deps.storage, start_after, limit)?) } QueryMsg::ADOVersions { ado_type, start_after, limit, - } => encode_binary(&query_ado_versions( + } => encode_binary(&query::ado_versions( deps.storage, &ado_type, start_after, limit, )?), - QueryMsg::ADOMetadata { ado_type } => encode_binary(&query_ado_metadata(deps, ado_type)?), + // QueryMsg::UnpublishedADOVersions { ado_type } => { + // encode_binary(&query::unpublished_ado_versions(deps.storage, &ado_type)?) + // } + QueryMsg::ADOMetadata { ado_type } => encode_binary(&query::ado_metadata(deps, ado_type)?), QueryMsg::ActionFee { ado_type, action } => { - encode_binary(&query_action_fee(deps, ado_type, action)?) + encode_binary(&query::action_fee(deps, ado_type, action)?) } QueryMsg::ActionFeeByCodeId { code_id, action } => { - encode_binary(&query_action_fee_by_code_id(deps, code_id, action)?) + encode_binary(&query::action_fee_by_code_id(deps, code_id, action)?) + } + // Base queries + QueryMsg::Version {} => encode_binary(&ADOContract::default().query_version(deps)?), + QueryMsg::Type {} => encode_binary(&ADOContract::default().query_type(deps)?), + QueryMsg::Owner {} => encode_binary(&ADOContract::default().query_contract_owner(deps)?), + QueryMsg::KernelAddress {} => { + encode_binary(&ADOContract::default().query_kernel_address(deps)?) } } } - -fn query_code_id(deps: Deps, key: String) -> Result { - let code_id = read_code_id(deps.storage, &ADOVersion::from_string(key))?; - Ok(code_id) -} - -fn query_ado_type(deps: Deps, code_id: u64) -> Result, ContractError> { - let ado_version = ADO_TYPE.may_load(deps.storage, code_id)?; - Ok(ado_version) -} - -const DEFAULT_LIMIT: u32 = 10; -const MAX_LIMIT: u32 = 100; - -pub fn query_all_ado_types( - storage: &dyn Storage, - start_after: Option, - limit: Option, -) -> Result, ContractError> { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start = start_after.map(|s| Bound::ExclusiveRaw(s.into())); - - let ado_types: StdResult> = CODE_ID - .keys(storage, start, None, Order::Ascending) - .take(limit) - .collect(); - Ok(ado_types?) -} - -pub fn query_ado_versions( - storage: &dyn Storage, - ado_type: &str, - start_after: Option, - limit: Option, -) -> Result, ContractError> { - let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; - let start_after = start_after.unwrap_or(ado_type.to_string()); - let start = Some(Bound::exclusive(start_after.as_str())); - - // All versions have @ as starting point, we can add A which has higher ascii than @ to get the - let end_ado_type = format!("{ado_type}A"); - let end = Some(Bound::exclusive(end_ado_type.as_str())); - - let mut versions: Vec = CODE_ID - .keys(storage, start, end, Order::Ascending) - .take(limit) - .map(|item| item.unwrap()) - .collect(); - versions.sort_by(|a, b| { - let version_a: Version = ADOVersion::from_string(a).get_version().parse().unwrap(); - let version_b: Version = ADOVersion::from_string(b).get_version().parse().unwrap(); - version_b.cmp(&version_a) - }); - Ok(versions) -} - -fn query_ado_metadata(deps: Deps, ado_type: String) -> Result { - let ado_version = ADOVersion::from_string(ado_type); - let publisher = PUBLISHER.load(deps.storage, ado_version.as_str())?; - let latest_version = read_latest_code_id(deps.storage, ado_version.get_type())?; - - Ok(ADOMetadata { - publisher, - latest_version: latest_version.0, - }) -} - -fn query_action_fee( - deps: Deps, - ado_type: String, - action: String, -) -> Result, ContractError> { - let ado_version = ADOVersion::from_string(ado_type); - Ok(ACTION_FEES.may_load(deps.storage, &(ado_version.into_string(), action))?) -} - -fn query_action_fee_by_code_id( - deps: Deps, - code_id: u64, - action: String, -) -> Result, ContractError> { - let ado_version = ADO_TYPE.load(deps.storage, code_id)?; - Ok(ACTION_FEES.may_load(deps.storage, &(ado_version, action))?) -} diff --git a/andromeda-core/contracts/os/andromeda-adodb/src/execute.rs b/andromeda-core/contracts/os/andromeda-adodb/src/execute.rs new file mode 100644 index 0000000..2425011 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-adodb/src/execute.rs @@ -0,0 +1,257 @@ +use crate::state::{ + read_code_id, remove_code_id, save_action_fees, store_code_id, ACTION_FEES, ADO_TYPE, + LATEST_VERSION, PUBLISHER, UNPUBLISHED_CODE_IDS, UNPUBLISHED_VERSIONS, +}; + +use andromeda_std::ado_contract::ADOContract; + +use andromeda_std::error::ContractError; +use andromeda_std::os::adodb::{ADOVersion, ActionFee}; +use cosmwasm_std::{attr, ensure, DepsMut, Env, MessageInfo, Response}; + +#[allow(clippy::too_many_arguments)] +pub fn publish( + deps: DepsMut, + _env: Env, + info: MessageInfo, + code_id: u64, + ado_type: String, + version: String, + action_fees: Option>, + publisher: Option, +) -> Result { + ensure!( + ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + // Can't republish removed code ids + let unpublished_code_id = UNPUBLISHED_CODE_IDS + .may_load(deps.storage, code_id)? + .unwrap_or(false); + ensure!(!unpublished_code_id, ContractError::UnpublishedCodeID {}); + + // Can't republish an unpublished version of the same ADO type + let unpublished_version = UNPUBLISHED_VERSIONS + .may_load(deps.storage, (&ado_type, version.as_str()))? + .unwrap_or(false); + ensure!(!unpublished_version, ContractError::UnpublishedVersion {}); + + ensure!( + // Using trim to rule out non-empty strings made up of only spaces + !ado_type.trim().is_empty(), + ContractError::InvalidADOType { + msg: Some("ado_type can't be an empty string".to_string()) + } + ); + let current_ado_version = LATEST_VERSION.may_load(deps.storage, &ado_type)?; + ensure!( + semver::Version::parse(&version).is_ok(), + ContractError::InvalidADOVersion { + msg: Some("Provided version is not valid semver".to_string()) + } + ); + let new_version = semver::Version::parse(&version).unwrap(); + if let Some(ado_version) = current_ado_version { + let current_version = semver::Version::parse(&ado_version.0).unwrap(); + ensure!( + new_version > current_version, + ContractError::InvalidADOVersion { + msg: Some("Version must be newer than the current version".to_string()) + } + ); + } + + //TODO: Get Code ID info with cosmwasm 1.2 + + let version = ADOVersion::from_type(ado_type).with_version(version); + ensure!( + version.validate(), + ContractError::InvalidADOVersion { msg: None } + ); + + // Ensure version is not already published + let curr_code_id = read_code_id(deps.storage, &version); + ensure!( + curr_code_id.is_err(), + ContractError::InvalidADOVersion { + msg: Some(String::from("Version already published")) + } + ); + + store_code_id(deps.storage, &version, code_id)?; + PUBLISHER.save( + deps.storage, + version.as_str(), + &publisher.clone().unwrap_or(info.sender.to_string()), + )?; + + if let Some(fees) = action_fees { + save_action_fees(deps.storage, deps.api, &version, fees)?; + } + + Ok(Response::default().add_attributes(vec![ + attr("action", "publish_ado"), + attr("ado_type", version.into_string()), + attr("code_id", code_id.to_string()), + attr("publisher", publisher.unwrap_or(info.sender.to_string())), + ])) +} + +#[allow(clippy::too_many_arguments)] +pub fn unpublish( + deps: DepsMut, + _env: Env, + info: MessageInfo, + ado_type: String, + version: String, +) -> Result { + ensure!( + ADOContract::default().is_owner_or_operator(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + ensure!( + // Using trim to rule out non-empty strings made up of only spaces + !ado_type.trim().is_empty(), + ContractError::InvalidADOType { + msg: Some("ado_type can't be an empty string".to_string()) + } + ); + ensure!( + semver::Version::parse(&version).is_ok(), + ContractError::InvalidADOVersion { + msg: Some("Provided version is not valid semver".to_string()) + } + ); + + //TODO: Get Code ID info with cosmwasm 1.2 + + let ado_version = ADOVersion::from_type(ado_type.clone()).with_version(version.clone()); + ensure!( + ado_version.validate(), + ContractError::InvalidADOVersion { msg: None } + ); + + // Ensure version is already published + let code_id = + read_code_id(deps.storage, &ado_version) + .ok() + .ok_or(ContractError::InvalidADOVersion { + msg: Some("Version not already published".to_string()), + })?; + // If this fails then the CodeID isn't available + + // Verify Code ID exists + ADO_TYPE + .load(deps.storage, &code_id.to_string()) + .ok() + .ok_or(ContractError::InvalidCodeID { + msg: Some("Code ID not already published".to_string()), + })?; + + remove_code_id(deps.storage, &ado_version, code_id)?; + + // Remove publisher for this version + PUBLISHER.remove(deps.storage, ado_version.as_str()); + + // Add the unpublished code id to the list + UNPUBLISHED_CODE_IDS.save(deps.storage, code_id, &true)?; + + // Set the value for ado type, ado version tuple as true, referring to its unpublished status + UNPUBLISHED_VERSIONS.save(deps.storage, (&ado_type, version.as_str()), &true)?; + + Ok(Response::default().add_attributes(vec![ + attr("action", "unpublish_ado"), + attr("ado_type", ado_type), + attr("ado_version", version), + attr("code_id", code_id.to_string()), + attr("remover", info.sender.to_string()), + ])) +} + +pub fn update_action_fees( + deps: DepsMut, + info: MessageInfo, + ado_version: &ADOVersion, + action_fees: Vec, +) -> Result { + ensure!( + ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + let ado_type_exists = read_code_id(deps.storage, ado_version); + ensure!( + ado_type_exists.is_ok(), + ContractError::InvalidADOVersion { + msg: Some("ADO type does not exist".to_string()) + } + ); + + save_action_fees(deps.storage, deps.api, ado_version, action_fees)?; + + Ok(Response::default().add_attributes(vec![ + attr("action", "update_action_fees"), + attr("ado_type", ado_version.clone().into_string()), + ])) +} + +pub fn remove_actions( + deps: DepsMut, + info: MessageInfo, + ado_version: &ADOVersion, + actions: Vec, +) -> Result { + ensure!( + ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + let ado_type_exists = read_code_id(deps.storage, ado_version); + ensure!( + ado_type_exists.is_ok(), + ContractError::InvalidADOVersion { + msg: Some("ADO type does not exist".to_string()) + } + ); + + let mut res = Response::default().add_attributes(vec![ + attr("action", "remove_actions"), + attr("ado_type", ado_version.clone().into_string()), + ]); + + for action in actions { + ACTION_FEES.remove( + deps.storage, + &(ado_version.clone().into_string(), action.clone()), + ); + res = res.add_attribute("action_fee_removed", action); + } + + Ok(res) +} + +pub fn update_publisher( + deps: DepsMut, + info: MessageInfo, + ado_version: &ADOVersion, + publisher: String, +) -> Result { + ensure!( + ADOContract::default().is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + let ado_type_exists = read_code_id(deps.storage, ado_version); + ensure!( + ado_type_exists.is_ok(), + ContractError::InvalidADOVersion { + msg: Some("ADO type does not exist".to_string()) + } + ); + + PUBLISHER.save(deps.storage, ado_version.as_str(), &publisher)?; + + Ok(Response::default().add_attributes(vec![ + attr("action", "update_publisher"), + attr("ado_type", ado_version.clone().into_string()), + attr("publisher", publisher), + ])) +} diff --git a/andromeda-core/contracts/os/andromeda-adodb/src/lib.rs b/andromeda-core/contracts/os/andromeda-adodb/src/lib.rs index dbcda2e..37d6561 100644 --- a/andromeda-core/contracts/os/andromeda-adodb/src/lib.rs +++ b/andromeda-core/contracts/os/andromeda-adodb/src/lib.rs @@ -1,6 +1,9 @@ pub mod contract; + +pub mod execute; #[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] pub mod mock; +pub mod query; mod state; #[cfg(test)] diff --git a/andromeda-core/contracts/os/andromeda-adodb/src/mock.rs b/andromeda-core/contracts/os/andromeda-adodb/src/mock.rs index b8c7a15..3014f2a 100644 --- a/andromeda-core/contracts/os/andromeda-adodb/src/mock.rs +++ b/andromeda-core/contracts/os/andromeda-adodb/src/mock.rs @@ -36,6 +36,13 @@ pub fn mock_publish( } } +pub fn mock_unpublish(ado_type: impl Into, version: impl Into) -> ExecuteMsg { + ExecuteMsg::Unpublish { + ado_type: ado_type.into(), + version: version.into(), + } +} + /// Used to generate a Code ID query message pub fn mock_get_code_id_msg(code_id_key: String) -> QueryMsg { QueryMsg::CodeId { key: code_id_key } diff --git a/andromeda-core/contracts/os/andromeda-adodb/src/query.rs b/andromeda-core/contracts/os/andromeda-adodb/src/query.rs new file mode 100644 index 0000000..2173c4a --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-adodb/src/query.rs @@ -0,0 +1,129 @@ +use crate::state::{ + read_code_id, read_latest_code_id, ACTION_FEES, ADO_TYPE, CODE_ID, PUBLISHER, + UNPUBLISHED_CODE_IDS, +}; + +use andromeda_std::error::ContractError; +use andromeda_std::os::adodb::{ADOMetadata, ADOVersion, ActionFee, IsUnpublishedCodeIdResponse}; +use cosmwasm_std::{Deps, Order, StdResult, Storage}; + +use cw_storage_plus::Bound; +use semver::Version; + +pub fn code_id(deps: Deps, key: String) -> Result { + let code_id = read_code_id(deps.storage, &ADOVersion::from_string(key))?; + Ok(code_id) +} + +pub fn unpublished_code_ids(deps: Deps) -> Result, ContractError> { + let unpublished_code_ids = UNPUBLISHED_CODE_IDS + .keys(deps.storage, None, None, Order::Ascending) + .collect::, _>>(); + // Returns empty vector if there are no unpublished code ids + Ok(unpublished_code_ids.unwrap_or(vec![])) +} + +pub fn is_unpublished_code_id( + deps: Deps, + code_id: u64, +) -> Result { + let is_unpublished_code_id = UNPUBLISHED_CODE_IDS + .load(deps.storage, code_id) + .unwrap_or(false); + Ok(IsUnpublishedCodeIdResponse { + is_unpublished_code_id, + }) +} + +pub fn ado_type(deps: Deps, code_id: u64) -> Result, ContractError> { + let ado_version = ADO_TYPE.may_load(deps.storage, &code_id.to_string())?; + Ok(ado_version) +} + +const DEFAULT_LIMIT: u32 = 100; +const MAX_LIMIT: u32 = 200; + +pub fn all_ado_types( + storage: &dyn Storage, + start_after: Option, + limit: Option, +) -> Result, ContractError> { + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start = start_after.map(|s| Bound::ExclusiveRaw(s.into())); + + let ado_types: StdResult> = CODE_ID + .keys(storage, start, None, Order::Ascending) + .take(limit) + .collect(); + Ok(ado_types?) +} + +pub fn ado_versions( + storage: &dyn Storage, + ado_type: &str, + start_after: Option, + limit: Option, +) -> Result, ContractError> { + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT) as usize; + let start_after = start_after.unwrap_or(ado_type.to_string()); + let start = Some(Bound::exclusive(start_after.as_str())); + + // All versions have @ as starting point, we can add A which has higher ascii than @ to get the + let end_ado_type = format!("{ado_type}A"); + let end = Some(Bound::exclusive(end_ado_type.as_str())); + + let mut versions: Vec = CODE_ID + .keys(storage, start, end, Order::Ascending) + .take(limit) + .map(|item| item.unwrap()) + .collect(); + versions.sort_by(|a, b| { + let version_a: Version = ADOVersion::from_string(a).get_version().parse().unwrap(); + let version_b: Version = ADOVersion::from_string(b).get_version().parse().unwrap(); + version_b.cmp(&version_a) + }); + Ok(versions) +} + +// pub fn unpublished_ado_versions( +// storage: &dyn Storage, +// ado_type: &str, +// version: &str, +// ) -> Result, ContractError> { +// let versions = UNPUBLISHED_VERSIONS +// .may_load(storage, (ado_type, version))? +// .unwrap_or(false); +// match versions { +// Some(versions) => Ok(versions), +// None => Ok(vec![]), +// } +// } + +pub fn ado_metadata(deps: Deps, ado_type: String) -> Result { + let ado_version = ADOVersion::from_string(ado_type); + let publisher = PUBLISHER.load(deps.storage, ado_version.as_str())?; + let latest_version = read_latest_code_id(deps.storage, ado_version.get_type())?; + + Ok(ADOMetadata { + publisher, + latest_version: latest_version.0, + }) +} + +pub fn action_fee( + deps: Deps, + ado_type: String, + action: String, +) -> Result, ContractError> { + let ado_version = ADOVersion::from_string(ado_type); + Ok(ACTION_FEES.may_load(deps.storage, &(ado_version.into_string(), action))?) +} + +pub fn action_fee_by_code_id( + deps: Deps, + code_id: u64, + action: String, +) -> Result, ContractError> { + let ado_version = ADO_TYPE.load(deps.storage, &code_id.to_string())?; + Ok(ACTION_FEES.may_load(deps.storage, &(ado_version.get_type(), action))?) +} diff --git a/andromeda-core/contracts/os/andromeda-adodb/src/state.rs b/andromeda-core/contracts/os/andromeda-adodb/src/state.rs index d8fa210..358b038 100644 --- a/andromeda-core/contracts/os/andromeda-adodb/src/state.rs +++ b/andromeda-core/contracts/os/andromeda-adodb/src/state.rs @@ -2,15 +2,19 @@ use andromeda_std::{ error::ContractError, os::adodb::{ADOVersion, ActionFee}, }; -use cosmwasm_std::{ensure, StdResult, Storage}; +use cosmwasm_std::{ensure, Api, StdResult, Storage}; use cw_storage_plus::Map; /// Stores a mapping from an ADO type/version to its code ID pub const CODE_ID: Map<&str, u64> = Map::new("code_id"); +/// Stores unpublished code IDs to prevent resubmission of malicious contracts +pub const UNPUBLISHED_CODE_IDS: Map = Map::new("unpublished_code_ids"); +/// Stores whether unpublished or not for a pair of (ADO type, ADO version). True means unpublished +pub const UNPUBLISHED_VERSIONS: Map<(&str, &str), bool> = Map::new("unpublished_versions"); /// Stores the latest version for a given ADO pub const LATEST_VERSION: Map<&str, (String, u64)> = Map::new("latest_version"); /// Stores a mapping from code ID to ADO -pub const ADO_TYPE: Map = Map::new("ado_type"); +pub const ADO_TYPE: Map<&str, ADOVersion> = Map::new("ado_type"); /// Stores a mapping from ADO to its publisher pub const PUBLISHER: Map<&str, String> = Map::new("publisher"); /// Stores a mapping from an (ADO,Action) to its action fees @@ -21,21 +25,27 @@ pub fn store_code_id( ado_version: &ADOVersion, code_id: u64, ) -> Result<(), ContractError> { - let curr_type = ADO_TYPE.may_load(storage, code_id)?; + let curr_type = ADO_TYPE.may_load(storage, &code_id.to_string())?; ensure!( - curr_type.is_none() || curr_type.unwrap() == ado_version.get_type(), + curr_type.is_none() || &curr_type.unwrap() == ado_version, ContractError::Unauthorized {} ); ADO_TYPE - .save(storage, code_id, &ado_version.clone().into_string()) - .unwrap(); - LATEST_VERSION - .save( - storage, - &ado_version.get_type(), - &(ado_version.get_version(), code_id), - ) + .save(storage, &code_id.to_string(), ado_version) .unwrap(); + let version = semver::Version::parse(&ado_version.get_version()) + .ok() + .ok_or(ContractError::InvalidADOVersion { msg: None })?; + let prerelease = version.pre.parse::().unwrap_or_default(); + if prerelease.is_empty() { + LATEST_VERSION + .save( + storage, + &ado_version.get_type(), + &(ado_version.get_version(), code_id), + ) + .unwrap(); + } CODE_ID .save(storage, ado_version.as_str(), &code_id) .unwrap(); @@ -43,6 +53,65 @@ pub fn store_code_id( Ok(()) } +pub fn remove_code_id( + storage: &mut dyn Storage, + ado_version: &ADOVersion, + code_id: u64, +) -> Result<(), ContractError> { + let curr_type = ADO_TYPE.may_load(storage, &code_id.to_string())?; + ensure!( + curr_type.is_none() || &curr_type.unwrap() == ado_version, + ContractError::Unauthorized {} + ); + ADO_TYPE.remove(storage, &code_id.to_string()); + let version_code = LATEST_VERSION.may_load(storage, &ado_version.get_type())?; + if let Some(version_code) = version_code { + // This means that the code_id we're trying to unpublish is also the latest + if version_code.1 == code_id { + let mut penultimate_version = semver::Version::new(0, 0, 0); + let latest_version = semver::Version::parse(&ado_version.get_version()).unwrap(); + CODE_ID + .keys(storage, None, None, cosmwasm_std::Order::Descending) + .map(|v| v.unwrap()) + // Filter out the keys by type first + .filter(|v| v.starts_with(&ado_version.get_type())) + // We want to get the penultimate version, since it will replace the latest version + .for_each(|v| { + if let Some((_, version)) = v.split_once('@') { + let current_version = semver::Version::parse(version).unwrap(); + if penultimate_version < current_version && current_version < latest_version + { + penultimate_version = current_version; + }; + }; + }); + // In that case, the version we're removing is the only one for that ADO type. + if penultimate_version == semver::Version::new(0, 0, 0) { + LATEST_VERSION.remove(storage, &ado_version.get_type()); + } else { + let version_type = ADOVersion::from_type(ado_version.get_type()) + .with_version(penultimate_version.to_string()); + let penultimate_version_id = CODE_ID.load(storage, version_type.as_str())?; + LATEST_VERSION.save( + storage, + &ado_version.get_type(), + &(penultimate_version.to_string(), penultimate_version_id), + )?; + } + } + } + CODE_ID.remove(storage, ado_version.as_str()); + + // Check if there is any default ado set for this ado type. Defaults do not have versions appended to them. + let default_ado = ADOVersion::from_type(ado_version.get_type()); + let default_code_id = read_code_id(storage, &default_ado); + + if default_code_id.is_ok() { + CODE_ID.remove(storage, default_ado.as_str()); + } + Ok(()) +} + pub fn read_code_id(storage: &dyn Storage, ado_version: &ADOVersion) -> StdResult { if ado_version.get_version() == "latest" { let (_version, code_id) = read_latest_code_id(storage, ado_version.get_type())?; @@ -56,10 +125,20 @@ pub fn read_latest_code_id(storage: &dyn Storage, ado_type: String) -> StdResult LATEST_VERSION.load(storage, &ado_type) } -// pub fn read_all_ado_types(storage: &dyn Storage) -> StdResult> { -// let ado_types = CODE_ID -// .keys(storage, None, None, Order::Ascending) -// .flatten() -// .collect(); -// Ok(ado_types) -// } +pub fn save_action_fees( + storage: &mut dyn Storage, + api: &dyn Api, + ado_version: &ADOVersion, + fees: Vec, +) -> Result<(), ContractError> { + for action_fee in fees { + action_fee.validate_asset(api)?; + ACTION_FEES.save( + storage, + &(ado_version.get_type(), action_fee.clone().action), + &action_fee.clone(), + )?; + } + + Ok(()) +} diff --git a/andromeda-core/contracts/os/andromeda-adodb/src/tests.rs b/andromeda-core/contracts/os/andromeda-adodb/src/tests.rs index 0372ec5..d786706 100644 --- a/andromeda-core/contracts/os/andromeda-adodb/src/tests.rs +++ b/andromeda-core/contracts/os/andromeda-adodb/src/tests.rs @@ -3,7 +3,7 @@ use andromeda_std::testing::mock_querier::{mock_dependencies_custom, MOCK_KERNEL use cosmwasm_std::{from_json, Uint128}; use crate::contract::{execute, instantiate, query}; -use crate::state::{ACTION_FEES, CODE_ID, LATEST_VERSION, PUBLISHER}; +use crate::state::{ACTION_FEES, CODE_ID, LATEST_VERSION, PUBLISHER, UNPUBLISHED_CODE_IDS}; use andromeda_std::error::ContractError; use andromeda_std::os::adodb::{ADOVersion, ActionFee, ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -46,17 +46,71 @@ fn test_publish() { ActionFee { action: "action".to_string(), amount: Uint128::from(1u128), - asset: "somecw20token".to_string(), + asset: "cw20:somecw20token".to_string(), receiver: None, }, ActionFee { action: "action2".to_string(), amount: Uint128::from(2u128), - asset: "uusd".to_string(), + asset: "native:uusd".to_string(), receiver: None, }, ]; + // Empty ado_type + let ado_version = ADOVersion::from_type("").with_version("0.1.0"); + let code_id = 1; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let err = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + + assert_eq!( + err, + ContractError::InvalidADOType { + msg: Some("ado_type can't be an empty string".to_string()) + } + ); + + // Invalid version + let ado_version = ADOVersion::from_type("ado_type"); + let code_id = 1; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let err = execute(deps.as_mut(), env.clone(), info.clone(), msg); + assert!(err.is_err()); + + // ado_type made only of spaces + let ado_version = ADOVersion::from_type(" ").with_version("0.1.0"); + let code_id = 1; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let err = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + + assert_eq!( + err, + ContractError::InvalidADOType { + msg: Some("ado_type can't be an empty string".to_string()) + } + ); + let ado_version = ADOVersion::from_type("ado_type").with_version("0.1.0"); let code_id = 1; let msg = ExecuteMsg::Publish { @@ -67,7 +121,7 @@ fn test_publish() { publisher: Some(owner.clone()), }; - let resp = execute(deps.as_mut(), env.clone(), info, msg.clone()); + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); assert!(resp.is_ok()); let publisher = PUBLISHER @@ -91,18 +145,324 @@ fn test_publish() { let fee = ACTION_FEES .load( deps.as_ref().storage, - &(ado_version.clone().into_string(), action_fee.clone().action), + &(ado_version.get_type(), action_fee.clone().action), ) .unwrap(); assert_eq!(fee, action_fee); } + // Test prelease + let ado_version = ADOVersion::from_type("ado_type_with_beta").with_version("0.1.0-beta.1"); + let code_id = 3; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: None, + publisher: None, + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); + assert!(resp.is_ok()); + + let publisher = PUBLISHER + .load(deps.as_ref().storage, ado_version.as_str()) + .unwrap(); + assert_eq!(publisher, owner); + + let code_id = CODE_ID + .load(deps.as_ref().storage, ado_version.as_str()) + .unwrap(); + assert_eq!(code_id, 3u64); + + let vers_code_id = LATEST_VERSION + .may_load(deps.as_ref().storage, &ado_version.get_type()) + .unwrap(); + assert!(vers_code_id.is_none()); + // Test unauthorised let unauth_info = mock_info("not_owner", &[]); - let resp = execute(deps.as_mut(), env, unauth_info, msg); + let resp = execute(deps.as_mut(), env.clone(), unauth_info, msg); assert!(resp.is_err()); } +#[test] +fn test_unpublish() { + let owner = String::from("owner"); + let mut deps = mock_dependencies_custom(&[]); + let env = mock_env(); + let info = mock_info(owner.as_str(), &[]); + + instantiate( + deps.as_mut(), + mock_env(), + mock_info(&owner, &[]), + InstantiateMsg { + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + owner: None, + }, + ) + .unwrap(); + + let action_fees = vec![ + ActionFee { + action: "action".to_string(), + amount: Uint128::from(1u128), + asset: "cw20:somecw20token".to_string(), + receiver: None, + }, + ActionFee { + action: "action2".to_string(), + amount: Uint128::from(2u128), + asset: "native:uusd".to_string(), + receiver: None, + }, + ]; + let ado_version = ADOVersion::from_type("ado_type").with_version("0.1.0"); + let code_id = 1; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); + + assert!(resp.is_ok()); + let publisher = PUBLISHER + .load(deps.as_ref().storage, ado_version.as_str()) + .unwrap(); + assert_eq!(publisher, owner); + + let code_id = CODE_ID + .load(deps.as_ref().storage, ado_version.as_str()) + .unwrap(); + assert_eq!(code_id, 1u64); + + let vers_code_id = LATEST_VERSION + .load(deps.as_ref().storage, &ado_version.get_type()) + .unwrap(); + assert_eq!(vers_code_id.0, ado_version.get_version()); + assert_eq!(vers_code_id.1, code_id); + + // TEST ACTION FEE + for action_fee in action_fees.clone() { + let fee = ACTION_FEES + .load( + deps.as_ref().storage, + &(ado_version.get_type(), action_fee.clone().action), + ) + .unwrap(); + assert_eq!(fee, action_fee); + } + + // Test unauthorised + let unauth_info = mock_info("not_owner", &[]); + let resp = execute(deps.as_mut(), env.clone(), unauth_info.clone(), msg); + assert!(resp.is_err()); + + // Test unpublish + + // Unauthorized + + let msg = ExecuteMsg::Unpublish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + }; + + let err = execute(deps.as_mut(), env.clone(), unauth_info, msg).unwrap_err(); + + assert_eq!(err, ContractError::Unauthorized {}); + + // Invalid Version + let invalid_ado_version = ADOVersion::from_type("ado_type").with_version("0.2.0"); + let msg = ExecuteMsg::Unpublish { + ado_type: ado_version.get_type(), + version: invalid_ado_version.get_version(), + }; + + let err = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + + assert_eq!( + err, + ContractError::InvalidADOVersion { + msg: Some(String::from("Version not already published")) + } + ); + + // Works + let msg = ExecuteMsg::Unpublish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + + assert!(resp.is_ok()); + + let publisher = PUBLISHER.load(deps.as_ref().storage, ado_version.as_str()); + assert!(publisher.is_err()); + + let code_id = CODE_ID.load(deps.as_ref().storage, ado_version.as_str()); + assert!(code_id.is_err()); + + let vers_code_id = LATEST_VERSION.load(deps.as_ref().storage, &ado_version.get_type()); + assert!(vers_code_id.is_err()); + + // Check on unpublished code ids + let unpublished_code_ids = UNPUBLISHED_CODE_IDS.load(deps.as_ref().storage, 1).unwrap(); + // The code id that was originally published and then unpublished is 1 + // True means that it's unpublished + assert!(unpublished_code_ids); + + // Make sure we can't republish an unpublished code id + let ado_version = ADOVersion::from_type("ado_type").with_version("0.1.0"); + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id: 1, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let err = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + assert_eq!(err, ContractError::UnpublishedCodeID {}); + + // Make sure we can't republish unpublished versions of corresponding ADO types + // same type same version + let ado_version = ADOVersion::from_type("ado_type").with_version("0.1.0"); + let code_id = 2; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let err = execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap_err(); + assert_eq!(err, ContractError::UnpublishedVersion {}); + + // Different type same version should work + let ado_version = ADOVersion::from_type("ado_different_type").with_version("0.1.0"); + let code_id = 3; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + assert!(resp.is_ok()); + + // Works with new code id and version of the same ado type + let ado_version = ADOVersion::from_type("ado_type").with_version("0.2.0"); + let code_id = 2; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + assert!(resp.is_ok()); + + // Publish 2 versions of the same ADO type + let ado_version = ADOVersion::from_type("splitter").with_version("0.1.0"); + let code_id = 10; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + assert!(resp.is_ok()); + + let ado_version = ADOVersion::from_type("splitter").with_version("0.2.0"); + let code_id = 11; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees.clone()), + publisher: Some(owner.clone()), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + assert!(resp.is_ok()); + + let msg = ExecuteMsg::Unpublish { + ado_type: "splitter".to_string(), + version: "0.2.0".to_string(), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + + assert!(resp.is_ok()); + + let vers_code_id = LATEST_VERSION + .load(deps.as_ref().storage, "splitter") + .unwrap(); + // We published 2 versions of the splitter. The first being version 0.1.0, and the other 0.2.0. + // While unpublishing the latest version, the penultimate version was set instead as the latest version + assert_eq!(vers_code_id, ("0.1.0".to_string(), 10)); + + // Let's try removing the penultimate version, the latest version should remain unchanged + // First we'll publish a newer version so that we'll have two. + let ado_version = ADOVersion::from_type("splitter").with_version("0.3.0"); + let code_id = 12; + let msg = ExecuteMsg::Publish { + ado_type: ado_version.get_type(), + version: ado_version.get_version(), + code_id, + action_fees: Some(action_fees), + publisher: Some(owner), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + // Version 0.3.0 should now be the latest version, and removing 0.1.0 won't affect that. + assert!(resp.is_ok()); + + // Remove version 0.1.0 + let msg = ExecuteMsg::Unpublish { + ado_type: "splitter".to_string(), + version: "0.1.0".to_string(), + }; + + let resp = execute(deps.as_mut(), env.clone(), info.clone(), msg); + + assert!(resp.is_ok()); + + let vers_code_id = LATEST_VERSION + .load(deps.as_ref().storage, "splitter") + .unwrap(); + assert_eq!(vers_code_id, ("0.3.0".to_string(), 12)); + + // 0.3.0 is now the only version remaining for the splitter type, removing it should not result in errors + let msg = ExecuteMsg::Unpublish { + ado_type: "splitter".to_string(), + version: "0.3.0".to_string(), + }; + + let resp = execute(deps.as_mut(), env, info, msg); + assert!(resp.is_ok()); + + // There shouldn't be any versions remaining since 0.3.0 was the last one + let vers_code_id = LATEST_VERSION + .may_load(deps.as_ref().storage, &ado_version.get_type()) + .unwrap(); + assert!(vers_code_id.is_none()); +} + #[test] fn test_update_action_fees() { let owner = String::from("owner"); @@ -127,13 +487,13 @@ fn test_update_action_fees() { ActionFee { action: "action".to_string(), amount: Uint128::from(1u128), - asset: "somecw20token".to_string(), + asset: "cw20:somecw20token".to_string(), receiver: None, }, ActionFee { action: "action2".to_string(), amount: Uint128::from(2u128), - asset: "uusd".to_string(), + asset: "native:uusd".to_string(), receiver: None, }, ]; @@ -163,7 +523,7 @@ fn test_update_action_fees() { let fee = ACTION_FEES .load( deps.as_ref().storage, - &(ado_version.clone().into_string(), action_fee.clone().action), + &(ado_version.get_type(), action_fee.clone().action), ) .unwrap(); assert_eq!(fee, action_fee); diff --git a/andromeda-core/contracts/os/andromeda-economics/Cargo.toml b/andromeda-core/contracts/os/andromeda-economics/Cargo.toml index 13c839d..7711b5e 100644 --- a/andromeda-core/contracts/os/andromeda-economics/Cargo.toml +++ b/andromeda-core/contracts/os/andromeda-economics/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "andromeda-economics" -version = "0.2.0" +version = "1.1.1" authors = ["Connor Barr "] edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" exclude = [ # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. @@ -25,13 +25,12 @@ testing = ["cw-multi-test"] cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw2 = { workspace = true } + cw20 = { workspace = true } andromeda-std = { workspace = true } -semver = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } [dev-dependencies] -# andromeda-testing = { version = "0.1.0", path = "../../../packages/andromeda-testing" } +# andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/os/andromeda-economics/README.md b/andromeda-core/contracts/os/andromeda-economics/README.md index a883785..a98cb6d 100644 --- a/andromeda-core/contracts/os/andromeda-economics/README.md +++ b/andromeda-core/contracts/os/andromeda-economics/README.md @@ -1,3 +1,10 @@ -# Andromeda Factory +# Overview -A repository containing the NFT contract for Andromeda Protocol on Terra. This contract's primary purpose is to initialise and register ADO collections. Registration is done by a mapping between the ADO collection's symbol and the contract address for the given ADO collection. Documentation can be found [here](https://app.gitbook.com/@andromedaprotocol/s/andromeda/contracts/andromeda-factory). +The Economics ADO allows users to deposit funds to be used to pay fees implemented on ADO actions (Execute Messages) by the ADODB. Deposited funds can be either native funds such as "uandr" or CW20 tokens where the contract address is used. The fees are automatically called by the ADO that implements them. + +Fees are charged in the following order: +- ADO: First, the ADO requesting the fees is checked for funds and if available will use these funds to pay the fee. +- App: The App contract of the ADO requesting the fees. +- Payee: The address that sent the message to the ADO that is requesting the fees. + +[Economics Full Documentation](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/economics-engine) \ No newline at end of file diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/andromeda-economics.json b/andromeda-core/contracts/os/andromeda-economics/schema/andromeda-economics.json deleted file mode 100644 index 1477350..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/andromeda-economics.json +++ /dev/null @@ -1,261 +0,0 @@ -{ - "contract_name": "andromeda-economics", - "contract_version": "0.2.0", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "description": "Address of the Kernel contract on chain", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Deposit funds to be used by the Andromeda economics module to pay for ADO fees.\n\nAn optional valid VFS path can be provided to deposit funds on behalf of another address.", - "type": "object", - "required": [ - "deposit" - ], - "properties": { - "deposit": { - "type": "object", - "properties": { - "address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Pay a fee for the given action. The sender must be a valid ADO contract.\n\nFees are paid in the following fallthrough priority: 1. The balance of the ADO contract itself 2. The balance of the App contract for the ADO 3. The provided payee address", - "type": "object", - "required": [ - "pay_fee" - ], - "properties": { - "pay_fee": { - "type": "object", - "required": [ - "action", - "payee" - ], - "properties": { - "action": { - "type": "string" - }, - "payee": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Withdraw native funds from the Andromeda economics module.\n\nIf no amount is provided all funds are withdrawn for the given asset.", - "type": "object", - "required": [ - "withdraw" - ], - "properties": { - "withdraw": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "asset": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Withdraw CW20 funds from the Andromeda economics module.\n\nIf no amount is provided all funds are withdrawn for the given asset.", - "type": "object", - "required": [ - "withdraw_cw20" - ], - "properties": { - "withdraw_cw20": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "asset": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Queries the current balance for a given AndrAddr and asset tuple\n\nReturns a `Uint128` representing the current balance", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address", - "asset" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "asset": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "balance": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/raw/execute.json b/andromeda-core/contracts/os/andromeda-economics/schema/raw/execute.json deleted file mode 100644 index 3a09b34..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/raw/execute.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Deposit funds to be used by the Andromeda economics module to pay for ADO fees.\n\nAn optional valid VFS path can be provided to deposit funds on behalf of another address.", - "type": "object", - "required": [ - "deposit" - ], - "properties": { - "deposit": { - "type": "object", - "properties": { - "address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Pay a fee for the given action. The sender must be a valid ADO contract.\n\nFees are paid in the following fallthrough priority: 1. The balance of the ADO contract itself 2. The balance of the App contract for the ADO 3. The provided payee address", - "type": "object", - "required": [ - "pay_fee" - ], - "properties": { - "pay_fee": { - "type": "object", - "required": [ - "action", - "payee" - ], - "properties": { - "action": { - "type": "string" - }, - "payee": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Withdraw native funds from the Andromeda economics module.\n\nIf no amount is provided all funds are withdrawn for the given asset.", - "type": "object", - "required": [ - "withdraw" - ], - "properties": { - "withdraw": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "asset": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Withdraw CW20 funds from the Andromeda economics module.\n\nIf no amount is provided all funds are withdrawn for the given asset.", - "type": "object", - "required": [ - "withdraw_cw20" - ], - "properties": { - "withdraw_cw20": { - "type": "object", - "required": [ - "asset" - ], - "properties": { - "amount": { - "anyOf": [ - { - "$ref": "#/definitions/Uint128" - }, - { - "type": "null" - } - ] - }, - "asset": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "receive" - ], - "properties": { - "receive": { - "$ref": "#/definitions/Cw20ReceiveMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Cw20ReceiveMsg": { - "description": "Cw20ReceiveMsg should be de/serialized under `Receive()` variant in a ExecuteMsg", - "type": "object", - "required": [ - "amount", - "msg", - "sender" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/raw/instantiate.json b/andromeda-core/contracts/os/andromeda-economics/schema/raw/instantiate.json deleted file mode 100644 index 4ac8dac..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/raw/instantiate.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "description": "Address of the Kernel contract on chain", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/raw/query.json b/andromeda-core/contracts/os/andromeda-economics/schema/raw/query.json deleted file mode 100644 index 8d3765f..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/raw/query.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "description": "Queries the current balance for a given AndrAddr and asset tuple\n\nReturns a `Uint128` representing the current balance", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address", - "asset" - ], - "properties": { - "address": { - "$ref": "#/definitions/AndrAddr" - }, - "asset": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_a_d_o_type.json b/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_a_d_o_type.json deleted file mode 100644 index f4c601d..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_a_d_o_type.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_String", - "type": [ - "string", - "null" - ] -} diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_balance.json b/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_balance.json deleted file mode 100644 index 7dcf4d4..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_balance.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "$ref": "#/definitions/Uint128" - } - }, - "additionalProperties": false, - "definitions": { - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_code_id.json b/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_code_id.json deleted file mode 100644 index 7b729a7..0000000 --- a/andromeda-core/contracts/os/andromeda-economics/schema/raw/response_to_code_id.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "uint64", - "type": "integer", - "format": "uint64", - "minimum": 0.0 -} diff --git a/andromeda-core/contracts/os/andromeda-economics/src/contract.rs b/andromeda-core/contracts/os/andromeda-economics/src/contract.rs index 0693886..8d46c1c 100644 --- a/andromeda-core/contracts/os/andromeda-economics/src/contract.rs +++ b/andromeda-core/contracts/os/andromeda-economics/src/contract.rs @@ -1,21 +1,18 @@ -use crate::state::BALANCES; -use andromeda_std::ado_base::{AndromedaQuery, InstantiateMsg as BaseInstantiateMsg}; +use andromeda_std::ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}; use andromeda_std::ado_contract::ADOContract; -use andromeda_std::amp::AndrAddr; - -use andromeda_std::error::{from_semver, ContractError}; -use andromeda_std::os::aos_querier::AOSQuerier; -use andromeda_std::os::economics::{ - BalanceResponse, Cw20HookMsg, ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg, -}; +use andromeda_std::common::encode_binary; +use andromeda_std::common::reply::ReplyId; +use andromeda_std::error::ContractError; +use andromeda_std::os::economics::{Cw20HookMsg, ExecuteMsg, InstantiateMsg, QueryMsg}; #[allow(unused_imports)] use cosmwasm_std::{ attr, coin, ensure, entry_point, from_json, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, MessageInfo, Response, Storage, SubMsg, Uint128, WasmMsg, }; -use cw2::{get_contract_version, set_contract_version}; -use cw20::{Cw20ExecuteMsg, Cw20ReceiveMsg}; -use semver::Version; +use cosmwasm_std::{Reply, StdError}; +use cw20::Cw20ReceiveMsg; + +use crate::{execute, query}; // version info for migration info const CONTRACT_NAME: &str = "crates.io:andromeda-economics"; @@ -28,22 +25,40 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "economics".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, ) } +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply(_deps: DepsMut, _env: Env, msg: Reply) -> Result { + if msg.result.is_err() { + return Err(ContractError::Std(StdError::generic_err( + msg.result.unwrap_err(), + ))); + } + + match ReplyId::from_repr(msg.id) { + Some(ReplyId::Cw20WithdrawMsg) => Err(ContractError::Std(StdError::generic_err( + msg.result.unwrap_err(), + ))), + Some(ReplyId::PayFee) => Err(ContractError::Std(StdError::generic_err( + msg.result.unwrap_err(), + ))), + _ => Ok(Response::default()), + } +} + #[cfg_attr(not(feature = "library"), entry_point)] pub fn execute( deps: DepsMut, @@ -52,14 +67,18 @@ pub fn execute( msg: ExecuteMsg, ) -> Result { match msg { - ExecuteMsg::Deposit { address } => execute_deposit_native(deps, info, address), - ExecuteMsg::PayFee { payee, action } => execute_pay_fee(deps, env, info, payee, action), + ExecuteMsg::Deposit { address } => execute::deposit_native(deps, info, address), + ExecuteMsg::PayFee { payee, action } => execute::pay_fee(deps, env, info, payee, action), ExecuteMsg::Withdraw { amount, asset } => { - execute_withdraw_native(deps, info, amount, asset) + execute::withdraw_native(deps, info, amount, asset) } - ExecuteMsg::Receive(cw20msg) => cw20_receive(deps, env, info, cw20msg), ExecuteMsg::WithdrawCW20 { amount, asset } => { - execute_withdraw_cw20(deps, info, amount, asset) + execute::withdraw_cw20(deps, info, amount, asset) + } + ExecuteMsg::Receive(cw20msg) => cw20_receive(deps, env, info, cw20msg), + // Base message + ExecuteMsg::Ownership(ownership_message) => { + ADOContract::default().execute_ownership(deps, env, info, ownership_message) } } } @@ -75,378 +94,28 @@ pub fn cw20_receive( match from_json::(&msg.msg)? { Cw20HookMsg::Deposit { address } => { - execute_cw20_deposit(deps, info, sender, amount, address) - } - } -} - -pub fn execute_cw20_deposit( - deps: DepsMut, - info: MessageInfo, - sender: Addr, - amount: Uint128, - address: Option, -) -> Result { - ensure!( - amount > Uint128::zero(), - ContractError::InvalidFunds { - msg: "Cannot send 0 amount to deposit".to_string() - } - ); - let token_address = info.sender; - let resp = Response::default().add_attributes(vec![ - attr("action", "receive"), - attr("sender", sender.to_string()), - attr("amount", amount.to_string()), - attr("token_address", token_address.to_string()), - ]); - - let sender = if let Some(address) = address { - address.get_raw_address(&deps.as_ref())? - } else { - sender - }; - - let balance = BALANCES - .load(deps.storage, (sender.clone(), token_address.to_string())) - .unwrap_or_default(); - - BALANCES.save( - deps.storage, - (sender, token_address.to_string()), - &(balance + amount), - )?; - - Ok(resp) -} - -pub fn execute_deposit_native( - deps: DepsMut, - info: MessageInfo, - address: Option, -) -> Result { - ensure!(!info.funds.is_empty(), ContractError::CoinNotFound {}); - - let addr = address - .unwrap_or(AndrAddr::from_string(info.sender.to_string())) - .get_raw_address(&deps.as_ref())?; - - let mut resp = Response::default().add_attributes(vec![ - attr("action", "deposit"), - attr("depositee", info.sender.to_string()), - attr("recipient", addr.to_string()), - ]); - - for funds in info.funds { - let balance = BALANCES - .load( - deps.as_ref().storage, - (addr.clone(), funds.denom.to_string()), - ) - .unwrap_or_default(); - - BALANCES.save( - deps.storage, - (addr.clone(), funds.denom.to_string()), - &(balance + funds.amount), - )?; - - resp = resp.add_attribute( - "deposited_funds", - format!("{}{}", funds.amount, funds.denom), - ); - } - - Ok(resp) -} - -pub(crate) fn spend_balance( - storage: &mut dyn Storage, - addr: &Addr, - asset: String, - amount: Uint128, -) -> Result { - let balance = BALANCES - .load(storage, (addr.clone(), asset.to_string())) - .unwrap_or_default(); - - let remainder = if amount > balance { - amount - balance - } else { - Uint128::zero() - }; - let post_balance = if balance > amount { - balance - amount - } else { - Uint128::zero() - }; - - BALANCES.save(storage, (addr.clone(), asset), &post_balance)?; - - Ok(remainder) -} - -/// Charges a fee depending on the sending ADO and the action being performed. -/// Sender must be an ADO contract else this will error. -/// -/// Fees are charged in the following order: -/// 1. ADO -/// 2. App -/// 3. Payee -fn execute_pay_fee( - deps: DepsMut, - _env: Env, - info: MessageInfo, - payee: Addr, - action: String, -) -> Result { - let mut resp = Response::default(); - - resp.attributes = vec![ - attr("action", action.clone()), - attr("sender", info.sender.to_string()), - attr("payee", payee.to_string()), - ]; - - let contract_info = deps.querier.query_wasm_contract_info(info.sender.clone()); - if let Ok(contract_info) = contract_info { - let code_id = contract_info.code_id; - let adodb_addr = ADOContract::default().get_adodb_address(deps.storage, &deps.querier)?; - let ado_type = AOSQuerier::ado_type_getter(&deps.querier, &adodb_addr, code_id)?; - if ado_type.is_none() { - // Not an ADO - return Ok(resp); - } - - let ado_type = ado_type.unwrap(); - let fee = AOSQuerier::action_fee_getter( - &deps.querier, - &adodb_addr, - ado_type.as_str(), - action.as_str(), - )?; - - match fee { - // No fee - None => Ok(resp), - Some(fee) => { - let asset_string = fee.asset.to_string(); - let asset = asset_string.split(':').last().unwrap(); - - // Charge ADO first - let mut remainder = - spend_balance(deps.storage, &info.sender, asset.to_string(), fee.amount)?; - - // Next charge the app - if remainder > Uint128::zero() { - let app_contract = deps.querier.query_wasm_smart::>( - &info.sender, - &AndromedaQuery::AppContract {}, - )?; - remainder = if let Some(app_contract) = app_contract { - spend_balance(deps.storage, &app_contract, asset.to_string(), remainder)? - } else { - remainder - }; - } - - // Next charge the payee - if remainder > Uint128::zero() { - remainder = spend_balance(deps.storage, &payee, asset.to_string(), remainder)?; - } - - // If balance remaining then not enough funds to pay fee - ensure!( - remainder == Uint128::zero(), - ContractError::InsufficientFunds {} - ); - - let recipient = if let Some(receiver) = fee.receiver { - receiver - } else { - let publisher = AOSQuerier::ado_publisher_getter( - &deps.querier, - &adodb_addr, - ado_type.as_str(), - )?; - deps.api.addr_validate(&publisher)? - }; - - let receiver_balance = BALANCES - .load( - deps.as_ref().storage, - (recipient.clone(), asset.to_string()), - ) - .unwrap_or_default(); - BALANCES.save( - deps.storage, - (recipient.clone(), asset.to_string()), - &(receiver_balance + fee.amount), - )?; - - resp = resp - .add_attribute("paid_fee", format!("{}{}", fee.amount, fee.asset)) - .add_attribute("fee_recipient", recipient.to_string()); - Ok(resp) - } + execute::cw20_deposit(deps, info, sender, amount, address) } - } else { - // Not a contract - Err(ContractError::InvalidSender {}) } } -fn execute_withdraw_native( - deps: DepsMut, - info: MessageInfo, - amount: Option, - asset: String, -) -> Result { - let mut resp = Response::default(); - - let balance = BALANCES - .load(deps.storage, (info.sender.clone(), asset.to_string())) - .unwrap_or_default(); - - let amount = if let Some(amount) = amount { - amount - } else { - balance - }; - - ensure!( - balance >= amount && !balance.is_zero(), - ContractError::InsufficientFunds {} - ); - - spend_balance(deps.storage, &info.sender, asset.clone(), amount)?; - - let bank_msg = BankMsg::Send { - to_address: info.sender.clone().into(), - amount: vec![coin(amount.u128(), asset)], - }; - let cosmos_msg: CosmosMsg = CosmosMsg::Bank(bank_msg); - - resp.attributes = vec![ - attr("action", "withdraw"), - attr("sender", info.sender.to_string()), - attr("amount", amount), - ]; - - resp = resp.add_message(cosmos_msg); - - Ok(resp) -} - -pub(crate) fn cw20_withdraw_msg( - amount: Uint128, - asset: impl Into, - recipient: impl Into, -) -> SubMsg { - let exec_msg = Cw20ExecuteMsg::Transfer { - recipient: recipient.into(), - amount, - }; - - SubMsg::reply_on_error( - CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: asset.into(), - msg: to_json_binary(&exec_msg).unwrap(), - funds: vec![], - }), - 999, - ) -} - -fn execute_withdraw_cw20( - deps: DepsMut, - info: MessageInfo, - amount: Option, - asset: String, -) -> Result { - let mut resp = Response::default(); - - let balance = BALANCES - .load(deps.storage, (info.sender.clone(), asset.to_string())) - .unwrap_or_default(); - - let amount = if let Some(amount) = amount { - amount - } else { - balance - }; - - ensure!( - balance >= amount && !balance.is_zero(), - ContractError::InsufficientFunds {} - ); - - spend_balance(deps.storage, &info.sender, asset.clone(), amount)?; - - let msg = cw20_withdraw_msg(amount, asset, info.sender.clone()); - - resp.attributes = vec![ - attr("action", "withdraw"), - attr("sender", info.sender.to_string()), - attr("amount", amount), - ]; - - resp = resp.add_submessage(msg); - - Ok(resp) -} - #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] -pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> Result { +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::Balance { address, asset } => { - Ok(to_json_binary(&query_balance(_deps, address, asset)?)?) + Ok(to_json_binary(&query::balance(deps, address, asset)?)?) + } + // Base queries + QueryMsg::Version {} => encode_binary(&ADOContract::default().query_version(deps)?), + QueryMsg::Type {} => encode_binary(&ADOContract::default().query_type(deps)?), + QueryMsg::Owner {} => encode_binary(&ADOContract::default().query_contract_owner(deps)?), + QueryMsg::KernelAddress {} => { + encode_binary(&ADOContract::default().query_kernel_address(deps)?) } } } - -fn query_balance( - deps: Deps, - address: AndrAddr, - asset: String, -) -> Result { - let addr = address.get_raw_address(&deps)?; - let balance = BALANCES - .load(deps.storage, (addr, asset)) - .unwrap_or_default(); - Ok(BalanceResponse { balance }) -} diff --git a/andromeda-core/contracts/os/andromeda-economics/src/execute.rs b/andromeda-core/contracts/os/andromeda-economics/src/execute.rs new file mode 100644 index 0000000..aa9c040 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-economics/src/execute.rs @@ -0,0 +1,326 @@ +use andromeda_std::{ + ado_contract::ADOContract, amp::AndrAddr, common::reply::ReplyId, error::ContractError, + os::aos_querier::AOSQuerier, +}; +use cosmwasm_std::{ + attr, coin, ensure, to_json_binary, Addr, BankMsg, CosmosMsg, DepsMut, Empty, Env, MessageInfo, + Response, Storage, SubMsg, Uint128, WasmMsg, +}; +use cw20::Cw20ExecuteMsg; + +use crate::state::BALANCES; + +pub fn cw20_deposit( + deps: DepsMut, + info: MessageInfo, + sender: Addr, + amount: Uint128, + address: Option, +) -> Result { + ensure!( + amount > Uint128::zero(), + ContractError::InvalidFunds { + msg: "Cannot send 0 amount to deposit".to_string() + } + ); + let token_address = info.sender; + let resp = Response::default().add_attributes(vec![ + attr("action", "receive"), + attr("sender", sender.to_string()), + attr("amount", amount.to_string()), + attr("token_address", token_address.to_string()), + ]); + + let sender = if let Some(address) = address { + address.get_raw_address(&deps.as_ref())? + } else { + sender + }; + + let balance = BALANCES + .load(deps.storage, (sender.clone(), token_address.to_string())) + .unwrap_or_default(); + + BALANCES.save( + deps.storage, + (sender, token_address.to_string()), + &(balance + amount), + )?; + + Ok(resp) +} + +pub fn deposit_native( + deps: DepsMut, + info: MessageInfo, + address: Option, +) -> Result { + ensure!(!info.funds.is_empty(), ContractError::CoinNotFound {}); + + let addr = address + .unwrap_or(AndrAddr::from_string(info.sender.to_string())) + .get_raw_address(&deps.as_ref())?; + + let mut resp = Response::default().add_attributes(vec![ + attr("action", "deposit"), + attr("depositee", info.sender.to_string()), + attr("recipient", addr.to_string()), + ]); + + for funds in info.funds { + let balance = BALANCES + .load( + deps.as_ref().storage, + (addr.clone(), funds.denom.to_string()), + ) + .unwrap_or_default(); + + BALANCES.save( + deps.storage, + (addr.clone(), funds.denom.to_string()), + &(balance + funds.amount), + )?; + + resp = resp.add_attribute( + "deposited_funds", + format!("{}{}", funds.amount, funds.denom), + ); + } + + Ok(resp) +} + +pub(crate) fn spend_balance( + storage: &mut dyn Storage, + addr: &Addr, + asset: String, + amount: Uint128, +) -> Result { + let balance = BALANCES + .load(storage, (addr.clone(), asset.to_string())) + .unwrap_or_default(); + + let remainder = if amount > balance { + amount - balance + } else { + Uint128::zero() + }; + let post_balance = if balance > amount { + balance - amount + } else { + Uint128::zero() + }; + + BALANCES.save(storage, (addr.clone(), asset), &post_balance)?; + + Ok(remainder) +} + +/// Charges a fee depending on the sending ADO and the action being performed. +/// Sender must be an ADO contract else this will error. +/// +/// Fees are charged in the following order: +/// 1. Payee +pub fn pay_fee( + deps: DepsMut, + _env: Env, + info: MessageInfo, + payee: Addr, + action: String, +) -> Result { + let mut resp = Response::default(); + + resp.attributes = vec![ + attr("action", action.clone()), + attr("sender", info.sender.to_string()), + attr("payee", payee.to_string()), + ]; + + let contract_info = deps.querier.query_wasm_contract_info(info.sender); + if let Ok(contract_info) = contract_info { + let code_id = contract_info.code_id; + let adodb_addr = ADOContract::default().get_adodb_address(deps.storage, &deps.querier)?; + let ado_type = AOSQuerier::ado_type_getter(&deps.querier, &adodb_addr, code_id)?; + if ado_type.is_none() { + // Not an ADO + return Ok(resp); + } + + let ado_type = ado_type.unwrap(); + let fee = AOSQuerier::action_fee_getter( + &deps.querier, + &adodb_addr, + ado_type.as_str(), + action.as_str(), + )?; + + match fee { + // No fee + None => Ok(resp), + Some(fee) => { + fee.validate_asset(deps.api)?; + let asset = fee.get_asset_string()?; + + // Removing ADO/App payments temporarily pending discussion + // Charge ADO first + // let mut remainder = + // spend_balance(deps.storage, &info.sender, asset.to_string(), fee.amount)?; + + // Next charge the app + // if remainder > Uint128::zero() { + // let app_contract = deps.querier.query_wasm_smart::>( + // &info.sender, + // &AndromedaQuery::AppContract {}, + // )?; + // remainder = if let Some(app_contract) = app_contract { + // spend_balance(deps.storage, &app_contract, asset.to_string(), remainder)? + // } else { + // remainder + // }; + // } + + // Next charge the payee + // if remainder > Uint128::zero() { + let remainder = spend_balance(deps.storage, &payee, asset.to_string(), fee.amount)?; + // } + + // If balance remaining then not enough funds to pay fee + ensure!( + remainder == Uint128::zero(), + ContractError::InsufficientFunds {} + ); + + let recipient = if let Some(receiver) = fee.receiver.clone() { + receiver + } else { + let publisher = AOSQuerier::ado_publisher_getter( + &deps.querier, + &adodb_addr, + ado_type.as_str(), + )?; + deps.api.addr_validate(&publisher)? + }; + + let receiver_balance = BALANCES + .load( + deps.as_ref().storage, + (recipient.clone(), asset.to_string()), + ) + .unwrap_or_default(); + BALANCES.save( + deps.storage, + (recipient.clone(), asset.to_string()), + &(receiver_balance + fee.amount), + )?; + + resp = resp + .add_attribute("paid_fee", format!("{}{}", fee.amount, fee.asset)) + .add_attribute("fee_recipient", recipient.to_string()); + Ok(resp) + } + } + } else { + // Not a contract + Err(ContractError::InvalidSender {}) + } +} + +pub fn withdraw_native( + deps: DepsMut, + info: MessageInfo, + amount: Option, + asset: String, +) -> Result { + let mut resp = Response::default(); + + let balance = BALANCES + .load(deps.storage, (info.sender.clone(), asset.to_string())) + .unwrap_or_default(); + + let amount = if let Some(amount) = amount { + amount + } else { + balance + }; + + ensure!( + balance >= amount && !balance.is_zero(), + ContractError::InsufficientFunds {} + ); + + spend_balance(deps.storage, &info.sender, asset.clone(), amount)?; + + let bank_msg = BankMsg::Send { + to_address: info.sender.clone().into(), + amount: vec![coin(amount.u128(), asset)], + }; + let cosmos_msg: CosmosMsg = CosmosMsg::Bank(bank_msg); + + resp.attributes = vec![ + attr("action", "withdraw"), + attr("sender", info.sender.to_string()), + attr("amount", amount), + ]; + + resp = resp.add_message(cosmos_msg); + + Ok(resp) +} + +pub(crate) fn cw20_withdraw_msg( + amount: Uint128, + asset: impl Into, + recipient: impl Into, +) -> SubMsg { + let exec_msg = Cw20ExecuteMsg::Transfer { + recipient: recipient.into(), + amount, + }; + + SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: asset.into(), + msg: to_json_binary(&exec_msg).unwrap(), + funds: vec![], + }), + ReplyId::Cw20WithdrawMsg.repr(), + ) +} + +pub fn withdraw_cw20( + deps: DepsMut, + info: MessageInfo, + amount: Option, + asset: String, +) -> Result { + let mut resp = Response::default(); + + let balance = BALANCES + .load(deps.storage, (info.sender.clone(), asset.to_string())) + .unwrap_or_default(); + + let amount = if let Some(amount) = amount { + amount + } else { + balance + }; + + ensure!( + balance >= amount && !balance.is_zero(), + ContractError::InsufficientFunds {} + ); + + spend_balance(deps.storage, &info.sender, asset.clone(), amount)?; + + let msg = cw20_withdraw_msg(amount, asset, info.sender.clone()); + + resp.attributes = vec![ + attr("action", "withdraw"), + attr("sender", info.sender.to_string()), + attr("amount", amount), + ]; + + resp = resp.add_submessage(msg); + + Ok(resp) +} diff --git a/andromeda-core/contracts/os/andromeda-economics/src/lib.rs b/andromeda-core/contracts/os/andromeda-economics/src/lib.rs index dbcda2e..e8e7d8d 100644 --- a/andromeda-core/contracts/os/andromeda-economics/src/lib.rs +++ b/andromeda-core/contracts/os/andromeda-economics/src/lib.rs @@ -1,6 +1,8 @@ pub mod contract; +pub mod execute; #[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] pub mod mock; +pub mod query; mod state; #[cfg(test)] diff --git a/andromeda-core/contracts/os/andromeda-economics/src/query.rs b/andromeda-core/contracts/os/andromeda-economics/src/query.rs new file mode 100644 index 0000000..b5f132d --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-economics/src/query.rs @@ -0,0 +1,12 @@ +use andromeda_std::{amp::AndrAddr, error::ContractError}; +use cosmwasm_std::{Deps, Uint128}; + +use crate::state::BALANCES; + +pub fn balance(deps: Deps, address: AndrAddr, asset: String) -> Result { + let addr = address.get_raw_address(&deps)?; + let balance = BALANCES + .load(deps.storage, (addr, asset)) + .unwrap_or_default(); + Ok(balance) +} diff --git a/andromeda-core/contracts/os/andromeda-economics/src/tests/mock_querier.rs b/andromeda-core/contracts/os/andromeda-economics/src/tests/mock_querier.rs index 650dbb0..b1dfe6f 100644 --- a/andromeda-core/contracts/os/andromeda-economics/src/tests/mock_querier.rs +++ b/andromeda-core/contracts/os/andromeda-economics/src/tests/mock_querier.rs @@ -44,11 +44,12 @@ pub fn mock_dependencies_custom( &mut deps.storage, mock_env(), &deps.api, + &deps.querier, mock_info("sender", &[]), InstantiateMsg { ado_type: "vault".to_string(), ado_version: "test".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, diff --git a/andromeda-core/contracts/os/andromeda-economics/src/tests/mod.rs b/andromeda-core/contracts/os/andromeda-economics/src/tests/mod.rs index 90da65d..1182365 100644 --- a/andromeda-core/contracts/os/andromeda-economics/src/tests/mod.rs +++ b/andromeda-core/contracts/os/andromeda-economics/src/tests/mod.rs @@ -1,14 +1,15 @@ use andromeda_std::amp::AndrAddr; use andromeda_std::error::ContractError; +use andromeda_std::testing::mock_querier::MOCK_ADO_PUBLISHER; #[cfg(test)] use andromeda_std::testing::mock_querier::{ mock_dependencies_custom, MOCK_ACTION, MOCK_KERNEL_CONTRACT, }; -use andromeda_std::testing::mock_querier::{MOCK_ADO_PUBLISHER, MOCK_APP_CONTRACT}; use cosmwasm_std::{coin, to_json_binary, Addr, BankMsg, CosmosMsg, Uint128}; use cw20::Cw20ReceiveMsg; -use crate::contract::{cw20_withdraw_msg, execute, instantiate, spend_balance}; +use crate::contract::{execute, instantiate}; +use crate::execute::{cw20_withdraw_msg, spend_balance}; use crate::state::BALANCES; use andromeda_std::os::economics::{Cw20HookMsg, ExecuteMsg, InstantiateMsg}; @@ -161,175 +162,178 @@ fn test_pay_fee() { assert_eq!(balance, Uint128::from(10u128)); } +// Temporarily disabled // Tests payment for fees via the contract balance -#[test] -fn test_pay_fee_contract() { - let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let info = mock_info("creator", &[]); - let payee = "payee"; - - let msg = ExecuteMsg::PayFee { - payee: Addr::unchecked(payee), - action: MOCK_ACTION.to_string(), - }; - - BALANCES - .save( - deps.as_mut().storage, - (info.sender.clone(), "uusd".to_string()), - &Uint128::from(10u128), - ) - .unwrap(); - - let res = execute(deps.as_mut(), env, info.clone(), msg); - assert!(res.is_ok()); - - let balance = BALANCES - .load(deps.as_ref().storage, (info.sender, "uusd".to_string())) - .unwrap(); - assert_eq!(balance, Uint128::from(0u128)); - - // Check publisher balance - let publisher = Addr::unchecked(MOCK_ADO_PUBLISHER); - let balance = BALANCES - .load(deps.as_ref().storage, (publisher, "uusd".to_string())) - .unwrap_or_default(); - assert_eq!(balance, Uint128::from(10u128)); -} - -#[test] -fn test_pay_fee_app() { - let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let info = mock_info("creator", &[]); - let payee = "payee"; - - let msg = ExecuteMsg::PayFee { - payee: Addr::unchecked(payee), - action: MOCK_ACTION.to_string(), - }; - - BALANCES - .save( - deps.as_mut().storage, - (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), - &Uint128::from(10u128), - ) - .unwrap(); - - let res = execute(deps.as_mut(), env, info.clone(), msg); - assert!(res.is_ok()); - - let balance = BALANCES - .load(deps.as_ref().storage, (info.sender, "uusd".to_string())) - .unwrap(); - assert_eq!(balance, Uint128::from(0u128)); - - // Check publisher balance - let publisher = Addr::unchecked(MOCK_ADO_PUBLISHER); - let balance = BALANCES - .load(deps.as_ref().storage, (publisher, "uusd".to_string())) - .unwrap_or_default(); - assert_eq!(balance, Uint128::from(10u128)); -} - +// #[test] +// fn test_pay_fee_contract() { +// let mut deps = mock_dependencies_custom(&[]); +// let env = mock_env(); +// let info = mock_info("creator", &[]); +// let payee = "payee"; + +// let msg = ExecuteMsg::PayFee { +// payee: Addr::unchecked(payee), +// action: MOCK_ACTION.to_string(), +// }; + +// BALANCES +// .save( +// deps.as_mut().storage, +// (info.sender.clone(), "uusd".to_string()), +// &Uint128::from(10u128), +// ) +// .unwrap(); + +// let res = execute(deps.as_mut(), env, info.clone(), msg); +// assert!(res.is_ok()); + +// let balance = BALANCES +// .load(deps.as_ref().storage, (info.sender, "uusd".to_string())) +// .unwrap(); +// assert_eq!(balance, Uint128::from(0u128)); + +// // Check publisher balance +// let publisher = Addr::unchecked(MOCK_ADO_PUBLISHER); +// let balance = BALANCES +// .load(deps.as_ref().storage, (publisher, "uusd".to_string())) +// .unwrap_or_default(); +// assert_eq!(balance, Uint128::from(10u128)); +// } + +// Temporarily disabled +// #[test] +// fn test_pay_fee_app() { +// let mut deps = mock_dependencies_custom(&[]); +// let env = mock_env(); +// let info = mock_info("creator", &[]); +// let payee = "payee"; + +// let msg = ExecuteMsg::PayFee { +// payee: Addr::unchecked(payee), +// action: MOCK_ACTION.to_string(), +// }; + +// BALANCES +// .save( +// deps.as_mut().storage, +// (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), +// &Uint128::from(10u128), +// ) +// .unwrap(); + +// let res = execute(deps.as_mut(), env, info.clone(), msg); +// assert!(res.is_ok()); + +// let balance = BALANCES +// .load(deps.as_ref().storage, (info.sender, "uusd".to_string())) +// .unwrap(); +// assert_eq!(balance, Uint128::from(0u128)); + +// // Check publisher balance +// let publisher = Addr::unchecked(MOCK_ADO_PUBLISHER); +// let balance = BALANCES +// .load(deps.as_ref().storage, (publisher, "uusd".to_string())) +// .unwrap_or_default(); +// assert_eq!(balance, Uint128::from(10u128)); +// } + +// Temporarily disabled // Tests payment of fees via fallthrough -#[test] -fn test_pay_fee_joint() { - let mut deps = mock_dependencies_custom(&[]); - let env = mock_env(); - let info = mock_info("creator", &[]); - let payee = "payee"; - - let msg = ExecuteMsg::PayFee { - payee: Addr::unchecked(payee), - action: MOCK_ACTION.to_string(), - }; - - // Contract balance - BALANCES - .save( - deps.as_mut().storage, - (info.sender.clone(), "uusd".to_string()), - &Uint128::from(4u128), - ) - .unwrap(); - // Payee balance - BALANCES - .save( - deps.as_mut().storage, - (Addr::unchecked(payee), "uusd".to_string()), - &Uint128::from(3u128), - ) - .unwrap(); - // App balance - BALANCES - .save( - deps.as_mut().storage, - (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), - &Uint128::from(3u128), - ) - .unwrap(); - - let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); - assert!(res.is_ok()); - - // Check contract balance - let balance = BALANCES - .load( - deps.as_ref().storage, - (info.sender.clone(), "uusd".to_string()), - ) - .unwrap(); - assert_eq!(balance, Uint128::from(0u128)); - - // Check payee balance - let balance = BALANCES - .load( - deps.as_ref().storage, - (Addr::unchecked(payee), "uusd".to_string()), - ) - .unwrap(); - assert_eq!(balance, Uint128::from(0u128)); - - // Check app balance - let balance = BALANCES - .load( - deps.as_ref().storage, - (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), - ) - .unwrap(); - assert_eq!(balance, Uint128::from(0u128)); - - // Check publisher balance - let publisher = Addr::unchecked(MOCK_ADO_PUBLISHER); - let balance = BALANCES - .load(deps.as_ref().storage, (publisher, "uusd".to_string())) - .unwrap_or_default(); - assert_eq!(balance, Uint128::from(10u128)); - - // Check insufficient funds - // Contract balance - BALANCES - .save( - deps.as_mut().storage, - (info.sender.clone(), "uusd".to_string()), - &Uint128::from(4u128), - ) - .unwrap(); - // App balance - BALANCES - .save( - deps.as_mut().storage, - (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), - &Uint128::from(3u128), - ) - .unwrap(); - - let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(res, ContractError::InsufficientFunds {}); -} +// #[test] +// fn test_pay_fee_joint() { +// let mut deps = mock_dependencies_custom(&[]); +// let env = mock_env(); +// let info = mock_info("creator", &[]); +// let payee = "payee"; + +// let msg = ExecuteMsg::PayFee { +// payee: Addr::unchecked(payee), +// action: MOCK_ACTION.to_string(), +// }; + +// // Contract balance +// BALANCES +// .save( +// deps.as_mut().storage, +// (info.sender.clone(), "uusd".to_string()), +// &Uint128::from(4u128), +// ) +// .unwrap(); +// // Payee balance +// BALANCES +// .save( +// deps.as_mut().storage, +// (Addr::unchecked(payee), "uusd".to_string()), +// &Uint128::from(3u128), +// ) +// .unwrap(); +// // App balance +// BALANCES +// .save( +// deps.as_mut().storage, +// (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), +// &Uint128::from(3u128), +// ) +// .unwrap(); + +// let res = execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()); +// assert!(res.is_ok()); + +// // Check contract balance +// let balance = BALANCES +// .load( +// deps.as_ref().storage, +// (info.sender.clone(), "uusd".to_string()), +// ) +// .unwrap(); +// assert_eq!(balance, Uint128::from(0u128)); + +// // Check payee balance +// let balance = BALANCES +// .load( +// deps.as_ref().storage, +// (Addr::unchecked(payee), "uusd".to_string()), +// ) +// .unwrap(); +// assert_eq!(balance, Uint128::from(0u128)); + +// // Check app balance +// let balance = BALANCES +// .load( +// deps.as_ref().storage, +// (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), +// ) +// .unwrap(); +// assert_eq!(balance, Uint128::from(0u128)); + +// // Check publisher balance +// let publisher = Addr::unchecked(MOCK_ADO_PUBLISHER); +// let balance = BALANCES +// .load(deps.as_ref().storage, (publisher, "uusd".to_string())) +// .unwrap_or_default(); +// assert_eq!(balance, Uint128::from(10u128)); + +// // Check insufficient funds +// // Contract balance +// BALANCES +// .save( +// deps.as_mut().storage, +// (info.sender.clone(), "uusd".to_string()), +// &Uint128::from(4u128), +// ) +// .unwrap(); +// // App balance +// BALANCES +// .save( +// deps.as_mut().storage, +// (Addr::unchecked(MOCK_APP_CONTRACT), "uusd".to_string()), +// &Uint128::from(3u128), +// ) +// .unwrap(); + +// let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); +// assert_eq!(res, ContractError::InsufficientFunds {}); +// } #[test] fn test_withdraw() { diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/.cargo/config b/andromeda-core/contracts/os/andromeda-ibc-registry/.cargo/config new file mode 100644 index 0000000..336b618 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --example schema" diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/Cargo.toml b/andromeda-core/contracts/os/andromeda-ibc-registry/Cargo.toml new file mode 100644 index 0000000..b6121fe --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "andromeda-ibc-registry" +version = "1.0.0" +edition = "2021" +rust-version = "1.75.0" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +testing = ["cw-multi-test"] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-storage-plus = { workspace = true } +cw-utils = { workspace = true } +cw20 = { workspace = true } + + +andromeda-std = { workspace = true, features = ["rates"] } +andromeda-data-storage = { workspace = true } + + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/examples/schema.rs b/andromeda-core/contracts/os/andromeda-ibc-registry/examples/schema.rs new file mode 100644 index 0000000..313a94b --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/examples/schema.rs @@ -0,0 +1,10 @@ +use andromeda_std::os::ibc_registry::{ExecuteMsg, InstantiateMsg, QueryMsg}; +use cosmwasm_schema::write_api; +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + + } +} diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/src/contract.rs b/andromeda-core/contracts/os/andromeda-ibc-registry/src/contract.rs new file mode 100644 index 0000000..18b50d8 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/src/contract.rs @@ -0,0 +1,194 @@ +use crate::state::REGISTRY; +use andromeda_std::ado_base::permissioning::{LocalPermission, Permission}; +use andromeda_std::common::actions::call_action; +use andromeda_std::os::ibc_registry::{ + verify_denom, AllDenomInfoResponse, DenomInfo, DenomInfoResponse, ExecuteMsg, IBCDenomInfo, + InstantiateMsg, QueryMsg, +}; +use andromeda_std::{ + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + ado_contract::ADOContract, + common::{context::ExecuteContext, encode_binary}, + error::ContractError, +}; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{ + attr, ensure, Binary, Deps, DepsMut, Env, MessageInfo, Order, Response, StdError, Storage, +}; +use cw_storage_plus::Bound; +use std::collections::HashSet; + +// version info for migration info +const CONTRACT_NAME: &str = "crates.io:andromeda-ibc-registry"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +const STORE_DENOM_INFO: &str = "StoreDenomInfo"; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let resp = ADOContract::default().instantiate( + deps.storage, + env, + deps.api, + &deps.querier, + info, + BaseInstantiateMsg { + ado_type: CONTRACT_NAME.to_string(), + ado_version: CONTRACT_VERSION.to_string(), + kernel_address: msg.kernel_address.into_string(), + owner: msg.owner, + }, + )?; + + // Save service address + let service_address = msg + .service_address + .get_raw_address(&deps.as_ref())? + .into_string(); + + ADOContract::default().permission_action(STORE_DENOM_INFO, deps.storage)?; + ADOContract::set_permission( + deps.storage, + STORE_DENOM_INFO, + service_address.clone(), + Permission::Local(LocalPermission::Whitelisted(None)), + )?; + + Ok(resp.add_attribute("service_address", service_address)) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let ctx = ExecuteContext::new(deps, info, env); + match msg { + ExecuteMsg::AMPReceive(pkt) => { + ADOContract::default().execute_amp_receive(ctx, pkt, handle_execute) + } + _ => handle_execute(ctx, msg), + } +} + +fn handle_execute(mut ctx: ExecuteContext, msg: ExecuteMsg) -> Result { + let action = msg.as_ref().to_string(); + + let action_response = call_action( + &mut ctx.deps, + &ctx.info, + &ctx.env, + &ctx.amp_ctx, + msg.as_ref(), + )?; + + let res = match msg { + ExecuteMsg::StoreDenomInfo { ibc_denom_info } => { + execute_store_denom_info(ctx, action, ibc_denom_info) + } + _ => ADOContract::default().execute(ctx, msg), + }?; + + Ok(res + .add_submessages(action_response.messages) + .add_attributes(action_response.attributes) + .add_events(action_response.events)) +} + +pub fn execute_store_denom_info( + mut ctx: ExecuteContext, + action: String, + ibc_denom_info: Vec, +) -> Result { + let sender = ctx.info.sender.clone(); + // Verify authority + ADOContract::default().is_permissioned_strict( + ctx.deps.branch(), + ctx.env.clone(), + action, + sender.clone(), + )?; + + // Vector can't be empty + ensure!( + !ibc_denom_info.is_empty(), + ContractError::NoDenomInfoProvided {} + ); + + let mut seen_denoms = HashSet::new(); // To track unique denoms + for info in ibc_denom_info { + let denom = info.denom.to_lowercase(); + verify_denom(&denom)?; + + // Check for duplicates + if !seen_denoms.insert(denom.clone()) { + return Err(ContractError::DuplicateDenoms { denom }); + } + + // Store the denom info + REGISTRY.save(ctx.deps.storage, denom, &info.denom_info)?; + } + + Ok(Response::new().add_attributes(vec![ + attr("action", "store_denom_info"), + attr("sender", sender), + ])) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::DenomInfo { denom } => encode_binary(&get_denom_info(deps.storage, denom)?), + QueryMsg::AllDenomInfo { limit, start_after } => { + encode_binary(&get_all_denom_info(deps.storage, limit, start_after)?) + } + } +} + +pub fn get_denom_info( + storage: &dyn Storage, + denom: String, +) -> Result { + let denom_info = REGISTRY.load(storage, denom)?; + Ok(DenomInfoResponse { denom_info }) +} + +pub fn get_all_denom_info( + storage: &dyn Storage, + limit: Option, + start_after: Option, +) -> Result { + // Convert `start_after` into a Bound if provided + let min = Some(Bound::inclusive(start_after.unwrap_or(0).to_string())); + + // Set the limit, defaulting to 100 if none is provided + let limit = limit.unwrap_or(100) as usize; + + // Query the registry with pagination + let denom_info_iter: Result, StdError> = REGISTRY + .range(storage, min, None, Order::Ascending) + .take(limit) + .collect(); + + // Collect the results into a vector of `DenomInfo` + let denom_info_list: Vec = denom_info_iter? + .into_iter() + .map(|(_, denom_info)| denom_info) + .collect(); + + Ok(AllDenomInfoResponse { + denom_info: denom_info_list, + }) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) +} diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/src/lib.rs b/andromeda-core/contracts/os/andromeda-ibc-registry/src/lib.rs new file mode 100644 index 0000000..bcbc58b --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/src/lib.rs @@ -0,0 +1,7 @@ +pub mod contract; +pub mod state; +#[cfg(test)] +pub mod testing; + +#[cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +pub mod mock; diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/src/mock.rs b/andromeda-core/contracts/os/andromeda-ibc-registry/src/mock.rs new file mode 100644 index 0000000..de333ec --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/src/mock.rs @@ -0,0 +1,27 @@ +#![cfg(all(not(target_arch = "wasm32"), feature = "testing"))] +use crate::contract::{execute, instantiate, query}; +use andromeda_std::amp::AndrAddr; +use andromeda_std::os::ibc_registry::{ExecuteMsg, IBCDenomInfo, InstantiateMsg}; +use cosmwasm_std::{Addr, Empty}; +use cw_multi_test::{Contract, ContractWrapper}; + +pub fn mock_andromeda_ibc_registry() -> Box> { + let contract = ContractWrapper::new_with_empty(execute, instantiate, query); + Box::new(contract) +} + +pub fn mock_ibc_registry_instantiate_msg( + kernel_address: Addr, + owner: Option, + service_address: AndrAddr, +) -> InstantiateMsg { + InstantiateMsg { + kernel_address, + owner, + service_address, + } +} + +pub fn mock_execute_store_denom_info_msg(ibc_denom_info: Vec) -> ExecuteMsg { + ExecuteMsg::StoreDenomInfo { ibc_denom_info } +} diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/src/state.rs b/andromeda-core/contracts/os/andromeda-ibc-registry/src/state.rs new file mode 100644 index 0000000..3dc70a3 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/src/state.rs @@ -0,0 +1,4 @@ +use andromeda_std::os::ibc_registry::DenomInfo; +use cw_storage_plus::Map; + +pub const REGISTRY: Map = Map::new("registry"); diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/mod.rs b/andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/mod.rs new file mode 100644 index 0000000..14f0038 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/mod.rs @@ -0,0 +1 @@ +mod tests; diff --git a/andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/tests.rs b/andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/tests.rs new file mode 100644 index 0000000..3b4c0e7 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-ibc-registry/src/testing/tests.rs @@ -0,0 +1,24 @@ +use andromeda_std::amp::AndrAddr; +use andromeda_std::os::ibc_registry::InstantiateMsg; +use andromeda_std::testing::mock_querier::MOCK_KERNEL_CONTRACT; +use cosmwasm_std::testing::mock_env; +use cosmwasm_std::testing::{mock_dependencies, mock_info}; +use cosmwasm_std::Addr; + +use crate::contract::instantiate; + +#[test] +fn proper_initialization() { + let mut deps = mock_dependencies(); + let info = mock_info("creator", &[]); + let msg = InstantiateMsg { + owner: None, + kernel_address: Addr::unchecked(MOCK_KERNEL_CONTRACT), + service_address: AndrAddr::from_string("service_address"), + }; + let env = mock_env(); + + let res = instantiate(deps.as_mut(), env, info, msg).unwrap(); + assert_eq!(0, res.messages.len()); +} +// The rest of the testing can be found in ibc registry's integration test diff --git a/andromeda-core/contracts/os/andromeda-kernel/Cargo.toml b/andromeda-core/contracts/os/andromeda-kernel/Cargo.toml index 2e27f1d..d84929c 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/Cargo.toml +++ b/andromeda-core/contracts/os/andromeda-kernel/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "andromeda-kernel" -version = "0.2.15" +version = "1.1.1" authors = ["Connor Barr "] edition = "2021" rust-version = "1.65.0" @@ -25,12 +25,10 @@ testing = ["cw-multi-test"] cosmwasm-std = { workspace = true, features = ["ibc3"] } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } -cw2 = { workspace = true } -semver = { workspace = true } -enum-repr = { workspace = true } + serde-json-wasm = "1.0.0" serde-cw-value = "0.7.0" -sha256 = "1.1.4" +sha256 = "=1.1.4" osmosis-std-derive = "0.15.3" osmosis-std = "0.1.4" prost = { version = "0.11.2", default-features = false, features = [ @@ -49,4 +47,4 @@ andromeda-std = { workspace = true } cw-multi-test = { workspace = true, optional = true } [dev-dependencies] -# andromeda-testing = { version = "0.1.0", path = "../../../packages/andromeda-testing" } +# andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/os/andromeda-kernel/README.md b/andromeda-core/contracts/os/andromeda-kernel/README.md index a883785..21fa95b 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/README.md +++ b/andromeda-core/contracts/os/andromeda-kernel/README.md @@ -1,3 +1,10 @@ -# Andromeda Factory +# Overview +The Andromeda Kernel acts as the core of the operating system. It receives and handles packets from ADOs to be relayed to a specified recipient. The Kernel keeps track of the original sender of the message. It also verifies that the packet is sent by an Andromeda certified ADO before relaying the message. +The Kernel is also responsible for: -A repository containing the NFT contract for Andromeda Protocol on Terra. This contract's primary purpose is to initialise and register ADO collections. Registration is done by a mapping between the ADO collection's symbol and the contract address for the given ADO collection. Documentation can be found [here](https://app.gitbook.com/@andromedaprotocol/s/andromeda/contracts/andromeda-factory). +- Relaying any IBC messages across any two chains that have an Andromeda Kernel deployed and a channel set up. +- Keeping track of the other AMP ADOs such as the ADODB, VFS, and Economics. + +All of our ADOs have an AMPReceive execute message to handle receiving packets from the Kernel. + +[Kernel Full Documentation](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/kernel) \ No newline at end of file diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/andromeda-kernel.json b/andromeda-core/contracts/os/andromeda-kernel/schema/andromeda-kernel.json deleted file mode 100644 index 70eaa00..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/andromeda-kernel.json +++ /dev/null @@ -1,647 +0,0 @@ -{ - "contract_name": "andromeda-kernel", - "contract_version": "0.2.15", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "chain_name" - ], - "properties": { - "chain_name": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Receives an AMP Packet for relaying", - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "description": "Constructs an AMPPkt with a given AMPMsg and sends it to the recipient", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "message" - ], - "properties": { - "message": { - "$ref": "#/definitions/AMPMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Upserts a key address to the kernel, restricted to the owner of the kernel", - "type": "object", - "required": [ - "upsert_key_address" - ], - "properties": { - "upsert_key_address": { - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "type": "string" - }, - "value": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Creates an ADO with the given type and message", - "type": "object", - "required": [ - "create" - ], - "properties": { - "create": { - "type": "object", - "required": [ - "ado_type", - "msg" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "chain": { - "type": [ - "string", - "null" - ] - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Assigns a given channel to the given chain", - "type": "object", - "required": [ - "assign_channels" - ], - "properties": { - "assign_channels": { - "type": "object", - "required": [ - "chain", - "kernel_address" - ], - "properties": { - "chain": { - "type": "string" - }, - "direct_channel_id": { - "type": [ - "string", - "null" - ] - }, - "ics20_channel_id": { - "type": [ - "string", - "null" - ] - }, - "kernel_address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Recovers funds from failed IBC messages", - "type": "object", - "required": [ - "recover" - ], - "properties": { - "recover": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "internal" - ], - "properties": { - "internal": { - "$ref": "#/definitions/InternalMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "InternalMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "register_user_cross_chain" - ], - "properties": { - "register_user_cross_chain": { - "type": "object", - "required": [ - "address", - "chain", - "username" - ], - "properties": { - "address": { - "type": "string" - }, - "chain": { - "type": "string" - }, - "username": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "key_address" - ], - "properties": { - "key_address": { - "type": "object", - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "verify_address" - ], - "properties": { - "verify_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "channel_info" - ], - "properties": { - "channel_info": { - "type": "object", - "required": [ - "chain" - ], - "properties": { - "chain": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "recoveries" - ], - "properties": { - "recoveries": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "channel_info": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ChannelInfoResponse", - "anyOf": [ - { - "$ref": "#/definitions/ChannelInfoResponse" - }, - { - "type": "null" - } - ], - "definitions": { - "ChannelInfoResponse": { - "type": "object", - "required": [ - "kernel_address", - "supported_modules" - ], - "properties": { - "direct": { - "type": [ - "string", - "null" - ] - }, - "ics20": { - "type": [ - "string", - "null" - ] - }, - "kernel_address": { - "type": "string" - }, - "supported_modules": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - } - }, - "key_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Addr", - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "recoveries": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_Coin", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } - }, - "verify_address": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VerifyAddressResponse", - "type": "object", - "required": [ - "verify_address" - ], - "properties": { - "verify_address": { - "type": "boolean" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/execute.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/execute.json deleted file mode 100644 index 56ffdfd..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/execute.json +++ /dev/null @@ -1,428 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "description": "Receives an AMP Packet for relaying", - "type": "object", - "required": [ - "amp_receive" - ], - "properties": { - "amp_receive": { - "$ref": "#/definitions/AMPPkt" - } - }, - "additionalProperties": false - }, - { - "description": "Constructs an AMPPkt with a given AMPMsg and sends it to the recipient", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "message" - ], - "properties": { - "message": { - "$ref": "#/definitions/AMPMsg" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Upserts a key address to the kernel, restricted to the owner of the kernel", - "type": "object", - "required": [ - "upsert_key_address" - ], - "properties": { - "upsert_key_address": { - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "type": "string" - }, - "value": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Creates an ADO with the given type and message", - "type": "object", - "required": [ - "create" - ], - "properties": { - "create": { - "type": "object", - "required": [ - "ado_type", - "msg" - ], - "properties": { - "ado_type": { - "type": "string" - }, - "chain": { - "type": [ - "string", - "null" - ] - }, - "msg": { - "$ref": "#/definitions/Binary" - }, - "owner": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Assigns a given channel to the given chain", - "type": "object", - "required": [ - "assign_channels" - ], - "properties": { - "assign_channels": { - "type": "object", - "required": [ - "chain", - "kernel_address" - ], - "properties": { - "chain": { - "type": "string" - }, - "direct_channel_id": { - "type": [ - "string", - "null" - ] - }, - "ics20_channel_id": { - "type": [ - "string", - "null" - ] - }, - "kernel_address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "description": "Recovers funds from failed IBC messages", - "type": "object", - "required": [ - "recover" - ], - "properties": { - "recover": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "internal" - ], - "properties": { - "internal": { - "$ref": "#/definitions/InternalMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "AMPCtx": { - "type": "object", - "required": [ - "id", - "origin", - "previous_sender" - ], - "properties": { - "id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "origin": { - "type": "string" - }, - "origin_username": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "previous_sender": { - "type": "string" - } - }, - "additionalProperties": false - }, - "AMPMsg": { - "description": "This struct defines how the kernel parses and relays messages between ADOs If the desired recipient is via IBC then namespacing must be employed The attached message must be a binary encoded execute message for the receiving ADO Funds can be attached for an individual message and will be attached accordingly", - "type": "object", - "required": [ - "config", - "funds", - "message", - "recipient" - ], - "properties": { - "config": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/AMPMsgConfig" - } - ] - }, - "funds": { - "description": "Any funds to be attached to the message, defaults to an empty vector", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "message": { - "description": "The message to be sent to the recipient", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "recipient": { - "description": "The message recipient, can be a contract/wallet address or a namespaced URI", - "allOf": [ - { - "$ref": "#/definitions/AndrAddr" - } - ] - } - }, - "additionalProperties": false - }, - "AMPMsgConfig": { - "description": "The configuration of the message to be sent.\n\nUsed when a sub message is generated for the given AMP Msg (only used in the case of Wasm Messages).", - "type": "object", - "required": [ - "direct", - "exit_at_error", - "reply_on" - ], - "properties": { - "direct": { - "description": "Whether to send the message directly to the given recipient", - "type": "boolean" - }, - "exit_at_error": { - "description": "Determines whether the operation should terminate or proceed upon a failed message", - "type": "boolean" - }, - "gas_limit": { - "description": "An optional imposed gas limit for the message", - "type": [ - "integer", - "null" - ], - "format": "uint64", - "minimum": 0.0 - }, - "ibc_config": { - "anyOf": [ - { - "$ref": "#/definitions/IBCConfig" - }, - { - "type": "null" - } - ] - }, - "reply_on": { - "description": "When the message should reply, defaults to Always", - "allOf": [ - { - "$ref": "#/definitions/ReplyOn" - } - ] - } - }, - "additionalProperties": false - }, - "AMPPkt": { - "description": "An Andromeda packet contains all message protocol related data, this is what is sent between ADOs when communicating It contains an original sender, if used for authorisation the sender must be authorised The previous sender is the one who sent the message A packet may contain several messages which allows for message batching", - "type": "object", - "required": [ - "ctx", - "messages" - ], - "properties": { - "ctx": { - "$ref": "#/definitions/AMPCtx" - }, - "messages": { - "description": "Any messages associated with the packet", - "type": "array", - "items": { - "$ref": "#/definitions/AMPMsg" - } - } - }, - "additionalProperties": false - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "IBCConfig": { - "type": "object", - "properties": { - "recovery_addr": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - "InternalMsg": { - "oneOf": [ - { - "type": "object", - "required": [ - "register_user_cross_chain" - ], - "properties": { - "register_user_cross_chain": { - "type": "object", - "required": [ - "address", - "chain", - "username" - ], - "properties": { - "address": { - "type": "string" - }, - "chain": { - "type": "string" - }, - "username": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ] - }, - "ReplyOn": { - "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", - "oneOf": [ - { - "description": "Always perform a callback after SubMsg is processed", - "type": "string", - "enum": [ - "always" - ] - }, - { - "description": "Only callback if SubMsg returned an error, no callback on success case", - "type": "string", - "enum": [ - "error" - ] - }, - { - "description": "Only callback if SubMsg was successful, no callback on error case", - "type": "string", - "enum": [ - "success" - ] - }, - { - "description": "Never make a callback - this is like the original CosmosMsg semantics", - "type": "string", - "enum": [ - "never" - ] - } - ] - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/instantiate.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/instantiate.json deleted file mode 100644 index f2c2374..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/instantiate.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "chain_name" - ], - "properties": { - "chain_name": { - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/query.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/query.json deleted file mode 100644 index 5a748d9..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/query.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "key_address" - ], - "properties": { - "key_address": { - "type": "object", - "required": [ - "key" - ], - "properties": { - "key": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "verify_address" - ], - "properties": { - "verify_address": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "channel_info" - ], - "properties": { - "channel_info": { - "type": "object", - "required": [ - "chain" - ], - "properties": { - "chain": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "recoveries" - ], - "properties": { - "recoveries": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_channel_info.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_channel_info.json deleted file mode 100644 index 5f9f39d..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_channel_info.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_ChannelInfoResponse", - "anyOf": [ - { - "$ref": "#/definitions/ChannelInfoResponse" - }, - { - "type": "null" - } - ], - "definitions": { - "ChannelInfoResponse": { - "type": "object", - "required": [ - "kernel_address", - "supported_modules" - ], - "properties": { - "direct": { - "type": [ - "string", - "null" - ] - }, - "ics20": { - "type": [ - "string", - "null" - ] - }, - "kernel_address": { - "type": "string" - }, - "supported_modules": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_key_address.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_key_address.json deleted file mode 100644 index 4c7f193..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_key_address.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Addr", - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_recoveries.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_recoveries.json deleted file mode 100644 index 222bbbf..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_recoveries.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_Coin", - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - }, - "definitions": { - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_verify_address.json b/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_verify_address.json deleted file mode 100644 index 2c5028a..0000000 --- a/andromeda-core/contracts/os/andromeda-kernel/schema/raw/response_to_verify_address.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "VerifyAddressResponse", - "type": "object", - "required": [ - "verify_address" - ], - "properties": { - "verify_address": { - "type": "boolean" - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/ack.rs b/andromeda-core/contracts/os/andromeda-kernel/src/ack.rs index 3919c6f..eb6e593 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/ack.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/ack.rs @@ -19,7 +19,7 @@ pub fn make_ack_fail(err: String) -> Binary { to_json_binary(&res).unwrap() } -pub fn make_ack_create_ado_success() -> Binary { - let res = Ack::Result(b"1".into()); - to_json_binary(&res).unwrap() -} +// pub fn make_ack_create_ado_success() -> Binary { +// let res = Ack::Result(b"1".into()); +// to_json_binary(&res).unwrap() +// } diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/contract.rs b/andromeda-core/contracts/os/andromeda-kernel/src/contract.rs index 0a7a0db..6e40835 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/contract.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/contract.rs @@ -1,19 +1,17 @@ -use andromeda_std::ado_base::InstantiateMsg as BaseInstantiateMsg; +use andromeda_std::ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}; use andromeda_std::ado_contract::ADOContract; - use andromeda_std::common::context::ExecuteContext; use andromeda_std::common::encode_binary; +use andromeda_std::common::reply::ReplyId; use andromeda_std::error::ContractError; -use andromeda_std::os::kernel::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use andromeda_std::os::kernel::{ExecuteMsg, InstantiateMsg, QueryMsg}; use cosmwasm_std::{ - ensure, entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, + entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, }; -use cw2::{get_contract_version, set_contract_version}; -use semver::Version; use crate::ibc::{IBCLifecycleComplete, SudoMsg}; -use crate::reply::{on_reply_create_ado, on_reply_ibc_hooks_packet_send, ReplyId}; +use crate::reply::{on_reply_create_ado, on_reply_ibc_hooks_packet_send}; use crate::state::CURR_CHAIN; use crate::{execute, query, sudo}; @@ -28,19 +26,17 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - CURR_CHAIN.save(deps.storage, &msg.chain_name)?; ADOContract::default().instantiate( deps.storage, env.clone(), deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "kernel".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: env.contract.address.to_string(), owner: msg.owner, }, @@ -108,7 +104,17 @@ pub fn execute( kernel_address, ), ExecuteMsg::Recover {} => execute::recover(execute_env), + ExecuteMsg::UpdateChainName { chain_name } => { + execute::update_chain_name(execute_env, chain_name) + } ExecuteMsg::Internal(msg) => execute::internal(execute_env, msg), + // Base message + ExecuteMsg::Ownership(ownership_message) => ADOContract::default().execute_ownership( + execute_env.deps, + execute_env.env, + execute_env.info, + ownership_message, + ), } } @@ -129,40 +135,7 @@ pub fn sudo(deps: DepsMut, _env: Env, msg: SudoMsg) -> Result Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) -} - -fn from_semver(err: semver::Error) -> StdError { - StdError::generic_err(format!("Semver: {err}")) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -174,5 +147,10 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result encode_binary(&query::channel_info(deps, chain)?), QueryMsg::Recoveries { addr } => encode_binary(&query::recoveries(deps, addr)?), + QueryMsg::ChainName {} => encode_binary(&query::chain_name(deps)?), + // Base queries + QueryMsg::Version {} => encode_binary(&ADOContract::default().query_version(deps)?), + QueryMsg::Type {} => encode_binary(&ADOContract::default().query_type(deps)?), + QueryMsg::Owner {} => encode_binary(&ADOContract::default().query_contract_owner(deps)?), } } diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/execute.rs b/andromeda-core/contracts/os/andromeda-kernel/src/execute.rs index 5b2df67..dab0d56 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/execute.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/execute.rs @@ -1,35 +1,34 @@ use andromeda_std::ado_contract::ADOContract; use andromeda_std::amp::addresses::AndrAddr; -use andromeda_std::amp::messages::{AMPMsg, AMPPkt, IBCConfig}; +use andromeda_std::amp::messages::{AMPCtx, AMPMsg, AMPPkt, IBCConfig}; use andromeda_std::amp::{ADO_DB_KEY, VFS_KEY}; use andromeda_std::common::context::ExecuteContext; +use andromeda_std::common::has_coins_merged; +use andromeda_std::common::reply::ReplyId; use andromeda_std::error::ContractError; use andromeda_std::os::aos_querier::AOSQuerier; use andromeda_std::os::kernel::{ChannelInfo, IbcExecuteMsg, InternalMsg}; use andromeda_std::os::vfs::vfs_resolve_symlink; use cosmwasm_std::{ - attr, ensure, to_json_binary, Addr, BankMsg, Binary, CosmosMsg, DepsMut, Env, IbcMsg, - MessageInfo, Response, StdError, SubMsg, WasmMsg, + attr, ensure, to_json_binary, Addr, BankMsg, Binary, Coin, ContractInfoResponse, CosmosMsg, + DepsMut, Env, IbcMsg, MessageInfo, Response, StdError, SubMsg, WasmMsg, }; use crate::ibc::{generate_transfer_message, PACKET_LIFETIME}; +use crate::query; use crate::state::{ - IBCHooksPacketSendState, ADO_OWNER, CHAIN_TO_CHANNEL, CHANNEL_TO_CHAIN, IBC_FUND_RECOVERY, - KERNEL_ADDRESSES, OUTGOING_IBC_HOOKS_PACKETS, + IBCHooksPacketSendState, ADO_OWNER, CHAIN_TO_CHANNEL, CHANNEL_TO_CHAIN, CURR_CHAIN, + IBC_FUND_RECOVERY, KERNEL_ADDRESSES, OUTGOING_IBC_HOOKS_PACKETS, }; -use crate::{query, reply::ReplyId}; - -pub fn send(execute_env: ExecuteContext, message: AMPMsg) -> Result { - let res = MsgHandler::new(message).handle( - execute_env.deps, - execute_env.info, - execute_env.env, - execute_env.amp_ctx, - 0, - )?; +pub fn send(ctx: ExecuteContext, message: AMPMsg) -> Result { + ensure!( + has_coins_merged(ctx.info.funds.as_slice(), message.funds.as_slice()), + ContractError::InsufficientFunds {} + ); + let res = MsgHandler(message).handle(ctx.deps, ctx.info, ctx.env, ctx.amp_ctx, 0)?; Ok(res) } @@ -39,9 +38,9 @@ pub fn amp_receive( env: Env, packet: AMPPkt, ) -> Result { + // Only verified ADOs can access this function ensure!( - query::verify_address(deps.as_ref(), info.sender.to_string(),)?.verify_address - || packet.ctx.get_origin() == info.sender, + query::verify_address(deps.as_ref(), info.sender.to_string(),)?.verify_address, ContractError::Unauthorized {} ); ensure!( @@ -73,29 +72,39 @@ pub fn amp_receive( res.events.extend_from_slice(&msg_res.events); } + let message_funds = packet + .messages + .iter() + .flat_map(|m| m.funds.clone()) + .collect::>(); + ensure!( + has_coins_merged(info.funds.as_slice(), message_funds.as_slice()), + ContractError::InsufficientFunds {} + ); + Ok(res.add_attribute("action", "handle_amp_packet")) } pub fn upsert_key_address( - execute_env: ExecuteContext, + execute_ctx: ExecuteContext, key: String, value: String, ) -> Result { let contract = ADOContract::default(); ensure!( - contract.is_contract_owner(execute_env.deps.storage, execute_env.info.sender.as_str())?, + contract.is_contract_owner(execute_ctx.deps.storage, execute_ctx.info.sender.as_str())?, ContractError::Unauthorized {} ); // Updates to new value - if KERNEL_ADDRESSES.has(execute_env.deps.storage, &key) { - KERNEL_ADDRESSES.remove(execute_env.deps.storage, &key) + if KERNEL_ADDRESSES.has(execute_ctx.deps.storage, &key) { + KERNEL_ADDRESSES.remove(execute_ctx.deps.storage, &key) } KERNEL_ADDRESSES.save( - execute_env.deps.storage, + execute_ctx.deps.storage, &key, - &execute_env.deps.api.addr_validate(&value)?, + &execute_ctx.deps.api.addr_validate(&value)?, )?; Ok(Response::default().add_attributes(vec![ @@ -106,7 +115,7 @@ pub fn upsert_key_address( } pub fn create( - execute_env: ExecuteContext, + execute_ctx: ExecuteContext, ado_type: String, msg: Binary, owner: Option, @@ -117,50 +126,51 @@ pub fn create( chain.is_none() || owner.is_some(), ContractError::Unauthorized {} ); - if let Some(chain) = chain { - let channel_info = if let Some(channel_info) = - CHAIN_TO_CHANNEL.may_load(execute_env.deps.storage, &chain)? - { - Ok::(channel_info) - } else { - return Err(ContractError::InvalidPacket { - error: Some(format!("Channel not found for chain {chain}")), - }); - }?; - let kernel_msg = IbcExecuteMsg::CreateADO { - instantiation_msg: msg.clone(), - owner: owner.clone().unwrap(), - ado_type: ado_type.clone(), - }; - let ibc_msg = IbcMsg::SendPacket { - channel_id: channel_info.direct_channel_id.clone().unwrap(), - data: to_json_binary(&kernel_msg)?, - timeout: execute_env - .env - .block - .time - .plus_seconds(PACKET_LIFETIME) - .into(), - }; - Ok(Response::default() - .add_message(ibc_msg) - .add_attributes(vec![ - attr("action", "execute_create"), - attr("ado_type", ado_type), - attr("owner", owner.unwrap().to_string()), - attr("chain", chain), - attr("receiving_kernel_address", channel_info.kernel_address), - attr("msg", msg.to_string()), - ])) + if let Some(_chain) = chain { + Err(ContractError::CrossChainComponentsCurrentlyDisabled {}) + // let channel_info = if let Some(channel_info) = + // CHAIN_TO_CHANNEL.may_load(execute_ctx.deps.storage, &chain)? + // { + // Ok::(channel_info) + // } else { + // return Err(ContractError::InvalidPacket { + // error: Some(format!("Channel not found for chain {chain}")), + // }); + // }?; + // let kernel_msg = IbcExecuteMsg::CreateADO { + // instantiation_msg: msg.clone(), + // owner: owner.clone().unwrap(), + // ado_type: ado_type.clone(), + // }; + // let ibc_msg = IbcMsg::SendPacket { + // channel_id: channel_info.direct_channel_id.clone().unwrap(), + // data: to_json_binary(&kernel_msg)?, + // timeout: execute_ctx + // .env + // .block + // .time + // .plus_seconds(PACKET_LIFETIME) + // .into(), + // }; + // Ok(Response::default() + // .add_message(ibc_msg) + // .add_attributes(vec![ + // attr("action", "execute_create"), + // attr("ado_type", ado_type), + // attr("owner", owner.unwrap().to_string()), + // attr("chain", chain), + // attr("receiving_kernel_address", channel_info.kernel_address), + // attr("msg", msg.to_string()), + // ])) } else { - let vfs_addr = KERNEL_ADDRESSES.load(execute_env.deps.storage, VFS_KEY)?; - let adodb_addr = KERNEL_ADDRESSES.load(execute_env.deps.storage, ADO_DB_KEY)?; + let vfs_addr = KERNEL_ADDRESSES.load(execute_ctx.deps.storage, VFS_KEY)?; + let adodb_addr = KERNEL_ADDRESSES.load(execute_ctx.deps.storage, ADO_DB_KEY)?; - let ado_owner = owner.unwrap_or(AndrAddr::from_string(execute_env.info.sender.to_string())); + let ado_owner = owner.unwrap_or(AndrAddr::from_string(execute_ctx.info.sender.to_string())); let owner_addr = - ado_owner.get_raw_address_from_vfs(&execute_env.deps.as_ref(), vfs_addr)?; + ado_owner.get_raw_address_from_vfs(&execute_ctx.deps.as_ref(), vfs_addr)?; let code_id = - AOSQuerier::code_id_getter(&execute_env.deps.querier, &adodb_addr, &ado_type)?; + AOSQuerier::code_id_getter(&execute_ctx.deps.querier, &adodb_addr, &ado_type)?; let wasm_msg = WasmMsg::Instantiate { admin: Some(owner_addr.to_string()), code_id, @@ -170,13 +180,7 @@ pub fn create( }; let sub_msg = SubMsg::reply_always(wasm_msg, ReplyId::CreateADO.repr()); - // TODO: Is this check necessary? - // ensure!( - // !ADO_OWNER.exists(execute_env.deps.storage), - // ContractError::Unauthorized {} - // ); - - ADO_OWNER.save(execute_env.deps.storage, &owner_addr)?; + ADO_OWNER.save(execute_ctx.deps.storage, &owner_addr)?; Ok(Response::new() .add_submessage(sub_msg) @@ -186,29 +190,29 @@ pub fn create( } } -pub fn internal(env: ExecuteContext, msg: InternalMsg) -> Result { +pub fn internal(ctx: ExecuteContext, msg: InternalMsg) -> Result { match msg { InternalMsg::RegisterUserCrossChain { username, address, chain, - } => register_user_cross_chain(env, chain, username, address), + } => register_user_cross_chain(ctx, chain, username, address), } } pub fn register_user_cross_chain( - execute_env: ExecuteContext, + execute_ctx: ExecuteContext, chain: String, username: String, address: String, ) -> Result { - let vfs = KERNEL_ADDRESSES.load(execute_env.deps.storage, VFS_KEY)?; + let vfs = KERNEL_ADDRESSES.load(execute_ctx.deps.storage, VFS_KEY)?; ensure!( - execute_env.info.sender == vfs, + execute_ctx.info.sender == vfs, ContractError::Unauthorized {} ); let channel_info = - if let Some(channel_info) = CHAIN_TO_CHANNEL.may_load(execute_env.deps.storage, &chain)? { + if let Some(channel_info) = CHAIN_TO_CHANNEL.may_load(execute_ctx.deps.storage, &chain)? { Ok::(channel_info) } else { return Err(ContractError::InvalidPacket { @@ -219,10 +223,17 @@ pub fn register_user_cross_chain( username: username.clone(), address: address.clone(), }; + let channel_id = if let Some(direct_channel_id) = channel_info.direct_channel_id { + Ok::(direct_channel_id) + } else { + return Err(ContractError::InvalidPacket { + error: Some(format!("Channel not found for chain {chain}")), + }); + }?; let ibc_msg = IbcMsg::SendPacket { - channel_id: channel_info.direct_channel_id.clone().unwrap(), + channel_id, data: to_json_binary(&kernel_msg)?, - timeout: execute_env + timeout: execute_ctx .env .block .time @@ -242,7 +253,7 @@ pub fn register_user_cross_chain( } pub fn assign_channels( - execute_env: ExecuteContext, + execute_ctx: ExecuteContext, ics20_channel_id: Option, direct_channel_id: Option, chain: String, @@ -250,23 +261,31 @@ pub fn assign_channels( ) -> Result { let contract = ADOContract::default(); ensure!( - contract.is_contract_owner(execute_env.deps.storage, execute_env.info.sender.as_str())?, + contract.is_contract_owner(execute_ctx.deps.storage, execute_ctx.info.sender.as_str())?, ContractError::Unauthorized {} ); - let channel_info = ChannelInfo { - ics20_channel_id, - direct_channel_id, - kernel_address, - supported_modules: vec![], - }; - CHAIN_TO_CHANNEL.save(execute_env.deps.storage, &chain, &channel_info)?; - if let Some(channel) = channel_info.direct_channel_id.clone() { - CHANNEL_TO_CHAIN.save(execute_env.deps.storage, &channel, &chain)?; + let mut channel_info = CHAIN_TO_CHANNEL + .load(execute_ctx.deps.storage, &chain) + .unwrap_or_default(); + channel_info.kernel_address = kernel_address; + if let Some(channel) = direct_channel_id { + // Remove old direct channel to chain if it exists + if let Some(direct_channel_id) = channel_info.direct_channel_id { + CHANNEL_TO_CHAIN.remove(execute_ctx.deps.storage, &direct_channel_id); + } + CHANNEL_TO_CHAIN.save(execute_ctx.deps.storage, &channel, &chain)?; + channel_info.direct_channel_id = Some(channel); } - if let Some(channel) = channel_info.ics20_channel_id.clone() { - CHANNEL_TO_CHAIN.save(execute_env.deps.storage, &channel, &chain)?; + if let Some(channel) = ics20_channel_id { + // Remove old ics20 channel to chain if it exists + if let Some(ics20_channel_id) = channel_info.ics20_channel_id { + CHANNEL_TO_CHAIN.remove(execute_ctx.deps.storage, &ics20_channel_id); + } + CHANNEL_TO_CHAIN.save(execute_ctx.deps.storage, &channel, &chain)?; + channel_info.ics20_channel_id = Some(channel); } + CHAIN_TO_CHANNEL.save(execute_ctx.deps.storage, &chain, &channel_info)?; Ok(Response::default().add_attributes(vec![ attr("action", "assign_channel"), @@ -283,18 +302,18 @@ pub fn assign_channels( ])) } -pub fn recover(execute_env: ExecuteContext) -> Result { +pub fn recover(execute_ctx: ExecuteContext) -> Result { let recoveries = IBC_FUND_RECOVERY - .load(execute_env.deps.storage, &execute_env.info.sender) + .load(execute_ctx.deps.storage, &execute_ctx.info.sender) .unwrap_or_default(); - IBC_FUND_RECOVERY.remove(execute_env.deps.storage, &execute_env.info.sender); + IBC_FUND_RECOVERY.remove(execute_ctx.deps.storage, &execute_ctx.info.sender); ensure!( !recoveries.is_empty(), ContractError::Std(StdError::generic_err("No recoveries found")) ); let bank_msg = BankMsg::Send { - to_address: execute_env.info.sender.to_string(), + to_address: execute_ctx.info.sender.to_string(), amount: recoveries, }; let sub_msg = SubMsg::reply_always(bank_msg, ReplyId::Recovery.repr()); @@ -304,11 +323,31 @@ pub fn recover(execute_env: ExecuteContext) -> Result { .add_submessage(sub_msg)) } +pub fn update_chain_name( + execute_ctx: ExecuteContext, + chain_name: String, +) -> Result { + // Only owner can update CURR_CHAIN + let contract = ADOContract::default(); + ensure!( + contract.is_contract_owner(execute_ctx.deps.storage, execute_ctx.info.sender.as_str())?, + ContractError::Unauthorized {} + ); + + // Update CURR_CHAIN + CURR_CHAIN.save(execute_ctx.deps.storage, &chain_name)?; + + Ok(Response::default() + .add_attribute("action", "update_chain_name") + .add_attribute("sender", execute_ctx.info.sender.as_str()) + .add_attribute("chain_name", chain_name)) +} + /// Handles a given AMP message and returns a response /// /// Separated due to common functionality across multiple messages #[derive(Clone)] -struct MsgHandler(AMPMsg); +pub struct MsgHandler(AMPMsg); impl MsgHandler { pub fn new(msg: AMPMsg) -> Self { @@ -348,7 +387,7 @@ impl MsgHandler { match protocol { Some("ibc") => self.handle_ibc(deps, info, env, ctx, sequence), - _ => self.handle_local(deps, info, env, ctx, sequence), + _ => self.handle_local(deps, info, env, ctx.map(|ctx| ctx.ctx), sequence), } } @@ -359,12 +398,12 @@ impl MsgHandler { In both situations the sender can define the funds that are being attached to the message. */ - fn handle_local( + pub fn handle_local( &self, deps: DepsMut, info: MessageInfo, _env: Env, - ctx: Option, + ctx: Option, sequence: u64, ) -> Result { let mut res = Response::default(); @@ -372,10 +411,13 @@ impl MsgHandler { message, recipient, funds, + config, .. } = self.message(); let recipient_addr = recipient.get_raw_address(&deps.as_ref())?; + let adodb_addr = KERNEL_ADDRESSES.load(deps.storage, ADO_DB_KEY)?; + // A default message is a bank message if Binary::default() == message.clone() { ensure!( @@ -390,36 +432,57 @@ impl MsgHandler { amount: funds.clone(), }; + let mut attrs = vec![]; + for (idx, fund) in funds.iter().enumerate() { + attrs.push(attr(format!("funds:{sequence}:{idx}"), fund.to_string())); + } + attrs.push(attr(format!("recipient:{sequence}"), recipient_addr)); res = res .add_submessage(SubMsg::reply_on_error( CosmosMsg::Bank(sub_msg), ReplyId::AMPMsg.repr(), )) - .add_attributes(vec![ - attr(format!("recipient:{sequence}"), recipient_addr), - attr(format!("bank_send_amount:{sequence}"), funds[0].to_string()), - ]); + .add_attributes(attrs); } else { let origin = if let Some(amp_ctx) = ctx { - amp_ctx.ctx.get_origin() + amp_ctx.get_origin() } else { info.sender.to_string() }; let previous_sender = info.sender.to_string(); - let amp_msg = AMPMsg::new( - recipient_addr.clone(), - message.clone(), - Some(vec![funds[0].clone()]), - ); + // Ensure recipient is a smart contract + let ContractInfoResponse { + code_id: recipient_code_id, + .. + } = deps + .querier + .query_wasm_contract_info(recipient_addr.clone()) + .ok() + .ok_or(ContractError::InvalidPacket { + error: Some("Recipient is not a contract".to_string()), + })?; + + let sub_msg = if config.direct + || AOSQuerier::ado_type_getter(&deps.querier, &adodb_addr, recipient_code_id)? + .is_none() + { + // Message is direct (no AMP Ctx) + self.message() + .generate_sub_msg_direct(recipient_addr.clone(), ReplyId::AMPMsg.repr()) + } else { + let amp_msg = + AMPMsg::new(recipient_addr.clone(), message.clone(), Some(funds.clone())); + + let new_packet = AMPPkt::new(origin, previous_sender, vec![amp_msg]); - let new_packet = AMPPkt::new(origin, previous_sender, vec![amp_msg]); + new_packet.to_sub_msg( + recipient_addr.clone(), + Some(funds.clone()), + ReplyId::AMPMsg.repr(), + )? + }; - let sub_msg = new_packet.to_sub_msg( - recipient_addr.clone(), - Some(vec![funds[0].clone()]), - ReplyId::AMPMsg.repr(), - )?; res = res .add_submessage(sub_msg) .add_attributes(vec![attr(format!("recipient:{sequence}"), recipient_addr)]); @@ -475,7 +538,7 @@ impl MsgHandler { recipient, message, .. } = self.message(); ensure!( - Binary::default().eq(message), + !Binary::default().eq(message), ContractError::InvalidPacket { error: Some("Cannot send an empty message without funds via IBC".to_string()) } diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/ibc.rs b/andromeda-core/contracts/os/andromeda-kernel/src/ibc.rs index 4906f48..ffc3119 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/ibc.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/ibc.rs @@ -1,10 +1,10 @@ -use crate::ack::{make_ack_create_ado_success, make_ack_fail, make_ack_success}; +use crate::ack::{make_ack_fail, make_ack_success}; use crate::execute; use crate::proto::{DenomTrace, MsgTransfer, QueryDenomTraceRequest}; -use crate::reply::ReplyId; use crate::state::{CHANNEL_TO_CHAIN, KERNEL_ADDRESSES}; use andromeda_std::amp::VFS_KEY; use andromeda_std::common::context::ExecuteContext; +use andromeda_std::common::reply::ReplyId; use andromeda_std::error::{ContractError, Never}; use andromeda_std::{ amp::{messages::AMPMsg, AndrAddr}, @@ -164,28 +164,29 @@ pub fn do_ibc_packet_receive( } pub fn ibc_create_ado( - execute_env: ExecuteContext, - owner: AndrAddr, - ado_type: String, - msg: Binary, + _execute_ctx: ExecuteContext, + _owner: AndrAddr, + _ado_type: String, + _msg: Binary, ) -> Result { - let res = execute::create(execute_env, ado_type, msg, Some(owner), None)?; - Ok(IbcReceiveResponse::new() - .add_attributes(res.attributes) - .add_events(res.events) - .add_submessages(res.messages) - .set_ack(make_ack_create_ado_success())) + Err(ContractError::CrossChainComponentsCurrentlyDisabled {}) + // let res = execute::create(execute_env, ado_type, msg, Some(owner), None)?; + // Ok(IbcReceiveResponse::new() + // .add_attributes(res.attributes) + // .add_events(res.events) + // .add_submessages(res.messages) + // .set_ack(make_ack_create_ado_success())) } pub fn ibc_register_username( - execute_env: ExecuteContext, + execute_ctx: ExecuteContext, username: String, addr: String, ) -> Result { - let vfs_address = KERNEL_ADDRESSES.load(execute_env.deps.storage, VFS_KEY)?; + let vfs_address = KERNEL_ADDRESSES.load(execute_ctx.deps.storage, VFS_KEY)?; let msg = VFSExecuteMsg::RegisterUser { username, - address: Some(execute_env.deps.api.addr_validate(&addr)?), + address: Some(execute_ctx.deps.api.addr_validate(&addr)?), }; let sub_msg: SubMsg = SubMsg::reply_on_error( WasmMsg::Execute { diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/query.rs b/andromeda-core/contracts/os/andromeda-kernel/src/query.rs index f5de758..ebfc0fa 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/query.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/query.rs @@ -3,12 +3,12 @@ use andromeda_std::{ error::ContractError, os::{ aos_querier::AOSQuerier, - kernel::{ChannelInfoResponse, VerifyAddressResponse}, + kernel::{ChainNameResponse, ChannelInfoResponse, VerifyAddressResponse}, }, }; use cosmwasm_std::{Addr, Coin, Deps}; -use crate::state::{CHAIN_TO_CHANNEL, IBC_FUND_RECOVERY, KERNEL_ADDRESSES}; +use crate::state::{CHAIN_TO_CHANNEL, CURR_CHAIN, IBC_FUND_RECOVERY, KERNEL_ADDRESSES}; pub fn key_address(deps: Deps, key: String) -> Result { Ok(KERNEL_ADDRESSES.load(deps.storage, &key)?) @@ -19,7 +19,9 @@ pub fn verify_address(deps: Deps, address: String) -> Result Result, ContractError> { .may_load(deps.storage, &addr)? .unwrap_or_default()) } + +pub fn chain_name(deps: Deps) -> Result { + Ok(ChainNameResponse { + chain_name: CURR_CHAIN.may_load(deps.storage)?.unwrap_or_default(), + }) +} diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/reply.rs b/andromeda-core/contracts/os/andromeda-kernel/src/reply.rs index 2a95648..9ee8a81 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/reply.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/reply.rs @@ -6,24 +6,16 @@ use crate::{ }, }; use andromeda_std::{ - ado_base::AndromedaMsg, common::response::get_reply_address, error::ContractError, + ado_base::{ownership::OwnershipMessage, AndromedaMsg}, + common::reply::ReplyId, + common::response::get_reply_address, + error::ContractError, os::aos_querier::AOSQuerier, }; use cosmwasm_std::{ ensure, wasm_execute, Addr, DepsMut, Empty, Env, Reply, Response, SubMsg, SubMsgResponse, SubMsgResult, }; -use enum_repr::EnumRepr; - -#[EnumRepr(type = "u64")] -pub enum ReplyId { - AMPMsg = 1, - CreateADO = 2, - UpdateOwnership = 3, - IBCHooksPacketSend = 4, - Recovery = 5, - RegisterUsername = 6, -} /// Handles the reply from an ADO creation /// @@ -36,9 +28,10 @@ pub fn on_reply_create_ado(deps: DepsMut, env: Env, msg: Reply) -> Result = SubMsg::reply_on_success(wasm_msg, ReplyId::UpdateOwnership as u64); @@ -58,7 +51,9 @@ pub fn on_reply_ibc_hooks_packet_send( msg: Reply, ) -> Result { let SubMsgResult::Ok(SubMsgResponse { data: Some(b), .. }) = msg.result else { - return Err(ContractError::InvalidPacket { error: Some(format!("ibc hooks: failed reply: {:?}", msg.result)) }) + return Err(ContractError::InvalidPacket { + error: Some(format!("ibc hooks: failed reply: {:?}", msg.result)), + }); }; let MsgTransferResponse { sequence } = diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/sudo.rs b/andromeda-core/contracts/os/andromeda-kernel/src/sudo.rs index b3215e1..ea13864 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/sudo.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/sudo.rs @@ -24,7 +24,7 @@ pub mod ibc_lifecycle { OUTGOING_IBC_PACKETS.may_load(deps.storage, (&source_channel, sequence))?; let Some(inflight_packet) = sent_packet else { // If there isn't, continue - return Ok(response.add_attribute("msg", "received unexpected ack")) + return Ok(response.add_attribute("msg", "received unexpected ack")); }; OUTGOING_IBC_PACKETS.remove(deps.storage, (&source_channel, sequence)); @@ -61,7 +61,7 @@ pub mod ibc_lifecycle { OUTGOING_IBC_PACKETS.may_load(deps.storage, (&source_channel, sequence))?; let Some(inflight_packet) = sent_packet else { // If there isn't, continue - return Ok(response.add_attribute("msg", "received unexpected timeout")) + return Ok(response.add_attribute("msg", "received unexpected timeout")); }; // Remove the in-flight packet OUTGOING_IBC_PACKETS.remove(deps.storage, (&source_channel, sequence)); diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/testing/mod.rs b/andromeda-core/contracts/os/andromeda-kernel/src/testing/mod.rs index 14f0038..f3b9df6 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/testing/mod.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/testing/mod.rs @@ -1 +1,2 @@ +mod test_handler; mod tests; diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/testing/test_handler.rs b/andromeda-core/contracts/os/andromeda-kernel/src/testing/test_handler.rs new file mode 100644 index 0000000..3b1f421 --- /dev/null +++ b/andromeda-core/contracts/os/andromeda-kernel/src/testing/test_handler.rs @@ -0,0 +1,229 @@ +use crate::{execute::MsgHandler, state::KERNEL_ADDRESSES}; +use andromeda_std::{ + amp::{ + messages::{AMPCtx, AMPMsg, AMPPkt}, + ADO_DB_KEY, + }, + common::reply::ReplyId, + error::ContractError, + testing::mock_querier::{ + mock_dependencies_custom, FAKE_VFS_PATH, INVALID_CONTRACT, MOCK_ADODB_CONTRACT, + MOCK_APP_CONTRACT, MOCK_WALLET, + }, +}; +use cosmwasm_std::{ + coin, + testing::{mock_env, mock_info}, + to_json_binary, Addr, BankMsg, Binary, SubMsg, +}; + +struct TestHandleLocalCase { + name: &'static str, + sender: &'static str, + msg: AMPMsg, + ctx: Option, + expected_submessage: SubMsg, + expected_error: Option, +} + +#[test] +fn test_handle_local() { + let test_cases = vec![ + TestHandleLocalCase { + name: "Valid message to ADO (no funds/context)", + sender: "sender", + msg: AMPMsg::new(MOCK_APP_CONTRACT, to_json_binary(&true).unwrap(), None), + ctx: None, + expected_submessage: AMPPkt::new( + "sender", + "sender", + vec![AMPMsg::new( + MOCK_APP_CONTRACT, + to_json_binary(&true).unwrap(), + None, + )], + ) + .to_sub_msg(MOCK_APP_CONTRACT, None, ReplyId::AMPMsg.repr()) + .unwrap(), + expected_error: None, + }, + TestHandleLocalCase { + name: "Valid message to ADO (no funds)", + sender: "sender", + msg: AMPMsg::new(MOCK_APP_CONTRACT, to_json_binary(&true).unwrap(), None), + ctx: Some(AMPCtx::new("origin", MOCK_APP_CONTRACT, 1, None)), + expected_submessage: AMPPkt::new( + "origin", + "sender", + vec![AMPMsg::new( + MOCK_APP_CONTRACT, + to_json_binary(&true).unwrap(), + None, + )], + ) + .to_sub_msg(MOCK_APP_CONTRACT, None, ReplyId::AMPMsg.repr()) + .unwrap(), + expected_error: None, + }, + TestHandleLocalCase { + name: "Valid message to ADO w/ funds", + sender: "sender", + msg: AMPMsg::new( + MOCK_APP_CONTRACT, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ), + ctx: Some(AMPCtx::new("origin", MOCK_APP_CONTRACT, 1, None)), + expected_submessage: AMPPkt::new( + "origin", + "sender", + vec![AMPMsg::new( + MOCK_APP_CONTRACT, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + )], + ) + .to_sub_msg( + MOCK_APP_CONTRACT, + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ReplyId::AMPMsg.repr(), + ) + .unwrap(), + expected_error: None, + }, + TestHandleLocalCase { + name: "Valid message direct to Non-ADO (no funds)", + sender: "sender", + msg: AMPMsg::new(INVALID_CONTRACT, to_json_binary(&true).unwrap(), None), + ctx: None, + expected_submessage: AMPMsg::new( + INVALID_CONTRACT, + to_json_binary(&true).unwrap(), + None, + ) + .generate_sub_msg_direct(Addr::unchecked(INVALID_CONTRACT), ReplyId::AMPMsg.repr()), + expected_error: None, + }, + TestHandleLocalCase { + name: "Valid message direct to Non-ADO w/ funds", + sender: "sender", + msg: AMPMsg::new( + INVALID_CONTRACT, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ), + ctx: None, + expected_submessage: AMPMsg::new( + INVALID_CONTRACT, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ) + .generate_sub_msg_direct(Addr::unchecked(INVALID_CONTRACT), ReplyId::AMPMsg.repr()), + expected_error: None, + }, + TestHandleLocalCase { + name: "Recipient not a contract", + sender: "sender", + msg: AMPMsg::new( + MOCK_WALLET, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ), + ctx: None, + expected_submessage: AMPMsg::new( + INVALID_CONTRACT, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ) + .generate_sub_msg_direct(Addr::unchecked(INVALID_CONTRACT), ReplyId::AMPMsg.repr()), + expected_error: Some(ContractError::InvalidPacket { + error: Some("Recipient is not a contract".to_string()), + }), + }, + TestHandleLocalCase { + name: "Invalid Recipient Path", + sender: "sender", + msg: AMPMsg::new( + FAKE_VFS_PATH, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ), + ctx: None, + expected_submessage: AMPMsg::new( + FAKE_VFS_PATH, + to_json_binary(&true).unwrap(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ) + .generate_sub_msg_direct(Addr::unchecked(INVALID_CONTRACT), ReplyId::AMPMsg.repr()), + expected_error: Some(ContractError::InvalidPathname { + error: Some(format!( + "{:?} does not exist in the file system", + FAKE_VFS_PATH + )), + }), + }, + TestHandleLocalCase { + name: "Valid bank send message", + sender: "sender", + msg: AMPMsg::new( + "receiver", + Binary::default(), + Some(vec![coin(100, "denom"), coin(200, "denom_two")]), + ), + ctx: None, + expected_submessage: SubMsg::reply_on_error( + BankMsg::Send { + to_address: "receiver".to_string(), + amount: vec![coin(100, "denom"), coin(200, "denom_two")], + }, + ReplyId::AMPMsg.repr(), + ), + expected_error: None, + }, + TestHandleLocalCase { + name: "Bank send no funds", + sender: "sender", + msg: AMPMsg::new("receiver", Binary::default(), None), + ctx: None, + expected_submessage: SubMsg::reply_on_error( + BankMsg::Send { + to_address: "receiver".to_string(), + amount: vec![], + }, + ReplyId::AMPMsg.repr(), + ), + expected_error: Some(ContractError::InvalidPacket { + error: Some("No message or funds supplied".to_string()), + }), + }, + ]; + + for test in test_cases { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info(test.sender, &[]); + + KERNEL_ADDRESSES + .save( + deps.as_mut().storage, + ADO_DB_KEY, + &Addr::unchecked(MOCK_ADODB_CONTRACT), + ) + .unwrap(); + + let res = + MsgHandler::new(test.msg).handle_local(deps.as_mut(), info, mock_env(), test.ctx, 0); + + if let Some(err) = test.expected_error { + assert_eq!(res.unwrap_err(), err, "{}", test.name); + continue; + } + + let response = res.unwrap(); + + assert_eq!( + response.messages[0], test.expected_submessage, + "{}", + test.name + ); + } +} diff --git a/andromeda-core/contracts/os/andromeda-kernel/src/testing/tests.rs b/andromeda-core/contracts/os/andromeda-kernel/src/testing/tests.rs index 46314d2..fdeda9a 100644 --- a/andromeda-core/contracts/os/andromeda-kernel/src/testing/tests.rs +++ b/andromeda-core/contracts/os/andromeda-kernel/src/testing/tests.rs @@ -1,14 +1,18 @@ use crate::{ contract::{execute, instantiate}, ibc::PACKET_LIFETIME, - state::{ADO_OWNER, CHAIN_TO_CHANNEL, KERNEL_ADDRESSES}, + state::{ADO_OWNER, CHAIN_TO_CHANNEL, CHANNEL_TO_CHAIN, CURR_CHAIN, KERNEL_ADDRESSES}, }; use andromeda_std::{ - amp::{ADO_DB_KEY, VFS_KEY}, + amp::{ + messages::{AMPMsg, AMPPkt}, + ADO_DB_KEY, VFS_KEY, + }, error::ContractError, os::kernel::{ChannelInfo, ExecuteMsg, IbcExecuteMsg, InstantiateMsg, InternalMsg}, testing::mock_querier::{ - mock_dependencies_custom, MOCK_ADODB_CONTRACT, MOCK_FAKE_KERNEL_CONTRACT, MOCK_VFS_CONTRACT, + mock_dependencies_custom, MOCK_ADODB_CONTRACT, MOCK_FAKE_KERNEL_CONTRACT, + MOCK_KERNEL_CONTRACT, MOCK_VFS_CONTRACT, }, }; use cosmwasm_std::{ @@ -30,6 +34,42 @@ fn proper_initialization() { assert_eq!(0, res.messages.len()); } +#[test] +fn test_update_chain_name() { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("creator", &[]); + let env = mock_env(); + instantiate( + deps.as_mut(), + env.clone(), + info.clone(), + InstantiateMsg { + owner: None, + chain_name: "test".to_string(), + }, + ) + .unwrap(); + + let chain_name = "other".to_string(); + let update_chain_name_msg = ExecuteMsg::UpdateChainName { + chain_name: chain_name.clone(), + }; + + let fake_info = mock_info("fake", &[]); + + let err = execute( + deps.as_mut(), + env.clone(), + fake_info, + update_chain_name_msg.clone(), + ) + .unwrap_err(); + assert_eq!(err, ContractError::Unauthorized {}); + + execute(deps.as_mut(), env, info, update_chain_name_msg).unwrap(); + assert_eq!(CURR_CHAIN.load(deps.as_ref().storage).unwrap(), chain_name); +} + #[test] fn test_create_ado() { let mut deps = mock_dependencies_custom(&[]); @@ -128,3 +168,225 @@ fn test_register_user_cross_chain() { assert_eq!(res.messages.first().unwrap().msg, CosmosMsg::Ibc(expected)); } + +#[test] +fn test_assign_channels() { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("creator", &[]); + let env = mock_env(); + let chain = "chain"; + instantiate( + deps.as_mut(), + env.clone(), + info.clone(), + InstantiateMsg { + owner: None, + chain_name: "andromeda".to_string(), + }, + ) + .unwrap(); + + let channel_info = ChannelInfo { + kernel_address: MOCK_FAKE_KERNEL_CONTRACT.to_string(), + ics20_channel_id: Some("1".to_string()), + direct_channel_id: Some("2".to_string()), + supported_modules: vec![], + }; + let msg = ExecuteMsg::AssignChannels { + ics20_channel_id: channel_info.ics20_channel_id.clone(), + direct_channel_id: channel_info.direct_channel_id.clone(), + chain: chain.to_string(), + kernel_address: channel_info.kernel_address, + }; + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + let msg = ExecuteMsg::AssignChannels { + ics20_channel_id: None, + direct_channel_id: Some("3".to_string()), + chain: chain.to_string(), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + }; + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + let channel_info = CHAIN_TO_CHANNEL.load(deps.as_ref().storage, chain).unwrap(); + assert_eq!( + channel_info.direct_channel_id.clone().unwrap(), + "3".to_string() + ); + assert_eq!( + channel_info.ics20_channel_id.clone().unwrap(), + "1".to_string() + ); + assert_eq!( + channel_info.kernel_address, + MOCK_KERNEL_CONTRACT.to_string() + ); + + let ics20_channel_chain = CHANNEL_TO_CHAIN + .load( + deps.as_ref().storage, + &channel_info.ics20_channel_id.unwrap(), + ) + .unwrap(); + assert_eq!(ics20_channel_chain, chain.to_string()); + let direct_channel_chain = CHANNEL_TO_CHAIN + .load( + deps.as_ref().storage, + &channel_info.direct_channel_id.unwrap(), + ) + .unwrap(); + assert_eq!(direct_channel_chain, chain.to_string()); + + // Check that old direct channel was removed + let direct_channel_chain = CHANNEL_TO_CHAIN + .may_load(deps.as_ref().storage, "2") + .unwrap(); + assert!(direct_channel_chain.is_none()); + + let msg = ExecuteMsg::AssignChannels { + ics20_channel_id: Some("10".to_string()), + direct_channel_id: None, + chain: chain.to_string(), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + }; + execute(deps.as_mut(), env, info, msg).unwrap(); + + // The previous ics20 channel was "1" + let previous_ics20_channel_chain = CHANNEL_TO_CHAIN + .may_load(deps.as_ref().storage, "1") + .unwrap(); + assert!(previous_ics20_channel_chain.is_none()); + + let ics20_channel_chain = CHANNEL_TO_CHAIN + .may_load(deps.as_ref().storage, "10") + .unwrap(); + assert_eq!(ics20_channel_chain.unwrap(), chain.to_string()); +} + +#[test] +fn test_assign_channels_unauthorized() { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("creator", &[]); + let env = mock_env(); + let chain = "chain"; + instantiate( + deps.as_mut(), + env.clone(), + info, + InstantiateMsg { + owner: None, + chain_name: "andromeda".to_string(), + }, + ) + .unwrap(); + + let unauth_info = mock_info("attacker", &[]); + let msg = ExecuteMsg::AssignChannels { + ics20_channel_id: None, + direct_channel_id: Some("3".to_string()), + chain: chain.to_string(), + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), + }; + let err = execute(deps.as_mut(), env, unauth_info, msg).unwrap_err(); + assert_eq!(err, ContractError::Unauthorized {}); +} + +#[test] +fn test_send_cross_chain_no_channel() { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info(MOCK_VFS_CONTRACT, &[]); + let env = mock_env(); + instantiate( + deps.as_mut(), + env.clone(), + info.clone(), + InstantiateMsg { + owner: None, + chain_name: "andromeda".to_string(), + }, + ) + .unwrap(); + KERNEL_ADDRESSES + .save( + deps.as_mut().storage, + VFS_KEY, + &Addr::unchecked(MOCK_VFS_CONTRACT), + ) + .unwrap(); + let msg = ExecuteMsg::AssignChannels { + ics20_channel_id: None, + direct_channel_id: None, + chain: "chain2".to_string(), + kernel_address: Addr::unchecked("kernal2").to_string(), + }; + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + let internal_msg = InternalMsg::RegisterUserCrossChain { + username: "name".to_string(), + address: Addr::unchecked("addr").to_string(), + chain: "chain2".to_string(), + }; + let msg = ExecuteMsg::Internal(internal_msg); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidPacket { + error: Some("Channel not found for chain chain2".to_string()) + } + ); +} + +// Test provided by Quantstamp as part of audit +#[test] +fn test_handle_ibc_direct() { + let mut deps = mock_dependencies_custom(&[]); + let info = mock_info("user", &[]); + let env = mock_env(); + let chain = "andromeda"; + instantiate( + deps.as_mut(), + env.clone(), + info.clone(), + InstantiateMsg { + owner: None, + chain_name: "andromeda".to_string(), + }, + ) + .unwrap(); + // Test would fail without this because we need to check the adodb + let assign_key_msg = ExecuteMsg::UpsertKeyAddress { + key: ADO_DB_KEY.to_string(), + value: MOCK_ADODB_CONTRACT.to_string(), + }; + execute(deps.as_mut(), env.clone(), info.clone(), assign_key_msg).unwrap(); + + let channel_info = ChannelInfo { + kernel_address: MOCK_FAKE_KERNEL_CONTRACT.to_string(), + ics20_channel_id: Some("1".to_string()), + direct_channel_id: Some("2".to_string()), + supported_modules: vec![], + }; + KERNEL_ADDRESSES + .save( + deps.as_mut().storage, + VFS_KEY, + &Addr::unchecked(MOCK_VFS_CONTRACT), + ) + .unwrap(); + CHAIN_TO_CHANNEL + .save(deps.as_mut().storage, chain, &channel_info) + .unwrap(); + let dummy_msg = ExecuteMsg::UpsertKeyAddress { + key: "key".to_string(), + value: "value".to_string(), + }; + let amp_msg = AMPMsg::new( + "ibc://andromeda/..", + to_json_binary(&dummy_msg).unwrap(), + None, + ); + let packet = AMPPkt::new("user", "user", vec![amp_msg]); + let msg = ExecuteMsg::AMPReceive(packet); + let res = execute(deps.as_mut(), env, info, msg); + // * message fails even though it is a non-default binary message + assert!(res.is_ok()); +} diff --git a/andromeda-core/contracts/os/andromeda-vfs/Cargo.toml b/andromeda-core/contracts/os/andromeda-vfs/Cargo.toml index 112edf1..9d3e284 100644 --- a/andromeda-core/contracts/os/andromeda-vfs/Cargo.toml +++ b/andromeda-core/contracts/os/andromeda-vfs/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "andromeda-vfs" -version = "0.2.2" +version = "1.1.1" authors = ["Connor Barr "] edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" exclude = [ # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. @@ -26,13 +26,11 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } serde = { version = "1.0.127", default-features = false, features = ["derive"] } -cw2 = { workspace = true } -semver = { workspace = true } -andromeda-std = { workspace = true, features = ["modules"] } +andromeda-std = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true, optional = true } # [dev-dependencies] -# andromeda-testing = { version = "0.1.0", path = "../../../packages/andromeda-testing" } +# andromeda-testing = { workspace = true, optional = true } diff --git a/andromeda-core/contracts/os/andromeda-vfs/README.md b/andromeda-core/contracts/os/andromeda-vfs/README.md index a883785..d15eeee 100644 --- a/andromeda-core/contracts/os/andromeda-vfs/README.md +++ b/andromeda-core/contracts/os/andromeda-vfs/README.md @@ -1,3 +1,6 @@ -# Andromeda Factory +# Overview -A repository containing the NFT contract for Andromeda Protocol on Terra. This contract's primary purpose is to initialise and register ADO collections. Registration is done by a mapping between the ADO collection's symbol and the contract address for the given ADO collection. Documentation can be found [here](https://app.gitbook.com/@andromedaprotocol/s/andromeda/contracts/andromeda-factory). +The Virtual File System (VFS) is a part of the Andromeda Messaging System (AMP) which was heavily inspired by the linux file system. Users can register their address to a username. They can also register ADOs to paths. These paths can then be used and referenced in our ADO systems. +When an Andromeda App is made, it will register all paths for its child components and also register itself as a child of the instantiating address. Each component under the App is registered by its name, and the App itself is registered under its assigned name. + +[VFS Full Documentation](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/andromeda-messaging-protocol/virtual-file-system) \ No newline at end of file diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/andromeda-vfs.json b/andromeda-core/contracts/os/andromeda-vfs/schema/andromeda-vfs.json deleted file mode 100644 index 2590329..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/andromeda-vfs.json +++ /dev/null @@ -1,424 +0,0 @@ -{ - "contract_name": "andromeda-vfs", - "contract_version": "0.2.2", - "idl_version": "1.0.0", - "instantiate": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "description": "Address of the Kernel contract on chain", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "execute": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "add_path" - ], - "properties": { - "add_path": { - "type": "object", - "required": [ - "address", - "name" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - }, - "name": { - "type": "string" - }, - "parent_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "add_symlink" - ], - "properties": { - "add_symlink": { - "type": "object", - "required": [ - "name", - "symlink" - ], - "properties": { - "name": { - "type": "string" - }, - "parent_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "add_parent_path" - ], - "properties": { - "add_parent_path": { - "type": "object", - "required": [ - "name", - "parent_address" - ], - "properties": { - "name": { - "type": "string" - }, - "parent_address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_user" - ], - "properties": { - "register_user": { - "type": "object", - "required": [ - "username" - ], - "properties": { - "address": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - }, - "username": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_library" - ], - "properties": { - "register_library": { - "type": "object", - "required": [ - "lib_address", - "lib_name" - ], - "properties": { - "lib_address": { - "$ref": "#/definitions/Addr" - }, - "lib_name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_user_cross_chain" - ], - "properties": { - "register_user_cross_chain": { - "type": "object", - "required": [ - "address", - "chain" - ], - "properties": { - "address": { - "type": "string" - }, - "chain": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "query": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "resolve_path" - ], - "properties": { - "resolve_path": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "sub_dir" - ], - "properties": { - "sub_dir": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "paths" - ], - "properties": { - "paths": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_username" - ], - "properties": { - "get_username": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_library" - ], - "properties": { - "get_library": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "resolve_symlink" - ], - "properties": { - "resolve_symlink": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } - }, - "migrate": null, - "sudo": null, - "responses": { - "get_library": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "String", - "type": "string" - }, - "get_username": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "String", - "type": "string" - }, - "paths": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } - }, - "resolve_path": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Addr", - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "resolve_symlink": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndrAddr", - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - }, - "sub_dir": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PathDetails", - "type": "array", - "items": { - "$ref": "#/definitions/PathDetails" - }, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "PathDetails": { - "type": "object", - "required": [ - "address", - "name" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - } - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/execute.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/execute.json deleted file mode 100644 index 805bc74..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/execute.json +++ /dev/null @@ -1,192 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "ExecuteMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "add_path" - ], - "properties": { - "add_path": { - "type": "object", - "required": [ - "address", - "name" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - }, - "name": { - "type": "string" - }, - "parent_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "add_symlink" - ], - "properties": { - "add_symlink": { - "type": "object", - "required": [ - "name", - "symlink" - ], - "properties": { - "name": { - "type": "string" - }, - "parent_address": { - "anyOf": [ - { - "$ref": "#/definitions/AndrAddr" - }, - { - "type": "null" - } - ] - }, - "symlink": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "add_parent_path" - ], - "properties": { - "add_parent_path": { - "type": "object", - "required": [ - "name", - "parent_address" - ], - "properties": { - "name": { - "type": "string" - }, - "parent_address": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_user" - ], - "properties": { - "register_user": { - "type": "object", - "required": [ - "username" - ], - "properties": { - "address": { - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - }, - "username": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_library" - ], - "properties": { - "register_library": { - "type": "object", - "required": [ - "lib_address", - "lib_name" - ], - "properties": { - "lib_address": { - "$ref": "#/definitions/Addr" - }, - "lib_name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "register_user_cross_chain" - ], - "properties": { - "register_user_cross_chain": { - "type": "object", - "required": [ - "address", - "chain" - ], - "properties": { - "address": { - "type": "string" - }, - "chain": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/instantiate.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/instantiate.json deleted file mode 100644 index 4ac8dac..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/instantiate.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "InstantiateMsg", - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "description": "Address of the Kernel contract on chain", - "type": "string" - }, - "owner": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/query.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/query.json deleted file mode 100644 index 03495c3..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/query.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "resolve_path" - ], - "properties": { - "resolve_path": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "sub_dir" - ], - "properties": { - "sub_dir": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "paths" - ], - "properties": { - "paths": { - "type": "object", - "required": [ - "addr" - ], - "properties": { - "addr": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_username" - ], - "properties": { - "get_username": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "get_library" - ], - "properties": { - "get_library": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "resolve_symlink" - ], - "properties": { - "resolve_symlink": { - "type": "object", - "required": [ - "path" - ], - "properties": { - "path": { - "$ref": "#/definitions/AndrAddr" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "AndrAddr": { - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_andr_query.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_andr_query.json deleted file mode 100644 index 6068330..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_andr_query.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndromedaQuery", - "oneOf": [ - { - "type": "object", - "required": [ - "get" - ], - "properties": { - "get": { - "anyOf": [ - { - "$ref": "#/definitions/Binary" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "owner" - ], - "properties": { - "owner": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "operators" - ], - "properties": { - "operators": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "kernel_address" - ], - "properties": { - "kernel_address": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "original_publisher" - ], - "properties": { - "original_publisher": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "block_height_upon_creation" - ], - "properties": { - "block_height_upon_creation": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "is_operator" - ], - "properties": { - "is_operator": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module" - ], - "properties": { - "module": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "$ref": "#/definitions/Uint64" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "module_ids" - ], - "properties": { - "module_ids": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - } - ], - "definitions": { - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_library.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_library.json deleted file mode 100644 index f689ace..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_library.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "String", - "type": "string" -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_username.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_username.json deleted file mode 100644 index f689ace..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_get_username.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "String", - "type": "string" -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_key_address.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_key_address.json deleted file mode 100644 index 4c7f193..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_key_address.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Addr", - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_paths.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_paths.json deleted file mode 100644 index 4290cb1..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_paths.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_String", - "type": "array", - "items": { - "type": "string" - } -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_path.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_path.json deleted file mode 100644 index 4c7f193..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_path.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Addr", - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_symlink.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_symlink.json deleted file mode 100644 index 4c67205..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_resolve_symlink.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AndrAddr", - "description": "An address that can be used within the Andromeda ecosystem. Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33\n\nThis address can be one of two things: 1. A valid human readable address e.g. `cosmos1...` 2. A valid Andromeda VFS path e.g. `/home/user/app/component`\n\nVFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so:\n\n`:///` or `ibc://cosmoshub-4/user/app/component`", - "type": "string" -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_sub_dir.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_sub_dir.json deleted file mode 100644 index e793cc4..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_sub_dir.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Array_of_PathDetails", - "type": "array", - "items": { - "$ref": "#/definitions/PathDetails" - }, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "PathDetails": { - "type": "object", - "required": [ - "address", - "name" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_verify_address.json b/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_verify_address.json deleted file mode 100644 index a7fe2bf..0000000 --- a/andromeda-core/contracts/os/andromeda-vfs/schema/raw/response_to_verify_address.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Boolean", - "type": "boolean" -} diff --git a/andromeda-core/contracts/os/andromeda-vfs/src/contract.rs b/andromeda-core/contracts/os/andromeda-vfs/src/contract.rs index ad2a47c..61a7fd8 100644 --- a/andromeda-core/contracts/os/andromeda-vfs/src/contract.rs +++ b/andromeda-core/contracts/os/andromeda-vfs/src/contract.rs @@ -1,14 +1,13 @@ use andromeda_std::ado_contract::ADOContract; - -use andromeda_std::os::vfs::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +use andromeda_std::os::vfs::{ExecuteMsg, InstantiateMsg, QueryMsg}; use andromeda_std::{ - ado_base::InstantiateMsg as BaseInstantiateMsg, common::encode_binary, error::ContractError, + ado_base::{InstantiateMsg as BaseInstantiateMsg, MigrateMsg}, + common::encode_binary, + error::ContractError, }; use cosmwasm_std::{ - ensure, entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, + entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdError, }; -use cw2::{get_contract_version, set_contract_version}; -use semver::Version; use crate::{execute, query}; @@ -23,16 +22,15 @@ pub fn instantiate( info: MessageInfo, msg: InstantiateMsg, ) -> Result { - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; ADOContract::default().instantiate( deps.storage, env, deps.api, + &deps.querier, info, BaseInstantiateMsg { - ado_type: "vfs".to_string(), + ado_type: CONTRACT_NAME.to_string(), ado_version: CONTRACT_VERSION.to_string(), - operators: None, kernel_address: msg.kernel_address, owner: msg.owner, }, @@ -73,10 +71,10 @@ pub fn execute( ExecuteMsg::RegisterUser { username, address } => { execute::register_user(execute_env, username, address) } - ExecuteMsg::AddParentPath { + ExecuteMsg::AddChild { name, parent_address, - } => execute::add_parent_path(execute_env, name, parent_address), + } => execute::add_child(execute_env, name, parent_address), ExecuteMsg::RegisterLibrary { lib_name, lib_address, @@ -84,55 +82,41 @@ pub fn execute( ExecuteMsg::RegisterUserCrossChain { chain, address } => { execute::register_user_cross_chain(execute_env, chain, address) } + // Base message + ExecuteMsg::Ownership(ownership_message) => ADOContract::default().execute_ownership( + execute_env.deps, + execute_env.env, + execute_env.info, + ownership_message, + ), } } #[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { - // New version - let version: Version = CONTRACT_VERSION.parse().map_err(from_semver)?; - - // Old version - let stored = get_contract_version(deps.storage)?; - let storage_version: Version = stored.version.parse().map_err(from_semver)?; - - let contract = ADOContract::default(); - - ensure!( - stored.contract == CONTRACT_NAME, - ContractError::CannotMigrate { - previous_contract: stored.contract, - } - ); - - // New version has to be newer/greater than the old version - ensure!( - storage_version < version, - ContractError::CannotMigrate { - previous_contract: stored.version, - } - ); - - set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; - - // Update the ADOContract's version - contract.execute_update_version(deps)?; - - Ok(Response::default()) -} - -fn from_semver(err: semver::Error) -> StdError { - StdError::generic_err(format!("Semver: {err}")) + ADOContract::default().migrate(deps, CONTRACT_NAME, CONTRACT_VERSION) } #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result { match msg { QueryMsg::ResolvePath { path } => encode_binary(&query::resolve_path(deps, path)?), - QueryMsg::SubDir { path } => encode_binary(&query::subdir(deps, path)?), + QueryMsg::SubDir { + path, + min, + max, + limit, + } => encode_binary(&query::subdir(deps, path, min, max, limit)?), QueryMsg::Paths { addr } => encode_binary(&query::paths(deps, addr)?), QueryMsg::GetUsername { address } => encode_binary(&query::get_username(deps, address)?), QueryMsg::GetLibrary { address } => encode_binary(&query::get_library_name(deps, address)?), QueryMsg::ResolveSymlink { path } => encode_binary(&query::get_symlink(deps, path)?), + // Base queries + QueryMsg::Version {} => encode_binary(&ADOContract::default().query_version(deps)?), + QueryMsg::Type {} => encode_binary(&ADOContract::default().query_type(deps)?), + QueryMsg::Owner {} => encode_binary(&ADOContract::default().query_contract_owner(deps)?), + QueryMsg::KernelAddress {} => { + encode_binary(&ADOContract::default().query_kernel_address(deps)?) + } } } diff --git a/andromeda-core/contracts/os/andromeda-vfs/src/execute.rs b/andromeda-core/contracts/os/andromeda-vfs/src/execute.rs index 71265b4..2b27a5a 100644 --- a/andromeda-core/contracts/os/andromeda-vfs/src/execute.rs +++ b/andromeda-core/contracts/os/andromeda-vfs/src/execute.rs @@ -28,6 +28,7 @@ pub fn add_path( address: Addr, parent_address: Option, ) -> Result { + let name = name.to_lowercase(); let kernel_address = ADOContract::default().get_kernel_address(env.deps.storage)?; ensure!( parent_address.is_none() @@ -37,7 +38,12 @@ pub fn add_path( ContractError::Unauthorized {} ); let parent_andr_addr = parent_address.unwrap_or(AndrAddr::from_string(env.info.sender)); - let parent_addr = resolve_pathname(env.deps.storage, env.deps.api, parent_andr_addr)?; + let parent_addr = resolve_pathname( + env.deps.storage, + env.deps.api, + parent_andr_addr, + &mut vec![], + )?; validate_component_name(name.clone())?; add_pathname( env.deps.storage, @@ -59,6 +65,8 @@ pub fn add_symlink( symlink: AndrAddr, parent_address: Option, ) -> Result { + let name = name.to_lowercase(); + let symlink = symlink.to_lowercase(); let kernel_address = ADOContract::default().get_kernel_address(env.deps.storage)?; ensure!( parent_address.is_none() @@ -68,10 +76,16 @@ pub fn add_symlink( ContractError::Unauthorized {} ); let parent_andr_addr = parent_address.unwrap_or(AndrAddr::from_string(env.info.sender)); - let parent_addr = resolve_pathname(env.deps.storage, env.deps.api, parent_andr_addr)?; + let parent_addr = resolve_pathname( + env.deps.storage, + env.deps.api, + parent_andr_addr, + &mut vec![], + )?; validate_component_name(name.clone())?; add_path_symlink( env.deps.storage, + env.deps.api, parent_addr.clone(), name.clone(), symlink.clone(), @@ -84,37 +98,65 @@ pub fn add_symlink( ])) } -pub fn add_parent_path( +pub fn add_child( env: ExecuteEnv, name: String, parent_address: AndrAddr, ) -> Result { + let ExecuteEnv { deps, info, .. } = env; + let name = name.to_lowercase(); + + let sender_code_id_res = deps.querier.query_wasm_contract_info(info.sender.clone()); + // Sender must be a contract + ensure!(sender_code_id_res.is_ok(), ContractError::Unauthorized {}); + let sender_code_id = sender_code_id_res?.code_id; + let ado_type = AOSQuerier::ado_type_getter( + &deps.querier, + &ADOContract::default().get_adodb_address(deps.as_ref().storage, &deps.querier)?, + sender_code_id, + )?; + // Sender must be an app contract + ensure!( + ado_type.is_some() && ado_type.unwrap().contains("app-contract"), + ContractError::Unauthorized {} + ); + validate_component_name(name.clone())?; - let parent_address = resolve_pathname(env.deps.storage, env.deps.api, parent_address)?; + let parent_address = resolve_pathname(deps.storage, deps.api, parent_address, &mut vec![])?; let existing = paths() - .load(env.deps.storage, &(parent_address.clone(), name.clone())) + .load(deps.storage, &(parent_address.clone(), name.clone())) .ok(); // Ensure that this path is not already added or if already added it should point to same address as above. This prevent external users to override existing paths. // Only add path method can override existing paths as its safe because only owner of the path can execute it match existing { None => { - add_pathname(env.deps.storage, parent_address, name, env.info.sender)?; + add_pathname(deps.storage, parent_address, name, info.sender)?; } Some(path) => { - ensure!( - path.address == env.info.sender, - ContractError::Unauthorized {} - ) + ensure!(path.address == info.sender, ContractError::Unauthorized {}) } }; Ok(Response::default()) } +const MAX_USERNAME_LENGTH: u64 = 30; + pub fn register_user( env: ExecuteEnv, username: String, address: Option, ) -> Result { + #[cfg(not(test))] + ensure!(false, ContractError::TemporarilyDisabled {}); + ensure!( + username.len() as u64 <= MAX_USERNAME_LENGTH, + ContractError::InvalidUsername { + error: Some(format!( + "Username must be less than {MAX_USERNAME_LENGTH} characters" + )) + } + ); + let username = username.to_lowercase(); let kernel = &ADOContract::default().get_kernel_address(env.deps.storage)?; let curr_chain = AOSQuerier::get_current_chain(&env.deps.querier, kernel)?; // Can only register username directly on Andromeda chain @@ -134,17 +176,38 @@ pub fn register_user( ); let sender = address.unwrap_or(env.info.sender.clone()); let current_user_address = USERS.may_load(env.deps.storage, username.as_str())?; - if current_user_address.is_some() { - ensure!( - current_user_address.unwrap() == sender, - ContractError::Unauthorized {} - ); - } + ensure!( + current_user_address.is_none(), + ContractError::InvalidUsername { + error: Some("Username already taken".to_string()) + } + ); //Remove username registration from previous username - USERS.remove(env.deps.storage, username.as_str()); + let current_username = ADDRESS_USERNAME.may_load(env.deps.storage, sender.as_ref())?; + if let Some(current_username) = current_username { + USERS.remove(env.deps.storage, current_username.as_str()); + } + + // If the username is a valid address, it should be equal to info.sender + match env.deps.api.addr_validate(&username) { + Ok(username) => { + // No need to validate the username any further if this passess + ensure!( + username == env.info.sender, + ContractError::InvalidUsername { + error: Some( + "Usernames that are valid addresses should be the same as the sender's address" + .to_string() + ) + } + ) + } + Err(_) => { + validate_username(username.clone())?; + } + } - validate_username(username.clone())?; USERS.save(env.deps.storage, username.as_str(), &sender)?; //Update current address' username ADDRESS_USERNAME.save(env.deps.storage, sender.as_ref(), &username)?; diff --git a/andromeda-core/contracts/os/andromeda-vfs/src/query.rs b/andromeda-core/contracts/os/andromeda-vfs/src/query.rs index bd640f3..d6cb8b4 100644 --- a/andromeda-core/contracts/os/andromeda-vfs/src/query.rs +++ b/andromeda-core/contracts/os/andromeda-vfs/src/query.rs @@ -1,4 +1,4 @@ -use andromeda_std::os::vfs::validate_path_name; +use andromeda_std::os::vfs::{validate_path_name, SubDirBound}; use andromeda_std::{amp::AndrAddr, error::ContractError}; use cosmwasm_std::{Addr, Deps}; @@ -8,12 +8,18 @@ use crate::state::{ }; pub fn resolve_path(deps: Deps, path: AndrAddr) -> Result { - validate_path_name(path.to_string())?; - resolve_pathname(deps.storage, deps.api, path) + validate_path_name(deps.api, path.to_string())?; + resolve_pathname(deps.storage, deps.api, path, &mut vec![]) } -pub fn subdir(deps: Deps, path: AndrAddr) -> Result, ContractError> { - validate_path_name(path.to_string())?; - get_subdir(deps.storage, deps.api, path) +pub fn subdir( + deps: Deps, + path: AndrAddr, + min: Option, + max: Option, + limit: Option, +) -> Result, ContractError> { + validate_path_name(deps.api, path.to_string())?; + get_subdir(deps.storage, deps.api, path, min, max, limit) } pub fn paths(deps: Deps, addr: Addr) -> Result, ContractError> { diff --git a/andromeda-core/contracts/os/andromeda-vfs/src/state.rs b/andromeda-core/contracts/os/andromeda-vfs/src/state.rs index 2a1b30a..7e2378a 100644 --- a/andromeda-core/contracts/os/andromeda-vfs/src/state.rs +++ b/andromeda-core/contracts/os/andromeda-vfs/src/state.rs @@ -1,6 +1,10 @@ -use andromeda_std::{amp::AndrAddr, error::ContractError}; -use cosmwasm_std::{ensure, Addr, Api, StdError, Storage}; -use cw_storage_plus::{Index, IndexList, IndexedMap, Map, MultiIndex}; +use andromeda_std::{ + amp::AndrAddr, + error::ContractError, + os::vfs::{validate_path_name, SubDirBound}, +}; +use cosmwasm_std::{ensure, Addr, Api, Storage}; +use cw_storage_plus::{Bound, Index, IndexList, IndexedMap, Map, MultiIndex}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] @@ -47,6 +51,11 @@ pub const LIBRARIES: Map<&str, Addr> = Map::new("libraries"); pub const ADDRESS_USERNAME: Map<&str, String> = Map::new("address_username"); pub const ADDRESS_LIBRARY: Map<&str, String> = Map::new("address_library"); +/** + Splits a pathname into its components. + + * **path**: The full path to be split +*/ pub fn split_pathname(path: String) -> Vec { path.split('/') .filter(|string| !string.is_empty()) @@ -54,21 +63,33 @@ pub fn split_pathname(path: String) -> Vec { .collect::>() } +/** + Resolves a given path to an address. + + * **storage**: CosmWasm storage struct + * **api**: CosmWasm API struct + * **path**: The full path to be resolved + * **resolved_paths**: A vector of resolved paths to prevent looping or paths that are too long +*/ pub fn resolve_pathname( storage: &dyn Storage, api: &dyn Api, pathname: AndrAddr, + resolved_paths: &mut Vec<(Addr, String)>, ) -> Result { + let pathname = pathname.to_lowercase(); // As cross-chain queries are not currently possible we need to ensure the pathname being resolved is local ensure!( pathname.get_protocol().is_none(), - ContractError::InvalidAddress {} + ContractError::InvalidPathname { + error: Some("Cannot resolve paths with protocols at this time".to_string()) + } ); if pathname.is_vfs_path() { match pathname.get_root_dir() { - "home" => resolve_home_path(storage, api, pathname), - "lib" => resolve_lib_path(storage, api, pathname), + "home" => resolve_home_path(storage, api, pathname, resolved_paths), + "lib" => resolve_lib_path(storage, api, pathname, resolved_paths), &_ => Err(ContractError::InvalidAddress {}), } } else { @@ -76,63 +97,109 @@ pub fn resolve_pathname( } } +/** + Resolves a given home path. + + * **storage**: CosmWasm storage struct + * **api**: CosmWasm API struct + * **path**: The full path to be resolved + * **resolved_paths**: A vector of resolved paths to prevent looping or paths that are too long +*/ fn resolve_home_path( storage: &dyn Storage, api: &dyn Api, - pathname: AndrAddr, + path: AndrAddr, + resolved_paths: &mut Vec<(Addr, String)>, ) -> Result { - let mut parts = split_pathname(pathname.to_string()); + validate_path_name(api, path.to_string())?; + let parts = split_pathname(path.to_string()); - let username_or_address = if parts[0].starts_with('~') && parts.len() == 1 { - parts[0].remove(0); - parts[0].as_str() - } else { - parts[1].as_str() - }; + let amount_to_skip = if parts[0].starts_with('~') { 0 } else { 1 }; + let username_or_address = parts[amount_to_skip] + .strip_prefix('~') + .unwrap_or(&parts[amount_to_skip]); let user_address = match api.addr_validate(username_or_address) { Ok(addr) => addr, Err(_e) => USERS.load(storage, username_or_address)?, }; - resolve_path(storage, api, parts, user_address) + let mut remaining_parts = parts.to_vec(); + + remaining_parts.drain(0..amount_to_skip + 1); + resolve_path(storage, api, remaining_parts, user_address, resolved_paths) } +/** + Resolves a given library path. + + * **storage**: CosmWasm storage struct + * **api**: CosmWasm API struct + * **path**: The full path to be resolved + * **resolved_paths**: A vector of resolved paths to prevent looping or paths that are too long +*/ fn resolve_lib_path( storage: &dyn Storage, api: &dyn Api, - pathname: AndrAddr, + path: AndrAddr, + resolved_paths: &mut Vec<(Addr, String)>, ) -> Result { - let mut parts = split_pathname(pathname.to_string()); + let parts = split_pathname(path.to_string()); - let username_or_address = if parts[0].starts_with('~') && parts.len() == 1 { - parts[0].remove(0); - parts[0].as_str() - } else { - parts[1].as_str() - }; - let user_address = match api.addr_validate(username_or_address) { + let library_or_address = parts[1].as_str(); + + let lib_address = match api.addr_validate(library_or_address) { Ok(addr) => addr, - Err(_e) => LIBRARIES.load(storage, username_or_address)?, + Err(_e) => LIBRARIES.load(storage, library_or_address)?, }; - - resolve_path(storage, api, parts, user_address) + let mut remaining_parts = parts.to_vec(); + remaining_parts.drain(0..2); + resolve_path(storage, api, remaining_parts, lib_address, resolved_paths) } +const MAX_DEPTH: u8 = 50; + +/** + Resolves a given path after the first section has been resolved. + + Iterates through the path and resolves each section until the final section is resolved before returning the address. + + * **storage**: CosmWasm storage struct + * **api**: CosmWasm API struct + * **parts**: The remaining parts of the path to resolve + * **parent_address**: The address of the parent lib/user + * **resolved_paths**: A vector of resolved paths to prevent looping or paths that are too long +*/ fn resolve_path( storage: &dyn Storage, api: &dyn Api, parts: Vec, - user_address: Addr, + parent_address: Addr, + resolved_paths: &mut Vec<(Addr, String)>, ) -> Result { - let mut address = user_address; - for (idx, part) in parts.iter().enumerate() { - // Skip username and root dir - if idx <= 1 { - continue; - } - let info = paths().load(storage, &(address, part.clone()))?; + let mut address = parent_address; + // Preemptive length check to prevent resolving paths that are too long + ensure!( + parts.len() as u8 <= MAX_DEPTH, + ContractError::InvalidAddress {} + ); + + for part in parts.iter() { + // To prevent resolving paths that are too long + ensure!( + resolved_paths.len() as u8 <= MAX_DEPTH, + ContractError::InvalidAddress {} + ); + // Prevent looping + ensure!( + !resolved_paths.contains(&(address.clone(), part.clone())), + ContractError::InvalidPathname { + error: Some("Pathname contains a looping reference".to_string()) + } + ); + let info = paths().load(storage, &(address.clone(), part.clone()))?; + resolved_paths.push((address, part.clone())); address = match info.symlink { - Some(symlink) => resolve_pathname(storage, api, symlink)?, + Some(symlink) => resolve_pathname(storage, api, symlink, resolved_paths)?, None => info.address, }; } @@ -140,18 +207,31 @@ fn resolve_path( Ok(address) } +const MAX_LIMIT: u32 = 100u32; +const DEFAULT_LIMIT: u32 = 50u32; + pub fn get_subdir( storage: &dyn Storage, api: &dyn Api, pathname: AndrAddr, + min: Option, + max: Option, + limit: Option, ) -> Result, ContractError> { - let address = resolve_pathname(storage, api, pathname)?; + let address = resolve_pathname(storage, api, pathname, &mut vec![])?; + let limit = limit.unwrap_or(DEFAULT_LIMIT).min(MAX_LIMIT); let subdirs = paths() .idx .parent .prefix(address) - .range(storage, None, None, cosmwasm_std::Order::Ascending) + .range( + storage, + min.map(Bound::inclusive), + max.map(Bound::inclusive), + cosmwasm_std::Order::Ascending, + ) + .take(limit as usize) .map(|r| r.unwrap().1) .collect(); @@ -189,7 +269,7 @@ pub fn add_pathname( parent_addr: Addr, name: String, address: Addr, -) -> Result<(), StdError> { +) -> Result<(), ContractError> { paths().save( storage, &(parent_addr.clone(), name.clone()), @@ -199,25 +279,34 @@ pub fn add_pathname( parent_address: parent_addr, symlink: None, }, - ) + )?; + Ok(()) } pub fn add_path_symlink( storage: &mut dyn Storage, + api: &dyn Api, parent_addr: Addr, name: String, symlink: AndrAddr, -) -> Result<(), StdError> { +) -> Result<(), ContractError> { paths().save( storage, &(parent_addr.clone(), name.clone()), &PathInfo { - name, + name: name.clone(), address: Addr::unchecked("invalidaddress"), - parent_address: parent_addr, - symlink: Some(symlink), + parent_address: parent_addr.clone(), + symlink: Some(symlink.clone()), }, - ) + )?; + if symlink.get_protocol().is_none() { + // Ensure that the symlink resolves to a valid address + let pathname = AndrAddr::from_string(format!("~{}/{}", parent_addr, name)); + resolve_pathname(storage, api, pathname, &mut vec![])?; + } + + Ok(()) } pub fn resolve_symlink( @@ -237,7 +326,7 @@ pub fn resolve_symlink( } else { AndrAddr::from_string(format!("/{reconstructed_addr}")) }; - let addr = resolve_pathname(storage, api, remaining_path)?; + let addr = resolve_pathname(storage, api, remaining_path, &mut vec![])?; let info = paths().load(storage, &(addr, final_part))?; match info.symlink { Some(symlink) => Ok(symlink), @@ -247,8 +336,7 @@ pub fn resolve_symlink( #[cfg(test)] mod test { - use andromeda_std::os::vfs::validate_username; - use cosmwasm_std::testing::mock_dependencies; + use cosmwasm_std::{testing::mock_dependencies, DepsMut}; use super::*; @@ -262,25 +350,16 @@ mod test { assert_eq!(res, expected) } - #[test] - fn test_validate_username() { - let valid_user = "username1980"; - validate_username(valid_user.to_string()).unwrap(); - - let empty_user = ""; - let res = validate_username(empty_user.to_string()); - assert!(res.is_err()); - - let invalid_user = "///////"; - let res = validate_username(invalid_user.to_string()); - assert!(res.is_err()); - } - #[test] fn test_resolve_pathname() { let path = AndrAddr::from_string("cosmos1..."); - let res = - resolve_pathname(&mock_dependencies().storage, &mock_dependencies().api, path).unwrap(); + let res = resolve_pathname( + &mock_dependencies().storage, + &mock_dependencies().api, + path, + &mut vec![], + ) + .unwrap(); assert_eq!(res, Addr::unchecked("cosmos1...")); } @@ -305,6 +384,7 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("/home/{username}")), + &mut vec![], ) .unwrap(); assert_eq!(res, username_address); @@ -313,6 +393,7 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("~{username}")), + &mut vec![], ) .unwrap(); assert_eq!(res, username_address); @@ -321,9 +402,9 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("~/{username}")), - ) - .unwrap(); - assert_eq!(res, username_address); + &mut vec![], + ); + assert!(res.is_err()); paths() .save( @@ -342,6 +423,15 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("/home/{username}/{first_directory}")), + &mut vec![], + ) + .unwrap(); + assert_eq!(res, first_directory_address); + let res = resolve_home_path( + deps.as_ref().storage, + deps.as_ref().api, + AndrAddr::from_string(format!("~{username}/{first_directory}")), + &mut vec![], ) .unwrap(); assert_eq!(res, first_directory_address); @@ -368,6 +458,7 @@ mod test { AndrAddr::from_string(format!( "/home/{username}/{first_directory}/{second_directory}" )), + &mut vec![], ) .unwrap(); assert_eq!(res, second_directory_address); @@ -391,6 +482,7 @@ mod test { AndrAddr::from_string(format!( "/home/{username}/{first_directory}/{second_directory}/{file}" )), + &mut vec![], ) .unwrap(); assert_eq!(res, file_address) @@ -417,6 +509,7 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("/lib/{lib_name}")), + &mut vec![], ) .unwrap(); assert_eq!(res, username_address); @@ -438,6 +531,7 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("/lib/{lib_name}/{first_directory}")), + &mut vec![], ) .unwrap(); assert_eq!(res, first_directory_address); @@ -464,6 +558,7 @@ mod test { AndrAddr::from_string(format!( "/lib/{lib_name}/{first_directory}/{second_directory}" )), + &mut vec![], ) .unwrap(); assert_eq!(res, second_directory_address); @@ -487,6 +582,7 @@ mod test { AndrAddr::from_string(format!( "/lib/{lib_name}/{first_directory}/{second_directory}/{file}" )), + &mut vec![], ) .unwrap(); assert_eq!(res, file_address) @@ -522,6 +618,7 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("/home/{username}/{first_directory}")), + &mut vec![], ) .unwrap(); assert_eq!(res, first_directory_address); @@ -529,8 +626,10 @@ mod test { let symlink_parent = Addr::unchecked("parentaddress"); let symlink_name = "symlink"; let symlink = AndrAddr::from_string(format!("/home/{username}/{first_directory}")); + let DepsMut { api, storage, .. } = deps.as_mut(); add_path_symlink( - deps.as_mut().storage, + storage, + api, symlink_parent.clone(), symlink_name.to_string(), symlink.clone(), @@ -541,6 +640,7 @@ mod test { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(format!("/home/{symlink_parent}/{symlink_name}")), + &mut vec![], ) .unwrap(); assert_eq!(res, first_directory_address); @@ -596,4 +696,147 @@ mod test { assert_eq!(res, AndrAddr::from_string("/home/someuser")); } + + #[test] + fn test_resolve_path_too_long() { + let mut deps = mock_dependencies(); + let mut path = "~u1".to_owned(); + + for i in 0..MAX_DEPTH + 1 { + path.push_str(format!("/d{}", i).as_str()); + } + + USERS + .save(deps.as_mut().storage, "u1", &Addr::unchecked("u1")) + .unwrap(); + + let res = resolve_home_path( + deps.as_ref().storage, + deps.as_ref().api, + AndrAddr::from_string(path), + &mut vec![], + ); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::InvalidAddress {}); + + let mut deps = mock_dependencies(); + let mut path: String = "/lib/u1".to_owned(); + + for i in 0..MAX_DEPTH + 1 { + path.push_str(format!("/d{}", i).as_str()); + } + + LIBRARIES + .save(deps.as_mut().storage, "u1", &Addr::unchecked("u1")) + .unwrap(); + + let res = resolve_lib_path( + deps.as_ref().storage, + deps.as_ref().api, + AndrAddr::from_string(path), + &mut vec![], + ); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::InvalidAddress {}) + } + + #[test] + fn test_resolve_path_loop() { + let mut deps = mock_dependencies(); + let path = "~u1/d0".to_owned(); + + USERS + .save(deps.as_mut().storage, "u1", &Addr::unchecked("u1")) + .unwrap(); + paths() + .save( + deps.as_mut().storage, + &(Addr::unchecked("u1"), "d0".to_string()), + &PathInfo { + name: "d0".to_string(), + address: Addr::unchecked("d0"), + parent_address: Addr::unchecked("u1"), + symlink: None, + }, + ) + .unwrap(); + + let res = resolve_home_path( + deps.as_ref().storage, + deps.as_ref().api, + AndrAddr::from_string(path.clone()), + &mut vec![], + ); + + assert!(res.is_ok()); + + paths() + .save( + deps.as_mut().storage, + &(Addr::unchecked("d0"), "d1".to_string()), + &PathInfo { + name: "d0".to_string(), + address: Addr::unchecked("u1"), + parent_address: Addr::unchecked("d1"), + symlink: None, + }, + ) + .unwrap(); + + let new_path = format!("{}/d1/d0", path); + let res = resolve_home_path( + deps.as_ref().storage, + deps.as_ref().api, + AndrAddr::from_string(new_path), + &mut vec![], + ); + + assert!(res.is_err()); + assert_eq!( + res.unwrap_err(), + ContractError::InvalidPathname { + error: Some("Pathname contains a looping reference".to_string()) + } + ); + } + + #[test] + fn test_add_symlink_looping_reference() { + let mut deps = mock_dependencies(); + let username = "u1"; + let first_directory = "d1"; + + let username_address = Addr::unchecked("useraddress"); + let first_directory_address = Addr::unchecked("dir1address"); + + USERS + .save(deps.as_mut().storage, username, &username_address) + .unwrap(); + + let DepsMut { api, storage, .. } = deps.as_mut(); + add_pathname( + storage, + username_address, + first_directory.to_string(), + first_directory_address.clone(), + ) + .unwrap(); + + let res = add_path_symlink( + storage, + api, + first_directory_address, + username.to_string(), + AndrAddr::from_string(format!("/home/{username}/{first_directory}/{username}")), + ); + assert!(res.is_err()); + assert_eq!( + res.unwrap_err(), + ContractError::InvalidPathname { + error: Some("Pathname contains a looping reference".to_string()) + } + ) + } } diff --git a/andromeda-core/contracts/os/andromeda-vfs/src/testing/tests.rs b/andromeda-core/contracts/os/andromeda-vfs/src/testing/tests.rs index 65c2088..e6369b1 100644 --- a/andromeda-core/contracts/os/andromeda-vfs/src/testing/tests.rs +++ b/andromeda-core/contracts/os/andromeda-vfs/src/testing/tests.rs @@ -10,7 +10,8 @@ use andromeda_std::{ vfs::{ExecuteMsg, InstantiateMsg}, }, testing::mock_querier::{ - mock_dependencies_custom, MOCK_FAKE_KERNEL_CONTRACT, MOCK_KERNEL_CONTRACT, + mock_dependencies_custom, MOCK_APP_CONTRACT, MOCK_FAKE_KERNEL_CONTRACT, + MOCK_KERNEL_CONTRACT, }, }; use andromeda_std::{error::ContractError, os::vfs::QueryMsg}; @@ -41,7 +42,8 @@ fn proper_initialization() { #[test] fn test_register_user() { let mut deps = mock_dependencies_custom(&[]); - let username = "user1"; + // Using a username less than 3 characters long to simulate an invalid CosmWasm Address + let username = "u1"; let sender = "sender"; let info = mock_info(sender, &[]); let env = mock_env(); @@ -50,8 +52,135 @@ fn test_register_user() { address: None, }; instantiate_contract(deps.as_mut(), env.clone(), info.clone()); + execute(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); + + let saved = USERS.load(deps.as_ref().storage, username).unwrap(); + assert_eq!(saved, sender); + let username_saved = ADDRESS_USERNAME + .load(deps.as_ref().storage, sender) + .unwrap(); + assert_eq!(username_saved, username); + + let new_username = "u2"; + let msg = ExecuteMsg::RegisterUser { + username: new_username.to_string(), + address: None, + }; execute(deps.as_mut(), env, info, msg).unwrap(); + let saved = USERS.load(deps.as_ref().storage, new_username).unwrap(); + assert_eq!(saved, sender); + let username_saved = ADDRESS_USERNAME + .load(deps.as_ref().storage, sender) + .unwrap(); + assert_eq!(username_saved, new_username); + let deleted = USERS.may_load(deps.as_ref().storage, username).unwrap(); + assert!(deleted.is_none()) +} + +#[test] +fn test_register_user_duplicate() { + let mut deps = mock_dependencies_custom(&[]); + // Using a username less than 3 characters long to simulate an invalid CosmWasm Address + let username = "u1"; + let sender = "sender"; + let info = mock_info(sender, &[]); + let env = mock_env(); + let msg = ExecuteMsg::RegisterUser { + username: username.to_string(), + address: None, + }; + instantiate_contract(deps.as_mut(), env.clone(), info.clone()); + execute(deps.as_mut(), env.clone(), info.clone(), msg.clone()).unwrap(); + + let saved = USERS.load(deps.as_ref().storage, username).unwrap(); + assert_eq!(saved, sender); + let username_saved = ADDRESS_USERNAME + .load(deps.as_ref().storage, sender) + .unwrap(); + assert_eq!(username_saved, username); + + let res = execute(deps.as_mut(), env, info, msg); + assert!(res.is_err()); + assert_eq!( + res.unwrap_err(), + ContractError::InvalidUsername { + error: Some("Username already taken".to_string()) + } + ) +} + +// Test using a username that represents a valid CosmWasm Address that IS NOT the same as the sender's address +#[test] +fn test_register_user_valid_cosmwasm_address() { + let mut deps = mock_dependencies_custom(&[]); + // Using a username less than 3 characters long to simulate an invalid CosmWasm Address + let username = "user1"; + let sender = "sender"; + let info = mock_info(sender, &[]); + let env = mock_env(); + let msg = ExecuteMsg::RegisterUser { + username: username.to_string(), + address: None, + }; + instantiate_contract(deps.as_mut(), env.clone(), info.clone()); + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidUsername { + error: Some( + "Usernames that are valid addresses should be the same as the sender's address" + .to_string() + ) + } + ); + + let username = "SeNdEr"; + let info = mock_info("attacker", &[]); + let env = mock_env(); + let msg = ExecuteMsg::RegisterUser { + username: username.to_string(), + address: None, + }; + + let err = execute(deps.as_mut(), env, info, msg).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidUsername { + error: Some( + "Usernames that are valid addresses should be the same as the sender's address" + .to_string() + ) + } + ); + + let username = "SeNdEr"; + let info = mock_info(sender, &[]); + let env = mock_env(); + let msg = ExecuteMsg::RegisterUser { + username: username.to_string(), + address: None, + }; + + let res = execute(deps.as_mut(), env, info, msg); + assert!(res.is_ok()); +} + +// Test using a username that represents a valid CosmWasm Address that IS the same as the sender's address +#[test] +fn test_register_user_valid_cosmwasm_address_user() { + let mut deps = mock_dependencies_custom(&[]); + // Using a username less than 3 characters long to simulate an invalid CosmWasm Address + let username = "sender"; + let sender = "sender"; + let info = mock_info(sender, &[]); + let env = mock_env(); + let msg = ExecuteMsg::RegisterUser { + username: username.to_string(), + address: None, + }; + instantiate_contract(deps.as_mut(), env.clone(), info.clone()); + execute(deps.as_mut(), env, info, msg).unwrap(); let saved = USERS.load(deps.as_ref().storage, username).unwrap(); assert_eq!(saved, sender) } @@ -74,14 +203,20 @@ fn test_register_user_unauthorized() { .unwrap(); let res = execute(deps.as_mut(), env, info, msg).unwrap_err(); - assert_eq!(res, ContractError::Unauthorized {}) + assert_eq!( + res, + ContractError::InvalidUsername { + error: Some("Username already taken".to_string()) + } + ) } #[test] fn test_register_user_already_registered() { let mut deps = mock_dependencies_custom(&[]); - let username = "user1"; - let new_username = "user2"; + // Using a usernames less than 3 characters long to simulate an invalid CosmWasm Address + let username = "u1"; + let new_username = "u2"; let sender = "sender"; let info = mock_info(sender, &[]); let env = mock_env(); @@ -107,7 +242,8 @@ fn test_register_user_already_registered() { #[test] fn test_register_user_foreign_chain() { let mut deps = mock_dependencies_custom(&[]); - let username = "user1"; + // Using a usernames less than 3 characters long to simulate an invalid CosmWasm Address + let username = "u1"; let sender = "sender"; let info = mock_info(sender, &[]); let env = mock_env(); @@ -123,6 +259,7 @@ fn test_register_user_foreign_chain() { username: username.to_string(), address: None, }; + let err = execute(deps.as_mut(), env.clone(), info, msg).unwrap_err(); assert_eq!(err, ContractError::Unauthorized {}); @@ -214,6 +351,7 @@ fn test_add_path() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) .unwrap(); @@ -235,6 +373,7 @@ fn test_add_path() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) .unwrap(); @@ -282,6 +421,7 @@ fn test_add_symlink() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) .unwrap(); @@ -302,6 +442,7 @@ fn test_add_symlink() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) .unwrap(); @@ -322,10 +463,16 @@ fn test_add_symlink() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) .unwrap_err(); - assert_eq!(err, ContractError::InvalidAddress {}); + assert_eq!( + err, + ContractError::InvalidPathname { + error: Some("Cannot resolve paths with protocols at this time".to_string()) + } + ); let symlink_three_name = "symlink_three"; let msg = ExecuteMsg::AddSymlink { @@ -342,6 +489,7 @@ fn test_add_symlink() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) .unwrap(); @@ -360,26 +508,32 @@ fn test_add_symlink() { let path = format!("/home/{username}/{component_name}/{symlink_four_name}"); - let resolved_addr = resolve_pathname( + let err = resolve_pathname( deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) - .unwrap(); + .unwrap_err(); - assert_eq!(resolved_addr, component_addr); + assert_eq!( + err, + ContractError::InvalidPathname { + error: Some("Pathname contains a looping reference".to_string()) + } + ); } #[test] -fn test_add_parent_path() { - let mut deps = mock_dependencies(); +fn test_add_child() { + let mut deps = mock_dependencies_custom(&[]); let username = "u1"; let user_address = Addr::unchecked("useraddr"); let component_name = "f1"; - let sender = "sender"; + let sender = MOCK_APP_CONTRACT; let info = mock_info(sender, &[]); let env = mock_env(); - let msg = ExecuteMsg::AddParentPath { + let msg = ExecuteMsg::AddChild { name: component_name.to_string(), parent_address: AndrAddr::from_string(format!("/home/{user_address}")), }; @@ -396,12 +550,31 @@ fn test_add_parent_path() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path), + &mut vec![], ) .unwrap(); assert_eq!(resolved_addr, sender) } +#[test] +fn test_add_child_not_app_contract() { + let mut deps = mock_dependencies_custom(&[]); + let user_address = Addr::unchecked("useraddr"); + let component_name = "f1"; + let sender = "not_an_app_contract"; + let info = mock_info(sender, &[]); + let env = mock_env(); + let msg = ExecuteMsg::AddChild { + name: component_name.to_string(), + parent_address: AndrAddr::from_string(format!("/home/{user_address}")), + }; + + let res = execute(deps.as_mut(), env, info, msg); + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::Unauthorized {}) +} + /** * This test tries to override existing vfs path using add parent path method. * Here user_one will set his address as identifier in vfs. Another user user_two @@ -411,14 +584,14 @@ fn test_add_parent_path() { * VERY IMPORTANT from security perspective */ #[test] -fn test_override_add_parent_path() { - let mut deps = mock_dependencies(); +fn test_override_add_child() { + let mut deps = mock_dependencies_custom(&[]); let env = mock_env(); - let user_address = Addr::unchecked("user_one"); + let user_address = Addr::unchecked("userone"); let component_name = "identifier"; - let info = mock_info(user_address.as_str(), &[]); - let msg = ExecuteMsg::AddParentPath { + let info = mock_info(MOCK_APP_CONTRACT, &[]); + let msg = ExecuteMsg::AddChild { name: component_name.to_string(), parent_address: AndrAddr::from_string(format!("/home/{user_address}")), }; @@ -427,7 +600,7 @@ fn test_override_add_parent_path() { // Try to override above address with your address let info = mock_info("user_two", &[]); - let msg = ExecuteMsg::AddParentPath { + let msg = ExecuteMsg::AddChild { name: component_name.to_string(), parent_address: AndrAddr::from_string(format!("/home/{user_address}")), }; @@ -507,13 +680,13 @@ fn test_get_subdir() { let env = mock_env(); let root_paths = vec![ PathInfo { - name: "f1".to_string(), + name: "fi1".to_string(), address: Addr::unchecked("f1addr"), parent_address: sender.clone(), symlink: None, }, PathInfo { - name: "f2".to_string(), + name: "fi2".to_string(), address: Addr::unchecked("f2addr"), parent_address: sender.clone(), symlink: None, @@ -540,17 +713,14 @@ fn test_get_subdir() { // Add all root components for path in root_paths.clone() { - let _ = add_pathname( - deps.as_mut().storage, - sender.clone(), - path.name, - path.address, - ); + let DepsMut { storage, .. } = deps.as_mut(); + let _ = add_pathname(storage, sender.clone(), path.name, path.address); } for path in sub_paths.clone() { + let DepsMut { storage, .. } = deps.as_mut(); let _ = add_pathname( - deps.as_mut().storage, + storage, path.parent_address.clone(), path.name, path.address, @@ -558,18 +728,22 @@ fn test_get_subdir() { } for path in root_paths.clone() { - let path_name = format!("/home/{username}/{name}", name = path.name); + let path_name = format!("~{username}/{name}", name = path.name); let resolved_addr = resolve_pathname( deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path_name.clone()), + &mut vec![], ); assert!(resolved_addr.is_ok(), "{path_name} not found"); assert_eq!(resolved_addr.unwrap(), path.address) } let query_msg = QueryMsg::SubDir { - path: AndrAddr::from_string(format!("/home/{username}")), + path: AndrAddr::from_string(format!("~{username}")), + min: None, + max: None, + limit: None, }; let res = query(deps.as_ref(), env.clone(), query_msg).unwrap(); let val: Vec = from_json(res).unwrap(); @@ -578,6 +752,9 @@ fn test_get_subdir() { let subdir = &root_paths[0].name; let query_msg = QueryMsg::SubDir { path: AndrAddr::from_string(format!("/home/{username}/{subdir}")), + min: None, + max: None, + limit: None, }; let res = query(deps.as_ref(), env, query_msg).unwrap(); let val: Vec = from_json(res).unwrap(); @@ -632,15 +809,11 @@ fn test_get_paths() { // Add all root components for path in root_paths.clone() { - let _ = add_pathname( - deps.as_mut().storage, - sender.clone(), - path.name, - path.address.clone(), - ); + let DepsMut { storage, .. } = deps.as_mut(); + let _ = add_pathname(storage, sender.clone(), path.name, path.address.clone()); for sub_path in sub_paths.clone() { let _ = add_pathname( - deps.as_mut().storage, + storage, path.address.clone(), sub_path.name, sub_path.address, @@ -654,6 +827,7 @@ fn test_get_paths() { deps.as_ref().storage, deps.as_ref().api, AndrAddr::from_string(path_name.clone()), + &mut vec![], ); assert!(resolved_addr.is_ok(), "{path_name} not found"); assert_eq!(resolved_addr.unwrap(), path.address) diff --git a/andromeda-core/git-conventional-commits.yaml b/andromeda-core/git-conventional-commits.yaml new file mode 100644 index 0000000..79c0613 --- /dev/null +++ b/andromeda-core/git-conventional-commits.yaml @@ -0,0 +1,43 @@ +convention: + commitTypes: + - feat + - fix + - perf + - refactor + - style + - test + - build + - ops + - docs + - chore + - merge + - revert + - ci + commitScopes: [] + releaseTagGlobPattern: v[0-9]*.[0-9]*.[0-9]* +changelog: + commitTypes: + - feat + - fix + - perf + - merge + includeInvalidCommits: true + commitIgnoreRegexPattern: "^WIP " + headlines: + feat: Features + fix: Bug Fixes + perf: Performance Improvements + merge: Merges + breakingChange: BREAKING CHANGES + + ## GitHub + # commitUrl: https://github.com/ACCOUNT/REPOSITORY/commit/%commit% + # commitRangeUrl: https://github.com/ACCOUNT/REPOSITORY/compare/%from%...%to%?diff=split + + ## GitHub Issues + # issueRegexPattern: "#[0-9]+" + # issueUrl: https://github.com/ACCOUNT/REPOSITORY/issues/%issue% + + ## Jira Issues + # issueRegexPattern: "[A-Z][A-Z0-9]+-[0-9]+" + # issueUrl: https://WORKSPACE.atlassian.net/browse/%issue% diff --git a/andromeda-core/ibc-tests/.eslintrc.json b/andromeda-core/ibc-tests/.eslintrc.json deleted file mode 100644 index 1add2f8..0000000 --- a/andromeda-core/ibc-tests/.eslintrc.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "env": { "es6": true }, - "ignorePatterns": ["node_modules", "build", "coverage"], - "plugins": ["import", "eslint-comments"], - "extends": [ - "eslint:recommended", - "plugin:eslint-comments/recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/typescript", - "prettier" - ], - "globals": { "BigInt": true, "console": true, "WebAssembly": true }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "eslint-comments/disable-enable-pair": [ - "error", - { "allowWholeFile": true } - ], - "@typescript-eslint/no-non-null-assertion": "off", - "eslint-comments/no-unused-disable": "error", - "import/order": [ - "error", - { "newlines-between": "always", "alphabetize": { "order": "asc" } } - ], - "sort-imports": [ - "error", - { "ignoreDeclarationSort": true, "ignoreCase": true } - ], - "@typescript-eslint/no-unused-vars": ["off", { "argsIgnorePattern": "^_" }], - "object-shorthand": ["error", "always"] - } - } \ No newline at end of file diff --git a/andromeda-core/ibc-tests/.gitignore b/andromeda-core/ibc-tests/.gitignore deleted file mode 100644 index ecffbbd..0000000 --- a/andromeda-core/ibc-tests/.gitignore +++ /dev/null @@ -1,111 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -build/ - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -contracts/ - -*.cache.json -*.log.txt diff --git a/andromeda-core/ibc-tests/.prettierignore b/andromeda-core/ibc-tests/.prettierignore deleted file mode 100644 index f5e3657..0000000 --- a/andromeda-core/ibc-tests/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -# package.json is formatted by package managers, so we ignore it here -package.json -build \ No newline at end of file diff --git a/andromeda-core/ibc-tests/Cargo.toml b/andromeda-core/ibc-tests/Cargo.toml new file mode 100644 index 0000000..5a015ef --- /dev/null +++ b/andromeda-core/ibc-tests/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "ibc-tests" +version = "0.1.0" +edition = "2021" +rust-version = "1.75.0" +publish = false + +[[test]] +name = "validator_staking" + +[dependencies] +serde.workspace = true +tokio = "1.39.3" +cw-orch = "0.24.1" +cw-orch-daemon = "0.24.2" + +andromeda-testing-e2e = { workspace = true } + +andromeda-app-contract = { path = "../contracts/app/andromeda-app-contract", features = [ + "testing", +] } + +andromeda-validator-staking = { path = "../contracts/finance/andromeda-validator-staking", features = [ + "testing", +] } + +andromeda-finance = { workspace = true } +andromeda-std = { workspace = true } +andromeda-app = { workspace = true } +cosmwasm-std = { workspace = true, features = ["staking"] } +cosmrs = "0.19.0" +prost-types = "0.13.1" diff --git a/andromeda-core/ibc-tests/README.md b/andromeda-core/ibc-tests/README.md new file mode 100644 index 0000000..e8e2467 --- /dev/null +++ b/andromeda-core/ibc-tests/README.md @@ -0,0 +1,12 @@ +# Summary +This package is intended for e2e testing of ADOs. + +# Prerequest +1. You need to run the local network for e2e test. Currently this package is using `develop` branch of [localrelayer](https://github.com/andromedaprotocol/localrelayer/). +***Do not forget to switch to `develop` branch. Otherwise, it won't work.*** +2. Copy necessary artifacts to `ibc-tests/artifacts` and `packages/andromeda-testing-e2e/artifacts`. + +# Workflow +To run e2e tests, follow the following steps +1. Run the main function to setup aOS and necesary environment for each testing. +2. Run the test \ No newline at end of file diff --git a/andromeda-core/ibc-tests/package-lock.json b/andromeda-core/ibc-tests/package-lock.json deleted file mode 100644 index 2dbcf72..0000000 --- a/andromeda-core/ibc-tests/package-lock.json +++ /dev/null @@ -1,20748 +0,0 @@ -{ - "name": "andr_core_ibc_tests", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "andr_core_ibc_tests", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@confio/relayer": "^0.10.0", - "@cosmjs/cosmwasm-stargate": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/stargate": "^0.31.1", - "axios": "^1.4.0", - "sha256": "^0.2.0" - }, - "devDependencies": { - "@andromedaprotocol/andromeda.js": "^0.3.3", - "@ava/typescript": "^3.0.1", - "@istanbuljs/nyc-config-typescript": "^1.0.2", - "@types/chai": "^4.3.5", - "@types/cli-progress": "^3.11.0", - "@types/mocha": "^10.0.1", - "@types/mocha-steps": "^1.3.0", - "@types/node": "^18.0.6", - "@types/sha256": "^0.2.0", - "@types/sinon": "^10.0.13", - "@typescript-eslint/eslint-plugin": "^5.30.7", - "@typescript-eslint/parser": "^5.30.7", - "ava": "^4.3.1", - "chai": "^4.3.7", - "eslint": "^8.20.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import": "^2.26.0", - "mocha": "^10.2.0", - "mocha-steps": "^1.3.0", - "npm-run-all": "^4.1.5", - "nyc": "^15.1.0", - "prettier": "^2.7.1", - "sinon": "^14.0.0", - "ts-mocha": "^10.0.0", - "typescript": "^4.7.4" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@andromedaprotocol/andromeda.js/-/andromeda.js-0.3.3.tgz", - "integrity": "sha512-szjlwxQD0TRSSaKRqqlq7eiZDyy/vqiqe4shGVg/E5YsKe5/rWFtOwTDwfjjtUp82j/SvCox7zP5bh+KXEvIgQ==", - "dev": true, - "dependencies": { - "@cosmjs/cosmwasm-stargate": "^0.29.5", - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stargate": "^0.29.5", - "@injectivelabs/networks": "^1.0.93", - "@injectivelabs/sdk-ts": "1.0.452", - "@injectivelabs/utils": "1.0.81", - "@keplr-wallet/types": "^0.11.44", - "@terra-money/terra.js": "^3.1.7", - "axios": "^1.3.4", - "bech32": "^2.0.0", - "cosmjs-types": "^0.6.1", - "crypto-js": "^4.1.1", - "ethers": "^5.7.2", - "graphql-request": "^5.1.0", - "jsonschema": "^1.4.1", - "libsodium-wrappers": "0.7.6", - "lodash": "^4.17.21", - "long": "^5.2.1", - "pako": "^2.1.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/amino": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.5.tgz", - "integrity": "sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==", - "dev": true, - "dependencies": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/cosmwasm-stargate": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz", - "integrity": "sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA==", - "dev": true, - "dependencies": { - "@cosmjs/amino": "^0.29.5", - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stargate": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "pako": "^2.0.2" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/cosmwasm-stargate/node_modules/cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/cosmwasm-stargate/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "dev": true, - "dependencies": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/json-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz", - "integrity": "sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==", - "dev": true, - "dependencies": { - "@cosmjs/stream": "^0.29.5", - "xstream": "^11.14.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/socket": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.29.5.tgz", - "integrity": "sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==", - "dev": true, - "dependencies": { - "@cosmjs/stream": "^0.29.5", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/stargate": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.29.5.tgz", - "integrity": "sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw==", - "dev": true, - "dependencies": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/stargate/node_modules/cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/stargate/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/stream": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.29.5.tgz", - "integrity": "sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==", - "dev": true, - "dependencies": { - "xstream": "^11.14.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/tendermint-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz", - "integrity": "sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==", - "dev": true, - "dependencies": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/json-rpc": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/socket": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/tendermint-rpc/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@andromedaprotocol/andromeda.js/node_modules/@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==", - "dev": true - }, - "node_modules/@apollo/client": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.8.3.tgz", - "integrity": "sha512-mK86JM6hCpMEBGDgdO9U8ZYS8r9lPjXE1tVGpJMdSFUsIcXpmEfHUAbbFpPtYmxn8Qa7XsYy0dwDaDhpf4UUPw==", - "dev": true, - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "@wry/context": "^0.7.3", - "@wry/equality": "^0.5.6", - "@wry/trie": "^0.4.3", - "graphql-tag": "^2.12.6", - "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.17.5", - "prop-types": "^15.7.2", - "response-iterator": "^0.2.6", - "symbol-observable": "^4.0.0", - "ts-invariant": "^0.10.3", - "tslib": "^2.3.0", - "zen-observable-ts": "^1.2.5" - }, - "peerDependencies": { - "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0", - "graphql-ws": "^5.5.5", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" - }, - "peerDependenciesMeta": { - "graphql-ws": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "subscriptions-transport-ws": { - "optional": true - } - } - }, - "node_modules/@ava/typescript": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@ava/typescript/-/typescript-3.0.1.tgz", - "integrity": "sha512-/JXIUuKsvkaneaiA9ckk3ksFTqvu0mDNlChASrTe2BnDsvMbhQdPWyqQjJ9WRJWVhhs5TWn1/0Pp1G6Rv8Syrw==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "execa": "^5.1.1" - }, - "engines": { - "node": ">=12.22 <13 || >=14.17 <15 || >=16.4 <17 || >=17" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", - "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.15", - "@babel/helpers": "^7.22.15", - "@babel/parser": "^7.22.15", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", - "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", - "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.13.11" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", - "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@classic-terra/terra.proto": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@classic-terra/terra.proto/-/terra.proto-1.1.0.tgz", - "integrity": "sha512-bYhQG5LUaGF0KPRY9hYT/HEcd1QExZPQd6zLV/rQkCe/eDxfwFRLzZHpaaAdfWoAAZjsRWqJbUCqCg7gXBbJpw==", - "dev": true, - "dependencies": { - "@improbable-eng/grpc-web": "^0.14.1", - "google-protobuf": "^3.17.3", - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@classic-terra/terra.proto/node_modules/@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "dev": true, - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@classic-terra/terra.proto/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@confio/ics23": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", - "integrity": "sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==", - "dependencies": { - "@noble/hashes": "^1.0.0", - "protobufjs": "^6.8.8" - } - }, - "node_modules/@confio/relayer": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@confio/relayer/-/relayer-0.10.0.tgz", - "integrity": "sha512-/WW5Eyfgylby9u0wz6XakA7yo5hamdWh6pxkOYHPz0ls7ikd7Ld+c2fpRbL0Qg5wZn9+9P+Uhfj4l0pVl3WPgw==", - "dependencies": { - "@cosmjs/cosmwasm-stargate": "^0.31.0", - "@cosmjs/crypto": "^0.31.0", - "@cosmjs/encoding": "^0.31.0", - "@cosmjs/faucet-client": "^0.31.0", - "@cosmjs/math": "^0.31.0", - "@cosmjs/proto-signing": "^0.31.0", - "@cosmjs/stargate": "^0.31.0", - "@cosmjs/stream": "^0.31.0", - "@cosmjs/tendermint-rpc": "^0.31.0", - "@cosmjs/utils": "^0.31.0", - "ajv": "7.1.1", - "axios": "0.21.4", - "commander": "7.1.0", - "cosmjs-types": "^0.8.0", - "fast-safe-stringify": "2.0.4", - "js-yaml": "4.0.0", - "lodash": "4.17.21", - "prom-client": "13.1.0", - "protobufjs": "^6.10.3", - "table": "^6.7.1", - "triple-beam": "1.3.0", - "winston": "3.3.3" - }, - "bin": { - "ibc-relayer": "build/binary/ibc-relayer/index.js", - "ibc-setup": "build/binary/ibc-setup/index.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@confio/relayer/node_modules/@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@confio/relayer/node_modules/@cosmjs/proto-signing": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz", - "integrity": "sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg==", - "dependencies": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" - } - }, - "node_modules/@confio/relayer/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@confio/relayer/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@confio/relayer/node_modules/cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@confio/relayer/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/@cosmjs/amino": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.31.1.tgz", - "integrity": "sha512-kkB9IAkNEUFtjp/uwHv95TgM8VGJ4VWfZwrTyLNqBDD1EpSX2dsNrmUe7k8OMPzKlZUFcKmD4iA0qGvIwzjbGA==", - "dependencies": { - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1" - } - }, - "node_modules/@cosmjs/amino/node_modules/@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/amino/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@cosmjs/cosmwasm-stargate": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.31.1.tgz", - "integrity": "sha512-5hwv4oztFnpqnFaXhYxZc93na3qdxylT2kqms4pLzD8CWMEQmrwhdM4KpZimrsyZK55WiMQtTPsdSh7M8KLOow==", - "dependencies": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/proto-signing": "^0.31.1", - "@cosmjs/stargate": "^0.31.1", - "@cosmjs/tendermint-rpc": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", - "pako": "^2.0.2" - } - }, - "node_modules/@cosmjs/cosmwasm-stargate/node_modules/@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/cosmwasm-stargate/node_modules/@cosmjs/proto-signing": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz", - "integrity": "sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg==", - "dependencies": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" - } - }, - "node_modules/@cosmjs/cosmwasm-stargate/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@cosmjs/cosmwasm-stargate/node_modules/cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@cosmjs/cosmwasm-stargate/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/@cosmjs/crypto": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.31.1.tgz", - "integrity": "sha512-4R/SqdzdVzd4E5dpyEh1IKm5GbTqwDogutyIyyb1bcOXiX/x3CrvPI9Tb4WSIMDLvlb5TVzu2YnUV51Q1+6mMA==", - "dependencies": { - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers-sumo": "^0.7.11" - } - }, - "node_modules/@cosmjs/crypto/node_modules/@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/crypto/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@cosmjs/encoding": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.29.5.tgz", - "integrity": "sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ==", - "dev": true, - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/encoding/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "node_modules/@cosmjs/faucet-client": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/faucet-client/-/faucet-client-0.31.1.tgz", - "integrity": "sha512-DrploDHvk86yCI0UiNkFMdMEfyR2bn8uvnj0jY8bGYgih7J1t0z3M/OsYhmLJLsF8JlxVFoD/gpV4nD0apXukw==", - "dependencies": { - "axios": "^0.21.2" - } - }, - "node_modules/@cosmjs/faucet-client/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@cosmjs/json-rpc": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.31.1.tgz", - "integrity": "sha512-gIkCj2mUDHAxvmJnHtybXtMLZDeXrkDZlujjzhvJlWsIuj1kpZbKtYqh+eNlfwhMkMMAlQa/y4422jDmizW+ng==", - "dependencies": { - "@cosmjs/stream": "^0.31.1", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/math": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.31.1.tgz", - "integrity": "sha512-kiuHV6m6DSB8/4UV1qpFhlc4ul8SgLXTGRlYkYiIIP4l0YNeJ+OpPYaOlEgx4Unk2mW3/O2FWYj7Jc93+BWXng==", - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/@cosmjs/proto-signing": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.29.5.tgz", - "integrity": "sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA==", - "dev": true, - "dependencies": { - "@cosmjs/amino": "^0.29.5", - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0" - } - }, - "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/amino": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.5.tgz", - "integrity": "sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==", - "dev": true, - "dependencies": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5" - } - }, - "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "dev": true, - "dependencies": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/@cosmjs/proto-signing/node_modules/@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==", - "dev": true - }, - "node_modules/@cosmjs/proto-signing/node_modules/cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@cosmjs/proto-signing/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/@cosmjs/socket": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.31.1.tgz", - "integrity": "sha512-XTtEr+x3WGbqkzoGX0sCkwVqf5n+bBqDwqNgb+DWaBABQxHVRuuainrTVp0Yc91D3Iy2twLQzeBA9OrRxDSerw==", - "dependencies": { - "@cosmjs/stream": "^0.31.1", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/stargate": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.31.1.tgz", - "integrity": "sha512-TqOJZYOH5W3sZIjR6949GfjhGXO3kSHQ3/KmE+SuKyMMmQ5fFZ45beawiRtVF0/CJg5RyPFyFGJKhb1Xxv3Lcg==", - "dependencies": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/proto-signing": "^0.31.1", - "@cosmjs/stream": "^0.31.1", - "@cosmjs/tendermint-rpc": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/stargate/node_modules/@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/stargate/node_modules/@cosmjs/proto-signing": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz", - "integrity": "sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg==", - "dependencies": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" - } - }, - "node_modules/@cosmjs/stargate/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@cosmjs/stargate/node_modules/cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@cosmjs/stargate/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/@cosmjs/stream": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.31.1.tgz", - "integrity": "sha512-xsIGD9bpBvYYZASajCyOevh1H5pDdbOWmvb4UwGZ78doGVz3IC3Kb9BZKJHIX2fjq9CMdGVJHmlM+Zp5aM8yZA==", - "dependencies": { - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.31.1.tgz", - "integrity": "sha512-KX+wwi725sSePqIxfMPPOqg+xTETV8BHGOBhRhCZXEl5Fq48UlXXq3/yG1sn7K67ADC0kqHqcCF41Wn1GxNNPA==", - "dependencies": { - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/json-rpc": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/socket": "^0.31.1", - "@cosmjs/stream": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc/node_modules/@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "dependencies": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@cosmjs/tendermint-rpc/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@cosmjs/utils": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.31.1.tgz", - "integrity": "sha512-n4Se1wu4GnKwztQHNFfJvUeWcpvx3o8cWhSbNs9JQShEuB3nv3R5lqFBtDCgHZF/emFQAP+ZjF8bTfCs9UBGhA==" - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "dev": true, - "dependencies": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - } - }, - "node_modules/@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "dev": true, - "dependencies": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/providers/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@graphql-typed-document-node/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "dev": true, - "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@improbable-eng/grpc-web": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.15.0.tgz", - "integrity": "sha512-ERft9/0/8CmYalqOVnJnpdDry28q+j+nAlFFARdjyxXDJ+Mhgv9+F600QC8BR9ygOfrXRlAk6CvST2j+JCpQPg==", - "dev": true, - "peer": true, - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@improbable-eng/grpc-web-node-http-transport": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.15.0.tgz", - "integrity": "sha512-HLgJfVolGGpjc9DWPhmMmXJx8YGzkek7jcCFO1YYkSOoO81MWRZentPOd/JiKiZuU08wtc4BG+WNuGzsQB5jZA==", - "dev": true, - "peerDependencies": { - "@improbable-eng/grpc-web": ">=0.13.0" - } - }, - "node_modules/@improbable-eng/grpc-web-react-native-transport": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web-react-native-transport/-/grpc-web-react-native-transport-0.15.0.tgz", - "integrity": "sha512-Xk+abATz3eacJ0gA5sRYpyMCA+z/37ht4u6AsbtfcE3SXLYIPbTQ2iLQYyELAoyUWgAyEQxZ3iTs6OpR4z06FQ==", - "dev": true, - "peerDependencies": { - "@improbable-eng/grpc-web": ">=0.13.0" - } - }, - "node_modules/@injectivelabs/chain-api": { - "version": "1.9.6", - "resolved": "https://registry.npmjs.org/@injectivelabs/chain-api/-/chain-api-1.9.6.tgz", - "integrity": "sha512-Z17SsI816TEDiRLiswUZE+8n/nCUTyat9WPxsaccB7mmsjFtC7jVzVBgLKE3pTIsON1CkJhhWAO3ApHddyCWlg==", - "dev": true, - "dependencies": { - "@improbable-eng/grpc-web": "^0.13.0", - "google-protobuf": "^3.13.0" - } - }, - "node_modules/@injectivelabs/chain-api/node_modules/@improbable-eng/grpc-web": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.13.0.tgz", - "integrity": "sha512-vaxxT+Qwb7GPqDQrBV4vAAfH0HywgOLw6xGIKXd9Q8hcV63CQhmS3p4+pZ9/wVvt4Ph3ZDK9fdC983b9aGMUFg==", - "dev": true, - "dependencies": { - "browser-headers": "^0.4.0" - }, - "peerDependencies": { - "google-protobuf": "^3.2.0" - } - }, - "node_modules/@injectivelabs/exceptions": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.12.1.tgz", - "integrity": "sha512-aYmKgw8JzO3GoWFPrPurMOaPokmdh2/v2DW23mb3a51L40NZl5yDUaRilmzCWg+xtwmpWaWANBCgvcEpqtqxNw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@injectivelabs/grpc-web": "^0.0.1", - "@injectivelabs/ts-types": "^1.12.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2" - } - }, - "node_modules/@injectivelabs/grpc-web": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web/-/grpc-web-0.0.1.tgz", - "integrity": "sha512-Pu5YgaZp+OvR5UWfqbrPdHer3+gDf+b5fQoY+t2VZx1IAVHX8bzbN9EreYTvTYtFeDpYRWM8P7app2u4EX5wTw==", - "dev": true, - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@injectivelabs/indexer-api": { - "version": "1.10.0-rc.2.5", - "resolved": "https://registry.npmjs.org/@injectivelabs/indexer-api/-/indexer-api-1.10.0-rc.2.5.tgz", - "integrity": "sha512-QR5I/bw+4PAYcXwdR5OT4Q9yju/uk1Vj5SEtCgQH0GFlR7sGGpDOrSBpbeSQeHk89AAHyyQpAKJYe+0HPr21bA==", - "dev": true, - "dependencies": { - "@improbable-eng/grpc-web": "^0.14.0", - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@injectivelabs/indexer-api/node_modules/@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "dev": true, - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@injectivelabs/networks": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.12.1.tgz", - "integrity": "sha512-X1njEOynG6CPRfQe1k/bvPSuCGCICRu98oIgNpRh4/qx4N168hPaWx0Te3d9WXx2bgkelGrk8x/VFS4NdWrIYg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "@injectivelabs/utils": "^1.12.1", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2" - } - }, - "node_modules/@injectivelabs/networks/node_modules/@injectivelabs/utils": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.12.1.tgz", - "integrity": "sha512-BAug0w+WipBDLv5FO3ANTSmL3dNd61T0P6bp9mW5gZ0VKs4Jc5Uybv7lE5IUOWR2+nk8I90O45qpF4DbP/BnEg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "axios": "^0.21.1", - "bignumber.js": "^9.0.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - } - }, - "node_modules/@injectivelabs/networks/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@injectivelabs/ninja-api": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@injectivelabs/ninja-api/-/ninja-api-1.0.20.tgz", - "integrity": "sha512-bZNIX23iq/qwmLr70z6EnxVaE8uSmAvsHVs/XMHNtcmx9jYdtqg+6e1lhGZ7wxsRUUijUT9u6e5xLCHNPYSlKg==", - "dev": true, - "dependencies": { - "@injectivelabs/grpc-web": "^0.0.1", - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@injectivelabs/sdk-ts": { - "version": "1.0.452", - "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.0.452.tgz", - "integrity": "sha512-E/zB9eW40VCrHy6+bXyVval48RBR/cVjXxPgsxWAhDIkG1gaLFtJ1yjgItDchyjELaG2o4o4XH15hKud7jBLmw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@apollo/client": "^3.5.8", - "@cosmjs/amino": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stargate": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@ethersproject/bytes": "^5.7.0", - "@improbable-eng/grpc-web-node-http-transport": "^0.15.0", - "@improbable-eng/grpc-web-react-native-transport": "^0.15.0", - "@injectivelabs/chain-api": "1.9.6", - "@injectivelabs/exceptions": "^1.0.56", - "@injectivelabs/grpc-web": "^0.0.1", - "@injectivelabs/indexer-api": "1.10.0-rc.2.5", - "@injectivelabs/networks": "^1.0.93", - "@injectivelabs/ninja-api": "^1.0.11", - "@injectivelabs/token-metadata": "^1.0.170", - "@injectivelabs/ts-types": "^1.0.29", - "@injectivelabs/utils": "^1.0.81", - "@metamask/eth-sig-util": "^4.0.0", - "@types/google-protobuf": "^3.15.5", - "axios": "^0.27.2", - "bech32": "^2.0.0", - "bip39": "^3.0.4", - "eth-crypto": "^2.3.0", - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.4", - "ethers": "^5.6.4", - "ethjs-util": "^0.1.6", - "google-protobuf": "^3.21.0", - "graphql": "^16.3.0", - "http-status-codes": "^2.2.0", - "jscrypto": "^1.0.3", - "keccak256": "^1.0.6", - "link-module-alias": "^1.2.0", - "secp256k1": "^4.0.3", - "shx": "^0.3.2", - "snakecase-keys": "^5.4.1" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/amino": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.5.tgz", - "integrity": "sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==", - "dev": true, - "dependencies": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "dev": true, - "dependencies": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/json-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz", - "integrity": "sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==", - "dev": true, - "dependencies": { - "@cosmjs/stream": "^0.29.5", - "xstream": "^11.14.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/socket": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.29.5.tgz", - "integrity": "sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==", - "dev": true, - "dependencies": { - "@cosmjs/stream": "^0.29.5", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/stargate": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.29.5.tgz", - "integrity": "sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw==", - "dev": true, - "dependencies": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/stream": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.29.5.tgz", - "integrity": "sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==", - "dev": true, - "dependencies": { - "xstream": "^11.14.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/tendermint-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz", - "integrity": "sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==", - "dev": true, - "dependencies": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/json-rpc": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/socket": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/tendermint-rpc/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==", - "dev": true - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@injectivelabs/sdk-ts/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/@injectivelabs/token-metadata": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.12.1.tgz", - "integrity": "sha512-i5pJ3M2alxL9jM1RWgkVGwPcvkUmJCNxwfA7rZ8+PPNUwmPzckwuHy+6EYMLpuXy10ft6eskoDwd4/1CRgamFg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/networks": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "@injectivelabs/utils": "^1.12.1", - "@types/lodash.values": "^4.3.6", - "copyfiles": "^2.4.1", - "jsonschema": "^1.4.0", - "link-module-alias": "^1.2.0", - "lodash": "^4.17.21", - "lodash.values": "^4.3.0", - "shx": "^0.3.2" - } - }, - "node_modules/@injectivelabs/token-metadata/node_modules/@injectivelabs/utils": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.12.1.tgz", - "integrity": "sha512-BAug0w+WipBDLv5FO3ANTSmL3dNd61T0P6bp9mW5gZ0VKs4Jc5Uybv7lE5IUOWR2+nk8I90O45qpF4DbP/BnEg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "axios": "^0.21.1", - "bignumber.js": "^9.0.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - } - }, - "node_modules/@injectivelabs/token-metadata/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@injectivelabs/ts-types": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.12.1.tgz", - "integrity": "sha512-Bj/GtZLG8VPfANckzPHA8YWgdoq9acX6eOyqNTs9f1R+wA18SYjqoihS8zEexRfUzgxZSPaYEXCSMaawEZTIQQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "link-module-alias": "^1.2.0", - "shx": "^0.3.2" - } - }, - "node_modules/@injectivelabs/utils": { - "version": "1.0.81", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.0.81.tgz", - "integrity": "sha512-Eh3SEXj1E6eTnfxLWRWTax/AuGHJxrB2EkvewnKe0yZTr85x3+yn3+yNQjsKR+BrdyHDQ3KUJB5R+NSQlbK/Sw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@injectivelabs/exceptions": "^1.0.56", - "@injectivelabs/ts-types": "^1.0.29", - "axios": "^0.21.1", - "bignumber.js": "^9.0.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - } - }, - "node_modules/@injectivelabs/utils/node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/nyc-config-typescript": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.2.tgz", - "integrity": "sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "nyc": ">=15" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@keplr-wallet/types": { - "version": "0.11.64", - "resolved": "https://registry.npmjs.org/@keplr-wallet/types/-/types-0.11.64.tgz", - "integrity": "sha512-GgzeLDHHfZFyne3O7UIfFHj/uYqVbxAZI31RbBwt460OBbvwQzjrlZwvJW3vieWRAgxKSITjzEDBl2WneFTQdQ==", - "dev": true, - "dependencies": { - "axios": "^0.27.2", - "long": "^4.0.0" - } - }, - "node_modules/@keplr-wallet/types/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@keplr-wallet/types/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/samsam": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", - "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "node_modules/@terra-money/terra.js": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.10.tgz", - "integrity": "sha512-MqR16LjTUyVD4HnEavP1iBW0c1roCoRHH/E1x9P44pXzgtv2wsMeP+2un4Bnck4Nkv/46Xvy/BSKiY90ll3BKA==", - "dev": true, - "dependencies": { - "@classic-terra/terra.proto": "^1.1.0", - "@terra-money/terra.proto": "^2.1.0", - "axios": "^0.27.2", - "bech32": "^2.0.0", - "bip32": "^2.0.6", - "bip39": "^3.0.3", - "bufferutil": "^4.0.3", - "decimal.js": "^10.2.1", - "jscrypto": "^1.0.1", - "readable-stream": "^3.6.0", - "secp256k1": "^4.0.2", - "tmp": "^0.2.1", - "utf-8-validate": "^5.0.5", - "ws": "^7.5.9" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@terra-money/terra.js/node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "node_modules/@terra-money/terra.proto": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.1.0.tgz", - "integrity": "sha512-rhaMslv3Rkr+QsTQEZs64FKA4QlfO0DfQHaR6yct/EovenMkibDEQ63dEL6yJA6LCaEQGYhyVB9JO9pTUA8ybw==", - "dev": true, - "dependencies": { - "@improbable-eng/grpc-web": "^0.14.1", - "google-protobuf": "^3.17.3", - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/@terra-money/terra.proto/node_modules/@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "dev": true, - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@terra-money/terra.proto/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==", - "dev": true - }, - "node_modules/@types/cli-progress": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.1.tgz", - "integrity": "sha512-d9iA+0uys9N6wV/SvZkDEWMYwv+e/mhWPLa6lncQ1ZqrC3mXHnDmidanVGoVGnmCQ3mCxyu9S09Y2s18u5wL5w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/google-protobuf": { - "version": "3.15.6", - "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.6.tgz", - "integrity": "sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==", - "dev": true - }, - "node_modules/@types/lodash.values": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/@types/lodash.values/-/lodash.values-4.3.7.tgz", - "integrity": "sha512-Moex9/sWxtKEa+BKiH5zvmhfcieDlcz4wRxMhO/oJ2qOKUdujoU6dQjUTxWA8jwEREpHXmiY4HCwNRpycW8JQA==", - "dev": true, - "dependencies": { - "@types/lodash": "*" - } - }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true - }, - "node_modules/@types/mocha-steps": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/mocha-steps/-/mocha-steps-1.3.0.tgz", - "integrity": "sha512-hI0P9rS20BhHSXWTqLYcRYy6PGYk9vMZFNX7UF0ZWUrDMuqawtVRuTkYq7rG25sBSpL28BZggABBecFDK6ZZyg==", - "dev": true, - "dependencies": { - "@types/mocha": "*" - } - }, - "node_modules/@types/node": { - "version": "18.17.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.14.tgz", - "integrity": "sha512-ZE/5aB73CyGqgQULkLG87N9GnyGe5TcQjv34pwS8tfBs1IkCh0ASM69mydb2znqd6v0eX+9Ytvk6oQRqu8T1Vw==" - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", - "dev": true - }, - "node_modules/@types/sha256": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@types/sha256/-/sha256-0.2.0.tgz", - "integrity": "sha512-QYMr6HuxTQunFWRLZpGopbkgQFoFWOmKTBGgNSYiWMqU/CWnQSTo3edyHvgsRXsOWtOSOG/cmDptPzgCeOsQGw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/sinon": { - "version": "10.0.16", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz", - "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==", - "dev": true, - "dependencies": { - "@types/sinonjs__fake-timers": "*" - } - }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", - "dev": true - }, - "node_modules/@types/triple-beam": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", - "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@wry/context": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.3.tgz", - "integrity": "sha512-Nl8WTesHp89RF803Se9X3IiHjdmLBrIvPMaJkl+rKVJAYyPsz1TEUbu89943HpvujtSJgDUx9W4vZw3K1Mr3sA==", - "dev": true, - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@wry/equality": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.6.tgz", - "integrity": "sha512-D46sfMTngaYlrH+OspKf8mIJETntFnf6Hsjb0V41jAXJ7Bx2kB8Rv8RCUujuVWYttFtHkUNp7g+FwxNQAr6mXA==", - "dev": true, - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@wry/trie": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.4.3.tgz", - "integrity": "sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==", - "dev": true, - "dependencies": { - "tslib": "^2.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "node_modules/aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "dev": true, - "dependencies": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ajv": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.1.tgz", - "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrgv": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", - "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/arrify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", - "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/ava": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.3.tgz", - "integrity": "sha512-9Egq/d9R74ExrWohHeqUlexjDbgZJX5jA1Wq4KCTqc3wIfpGEK79zVy4rBtofJ9YKIxs4PzhJ8BgbW5PlAYe6w==", - "dev": true, - "dependencies": { - "acorn": "^8.7.1", - "acorn-walk": "^8.2.0", - "ansi-styles": "^6.1.0", - "arrgv": "^1.0.2", - "arrify": "^3.0.0", - "callsites": "^4.0.0", - "cbor": "^8.1.0", - "chalk": "^5.0.1", - "chokidar": "^3.5.3", - "chunkd": "^2.0.1", - "ci-info": "^3.3.1", - "ci-parallel-vars": "^1.0.1", - "clean-yaml-object": "^0.1.0", - "cli-truncate": "^3.1.0", - "code-excerpt": "^4.0.0", - "common-path-prefix": "^3.0.0", - "concordance": "^5.0.4", - "currently-unhandled": "^0.4.1", - "debug": "^4.3.4", - "del": "^6.1.1", - "emittery": "^0.11.0", - "figures": "^4.0.1", - "globby": "^13.1.1", - "ignore-by-default": "^2.1.0", - "indent-string": "^5.0.0", - "is-error": "^2.2.2", - "is-plain-object": "^5.0.0", - "is-promise": "^4.0.0", - "matcher": "^5.0.0", - "mem": "^9.0.2", - "ms": "^2.1.3", - "p-event": "^5.0.1", - "p-map": "^5.4.0", - "picomatch": "^2.3.1", - "pkg-conf": "^4.0.0", - "plur": "^5.1.0", - "pretty-ms": "^7.0.1", - "resolve-cwd": "^3.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.5", - "strip-ansi": "^7.0.1", - "supertap": "^3.0.1", - "temp-dir": "^2.0.0", - "write-file-atomic": "^4.0.1", - "yargs": "^17.5.1" - }, - "bin": { - "ava": "entrypoints/cli.mjs" - }, - "engines": { - "node": ">=12.22 <13 || >=14.17 <15 || >=16.4 <17 || >=18" - }, - "peerDependencies": { - "@ava/typescript": "*" - }, - "peerDependenciesMeta": { - "@ava/typescript": { - "optional": true - } - } - }, - "node_modules/ava/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dev": true, - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ava/node_modules/globby/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", - "dev": true - }, - "node_modules/bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bintrees": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", - "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" - }, - "node_modules/bip32": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", - "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", - "dev": true, - "dependencies": { - "@types/node": "10.12.18", - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.1.3", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bip32/node_modules/@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", - "dev": true - }, - "node_modules/bip39": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", - "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", - "dev": true, - "dependencies": { - "@noble/hashes": "^1.2.0" - } - }, - "node_modules/bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", - "dev": true, - "optional": true, - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "node_modules/blueimp-md5": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", - "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", - "dev": true - }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "node_modules/browser-headers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", - "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==", - "dev": true - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/caching-transform/node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.1.0.tgz", - "integrity": "sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001527", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001527.tgz", - "integrity": "sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "dependencies": { - "nofilter": "^3.1.0" - }, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/chai": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", - "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chunkd": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", - "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", - "dev": true - }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/ci-parallel-vars": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", - "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", - "dev": true - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/clean-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/code-excerpt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", - "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", - "dev": true, - "dependencies": { - "convert-to-spaces": "^2.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz", - "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concordance": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", - "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", - "dev": true, - "dependencies": { - "date-time": "^3.1.0", - "esutils": "^2.0.3", - "fast-diff": "^1.2.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.17.15", - "md5-hex": "^3.0.1", - "semver": "^7.3.2", - "well-known-symbols": "^2.0.0" - }, - "engines": { - "node": ">=10.18.0 <11 || >=12.14.0 <13 || >=14" - } - }, - "node_modules/convert-hex": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/convert-hex/-/convert-hex-0.1.0.tgz", - "integrity": "sha512-w20BOb1PiR/sEJdS6wNrUjF5CSfscZFUp7R9NSlXH8h2wynzXVEPFPJECAnkNylZ+cvf3p7TyRUHggDmrwXT9A==" - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/convert-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/convert-string/-/convert-string-0.1.0.tgz", - "integrity": "sha512-1KX9ESmtl8xpT2LN2tFnKSbV4NiarbVi8DVb39ZriijvtTklyrT+4dT1wsGMHKD3CJUjXgvJzstm9qL9ICojGA==" - }, - "node_modules/convert-to-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", - "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/copyfiles": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", - "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", - "dev": true, - "dependencies": { - "glob": "^7.0.5", - "minimatch": "^3.0.3", - "mkdirp": "^1.0.4", - "noms": "0.0.0", - "through2": "^2.0.1", - "untildify": "^4.0.0", - "yargs": "^16.1.0" - }, - "bin": { - "copyfiles": "copyfiles", - "copyup": "copyfiles" - } - }, - "node_modules/copyfiles/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/copyfiles/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/copyfiles/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/copyfiles/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/copyfiles/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/copyfiles/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/copyfiles/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/cosmjs-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.6.1.tgz", - "integrity": "sha512-fRz6yzElHHBULDyLArF/G1UkkTWW4r3RondBUGnmSsZWYI5NpfDn32MVa5aRmpaaf4tJI2cbnXHs9fykwU7Ttg==", - "dev": true, - "dependencies": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "node_modules/cosmjs-types/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "dev": true, - "dependencies": { - "node-fetch": "^2.6.12" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", - "dev": true - }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/date-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", - "dev": true, - "dependencies": { - "time-zone": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/del/node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/del/node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/del/node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/del/node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", - "dev": true, - "optional": true, - "dependencies": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0" - }, - "optionalDependencies": { - "secp256k1": "3.7.1" - } - }, - "node_modules/eccrypto/node_modules/acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eccrypto/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "optional": true - }, - "node_modules/eccrypto/node_modules/secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.508", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.508.tgz", - "integrity": "sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg==", - "dev": true - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emittery": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.11.0.tgz", - "integrity": "sha512-S/7tzL6v5i+4iJd627Nhv9cLFIo5weAIlGccqJFpnBoDB8U1TF2k5tez4J/QNuxyyhWuFqHg1L84Kd3m7iXg6g==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-ex/node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", - "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-eslint-comments": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", - "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5", - "ignore": "^5.0.5" - }, - "engines": { - "node": ">=6.5.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eth-crypto": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eth-crypto/-/eth-crypto-2.6.0.tgz", - "integrity": "sha512-GCX4ffFYRUGgnuWR5qxcZIRQJ1KEqPFiyXU9yVy7s6dtXIMlUXZQ2h+5ID6rFaOHWbpJbjfkC6YdhwtwRYCnug==", - "dev": true, - "dependencies": { - "@babel/runtime": "7.20.13", - "@ethereumjs/tx": "3.5.2", - "@types/bn.js": "5.1.1", - "eccrypto": "1.1.6", - "ethereumjs-util": "7.1.5", - "ethers": "5.7.2", - "secp256k1": "5.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/pubkey" - } - }, - "node_modules/eth-crypto/node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "dev": true - }, - "node_modules/eth-crypto/node_modules/secp256k1": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", - "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^5.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethereumjs-abi/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/extract-files": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", - "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", - "dev": true, - "engines": { - "node": "^10.17.0 || ^12.0.0 || >= 13.7.0" - }, - "funding": { - "url": "https://github.com/sponsors/jaydenseric" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.4.tgz", - "integrity": "sha512-mNlGUdKOeGNleyrmgbKYtbnCr9KZkZXU7eM89JRo8vY10f7Ul1Fbj07hUBW3N4fC0xM+fmfFfa2zM7mIizhpNQ==" - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "node_modules/figures": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/figures/-/figures-4.0.1.tgz", - "integrity": "sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", - "dev": true, - "dependencies": { - "flatted": "^3.2.7", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==", - "dev": true - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/graphql": { - "version": "16.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.0.tgz", - "integrity": "sha512-0oKGaR+y3qcS5mCu1vb7KG+a89vjn06C7Ihq/dDl3jA+A8B3TKomvi3CiEcVLJQGalbu8F52LxkOym7U5sSfbg==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" - } - }, - "node_modules/graphql-request": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-5.2.0.tgz", - "integrity": "sha512-pLhKIvnMyBERL0dtFI3medKqWOz/RhHdcgbZ+hMMIb32mEPa5MJSzS4AuXxfI4sRAu6JVVk5tvXuGfCWl9JYWQ==", - "dev": true, - "dependencies": { - "@graphql-typed-document-node/core": "^3.1.1", - "cross-fetch": "^3.1.5", - "extract-files": "^9.0.0", - "form-data": "^3.0.0" - }, - "peerDependencies": { - "graphql": "14 - 16" - } - }, - "node_modules/graphql-request/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/graphql-tag": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-status-codes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", - "integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==", - "dev": true - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz", - "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==", - "dev": true, - "engines": { - "node": ">=10 <11 || >=12 <13 || >=14" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/irregular-plurals": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", - "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-error": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", - "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-processinfo/node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/istanbul-lib-report/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "node_modules/js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jscrypto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/jscrypto/-/jscrypto-1.0.3.tgz", - "integrity": "sha512-lryZl0flhodv4SZHOqyb1bx5sKcJxj0VBo0Kzb4QMAg3L021IC9uGpl0RCZa+9KJwlRGSK2C80ITcwbe19OKLQ==", - "dev": true, - "bin": { - "jscrypto": "bin/cli.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "dev": true - }, - "node_modules/keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, - "node_modules/keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/libsodium": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.6.tgz", - "integrity": "sha512-hPb/04sEuLcTRdWDtd+xH3RXBihpmbPCsKW/Jtf4PsvdyKh+D6z2D2gvp/5BfoxseP+0FCOg66kE+0oGUE/loQ==", - "dev": true - }, - "node_modules/libsodium-sumo": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.11.tgz", - "integrity": "sha512-bY+7ph7xpk51Ez2GbE10lXAQ5sJma6NghcIDaSPbM/G9elfrjLa0COHl/7P6Wb/JizQzl5UQontOOP1z0VwbLA==" - }, - "node_modules/libsodium-wrappers": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.6.tgz", - "integrity": "sha512-OUO2CWW5bHdLr6hkKLHIKI4raEkZrf3QHkhXsJ1yCh6MZ3JDA7jFD3kCATNquuGSG6MjjPHQIQms0y0gBDzjQg==", - "dev": true, - "dependencies": { - "libsodium": "0.7.6" - } - }, - "node_modules/libsodium-wrappers-sumo": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.11.tgz", - "integrity": "sha512-DGypHOmJbB1nZn89KIfGOAkDgfv5N6SBGC3Qvmy/On0P0WD1JQvNRS/e3UL3aFF+xC0m+MYz5M+MnRnK2HMrKQ==", - "dependencies": { - "libsodium-sumo": "^0.7.11" - } - }, - "node_modules/link-module-alias": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/link-module-alias/-/link-module-alias-1.2.0.tgz", - "integrity": "sha512-ahPjXepbSVKbahTB6LxR//VHm8HPfI+QQygCH+E82spBY4HR5VPJTvlhKBc9F7muVxnS6C1rRfoPOXAbWO/fyw==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1" - }, - "bin": { - "link-module-alias": "index.js" - }, - "engines": { - "node": "> 8.0.0" - } - }, - "node_modules/link-module-alias/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/link-module-alias/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/link-module-alias/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/link-module-alias/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/link-module-alias/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", - "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" - }, - "node_modules/lodash.values": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz", - "integrity": "sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/logform": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz", - "integrity": "sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==", - "dependencies": { - "@colors/colors": "1.5.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - } - }, - "node_modules/long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "dev": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/matcher": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", - "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/md5-hex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", - "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", - "dev": true, - "dependencies": { - "blueimp-md5": "^2.10.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mem": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", - "integrity": "sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==", - "dev": true, - "dependencies": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sindresorhus/mem?sponsor=1" - } - }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha-steps": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz", - "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==", - "dev": true - }, - "node_modules/mocha/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mocha/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/nise": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", - "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp-build": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", - "devOptional": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true - }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true, - "engines": { - "node": ">=12.19" - } - }, - "node_modules/noms": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", - "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "~1.0.31" - } - }, - "node_modules/noms/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/noms/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/noms/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "bin": { - "npm-run-all": "bin/npm-run-all/index.js", - "run-p": "bin/run-p/index.js", - "run-s": "bin/run-s/index.js" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm-run-all/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/npm-run-all/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/npm-run-all/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/npm-run-all/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-all/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-all/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/nyc/node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/nyc/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/nyc/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/onetime/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/optimism": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.17.5.tgz", - "integrity": "sha512-TEcp8ZwK1RczmvMnvktxHSF2tKgMWjJ71xEFGX5ApLh67VsMSTy1ZUlipJw8W+KaqgOmQ+4pqwkeivY89j+4Vw==", - "dev": true, - "dependencies": { - "@wry/context": "^0.7.0", - "@wry/trie": "^0.4.3", - "tslib": "^2.3.0" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-event": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", - "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", - "dev": true, - "dependencies": { - "p-timeout": "^5.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", - "dev": true, - "dependencies": { - "aggregate-error": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module/node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/path-to-regexp/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true, - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz", - "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==", - "dev": true, - "dependencies": { - "find-up": "^6.0.0", - "load-json-file": "^7.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-conf/node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/pkg-conf/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/plur": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", - "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", - "dev": true, - "dependencies": { - "irregular-plurals": "^3.3.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", - "dev": true, - "dependencies": { - "parse-ms": "^2.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/prom-client": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.1.0.tgz", - "integrity": "sha512-jT9VccZCWrJWXdyEtQddCDszYsiuWj5T0ekrPszi/WEegj3IZy6Mm09iOOVM86A4IKMWq8hZkT2dD9MaSe+sng==", - "dependencies": { - "tdigest": "^0.1.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/protobufjs/node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readonly-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", - "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/response-iterator": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/response-iterator/-/response-iterator-0.2.6.tgz", - "integrity": "sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", - "engines": { - "node": ">=10" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/sha256": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/sha256/-/sha256-0.2.0.tgz", - "integrity": "sha512-kTWMJUaez5iiT9CcMv8jSq6kMhw3ST0uRdcIWl3D77s6AsLXNXRp3heeqqfu5+Dyfu4hwpQnMzhqHh8iNQxw0w==", - "dependencies": { - "convert-hex": "~0.1.0", - "convert-string": "~0.1.0" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shx": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", - "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", - "dev": true, - "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.5" - }, - "bin": { - "shx": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/sinon": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.2.tgz", - "integrity": "sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^9.1.2", - "@sinonjs/samsam": "^7.0.1", - "diff": "^5.0.0", - "nise": "^5.1.2", - "supports-color": "^7.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" - } - }, - "node_modules/sinon/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dev": true, - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/snakecase-keys": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-5.4.6.tgz", - "integrity": "sha512-7ipeNts8YTLbx/6zIaT1mQGrHG2vK+0TjywPD79QzIDJDcvNXBLX7DXQOt6by4DFdncu8lDPc+QHKHemtDEoQg==", - "dev": true, - "dependencies": { - "map-obj": "^4.1.0", - "snake-case": "^3.0.4", - "type-fest": "^2.5.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/snakecase-keys/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", - "engines": { - "node": "*" - } - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/store2": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz", - "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string.prototype.padend": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", - "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supertap": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", - "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", - "dev": true, - "dependencies": { - "indent-string": "^5.0.0", - "js-yaml": "^3.14.1", - "serialize-error": "^7.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/supertap/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/supertap/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-observable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/table/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/table/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/table/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tdigest": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", - "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", - "dependencies": { - "bintrees": "1.0.2" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tiny-secp256k1": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", - "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.3.0", - "bn.js": "^4.11.8", - "create-hmac": "^1.1.7", - "elliptic": "^6.4.0", - "nan": "^2.13.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/tiny-secp256k1/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "node_modules/ts-invariant": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", - "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz", - "integrity": "sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==", - "dev": true, - "dependencies": { - "ts-node": "7.0.1" - }, - "bin": { - "ts-mocha": "bin/ts-mocha" - }, - "engines": { - "node": ">= 6.X.X" - }, - "optionalDependencies": { - "tsconfig-paths": "^3.5.0" - }, - "peerDependencies": { - "mocha": "^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X" - } - }, - "node_modules/ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "dependencies": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "bin": { - "ts-node": "dist/bin.js" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/ts-node/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/ts-node/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==", - "dev": true - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "devOptional": true, - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/well-known-symbols": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", - "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==", - "dev": true, - "dependencies": { - "bs58check": "<3.0.0" - } - }, - "node_modules/winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "dependencies": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", - "dependencies": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xstream": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", - "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", - "dependencies": { - "globalthis": "^1.0.1", - "symbol-observable": "^2.0.3" - } - }, - "node_modules/xstream/node_modules/symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", - "dev": true - }, - "node_modules/zen-observable-ts": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", - "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", - "dev": true, - "dependencies": { - "zen-observable": "0.8.15" - } - } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@andromedaprotocol/andromeda.js": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@andromedaprotocol/andromeda.js/-/andromeda.js-0.3.3.tgz", - "integrity": "sha512-szjlwxQD0TRSSaKRqqlq7eiZDyy/vqiqe4shGVg/E5YsKe5/rWFtOwTDwfjjtUp82j/SvCox7zP5bh+KXEvIgQ==", - "dev": true, - "requires": { - "@cosmjs/cosmwasm-stargate": "^0.29.5", - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stargate": "^0.29.5", - "@injectivelabs/networks": "^1.0.93", - "@injectivelabs/sdk-ts": "1.0.452", - "@injectivelabs/utils": "1.0.81", - "@keplr-wallet/types": "^0.11.44", - "@terra-money/terra.js": "^3.1.7", - "axios": "^1.3.4", - "bech32": "^2.0.0", - "cosmjs-types": "^0.6.1", - "crypto-js": "^4.1.1", - "ethers": "^5.7.2", - "graphql-request": "^5.1.0", - "jsonschema": "^1.4.1", - "libsodium-wrappers": "0.7.6", - "lodash": "^4.17.21", - "long": "^5.2.1", - "pako": "^2.1.0" - }, - "dependencies": { - "@cosmjs/amino": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.5.tgz", - "integrity": "sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==", - "dev": true, - "requires": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5" - } - }, - "@cosmjs/cosmwasm-stargate": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz", - "integrity": "sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA==", - "dev": true, - "requires": { - "@cosmjs/amino": "^0.29.5", - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stargate": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "pako": "^2.0.2" - }, - "dependencies": { - "cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "dev": true, - "requires": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "@cosmjs/json-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz", - "integrity": "sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==", - "dev": true, - "requires": { - "@cosmjs/stream": "^0.29.5", - "xstream": "^11.14.0" - } - }, - "@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "dev": true, - "requires": { - "bn.js": "^5.2.0" - } - }, - "@cosmjs/socket": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.29.5.tgz", - "integrity": "sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==", - "dev": true, - "requires": { - "@cosmjs/stream": "^0.29.5", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "@cosmjs/stargate": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.29.5.tgz", - "integrity": "sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw==", - "dev": true, - "requires": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - }, - "dependencies": { - "cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "@cosmjs/stream": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.29.5.tgz", - "integrity": "sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==", - "dev": true, - "requires": { - "xstream": "^11.14.0" - } - }, - "@cosmjs/tendermint-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz", - "integrity": "sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==", - "dev": true, - "requires": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/json-rpc": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/socket": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - }, - "dependencies": { - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, - "@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==", - "dev": true - } - } - }, - "@apollo/client": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.8.3.tgz", - "integrity": "sha512-mK86JM6hCpMEBGDgdO9U8ZYS8r9lPjXE1tVGpJMdSFUsIcXpmEfHUAbbFpPtYmxn8Qa7XsYy0dwDaDhpf4UUPw==", - "dev": true, - "requires": { - "@graphql-typed-document-node/core": "^3.1.1", - "@wry/context": "^0.7.3", - "@wry/equality": "^0.5.6", - "@wry/trie": "^0.4.3", - "graphql-tag": "^2.12.6", - "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.17.5", - "prop-types": "^15.7.2", - "response-iterator": "^0.2.6", - "symbol-observable": "^4.0.0", - "ts-invariant": "^0.10.3", - "tslib": "^2.3.0", - "zen-observable-ts": "^1.2.5" - } - }, - "@ava/typescript": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@ava/typescript/-/typescript-3.0.1.tgz", - "integrity": "sha512-/JXIUuKsvkaneaiA9ckk3ksFTqvu0mDNlChASrTe2BnDsvMbhQdPWyqQjJ9WRJWVhhs5TWn1/0Pp1G6Rv8Syrw==", - "dev": true, - "requires": { - "escape-string-regexp": "^5.0.0", - "execa": "^5.1.1" - } - }, - "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", - "dev": true - }, - "@babel/core": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.15.tgz", - "integrity": "sha512-PtZqMmgRrvj8ruoEOIwVA3yoF91O+Hgw9o7DAUTNBA6Mo2jpu31clx9a7Nz/9JznqetTR6zwfC4L3LAjKQXUwA==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.15", - "@babel/helpers": "^7.22.15", - "@babel/parser": "^7.22.15", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", - "dev": true, - "requires": { - "@babel/types": "^7.22.15", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", - "dev": true, - "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "requires": { - "@babel/types": "^7.22.15" - } - }, - "@babel/helper-module-transforms": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", - "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" - } - }, - "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", - "dev": true - }, - "@babel/helpers": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", - "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", - "dev": true - }, - "@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.11" - } - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/traverse": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", - "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", - "to-fast-properties": "^2.0.0" - } - }, - "@classic-terra/terra.proto": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@classic-terra/terra.proto/-/terra.proto-1.1.0.tgz", - "integrity": "sha512-bYhQG5LUaGF0KPRY9hYT/HEcd1QExZPQd6zLV/rQkCe/eDxfwFRLzZHpaaAdfWoAAZjsRWqJbUCqCg7gXBbJpw==", - "dev": true, - "requires": { - "@improbable-eng/grpc-web": "^0.14.1", - "google-protobuf": "^3.17.3", - "long": "^4.0.0", - "protobufjs": "~6.11.2" - }, - "dependencies": { - "@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "dev": true, - "requires": { - "browser-headers": "^0.4.1" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" - }, - "@confio/ics23": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", - "integrity": "sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==", - "requires": { - "@noble/hashes": "^1.0.0", - "protobufjs": "^6.8.8" - } - }, - "@confio/relayer": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@confio/relayer/-/relayer-0.10.0.tgz", - "integrity": "sha512-/WW5Eyfgylby9u0wz6XakA7yo5hamdWh6pxkOYHPz0ls7ikd7Ld+c2fpRbL0Qg5wZn9+9P+Uhfj4l0pVl3WPgw==", - "requires": { - "@cosmjs/cosmwasm-stargate": "^0.31.0", - "@cosmjs/crypto": "^0.31.0", - "@cosmjs/encoding": "^0.31.0", - "@cosmjs/faucet-client": "^0.31.0", - "@cosmjs/math": "^0.31.0", - "@cosmjs/proto-signing": "^0.31.0", - "@cosmjs/stargate": "^0.31.0", - "@cosmjs/stream": "^0.31.0", - "@cosmjs/tendermint-rpc": "^0.31.0", - "@cosmjs/utils": "^0.31.0", - "ajv": "7.1.1", - "axios": "0.21.4", - "commander": "7.1.0", - "cosmjs-types": "^0.8.0", - "fast-safe-stringify": "2.0.4", - "js-yaml": "4.0.0", - "lodash": "4.17.21", - "prom-client": "13.1.0", - "protobufjs": "^6.10.3", - "table": "^6.7.1", - "triple-beam": "1.3.0", - "winston": "3.3.3" - }, - "dependencies": { - "@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "@cosmjs/proto-signing": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz", - "integrity": "sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg==", - "requires": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" - } - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - } - } - }, - "@cosmjs/amino": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.31.1.tgz", - "integrity": "sha512-kkB9IAkNEUFtjp/uwHv95TgM8VGJ4VWfZwrTyLNqBDD1EpSX2dsNrmUe7k8OMPzKlZUFcKmD4iA0qGvIwzjbGA==", - "requires": { - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1" - }, - "dependencies": { - "@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - } - } - }, - "@cosmjs/cosmwasm-stargate": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.31.1.tgz", - "integrity": "sha512-5hwv4oztFnpqnFaXhYxZc93na3qdxylT2kqms4pLzD8CWMEQmrwhdM4KpZimrsyZK55WiMQtTPsdSh7M8KLOow==", - "requires": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/proto-signing": "^0.31.1", - "@cosmjs/stargate": "^0.31.1", - "@cosmjs/tendermint-rpc": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", - "pako": "^2.0.2" - }, - "dependencies": { - "@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "@cosmjs/proto-signing": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz", - "integrity": "sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg==", - "requires": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - } - } - }, - "@cosmjs/crypto": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.31.1.tgz", - "integrity": "sha512-4R/SqdzdVzd4E5dpyEh1IKm5GbTqwDogutyIyyb1bcOXiX/x3CrvPI9Tb4WSIMDLvlb5TVzu2YnUV51Q1+6mMA==", - "requires": { - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers-sumo": "^0.7.11" - }, - "dependencies": { - "@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - } - } - }, - "@cosmjs/encoding": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.29.5.tgz", - "integrity": "sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - }, - "dependencies": { - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - } - } - }, - "@cosmjs/faucet-client": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/faucet-client/-/faucet-client-0.31.1.tgz", - "integrity": "sha512-DrploDHvk86yCI0UiNkFMdMEfyR2bn8uvnj0jY8bGYgih7J1t0z3M/OsYhmLJLsF8JlxVFoD/gpV4nD0apXukw==", - "requires": { - "axios": "^0.21.2" - }, - "dependencies": { - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, - "@cosmjs/json-rpc": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.31.1.tgz", - "integrity": "sha512-gIkCj2mUDHAxvmJnHtybXtMLZDeXrkDZlujjzhvJlWsIuj1kpZbKtYqh+eNlfwhMkMMAlQa/y4422jDmizW+ng==", - "requires": { - "@cosmjs/stream": "^0.31.1", - "xstream": "^11.14.0" - } - }, - "@cosmjs/math": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.31.1.tgz", - "integrity": "sha512-kiuHV6m6DSB8/4UV1qpFhlc4ul8SgLXTGRlYkYiIIP4l0YNeJ+OpPYaOlEgx4Unk2mW3/O2FWYj7Jc93+BWXng==", - "requires": { - "bn.js": "^5.2.0" - } - }, - "@cosmjs/proto-signing": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.29.5.tgz", - "integrity": "sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA==", - "dev": true, - "requires": { - "@cosmjs/amino": "^0.29.5", - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0" - }, - "dependencies": { - "@cosmjs/amino": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.5.tgz", - "integrity": "sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==", - "dev": true, - "requires": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5" - } - }, - "@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "dev": true, - "requires": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "dev": true, - "requires": { - "bn.js": "^5.2.0" - } - }, - "@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==", - "dev": true - }, - "cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "@cosmjs/socket": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.31.1.tgz", - "integrity": "sha512-XTtEr+x3WGbqkzoGX0sCkwVqf5n+bBqDwqNgb+DWaBABQxHVRuuainrTVp0Yc91D3Iy2twLQzeBA9OrRxDSerw==", - "requires": { - "@cosmjs/stream": "^0.31.1", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "@cosmjs/stargate": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.31.1.tgz", - "integrity": "sha512-TqOJZYOH5W3sZIjR6949GfjhGXO3kSHQ3/KmE+SuKyMMmQ5fFZ45beawiRtVF0/CJg5RyPFyFGJKhb1Xxv3Lcg==", - "requires": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/proto-signing": "^0.31.1", - "@cosmjs/stream": "^0.31.1", - "@cosmjs/tendermint-rpc": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - }, - "dependencies": { - "@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "@cosmjs/proto-signing": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz", - "integrity": "sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg==", - "requires": { - "@cosmjs/amino": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "cosmjs-types": "^0.8.0", - "long": "^4.0.0" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "cosmjs-types": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.8.0.tgz", - "integrity": "sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==", - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - } - } - }, - "@cosmjs/stream": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.31.1.tgz", - "integrity": "sha512-xsIGD9bpBvYYZASajCyOevh1H5pDdbOWmvb4UwGZ78doGVz3IC3Kb9BZKJHIX2fjq9CMdGVJHmlM+Zp5aM8yZA==", - "requires": { - "xstream": "^11.14.0" - } - }, - "@cosmjs/tendermint-rpc": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.31.1.tgz", - "integrity": "sha512-KX+wwi725sSePqIxfMPPOqg+xTETV8BHGOBhRhCZXEl5Fq48UlXXq3/yG1sn7K67ADC0kqHqcCF41Wn1GxNNPA==", - "requires": { - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/json-rpc": "^0.31.1", - "@cosmjs/math": "^0.31.1", - "@cosmjs/socket": "^0.31.1", - "@cosmjs/stream": "^0.31.1", - "@cosmjs/utils": "^0.31.1", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - }, - "dependencies": { - "@cosmjs/encoding": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.31.1.tgz", - "integrity": "sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA==", - "requires": { - "base64-js": "^1.3.0", - "bech32": "^1.1.4", - "readonly-date": "^1.0.0" - } - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "requires": { - "follow-redirects": "^1.14.0" - } - }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - } - } - }, - "@cosmjs/utils": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.31.1.tgz", - "integrity": "sha512-n4Se1wu4GnKwztQHNFfJvUeWcpvx3o8cWhSbNs9JQShEuB3nv3R5lqFBtDCgHZF/emFQAP+ZjF8bTfCs9UBGhA==" - }, - "@dabh/diagnostics": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", - "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", - "dev": true - }, - "@ethereumjs/common": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-2.6.5.tgz", - "integrity": "sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "ethereumjs-util": "^7.1.5" - } - }, - "@ethereumjs/tx": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-3.5.2.tgz", - "integrity": "sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==", - "dev": true, - "requires": { - "@ethereumjs/common": "^2.6.4", - "ethereumjs-util": "^7.1.5" - } - }, - "@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" - } - }, - "@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0" - } - }, - "@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" - } - }, - "@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0" - } - }, - "@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", - "dev": true, - "requires": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" - } - }, - "@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", - "dev": true, - "requires": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "dev": true - }, - "@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" - } - }, - "@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "dev": true, - "requires": { - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", - "bech32": "1.1.4", - "ws": "7.4.6" - }, - "dependencies": { - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true - }, - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "dev": true, - "requires": {} - } - } - }, - "@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "dev": true, - "requires": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", - "dev": true, - "requires": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" - } - }, - "@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", - "dev": true, - "requires": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" - } - }, - "@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "dev": true, - "requires": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", - "dev": true, - "requires": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "@graphql-typed-document-node/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "dev": true, - "requires": {} - }, - "@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@improbable-eng/grpc-web": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.15.0.tgz", - "integrity": "sha512-ERft9/0/8CmYalqOVnJnpdDry28q+j+nAlFFARdjyxXDJ+Mhgv9+F600QC8BR9ygOfrXRlAk6CvST2j+JCpQPg==", - "dev": true, - "peer": true, - "requires": { - "browser-headers": "^0.4.1" - } - }, - "@improbable-eng/grpc-web-node-http-transport": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.15.0.tgz", - "integrity": "sha512-HLgJfVolGGpjc9DWPhmMmXJx8YGzkek7jcCFO1YYkSOoO81MWRZentPOd/JiKiZuU08wtc4BG+WNuGzsQB5jZA==", - "dev": true, - "requires": {} - }, - "@improbable-eng/grpc-web-react-native-transport": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web-react-native-transport/-/grpc-web-react-native-transport-0.15.0.tgz", - "integrity": "sha512-Xk+abATz3eacJ0gA5sRYpyMCA+z/37ht4u6AsbtfcE3SXLYIPbTQ2iLQYyELAoyUWgAyEQxZ3iTs6OpR4z06FQ==", - "dev": true, - "requires": {} - }, - "@injectivelabs/chain-api": { - "version": "1.9.6", - "resolved": "https://registry.npmjs.org/@injectivelabs/chain-api/-/chain-api-1.9.6.tgz", - "integrity": "sha512-Z17SsI816TEDiRLiswUZE+8n/nCUTyat9WPxsaccB7mmsjFtC7jVzVBgLKE3pTIsON1CkJhhWAO3ApHddyCWlg==", - "dev": true, - "requires": { - "@improbable-eng/grpc-web": "^0.13.0", - "google-protobuf": "^3.13.0" - }, - "dependencies": { - "@improbable-eng/grpc-web": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.13.0.tgz", - "integrity": "sha512-vaxxT+Qwb7GPqDQrBV4vAAfH0HywgOLw6xGIKXd9Q8hcV63CQhmS3p4+pZ9/wVvt4Ph3ZDK9fdC983b9aGMUFg==", - "dev": true, - "requires": { - "browser-headers": "^0.4.0" - } - } - } - }, - "@injectivelabs/exceptions": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/exceptions/-/exceptions-1.12.1.tgz", - "integrity": "sha512-aYmKgw8JzO3GoWFPrPurMOaPokmdh2/v2DW23mb3a51L40NZl5yDUaRilmzCWg+xtwmpWaWANBCgvcEpqtqxNw==", - "dev": true, - "requires": { - "@injectivelabs/grpc-web": "^0.0.1", - "@injectivelabs/ts-types": "^1.12.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2" - } - }, - "@injectivelabs/grpc-web": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/grpc-web/-/grpc-web-0.0.1.tgz", - "integrity": "sha512-Pu5YgaZp+OvR5UWfqbrPdHer3+gDf+b5fQoY+t2VZx1IAVHX8bzbN9EreYTvTYtFeDpYRWM8P7app2u4EX5wTw==", - "dev": true, - "requires": { - "browser-headers": "^0.4.1" - } - }, - "@injectivelabs/indexer-api": { - "version": "1.10.0-rc.2.5", - "resolved": "https://registry.npmjs.org/@injectivelabs/indexer-api/-/indexer-api-1.10.0-rc.2.5.tgz", - "integrity": "sha512-QR5I/bw+4PAYcXwdR5OT4Q9yju/uk1Vj5SEtCgQH0GFlR7sGGpDOrSBpbeSQeHk89AAHyyQpAKJYe+0HPr21bA==", - "dev": true, - "requires": { - "@improbable-eng/grpc-web": "^0.14.0", - "google-protobuf": "^3.14.0" - }, - "dependencies": { - "@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "dev": true, - "requires": { - "browser-headers": "^0.4.1" - } - } - } - }, - "@injectivelabs/networks": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/networks/-/networks-1.12.1.tgz", - "integrity": "sha512-X1njEOynG6CPRfQe1k/bvPSuCGCICRu98oIgNpRh4/qx4N168hPaWx0Te3d9WXx2bgkelGrk8x/VFS4NdWrIYg==", - "dev": true, - "requires": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "@injectivelabs/utils": "^1.12.1", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2" - }, - "dependencies": { - "@injectivelabs/utils": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.12.1.tgz", - "integrity": "sha512-BAug0w+WipBDLv5FO3ANTSmL3dNd61T0P6bp9mW5gZ0VKs4Jc5Uybv7lE5IUOWR2+nk8I90O45qpF4DbP/BnEg==", - "dev": true, - "requires": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "axios": "^0.21.1", - "bignumber.js": "^9.0.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - } - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, - "@injectivelabs/ninja-api": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/@injectivelabs/ninja-api/-/ninja-api-1.0.20.tgz", - "integrity": "sha512-bZNIX23iq/qwmLr70z6EnxVaE8uSmAvsHVs/XMHNtcmx9jYdtqg+6e1lhGZ7wxsRUUijUT9u6e5xLCHNPYSlKg==", - "dev": true, - "requires": { - "@injectivelabs/grpc-web": "^0.0.1", - "google-protobuf": "^3.14.0" - } - }, - "@injectivelabs/sdk-ts": { - "version": "1.0.452", - "resolved": "https://registry.npmjs.org/@injectivelabs/sdk-ts/-/sdk-ts-1.0.452.tgz", - "integrity": "sha512-E/zB9eW40VCrHy6+bXyVval48RBR/cVjXxPgsxWAhDIkG1gaLFtJ1yjgItDchyjELaG2o4o4XH15hKud7jBLmw==", - "dev": true, - "requires": { - "@apollo/client": "^3.5.8", - "@cosmjs/amino": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stargate": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@ethersproject/bytes": "^5.7.0", - "@improbable-eng/grpc-web-node-http-transport": "^0.15.0", - "@improbable-eng/grpc-web-react-native-transport": "^0.15.0", - "@injectivelabs/chain-api": "1.9.6", - "@injectivelabs/exceptions": "^1.0.56", - "@injectivelabs/grpc-web": "^0.0.1", - "@injectivelabs/indexer-api": "1.10.0-rc.2.5", - "@injectivelabs/networks": "^1.0.93", - "@injectivelabs/ninja-api": "^1.0.11", - "@injectivelabs/token-metadata": "^1.0.170", - "@injectivelabs/ts-types": "^1.0.29", - "@injectivelabs/utils": "^1.0.81", - "@metamask/eth-sig-util": "^4.0.0", - "@types/google-protobuf": "^3.15.5", - "axios": "^0.27.2", - "bech32": "^2.0.0", - "bip39": "^3.0.4", - "eth-crypto": "^2.3.0", - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^7.1.4", - "ethers": "^5.6.4", - "ethjs-util": "^0.1.6", - "google-protobuf": "^3.21.0", - "graphql": "^16.3.0", - "http-status-codes": "^2.2.0", - "jscrypto": "^1.0.3", - "keccak256": "^1.0.6", - "link-module-alias": "^1.2.0", - "secp256k1": "^4.0.3", - "shx": "^0.3.2", - "snakecase-keys": "^5.4.1" - }, - "dependencies": { - "@cosmjs/amino": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.29.5.tgz", - "integrity": "sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==", - "dev": true, - "requires": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5" - } - }, - "@cosmjs/crypto": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.29.5.tgz", - "integrity": "sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==", - "dev": true, - "requires": { - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "@noble/hashes": "^1", - "bn.js": "^5.2.0", - "elliptic": "^6.5.4", - "libsodium-wrappers": "^0.7.6" - } - }, - "@cosmjs/json-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz", - "integrity": "sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==", - "dev": true, - "requires": { - "@cosmjs/stream": "^0.29.5", - "xstream": "^11.14.0" - } - }, - "@cosmjs/math": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.29.5.tgz", - "integrity": "sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==", - "dev": true, - "requires": { - "bn.js": "^5.2.0" - } - }, - "@cosmjs/socket": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.29.5.tgz", - "integrity": "sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==", - "dev": true, - "requires": { - "@cosmjs/stream": "^0.29.5", - "isomorphic-ws": "^4.0.1", - "ws": "^7", - "xstream": "^11.14.0" - } - }, - "@cosmjs/stargate": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.29.5.tgz", - "integrity": "sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw==", - "dev": true, - "requires": { - "@confio/ics23": "^0.6.8", - "@cosmjs/amino": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/proto-signing": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "cosmjs-types": "^0.5.2", - "long": "^4.0.0", - "protobufjs": "~6.11.3", - "xstream": "^11.14.0" - } - }, - "@cosmjs/stream": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.29.5.tgz", - "integrity": "sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==", - "dev": true, - "requires": { - "xstream": "^11.14.0" - } - }, - "@cosmjs/tendermint-rpc": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz", - "integrity": "sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==", - "dev": true, - "requires": { - "@cosmjs/crypto": "^0.29.5", - "@cosmjs/encoding": "^0.29.5", - "@cosmjs/json-rpc": "^0.29.5", - "@cosmjs/math": "^0.29.5", - "@cosmjs/socket": "^0.29.5", - "@cosmjs/stream": "^0.29.5", - "@cosmjs/utils": "^0.29.5", - "axios": "^0.21.2", - "readonly-date": "^1.0.0", - "xstream": "^11.14.0" - }, - "dependencies": { - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, - "@cosmjs/utils": { - "version": "0.29.5", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.29.5.tgz", - "integrity": "sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==", - "dev": true - }, - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "cosmjs-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.2.tgz", - "integrity": "sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==", - "dev": true, - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "@injectivelabs/token-metadata": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/token-metadata/-/token-metadata-1.12.1.tgz", - "integrity": "sha512-i5pJ3M2alxL9jM1RWgkVGwPcvkUmJCNxwfA7rZ8+PPNUwmPzckwuHy+6EYMLpuXy10ft6eskoDwd4/1CRgamFg==", - "dev": true, - "requires": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/networks": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "@injectivelabs/utils": "^1.12.1", - "@types/lodash.values": "^4.3.6", - "copyfiles": "^2.4.1", - "jsonschema": "^1.4.0", - "link-module-alias": "^1.2.0", - "lodash": "^4.17.21", - "lodash.values": "^4.3.0", - "shx": "^0.3.2" - }, - "dependencies": { - "@injectivelabs/utils": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.12.1.tgz", - "integrity": "sha512-BAug0w+WipBDLv5FO3ANTSmL3dNd61T0P6bp9mW5gZ0VKs4Jc5Uybv7lE5IUOWR2+nk8I90O45qpF4DbP/BnEg==", - "dev": true, - "requires": { - "@injectivelabs/exceptions": "^1.12.1", - "@injectivelabs/ts-types": "^1.12.1", - "axios": "^0.21.1", - "bignumber.js": "^9.0.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - } - }, - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, - "@injectivelabs/ts-types": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@injectivelabs/ts-types/-/ts-types-1.12.1.tgz", - "integrity": "sha512-Bj/GtZLG8VPfANckzPHA8YWgdoq9acX6eOyqNTs9f1R+wA18SYjqoihS8zEexRfUzgxZSPaYEXCSMaawEZTIQQ==", - "dev": true, - "requires": { - "link-module-alias": "^1.2.0", - "shx": "^0.3.2" - } - }, - "@injectivelabs/utils": { - "version": "1.0.81", - "resolved": "https://registry.npmjs.org/@injectivelabs/utils/-/utils-1.0.81.tgz", - "integrity": "sha512-Eh3SEXj1E6eTnfxLWRWTax/AuGHJxrB2EkvewnKe0yZTr85x3+yn3+yNQjsKR+BrdyHDQ3KUJB5R+NSQlbK/Sw==", - "dev": true, - "requires": { - "@injectivelabs/exceptions": "^1.0.56", - "@injectivelabs/ts-types": "^1.0.29", - "axios": "^0.21.1", - "bignumber.js": "^9.0.1", - "http-status-codes": "^2.2.0", - "link-module-alias": "^1.2.0", - "shx": "^0.3.2", - "snakecase-keys": "^5.1.2", - "store2": "^2.12.0" - }, - "dependencies": { - "axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.0" - } - } - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/nyc-config-typescript": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/nyc-config-typescript/-/nyc-config-typescript-1.0.2.tgz", - "integrity": "sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2" - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "@keplr-wallet/types": { - "version": "0.11.64", - "resolved": "https://registry.npmjs.org/@keplr-wallet/types/-/types-0.11.64.tgz", - "integrity": "sha512-GgzeLDHHfZFyne3O7UIfFHj/uYqVbxAZI31RbBwt460OBbvwQzjrlZwvJW3vieWRAgxKSITjzEDBl2WneFTQdQ==", - "dev": true, - "requires": { - "axios": "^0.27.2", - "long": "^4.0.0" - }, - "dependencies": { - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dev": true, - "requires": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==" - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" - }, - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - }, - "@sinonjs/samsam": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", - "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "@terra-money/terra.js": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-3.1.10.tgz", - "integrity": "sha512-MqR16LjTUyVD4HnEavP1iBW0c1roCoRHH/E1x9P44pXzgtv2wsMeP+2un4Bnck4Nkv/46Xvy/BSKiY90ll3BKA==", - "dev": true, - "requires": { - "@classic-terra/terra.proto": "^1.1.0", - "@terra-money/terra.proto": "^2.1.0", - "axios": "^0.27.2", - "bech32": "^2.0.0", - "bip32": "^2.0.6", - "bip39": "^3.0.3", - "bufferutil": "^4.0.3", - "decimal.js": "^10.2.1", - "jscrypto": "^1.0.1", - "readable-stream": "^3.6.0", - "secp256k1": "^4.0.2", - "tmp": "^0.2.1", - "utf-8-validate": "^5.0.5", - "ws": "^7.5.9" - }, - "dependencies": { - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - } - } - }, - "@terra-money/terra.proto": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@terra-money/terra.proto/-/terra.proto-2.1.0.tgz", - "integrity": "sha512-rhaMslv3Rkr+QsTQEZs64FKA4QlfO0DfQHaR6yct/EovenMkibDEQ63dEL6yJA6LCaEQGYhyVB9JO9pTUA8ybw==", - "dev": true, - "requires": { - "@improbable-eng/grpc-web": "^0.14.1", - "google-protobuf": "^3.17.3", - "long": "^4.0.0", - "protobufjs": "~6.11.2" - }, - "dependencies": { - "@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "dev": true, - "requires": { - "browser-headers": "^0.4.1" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "@types/bn.js": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz", - "integrity": "sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==", - "dev": true - }, - "@types/cli-progress": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.1.tgz", - "integrity": "sha512-d9iA+0uys9N6wV/SvZkDEWMYwv+e/mhWPLa6lncQ1ZqrC3mXHnDmidanVGoVGnmCQ3mCxyu9S09Y2s18u5wL5w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/google-protobuf": { - "version": "3.15.6", - "resolved": "https://registry.npmjs.org/@types/google-protobuf/-/google-protobuf-3.15.6.tgz", - "integrity": "sha512-pYVNNJ+winC4aek+lZp93sIKxnXt5qMkuKmaqS3WGuTq0Bw1ZDYNBgzG5kkdtwcv+GmYJGo3yEg6z2cKKAiEdw==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/lodash": { - "version": "4.14.198", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.198.tgz", - "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==", - "dev": true - }, - "@types/lodash.values": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/@types/lodash.values/-/lodash.values-4.3.7.tgz", - "integrity": "sha512-Moex9/sWxtKEa+BKiH5zvmhfcieDlcz4wRxMhO/oJ2qOKUdujoU6dQjUTxWA8jwEREpHXmiY4HCwNRpycW8JQA==", - "dev": true, - "requires": { - "@types/lodash": "*" - } - }, - "@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" - }, - "@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", - "dev": true - }, - "@types/mocha-steps": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@types/mocha-steps/-/mocha-steps-1.3.0.tgz", - "integrity": "sha512-hI0P9rS20BhHSXWTqLYcRYy6PGYk9vMZFNX7UF0ZWUrDMuqawtVRuTkYq7rG25sBSpL28BZggABBecFDK6ZZyg==", - "dev": true, - "requires": { - "@types/mocha": "*" - } - }, - "@types/node": { - "version": "18.17.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.14.tgz", - "integrity": "sha512-ZE/5aB73CyGqgQULkLG87N9GnyGe5TcQjv34pwS8tfBs1IkCh0ASM69mydb2znqd6v0eX+9Ytvk6oQRqu8T1Vw==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", - "dev": true - }, - "@types/sha256": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@types/sha256/-/sha256-0.2.0.tgz", - "integrity": "sha512-QYMr6HuxTQunFWRLZpGopbkgQFoFWOmKTBGgNSYiWMqU/CWnQSTo3edyHvgsRXsOWtOSOG/cmDptPzgCeOsQGw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/sinon": { - "version": "10.0.16", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz", - "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==", - "dev": true, - "requires": { - "@types/sinonjs__fake-timers": "*" - } - }, - "@types/sinonjs__fake-timers": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz", - "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", - "dev": true - }, - "@types/triple-beam": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.2.tgz", - "integrity": "sha512-txGIh+0eDFzKGC25zORnswy+br1Ha7hj5cMVwKIU7+s0U2AxxJru/jZSMU6OC9MJWP6+pc/hc6ZjyZShpsyY2g==" - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@wry/context": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.3.tgz", - "integrity": "sha512-Nl8WTesHp89RF803Se9X3IiHjdmLBrIvPMaJkl+rKVJAYyPsz1TEUbu89943HpvujtSJgDUx9W4vZw3K1Mr3sA==", - "dev": true, - "requires": { - "tslib": "^2.3.0" - } - }, - "@wry/equality": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.6.tgz", - "integrity": "sha512-D46sfMTngaYlrH+OspKf8mIJETntFnf6Hsjb0V41jAXJ7Bx2kB8Rv8RCUujuVWYttFtHkUNp7g+FwxNQAr6mXA==", - "dev": true, - "requires": { - "tslib": "^2.3.0" - } - }, - "@wry/trie": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.4.3.tgz", - "integrity": "sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==", - "dev": true, - "requires": { - "tslib": "^2.3.0" - } - }, - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", - "dev": true - }, - "aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "dev": true, - "requires": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - } - }, - "ajv": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.1.tgz", - "integrity": "sha512-ga/aqDYnUy/o7vbsRTFhhTsNeXiYb5JWDIcRIeZfwRNCefwjNTVYCGdGSUrEmiu3yDK3vFvNbgJxvrQW4JXrYQ==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - } - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true - }, - "array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - } - }, - "array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - } - }, - "arrgv": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arrgv/-/arrgv-1.0.2.tgz", - "integrity": "sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==", - "dev": true - }, - "arrify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz", - "integrity": "sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "ava": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/ava/-/ava-4.3.3.tgz", - "integrity": "sha512-9Egq/d9R74ExrWohHeqUlexjDbgZJX5jA1Wq4KCTqc3wIfpGEK79zVy4rBtofJ9YKIxs4PzhJ8BgbW5PlAYe6w==", - "dev": true, - "requires": { - "acorn": "^8.7.1", - "acorn-walk": "^8.2.0", - "ansi-styles": "^6.1.0", - "arrgv": "^1.0.2", - "arrify": "^3.0.0", - "callsites": "^4.0.0", - "cbor": "^8.1.0", - "chalk": "^5.0.1", - "chokidar": "^3.5.3", - "chunkd": "^2.0.1", - "ci-info": "^3.3.1", - "ci-parallel-vars": "^1.0.1", - "clean-yaml-object": "^0.1.0", - "cli-truncate": "^3.1.0", - "code-excerpt": "^4.0.0", - "common-path-prefix": "^3.0.0", - "concordance": "^5.0.4", - "currently-unhandled": "^0.4.1", - "debug": "^4.3.4", - "del": "^6.1.1", - "emittery": "^0.11.0", - "figures": "^4.0.1", - "globby": "^13.1.1", - "ignore-by-default": "^2.1.0", - "indent-string": "^5.0.0", - "is-error": "^2.2.2", - "is-plain-object": "^5.0.0", - "is-promise": "^4.0.0", - "matcher": "^5.0.0", - "mem": "^9.0.2", - "ms": "^2.1.3", - "p-event": "^5.0.1", - "p-map": "^5.4.0", - "picomatch": "^2.3.1", - "pkg-conf": "^4.0.0", - "plur": "^5.1.0", - "pretty-ms": "^7.0.1", - "resolve-cwd": "^3.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.5", - "strip-ansi": "^7.0.1", - "supertap": "^3.0.1", - "temp-dir": "^2.0.0", - "write-file-atomic": "^4.0.1", - "yargs": "^17.5.1" - }, - "dependencies": { - "globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dev": true, - "requires": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "dependencies": { - "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true - } - } - } - } - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, - "axios": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", - "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", - "dev": true - }, - "bignumber.js": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", - "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bintrees": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.2.tgz", - "integrity": "sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==" - }, - "bip32": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", - "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", - "dev": true, - "requires": { - "@types/node": "10.12.18", - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.1.3", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - }, - "dependencies": { - "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", - "dev": true - } - } - }, - "bip39": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz", - "integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==", - "dev": true, - "requires": { - "@noble/hashes": "^1.2.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "blueimp-md5": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz", - "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", - "dev": true - }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, - "browser-headers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", - "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", - "dev": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", - "devOptional": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-4.1.0.tgz", - "integrity": "sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001527", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001527.tgz", - "integrity": "sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==", - "dev": true - }, - "cbor": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", - "integrity": "sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==", - "dev": true, - "requires": { - "nofilter": "^3.1.0" - } - }, - "chai": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", - "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chunkd": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-2.0.1.tgz", - "integrity": "sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==", - "dev": true - }, - "ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true - }, - "ci-parallel-vars": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.1.tgz", - "integrity": "sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "clean-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", - "dev": true, - "requires": { - "escape-string-regexp": "5.0.0" - } - }, - "clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==", - "dev": true - }, - "cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "requires": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "code-excerpt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", - "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", - "dev": true, - "requires": { - "convert-to-spaces": "^2.0.1" - } - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "requires": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz", - "integrity": "sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==" - }, - "common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "concordance": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-5.0.4.tgz", - "integrity": "sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==", - "dev": true, - "requires": { - "date-time": "^3.1.0", - "esutils": "^2.0.3", - "fast-diff": "^1.2.0", - "js-string-escape": "^1.0.1", - "lodash": "^4.17.15", - "md5-hex": "^3.0.1", - "semver": "^7.3.2", - "well-known-symbols": "^2.0.0" - } - }, - "convert-hex": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/convert-hex/-/convert-hex-0.1.0.tgz", - "integrity": "sha512-w20BOb1PiR/sEJdS6wNrUjF5CSfscZFUp7R9NSlXH8h2wynzXVEPFPJECAnkNylZ+cvf3p7TyRUHggDmrwXT9A==" - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "convert-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/convert-string/-/convert-string-0.1.0.tgz", - "integrity": "sha512-1KX9ESmtl8xpT2LN2tFnKSbV4NiarbVi8DVb39ZriijvtTklyrT+4dT1wsGMHKD3CJUjXgvJzstm9qL9ICojGA==" - }, - "convert-to-spaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", - "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", - "dev": true - }, - "copyfiles": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", - "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", - "dev": true, - "requires": { - "glob": "^7.0.5", - "minimatch": "^3.0.3", - "mkdirp": "^1.0.4", - "noms": "0.0.0", - "through2": "^2.0.1", - "untildify": "^4.0.0", - "yargs": "^16.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "cosmjs-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.6.1.tgz", - "integrity": "sha512-fRz6yzElHHBULDyLArF/G1UkkTWW4r3RondBUGnmSsZWYI5NpfDn32MVa5aRmpaaf4tJI2cbnXHs9fykwU7Ttg==", - "dev": true, - "requires": { - "long": "^4.0.0", - "protobufjs": "~6.11.2" - }, - "dependencies": { - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "dev": true - } - } - }, - "crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "dev": true, - "requires": { - "node-fetch": "^2.6.12" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==", - "dev": true - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "date-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", - "integrity": "sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==", - "dev": true, - "requires": { - "time-zone": "^1.0.0" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true - }, - "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "default-require-extensions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", - "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", - "dev": true, - "requires": { - "strip-bom": "^4.0.0" - } - }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "del": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", - "dev": true, - "requires": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" - }, - "dependencies": { - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha512-F4wZ06PvqxYLFEZKkFxTDcns9oFNk34hvmJSEwdzsxVQ8YI5YaxtACgQatkYgv2VI2CFkUd2Y+xosPQnHv809g==", - "dev": true, - "optional": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "eccrypto": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/eccrypto/-/eccrypto-1.1.6.tgz", - "integrity": "sha512-d78ivVEzu7Tn0ZphUUaL43+jVPKTMPFGtmgtz1D0LrFn7cY3K8CdrvibuLz2AAkHBLKZtR8DMbB2ukRYFk987A==", - "dev": true, - "requires": { - "acorn": "7.1.1", - "elliptic": "6.5.4", - "es6-promise": "4.2.8", - "nan": "2.14.0", - "secp256k1": "3.7.1" - }, - "dependencies": { - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true, - "optional": true - }, - "secp256k1": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.7.1.tgz", - "integrity": "sha512-1cf8sbnRreXrQFdH6qsg2H71Xw91fCCS9Yp021GnUNJzWJS/py96fS4lHbnTnouLp08Xj6jBoBB6V78Tdbdu5g==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", - "elliptic": "^6.4.1", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" - } - } - } - }, - "electron-to-chromium": { - "version": "1.4.508", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.508.tgz", - "integrity": "sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "emittery": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.11.0.tgz", - "integrity": "sha512-S/7tzL6v5i+4iJd627Nhv9cLFIo5weAIlGccqJFpnBoDB8U1TF2k5tez4J/QNuxyyhWuFqHg1L84Kd3m7iXg6g==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - } - } - }, - "es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" - } - }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - } - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-eslint-comments": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz", - "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "ignore": "^5.0.5" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - } - } - }, - "eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", - "dev": true, - "requires": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "eth-crypto": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eth-crypto/-/eth-crypto-2.6.0.tgz", - "integrity": "sha512-GCX4ffFYRUGgnuWR5qxcZIRQJ1KEqPFiyXU9yVy7s6dtXIMlUXZQ2h+5ID6rFaOHWbpJbjfkC6YdhwtwRYCnug==", - "dev": true, - "requires": { - "@babel/runtime": "7.20.13", - "@ethereumjs/tx": "3.5.2", - "@types/bn.js": "5.1.1", - "eccrypto": "1.1.6", - "ethereumjs-util": "7.1.5", - "ethers": "5.7.2", - "secp256k1": "5.0.0" - }, - "dependencies": { - "node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "dev": true - }, - "secp256k1": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", - "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", - "dev": true, - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^5.0.0", - "node-gyp-build": "^4.2.0" - } - } - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, - "requires": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - }, - "dependencies": { - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, - "requires": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - } - } - }, - "ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", - "dev": true, - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - } - }, - "ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", - "dev": true, - "requires": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "extract-files": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz", - "integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true - }, - "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.4.tgz", - "integrity": "sha512-mNlGUdKOeGNleyrmgbKYtbnCr9KZkZXU7eM89JRo8vY10f7Ul1Fbj07hUBW3N4fC0xM+fmfFfa2zM7mIizhpNQ==" - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fecha": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", - "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" - }, - "figures": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/figures/-/figures-4.0.1.tgz", - "integrity": "sha512-rElJwkA/xS04Vfg+CaZodpso7VqBknOYbzi6I76hI4X80RUjkSxO2oAyPmGbuXUppywjqndOrQDl817hDnI++w==", - "dev": true, - "requires": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", - "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", - "dev": true, - "requires": { - "flatted": "^3.2.7", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "google-protobuf": { - "version": "3.21.2", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.21.2.tgz", - "integrity": "sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA==", - "dev": true - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "graphql": { - "version": "16.8.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.0.tgz", - "integrity": "sha512-0oKGaR+y3qcS5mCu1vb7KG+a89vjn06C7Ihq/dDl3jA+A8B3TKomvi3CiEcVLJQGalbu8F52LxkOym7U5sSfbg==", - "dev": true - }, - "graphql-request": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-5.2.0.tgz", - "integrity": "sha512-pLhKIvnMyBERL0dtFI3medKqWOz/RhHdcgbZ+hMMIb32mEPa5MJSzS4AuXxfI4sRAu6JVVk5tvXuGfCWl9JYWQ==", - "dev": true, - "requires": { - "@graphql-typed-document-node/core": "^3.1.1", - "cross-fetch": "^3.1.5", - "extract-files": "^9.0.0", - "form-data": "^3.0.0" - }, - "dependencies": { - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } - } - }, - "graphql-tag": { - "version": "2.12.6", - "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", - "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dev": true, - "requires": { - "react-is": "^16.7.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-status-codes": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", - "integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "dev": true - }, - "ignore-by-default": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-2.1.0.tgz", - "integrity": "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "irregular-plurals": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", - "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", - "dev": true - }, - "is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - } - }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-error": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", - "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.11" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "requires": {} - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "requires": { - "append-transform": "^2.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "dependencies": { - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - } - } - }, - "istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "dependencies": { - "make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "requires": { - "semver": "^7.5.3" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", - "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", - "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", - "requires": { - "argparse": "^2.0.1" - } - }, - "jscrypto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/jscrypto/-/jscrypto-1.0.3.tgz", - "integrity": "sha512-lryZl0flhodv4SZHOqyb1bx5sKcJxj0VBo0Kzb4QMAg3L021IC9uGpl0RCZa+9KJwlRGSK2C80ITcwbe19OKLQ==", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true - }, - "just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "dev": true - }, - "keccak": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.3.tgz", - "integrity": "sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==", - "dev": true, - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "keccak256": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.6.tgz", - "integrity": "sha512-8GLiM01PkdJVGUhR1e6M/AvWnSqYS0HaERI+K/QtStGDGlSTx2B1zTqZk4Zlqu5TxHJNTxWAdP9Y+WI50OApUw==", - "dev": true, - "requires": { - "bn.js": "^5.2.0", - "buffer": "^6.0.3", - "keccak": "^3.0.2" - } - }, - "keyv": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", - "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "libsodium": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.6.tgz", - "integrity": "sha512-hPb/04sEuLcTRdWDtd+xH3RXBihpmbPCsKW/Jtf4PsvdyKh+D6z2D2gvp/5BfoxseP+0FCOg66kE+0oGUE/loQ==", - "dev": true - }, - "libsodium-sumo": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium-sumo/-/libsodium-sumo-0.7.11.tgz", - "integrity": "sha512-bY+7ph7xpk51Ez2GbE10lXAQ5sJma6NghcIDaSPbM/G9elfrjLa0COHl/7P6Wb/JizQzl5UQontOOP1z0VwbLA==" - }, - "libsodium-wrappers": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.6.tgz", - "integrity": "sha512-OUO2CWW5bHdLr6hkKLHIKI4raEkZrf3QHkhXsJ1yCh6MZ3JDA7jFD3kCATNquuGSG6MjjPHQIQms0y0gBDzjQg==", - "dev": true, - "requires": { - "libsodium": "0.7.6" - } - }, - "libsodium-wrappers-sumo": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.11.tgz", - "integrity": "sha512-DGypHOmJbB1nZn89KIfGOAkDgfv5N6SBGC3Qvmy/On0P0WD1JQvNRS/e3UL3aFF+xC0m+MYz5M+MnRnK2HMrKQ==", - "requires": { - "libsodium-sumo": "^0.7.11" - } - }, - "link-module-alias": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/link-module-alias/-/link-module-alias-1.2.0.tgz", - "integrity": "sha512-ahPjXepbSVKbahTB6LxR//VHm8HPfI+QQygCH+E82spBY4HR5VPJTvlhKBc9F7muVxnS6C1rRfoPOXAbWO/fyw==", - "dev": true, - "requires": { - "chalk": "^2.4.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "load-json-file": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", - "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" - }, - "lodash.values": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz", - "integrity": "sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "logform": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.5.1.tgz", - "integrity": "sha512-9FyqAm9o9NKKfiAKfZoYo9bGXXuwMkxQiQttkT4YjjVtQVIQtK6LmVtlxmCaFswo6N4AfEkHqZTV0taDtPotNg==", - "requires": { - "@colors/colors": "1.5.0", - "@types/triple-beam": "^1.3.2", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^2.3.1", - "triple-beam": "^1.3.0" - } - }, - "long": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", - "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "requires": { - "get-func-name": "^2.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true - }, - "matcher": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", - "integrity": "sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==", - "dev": true, - "requires": { - "escape-string-regexp": "^5.0.0" - } - }, - "md5-hex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", - "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", - "dev": true, - "requires": { - "blueimp-md5": "^2.10.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mem": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/mem/-/mem-9.0.2.tgz", - "integrity": "sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^4.0.0" - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "requires": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - } - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } - } - }, - "mocha-steps": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz", - "integrity": "sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true - }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "nise": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", - "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - } - } - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true - }, - "node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-gyp-build": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", - "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", - "devOptional": true - }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "requires": { - "process-on-spawn": "^1.0.0" - } - }, - "node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true - }, - "nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "dev": true - }, - "noms": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", - "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "~1.0.31" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - } - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-all": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", - "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "chalk": "^2.4.1", - "cross-spawn": "^6.0.5", - "memorystream": "^0.3.1", - "minimatch": "^3.0.4", - "pidtree": "^0.3.0", - "read-pkg": "^3.0.0", - "shell-quote": "^1.6.1", - "string.prototype.padend": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "dependencies": { - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, - "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "requires": { - "fn.name": "1.x.x" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - }, - "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - } - } - }, - "optimism": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.17.5.tgz", - "integrity": "sha512-TEcp8ZwK1RczmvMnvktxHSF2tKgMWjJ71xEFGX5ApLh67VsMSTy1ZUlipJw8W+KaqgOmQ+4pqwkeivY89j+4Vw==", - "dev": true, - "requires": { - "@wry/context": "^0.7.0", - "@wry/trie": "^0.4.3", - "tslib": "^2.3.0" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", - "dev": true - }, - "p-event": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-5.0.1.tgz", - "integrity": "sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==", - "dev": true, - "requires": { - "p-timeout": "^5.0.2" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-map": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", - "dev": true, - "requires": { - "aggregate-error": "^4.0.0" - } - }, - "p-timeout": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", - "integrity": "sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - }, - "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - } - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", - "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - } - } - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pidtree": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", - "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "pkg-conf": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz", - "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==", - "dev": true, - "requires": { - "find-up": "^6.0.0", - "load-json-file": "^7.0.0" - }, - "dependencies": { - "find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "requires": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - } - }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "requires": { - "p-locate": "^6.0.0" - } - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "requires": { - "p-limit": "^4.0.0" - } - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true - }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true - } - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "plur": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz", - "integrity": "sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==", - "dev": true, - "requires": { - "irregular-plurals": "^3.3.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true - }, - "pretty-ms": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", - "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", - "dev": true, - "requires": { - "parse-ms": "^2.1.0" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "requires": { - "fromentries": "^1.2.0" - } - }, - "prom-client": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.1.0.tgz", - "integrity": "sha512-jT9VccZCWrJWXdyEtQddCDszYsiuWj5T0ekrPszi/WEegj3IZy6Mm09iOOVM86A4IKMWq8hZkT2dD9MaSe+sng==", - "requires": { - "tdigest": "^0.1.1" - } - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "protobufjs": { - "version": "6.11.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", - "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "dependencies": { - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - } - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - } - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "readonly-date": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/readonly-date/-/readonly-date-1.0.0.tgz", - "integrity": "sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==" - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "response-iterator": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/response-iterator/-/response-iterator-0.2.6.tgz", - "integrity": "sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dev": true, - "requires": { - "bn.js": "^5.2.0" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true - }, - "secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", - "dev": true, - "requires": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "requires": { - "type-fest": "^0.13.1" - }, - "dependencies": { - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha256": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/sha256/-/sha256-0.2.0.tgz", - "integrity": "sha512-kTWMJUaez5iiT9CcMv8jSq6kMhw3ST0uRdcIWl3D77s6AsLXNXRp3heeqqfu5+Dyfu4hwpQnMzhqHh8iNQxw0w==", - "requires": { - "convert-hex": "~0.1.0", - "convert-string": "~0.1.0" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true - }, - "shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "shx": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", - "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", - "dev": true, - "requires": { - "minimist": "^1.2.3", - "shelljs": "^0.8.5" - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "requires": { - "is-arrayish": "^0.3.1" - } - }, - "sinon": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.2.tgz", - "integrity": "sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^9.1.2", - "@sinonjs/samsam": "^7.0.1", - "diff": "^5.0.0", - "nise": "^5.1.2", - "supports-color": "^7.2.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - } - }, - "snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "dev": true, - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "snakecase-keys": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-5.4.6.tgz", - "integrity": "sha512-7ipeNts8YTLbx/6zIaT1mQGrHG2vK+0TjywPD79QzIDJDcvNXBLX7DXQOt6by4DFdncu8lDPc+QHKHemtDEoQg==", - "dev": true, - "requires": { - "map-obj": "^4.1.0", - "snake-case": "^3.0.4", - "type-fest": "^2.5.2" - }, - "dependencies": { - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - } - }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" - }, - "stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "store2": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz", - "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==", - "dev": true - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "string.prototype.padend": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz", - "integrity": "sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supertap": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/supertap/-/supertap-3.0.1.tgz", - "integrity": "sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==", - "dev": true, - "requires": { - "indent-string": "^5.0.0", - "js-yaml": "^3.14.1", - "serialize-error": "^7.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "symbol-observable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", - "dev": true - }, - "table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "tdigest": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz", - "integrity": "sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==", - "requires": { - "bintrees": "1.0.2" - } - }, - "temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "dev": true - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==", - "dev": true - }, - "tiny-secp256k1": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", - "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", - "dev": true, - "requires": { - "bindings": "^1.3.0", - "bn.js": "^4.11.8", - "create-hmac": "^1.1.7", - "elliptic": "^6.4.0", - "nan": "^2.13.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "ts-invariant": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz", - "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - }, - "ts-mocha": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz", - "integrity": "sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==", - "dev": true, - "requires": { - "ts-node": "7.0.1", - "tsconfig-paths": "^3.5.0" - } - }, - "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", - "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "source-map-support": "^0.5.6", - "yn": "^2.0.0" - }, - "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - } - } - }, - "tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - } - } - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", - "dev": true - }, - "tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - } - }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - } - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==", - "dev": true - }, - "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "devOptional": true, - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "well-known-symbols": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", - "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - } - }, - "wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==", - "dev": true, - "requires": { - "bs58check": "<3.0.0" - } - }, - "winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "requires": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - } - }, - "winston-transport": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", - "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", - "requires": { - "logform": "^2.3.2", - "readable-stream": "^3.6.0", - "triple-beam": "^1.3.0" - } - }, - "workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "requires": {} - }, - "xstream": { - "version": "11.14.0", - "resolved": "https://registry.npmjs.org/xstream/-/xstream-11.14.0.tgz", - "integrity": "sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==", - "requires": { - "globalthis": "^1.0.1", - "symbol-observable": "^2.0.3" - }, - "dependencies": { - "symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==" - } - } - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } - } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - }, - "zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==", - "dev": true - }, - "zen-observable-ts": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz", - "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==", - "dev": true, - "requires": { - "zen-observable": "0.8.15" - } - } - } -} diff --git a/andromeda-core/ibc-tests/package.json b/andromeda-core/ibc-tests/package.json deleted file mode 100644 index 8755ec2..0000000 --- a/andromeda-core/ibc-tests/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "andr_core_ibc_tests", - "version": "1.0.0", - "description": "IBC Integration Tests for Andromeda Core contracts", - "main": "index.js", - "scripts": { - "build": "tsc -p tsconfig.json", - "fix": "run-s fix:*", - "fix:prettier": "prettier \"**/*.{ts,md}\" --write", - "fix:lint": "eslint test --ext .ts --fix", - "test": "run-s test:*", - "test:lint": "eslint test --ext .ts", - "test:prettier": "prettier \"**/*.{ts,md}\" --list-different", - "test:unit": "ts-mocha -p tsconfig.json test/**/*.spec.ts --require mocha-steps --timeout 360000 --full-trace" - }, - "author": "", - "license": "ISC", - "dependencies": { - "@confio/relayer": "^0.10.0", - "@cosmjs/cosmwasm-stargate": "^0.31.1", - "@cosmjs/crypto": "^0.31.1", - "@cosmjs/stargate": "^0.31.1", - "axios": "^1.4.0", - "sha256": "^0.2.0" - }, - "devDependencies": { - "@andromedaprotocol/andromeda.js": "^0.3.3", - "@ava/typescript": "^3.0.1", - "@istanbuljs/nyc-config-typescript": "^1.0.2", - "@types/chai": "^4.3.5", - "@types/cli-progress": "^3.11.0", - "@types/mocha": "^10.0.1", - "@types/mocha-steps": "^1.3.0", - "@types/node": "^18.0.6", - "@types/sha256": "^0.2.0", - "@types/sinon": "^10.0.13", - "@typescript-eslint/eslint-plugin": "^5.30.7", - "@typescript-eslint/parser": "^5.30.7", - "ava": "^4.3.1", - "chai": "^4.3.7", - "eslint": "^8.20.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import": "^2.26.0", - "mocha": "^10.2.0", - "mocha-steps": "^1.3.0", - "npm-run-all": "^4.1.5", - "nyc": "^15.1.0", - "prettier": "^2.7.1", - "sinon": "^14.0.0", - "ts-mocha": "^10.0.0", - "typescript": "^4.7.4" - }, - "ava": { - "failFast": true, - "timeout": "120s", - "typescript": { - "rewritePaths": { - "src/": "build/" - }, - "compile": false - } - }, - "nyc": { - "extends": "@istanbuljs/nyc-config-typescript", - "exclude": [ - "**/*.spec.js" - ] - } -} diff --git a/andromeda-core/ibc-tests/src/interface_macro.rs b/andromeda-core/ibc-tests/src/interface_macro.rs new file mode 100644 index 0000000..462e401 --- /dev/null +++ b/andromeda-core/ibc-tests/src/interface_macro.rs @@ -0,0 +1,26 @@ +#[macro_export] +macro_rules! contract_interface { + ($contract_name:ident, $module_path:ident, $package_path:ident, $contract_id:expr, $wasm_path:expr) => { + #[interface($package_path::InstantiateMsg, $package_path::ExecuteMsg, $package_path::QueryMsg, MigrateMsg, id = $contract_id)] + pub struct $contract_name; + + impl Uploadable for $contract_name { + fn wrapper() -> Box> { + Box::new( + ContractWrapper::new_with_empty( + $module_path::contract::execute, + $module_path::contract::instantiate, + $module_path::contract::query, + ) + .with_migrate($module_path::contract::migrate), + ) + } + + fn wasm(_chain: &ChainInfoOwned) -> WasmPath { + artifacts_dir_from_workspace!() + .find_wasm_path($wasm_path) + .unwrap() + } + } + }; +} diff --git a/andromeda-core/ibc-tests/src/lib.rs b/andromeda-core/ibc-tests/src/lib.rs new file mode 100644 index 0000000..6c841d6 --- /dev/null +++ b/andromeda-core/ibc-tests/src/lib.rs @@ -0,0 +1 @@ +pub mod interface_macro; diff --git a/andromeda-core/ibc-tests/src/main.rs b/andromeda-core/ibc-tests/src/main.rs new file mode 100644 index 0000000..40f2494 --- /dev/null +++ b/andromeda-core/ibc-tests/src/main.rs @@ -0,0 +1,204 @@ +use std::cmp; + +use andromeda_std::ado_base::MigrateMsg; +use andromeda_testing_e2e::mock::{mock_app, MockAndromeda}; +use cosmwasm_std::{coin, to_json_binary, Uint128}; +use cw_orch::interface; +use cw_orch::prelude::*; +use cw_orch::{ + environment::{ChainKind, NetworkInfo}, + prelude::ChainInfo, +}; +use cw_orch_daemon::{ + queriers::{Staking, StakingBondStatus}, + DaemonBase, Wallet, +}; +use ibc_tests::contract_interface; + +use andromeda_app::app::{self, AppComponent}; +use andromeda_finance::validator_staking; + +const TESTNET_MNEMONIC: &str = "across left ignore gold echo argue track joy hire release captain enforce hotel wide flash hotel brisk joke midnight duck spare drop chronic stool"; +pub const TERRA_NETWORK: NetworkInfo = NetworkInfo { + chain_name: "terra", + pub_address_prefix: "terra", + coin_type: 330u32, +}; + +pub const LOCAL_TERRA: ChainInfo = ChainInfo { + kind: ChainKind::Local, + chain_id: "localterraa-1", + gas_denom: "uluna", + gas_price: 0.15, + grpc_urls: &["http://localhost:20331"], + network_info: TERRA_NETWORK, + lcd_url: None, + fcd_url: None, +}; + +contract_interface!( + AppContract, + andromeda_app_contract, + app, + "andromeda_app_contract", + "app_contract" +); + +fn main() { + println!("//=============================Prereparing test environment===================================//"); + + let local_terra = LOCAL_TERRA; + println!("//===============================Prereparing Andromeda OS=====================================//"); + let daemon = mock_app(local_terra.clone(), TESTNET_MNEMONIC); + let mock_andromeda = MockAndromeda::new(&daemon); + let MockAndromeda { + kernel_contract, + adodb_contract, + .. + } = &mock_andromeda; + + println!("//================================Andromeda OS Setup Completed================================//"); + println!( + "kernel_contract->code_id: {:?}, kernel_contract-> address {:?}", + kernel_contract.code_id(), + kernel_contract.addr_str() + ); + println!( + "adodb_contract->code_id: {:?}, adodb_contract-> address {:?}", + adodb_contract.code_id(), + adodb_contract.addr_str() + ); + println!("//============================================================================================//"); + + println!("Preparing App component"); + println!("//=======================================Preparing App=======================================//"); + let app_contract = AppContract::new(daemon.clone()); + app_contract.upload().unwrap(); + + adodb_contract.clone().execute_publish( + app_contract.code_id().unwrap(), + "app-contract".to_string(), + "0.1.0".to_string(), + ); + println!("app_contract->code_id: {:?}", app_contract.code_id()); + println!("//==============================Base Test Environment Ready=================================//"); + + prepare_validator_staking(&daemon, &mock_andromeda, &app_contract); +} + +contract_interface!( + ValidatorStakingContract, + andromeda_validator_staking, + validator_staking, + "validator_staking_contract", + "validator_staking" +); + +fn prepare_validator_staking( + daemon: &DaemonBase, + mock_andromeda: &MockAndromeda, + app_contract: &AppContract>, +) { + let denom = LOCAL_TERRA.gas_denom; + + println!("//===============================Preparing Validator Staking=================================//"); + let validator_staking_contract = ValidatorStakingContract::new(daemon.clone()); + validator_staking_contract.upload().unwrap(); + + let MockAndromeda { + kernel_contract, + adodb_contract, + .. + } = mock_andromeda; + adodb_contract.clone().execute_publish( + validator_staking_contract.code_id().unwrap(), + "validator-staking".to_string(), + "0.1.0".to_string(), + ); + + println!("//================================Validator Staking Prepared-=================================//"); + println!( + "validator_staking_contract->code_id: {:?}", + validator_staking_contract.code_id() + ); + println!("//============================================================================================//"); + + println!("//===========================Initialize app with Validator Staking============================//"); + let staking_querier = Staking::new(daemon); + let validators = daemon + .rt_handle + .block_on(async { staking_querier._validators(StakingBondStatus::Bonded).await }) + .unwrap(); + + if validators.len() < 5 { + println!("At least 5 validators are required for this test"); + return; + } + + let validator_staking_init_msg = validator_staking::InstantiateMsg { + default_validator: Addr::unchecked(&validators[0].address), // fourth validator + kernel_address: kernel_contract.addr_str().unwrap(), + owner: None, + }; + + let validator_staking_component = AppComponent::new( + "validator-staking-component", + "validator-staking", + to_json_binary(&validator_staking_init_msg).unwrap(), + ); + + let app_components = vec![validator_staking_component.clone()]; + let app_init_msg = app::InstantiateMsg { + app_components, + kernel_address: kernel_contract.addr_str().unwrap(), + name: "Validator Staking App".to_string(), + owner: None, + chain_info: None, + }; + + app_contract.instantiate(&app_init_msg, None, None).unwrap(); + + let get_addr_message = app::QueryMsg::GetAddress { + name: validator_staking_component.name, + }; + + let validator_staking_addr: String = daemon + .wasm_querier() + .smart_query(app_contract.addr_str().unwrap(), &get_addr_message) + .unwrap(); + + validator_staking_contract.set_address(&Addr::unchecked(validator_staking_addr)); + + println!("//==========================App with Validator Staking Initialized============================//"); + println!( + "app_contract->code_id: {:?}, app_contract-> address: {:?}", + app_contract.code_id(), + app_contract.addr_str() + ); + println!( + "validator_staking_contract->code_id: {:?}, validator_staking_contract-> address {:?}", + validator_staking_contract.code_id(), + validator_staking_contract.addr_str() + ); + println!("//============================================================================================//"); + + println!("//===============================Processing Stake For testing=================================//"); + validators.into_iter().for_each(|validator| { + let stake_msg = validator_staking::ExecuteMsg::Stake { + validator: Some(Addr::unchecked(validator.address.to_string())), + }; + let balance = daemon + .balance(daemon.sender_addr(), Some(denom.to_string())) + .unwrap(); + let amount_to_send = cmp::min(balance[0].amount, Uint128::new(10000000000)); + validator_staking_contract + .execute(&stake_msg, Some(&[coin(amount_to_send.u128(), denom)])) + .unwrap(); + println!( + "validator: {:?}, delegator: {:?}", + validator.address, + daemon.sender_addr() + ); + }); + println!("//============================================================================================//"); +} diff --git a/andromeda-core/ibc-tests/test/configs.ts b/andromeda-core/ibc-tests/test/configs.ts deleted file mode 100644 index b5c6bf0..0000000 --- a/andromeda-core/ibc-tests/test/configs.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { testutils } from "@confio/relayer"; -import { ChainDefinition as RelayerChainDefinition } from "@confio/relayer/build/lib/helpers"; - -// const BASE_URL = "localhost"; -const BASE_URL = process.env.LOCAL ? "localhost" : "18.212.50.191"; - -export interface ChainDefinition extends RelayerChainDefinition { - restUrl: string; -} - -const { osmosis: oldOsmo } = testutils; - -const faucetMnemonic = - "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius"; -const blockTime = 5000; - -const osmosisA: ChainDefinition = { - ...oldOsmo, - minFee: "0.25uosmo", - tendermintUrlWs: `ws://${BASE_URL}:20121`, - tendermintUrlHttp: `http://${BASE_URL}:20121`, - restUrl: `http://${BASE_URL}:20221`, - chainId: "localosmosis-1", - faucet: { - ...oldOsmo.faucet, - mnemonic: faucetMnemonic, - address0: "osmo19wpkq20hq9r08qht3qhrvya7fm00cflvrhu6s3", - }, - blockTime, - estimatedBlockTime: blockTime, - estimatedIndexerTime: blockTime, -}; - -const osmosisB: ChainDefinition = { - ...oldOsmo, - minFee: "0.25uosmo", - tendermintUrlWs: `ws://${BASE_URL}:20122`, - tendermintUrlHttp: `http://${BASE_URL}:20122`, - restUrl: `http://${BASE_URL}:20222`, - chainId: "localosmosis-2", - faucet: { - ...oldOsmo.faucet, - mnemonic: faucetMnemonic, - address0: "osmo19wpkq20hq9r08qht3qhrvya7fm00cflvrhu6s3", - }, - blockTime, - estimatedBlockTime: blockTime, - estimatedIndexerTime: blockTime, -}; - -const andromedaA: ChainDefinition = { - tendermintUrlWs: `ws://${BASE_URL}:20111`, - tendermintUrlHttp: `http://${BASE_URL}:20111`, - restUrl: `http://${BASE_URL}:20211`, - chainId: "localandromeda-1", - prefix: "andr", - denomStaking: "stake", - denomFee: "uandr", - minFee: "0.25uandr", - blockTime, - faucet: { - mnemonic: - "enlist hip relief stomach skate base shallow young switch frequent cry park", - pubkey0: { - type: "tendermint/PubKeySecp256k1", - value: "A9cXhWb8ZpqCzkA8dQCPV29KdeRLV3rUYxrkHudLbQtS", - }, - address0: "andr14qemq0vw6y3gc3u3e0aty2e764u4gs5lndxgyk", - }, - ics20Port: "transfer", - estimatedBlockTime: blockTime, - estimatedIndexerTime: blockTime, -}; - -const terraA: ChainDefinition = { - tendermintUrlWs: `ws://${BASE_URL}:20131`, - tendermintUrlHttp: `http://${BASE_URL}:20131`, - restUrl: `http://${BASE_URL}:20231`, - chainId: "localterra-1", - prefix: "terra", - denomStaking: "stake", - denomFee: "uluna", - minFee: "0.25uluna", - blockTime, - faucet: { - mnemonic: - "enlist hip relief stomach skate base shallow young switch frequent cry park", - pubkey0: { - type: "tendermint/PubKeySecp256k1", - value: "A9cXhWb8ZpqCzkA8dQCPV29KdeRLV3rUYxrkHudLbQtS", - }, - address0: "terra14qemq0vw6y3gc3u3e0aty2e764u4gs5lndxgyk", - }, - ics20Port: "transfer", - estimatedBlockTime: blockTime, - estimatedIndexerTime: blockTime, -}; - -const junoA: ChainDefinition = { - tendermintUrlWs: `ws://${BASE_URL}:20141`, - tendermintUrlHttp: `http://${BASE_URL}:20141`, - restUrl: `http://${BASE_URL}:20241`, - chainId: "localjuno-1", - prefix: "juno", - denomStaking: "stake", - denomFee: "ujunox", - minFee: "2ujunox", - blockTime, - faucet: { - mnemonic: - "enlist hip relief stomach skate base shallow young switch frequent cry park", - pubkey0: { - type: "tendermint/PubKeySecp256k1", - value: "A9cXhWb8ZpqCzkA8dQCPV29KdeRLV3rUYxrkHudLbQtS", - }, - address0: "juno14qemq0vw6y3gc3u3e0aty2e764u4gs5lndxgyk", - }, - ics20Port: "transfer", - estimatedBlockTime: blockTime, - estimatedIndexerTime: blockTime, -}; - -const junoB: ChainDefinition = { - tendermintUrlWs: `ws://${BASE_URL}:20142`, - tendermintUrlHttp: `http://${BASE_URL}:20142`, - restUrl: `http://${BASE_URL}:20242`, - chainId: "localjuno-2", - prefix: "juno", - denomStaking: "stake", - denomFee: "ujunox", - minFee: "2ujunox", - blockTime, - faucet: { - mnemonic: - "enlist hip relief stomach skate base shallow young switch frequent cry park", - pubkey0: { - type: "tendermint/PubKeySecp256k1", - value: "A9cXhWb8ZpqCzkA8dQCPV29KdeRLV3rUYxrkHudLbQtS", - }, - address0: "juno14qemq0vw6y3gc3u3e0aty2e764u4gs5lndxgyk", - }, - ics20Port: "transfer", - estimatedBlockTime: blockTime, - estimatedIndexerTime: blockTime, -}; - -export default { - osmosisA, - osmosisB, - andromedaA, - terraA, - junoA, - junoB, -}; diff --git a/andromeda-core/ibc-tests/test/contract.ts b/andromeda-core/ibc-tests/test/contract.ts deleted file mode 100644 index 8426e30..0000000 --- a/andromeda-core/ibc-tests/test/contract.ts +++ /dev/null @@ -1,71 +0,0 @@ -import fs from "fs"; - -import { CosmWasmSigner } from "@confio/relayer"; - -export default class Contract { - constructor(public address: string, public codeId?: number) {} - - static fromAddress(address: string) { - return new Contract(address); - } - - static async fromCodeId( - codeId: number, - instantiateMsg: Record, - signer: CosmWasmSigner, - log = false - ) { - const instantiate = await signer.sign.instantiate( - signer.senderAddress, - codeId, - instantiateMsg, - "Instantiate", - "auto" - ); - if (log) console.log(JSON.stringify(instantiate.events, null, 2)); - return new Contract(instantiate.contractAddress, codeId); - } - - static async fromWasmCode( - wasmPath: string, - instantiateMsg: Record, - signer: CosmWasmSigner - ) { - const wasm = fs.readFileSync(wasmPath); - const { codeId } = await signer.sign.upload( - signer.senderAddress, - wasm, - "auto" - ); - return Contract.fromCodeId(codeId, instantiateMsg, signer); - } - - async execute( - msg: Record, - signer: CosmWasmSigner, - funds: { amount: string; denom: string }[] = [], - memo = "auto", - senderAddress?: string - ) { - return signer.sign.execute( - senderAddress ?? signer.senderAddress, - this.address, - msg, - "auto", - memo, - funds - ); - } - - async query( - msg: Record, - signer: CosmWasmSigner - ): Promise { - return signer.sign.queryContractSmart(this.address, msg); - } - - async getPort(signer: CosmWasmSigner): Promise { - const { ibcPortId } = await signer.sign.getContract(this.address); - return ibcPortId!; - } -} diff --git a/andromeda-core/ibc-tests/test/ibc.spec.ts b/andromeda-core/ibc-tests/test/ibc.spec.ts deleted file mode 100644 index 0cbc4f5..0000000 --- a/andromeda-core/ibc-tests/test/ibc.spec.ts +++ /dev/null @@ -1,1143 +0,0 @@ -import { Link } from "@confio/relayer"; -import { - CosmWasmSigner, - randomAddress, -} from "@confio/relayer/build/lib/helpers"; -import { ChannelPair } from "@confio/relayer/build/lib/link"; -import { toBinary } from "@cosmjs/cosmwasm-stargate"; -import { assert } from "chai"; -import { Order } from "cosmjs-types/ibc/core/channel/v1/channel"; -import { step } from "mocha-steps"; -import digest from "sha256"; - -import configs, { ChainDefinition } from "./configs"; -import Contract from "./contract"; -import { CustomLogger } from "./logger"; -import { setupOS } from "./os"; -import { waitForChain } from "./relayer"; -import { - assertPacketsFromA, - assertPacketsFromB, - awaitMulti, - createAMPMsg, - getAllADONames, - parseAcknowledgementSuccess, - relayAll, - retryTill, - setupChainClient, - setupRelayerInfo, - uploadAllADOs, -} from "./utils"; - -const { osmosisA, osmosisB, terraA, andromedaA, junoA, junoB } = configs; - -interface Contracts { - kernel?: Contract; - vfs?: Contract; - economics?: Contract; - adodb?: Contract; -} - -interface ChainEnd { - client?: CosmWasmSigner; - os: Contracts; - ics20Chan: string; - ibcDenom: string; - name: string; - definition: ChainDefinition; - denom: string; -} -interface State { - link?: Link; - channel?: ChannelPair; - setup: boolean; - chainA: ChainEnd; - chainB: ChainEnd; - logger: CustomLogger; -} - -let state: State = { - setup: false, - logger: new CustomLogger(), - chainA: { - os: {}, - ics20Chan: "", - ibcDenom: "", - name: "andromeda", - definition: osmosisA, - denom: osmosisA.denomFee, - }, - chainB: { - os: {}, - ics20Chan: "", - ibcDenom: "", - name: "chain-aa", - definition: osmosisB, - denom: osmosisB.denomFee, - }, -}; - -async function setupState() { - if (state.setup) return; - - const [chainA, chainB] = (await awaitMulti([ - setupChainClient(state.chainA.definition), - setupChainClient(state.chainB.definition), - ])) as CosmWasmSigner[]; - - const [src, dest, buffer] = await retryTill(() => - setupRelayerInfo(state.chainA.definition, state.chainB.definition) - ); - - console.log("Creating link..."); - state.link = await Link.createWithNewConnections(src, dest, state.logger); - state.logger.log( - "Link A", - state.link.endA.clientID, - state.link.endA.connectionID - ); - state.logger.log( - "Link B", - state.link.endB.clientID, - state.link.endB.connectionID - ); - console.log("Created link"); - - console.log("Creating ics20 channel..."); - const channel = await state.link.createChannel( - "A", - state.chainA.definition.ics20Port, - state.chainB.definition.ics20Port, - Order.ORDER_UNORDERED, - "ics20-1" - ); - state.logger.log("Channel Created", channel); - state.chainA.ics20Chan = channel.src.channelId; - state.chainB.ics20Chan = channel.dest.channelId; - console.log("Created ics20 channel..."); - - const chainAIBCDenom = `ibc/${digest( - `${state.chainB.definition.ics20Port}/${state.chainB.ics20Chan}/${state.chainA.denom}` - ).toUpperCase()}`; - const chainBIBCDenom = `ibc/${digest( - `${state.chainA.definition.ics20Port}/${state.chainA.ics20Chan}/${state.chainB.denom}` - ).toUpperCase()}`; - state = { - ...state, - setup: true, - chainA: { - ...state.chainA, - client: chainA, - ibcDenom: chainAIBCDenom, - }, - chainB: { - ...state.chainB, - client: chainB, - ibcDenom: chainBIBCDenom, - }, - }; -} - -before(async () => { - await waitForChain(state.chainA.definition.tendermintUrlHttp); - await waitForChain(state.chainB.definition.tendermintUrlHttp); - await setupState(); -}); - -describe("Operating System", () => { - step("should be deployed correctly...", async () => { - const { chainA, chainB } = state; - const [addressesA, addressesB] = (await awaitMulti([ - setupOS(chainA.client! as CosmWasmSigner, chainA.name), - setupOS(chainB.client! as CosmWasmSigner, chainB.name), - ])) as Record[]; - for (const contract in addressesA) { - chainA.os[contract as keyof Contracts] = Contract.fromAddress( - addressesA[contract as keyof Contracts] - ); - } - for (const contract in addressesB) { - chainB.os[contract as keyof Contracts] = Contract.fromAddress( - addressesB[contract as keyof Contracts] - ); - } - }); - - step("should have assigned key addresses correctly", async () => { - const { chainA, chainB } = state; - - for (const name in chainA.os) { - if (name === "kernel") continue; - const query = { - key_address: { - key: name, - }, - }; - const resChainA = await chainA.os.kernel!.query(query, chainA.client!); - assert(resChainA == chainA.os[name as keyof Contracts]!.address); - const resChainB = await chainB.os.kernel!.query(query, chainB.client!); - assert(resChainB == chainB.os[name as keyof Contracts]!.address); - } - }); - - step("should clear existing recoveries", async () => { - await state.chainA.os - .kernel!.execute({ recover: {} }, state.chainA.client!) - .catch(() => { - return; - }); - await state.chainB.os - .kernel!.execute({ recover: {} }, state.chainB.client!) - .catch(() => { - return; - }); - }); - - step("should create a channel between kernels", async () => { - const { - link, - chainA: { os: osA, client: clientA }, - chainB: { os: osB, client: clientB }, - } = state; - const portA = await osA.kernel!.getPort(clientA!); - const portB = await osB.kernel!.getPort(clientB!); - - console.debug("Creating direct channel"); - const channel = await retryTill(() => - link?.createChannel( - "A", - portA, - portB, - Order.ORDER_UNORDERED, - "andr-kernel-1" - ) - ); - assert(!!channel, "channel not created"); - state.channel = channel; - // await relayAll(link!); - }); - - step("should assign the correct channel on chain A", async () => { - const { chainA, chainB, channel } = state; - - const chainABridgeMsg = { - assign_channels: { - ics20_channel_id: chainA.ics20Chan, - kernel_address: chainB.os.kernel!.address, - chain: chainB.name, - direct_channel_id: channel?.src.channelId, - }, - }; - await chainA.os.kernel!.execute(chainABridgeMsg, chainA.client!); - - const assignedChannels = await chainA.os.kernel!.query<{ - ics20: string; - direct: string; - }>( - { - channel_info: { chain: chainB.name }, - }, - chainA.client! - ); - assert(assignedChannels.ics20 == chainA.ics20Chan); - assert(assignedChannels.direct == channel?.src.channelId); - assert(assignedChannels.direct == channel?.src.channelId); - }); - - step("should assign the correct channel on chain B", async () => { - const { chainA, chainB, channel } = state; - const chainBBridgeMsg = { - assign_channels: { - ics20_channel_id: chainB.ics20Chan, - kernel_address: chainA.os.kernel!.address, - chain: chainA.name, - direct_channel_id: channel?.dest.channelId, - }, - }; - await chainB.os.kernel!.execute(chainBBridgeMsg, chainB.client!); - - const assignedChannels = await chainB.os.kernel!.query<{ - ics20: string; - direct: string; - }>( - { - channel_info: { chain: chainA.name }, - }, - chainB.client! - ); - assert(assignedChannels.ics20 == chainB.ics20Chan); - assert(assignedChannels.direct == channel?.dest.channelId); - }); - - step("should upload all contracts correctly", async () => { - const { chainA, chainB } = state; - await awaitMulti([ - uploadAllADOs(chainA.client!, chainA.os.adodb!), - uploadAllADOs(chainB.client!, chainB.os.adodb!), - ]); - assert(true); - }); - - step("should have published all contracts correctly", async () => { - const { - chainA: { os: osA, client: clientA }, - chainB: { os: osB, client: clientB }, - } = state; - const names = getAllADONames(); - const queryCodeId = async (name: string) => { - const query = { - code_id: { - key: name, - }, - }; - - const resA = await osA.adodb!.query(query, clientA!); - const resB = await osB.adodb!.query(query, clientB!); - }; - - const promises = names.map((name) => queryCodeId(name)); - - await awaitMulti(promises); - }); -}); - -describe("Basic IBC Token Transfers", async () => { - step("should send tokens from chain A to chain A", async () => { - const { chainA } = state; - const receiver = randomAddress(chainA.definition.prefix); - const transferAmount = { amount: "100", denom: chainA.denom }; - const msg = createAMPMsg(`${receiver}`, undefined, [transferAmount]); - const kernelMsg = { send: { message: msg } }; - const res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - - const balance = await chainA.client!.sign.getBalance( - receiver, - transferAmount.denom - ); - assert(balance.amount === transferAmount.amount, "Balance is incorrect"); - }); - - step("should send tokens from chain B to chain B", async () => { - const { chainB } = state; - const receiver = randomAddress(chainB.definition.prefix); - const transferAmount = { amount: "100", denom: chainB.denom }; - const msg = createAMPMsg(`${receiver}`, undefined, [transferAmount]); - const kernelMsg = { send: { message: msg } }; - const res = await chainB.os.kernel!.execute(kernelMsg, chainB.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - - const balance = await chainB.client!.sign.getBalance( - receiver, - transferAmount.denom - ); - assert(balance.amount === transferAmount.amount, "Balance is incorrect"); - }); - - step("should send tokens from chain A to chain B", async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainB.definition.prefix); - const transferAmount = { amount: "105", denom: chainA.denom }; - const msg = createAMPMsg( - `ibc://${chainB.name}/home/${receiver}`, - undefined, - [transferAmount] - ); - const kernelMsg = { send: { message: msg } }; - const res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssert, info] = await relayAll(link!); - if (shouldAssert) assertPacketsFromA(info, 1, true); - const chainBBalance = await chainB.client!.sign.getBalance( - receiver, - chainA.ibcDenom - ); - assert( - chainBBalance.amount === transferAmount.amount, - "Balance is incorrect" - ); - }); - - step("should send tokens from chain B to chain A", async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const transferAmount = { amount: "105", denom: chainB.denom }; - const msg = createAMPMsg( - `ibc://${chainA.name}/home/${receiver}`, - undefined, - [transferAmount] - ); - const kernelMsg = { send: { message: msg } }; - const res = await chainB.os.kernel!.execute(kernelMsg, chainB.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssert, info] = await relayAll(link!); - if (shouldAssert) assertPacketsFromB(info, 1, true); - const chainABalance = await chainA.client!.sign.getBalance( - receiver, - chainB.ibcDenom - ); - assert( - chainABalance.amount === transferAmount.amount, - "Balance is incorrect" - ); - }); - - step( - "should send chain A tokens from chain A to chain B using splitter", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainB.definition.prefix); - const splitterCodeId: number = await chainA.os.adodb!.query( - { code_id: { key: "splitter" } }, - chainA.client! - ); - const splitterInstMsg = { - kernel_address: chainA.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainB.name}/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const splitter = await Contract.fromCodeId( - splitterCodeId, - splitterInstMsg, - chainA.client! - ); - - state.logger.log( - "chain A tokens from chain A to chain B using splitter - Splitter address", - splitter.address - ); - state.logger.log( - "chain A tokens from chain A to chain B using splitter - Receiver address", - receiver - ); - - const transferAmount = { amount: "100", denom: chainA.denom }; - const msg = createAMPMsg(`${splitter.address}`, { send: {} }, [ - transferAmount, - ]); - const kernelMsg = { send: { message: msg } }; - const res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssertA, infoB] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoB, 1, true); - await relayAll(link!); - const chainABalance = await chainB.client!.sign.getBalance( - receiver, - chainA.ibcDenom - ); - assert( - chainABalance.amount === transferAmount.amount, - "Balance is incorrect" - ); - } - ); - - step( - "should send chain B tokens from chain A to chain B using splitter", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainB.definition.prefix); - const splitterCodeId: number = await chainA.os.adodb!.query( - { code_id: { key: "splitter" } }, - chainA.client! - ); - const splitterInstMsg = { - kernel_address: chainA.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainB.name}/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const splitter = await Contract.fromCodeId( - splitterCodeId, - splitterInstMsg, - chainA.client! - ); - - state.logger.log( - "chain B tokens from chain A to chain B using splitter - Splitter address", - splitter.address - ); - state.logger.log( - "chain B tokens from chain A to chain B using splitter - Receiver address", - receiver - ); - - const transferAmount = { amount: "100", denom: chainB.denom }; - const transferMsg = createAMPMsg( - `ibc://${chainA.name}/home/${chainA.client!.senderAddress}`, - undefined, - [transferAmount] - ); - const transferKernelMsg = { send: { message: transferMsg } }; - let res = await chainB.os.kernel!.execute( - transferKernelMsg, - chainB.client!, - [transferAmount] - ); - assert(res.transactionHash); - const [shouldAssert, info] = await relayAll(link!); - if (shouldAssert) assertPacketsFromB(info, 1, true); - - // Now send the ibc denom received above to the splitter - transferAmount.denom = chainB.ibcDenom; - const msg = createAMPMsg(`${splitter.address}`, { send: {} }, [ - transferAmount, - ]); - const kernelMsg = { send: { message: msg } }; - res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssertA, infoB] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoB, 1, true); - await relayAll(link!); - const chainABalance = await chainB.client!.sign.getBalance( - receiver, - chainB.denom - ); - assert( - chainABalance.amount === transferAmount.amount, - "Balance is incorrect" - ); - } - ); - - step( - "should send tokens from chain A to chain B and back to chain A", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const splitterCodeId: number = await chainB.os.adodb!.query( - { code_id: { key: "splitter" } }, - chainB.client! - ); - const splitterInstMsg = { - kernel_address: chainB.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainA.name}/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const splitter = await Contract.fromCodeId( - splitterCodeId, - splitterInstMsg, - chainB.client! - ); - - state.logger.log( - "Chain A to B to Chain A - Splitter address", - splitter.address - ); - state.logger.log("Chain A to B to Chain A - Receiver address", receiver); - - const transferAmount = { amount: "100", denom: chainA.denom }; - const msg = createAMPMsg( - `ibc://${chainB.name}/home/${splitter.address}`, - { send: {} }, - [transferAmount] - ); - const kernelMsg = { send: { message: msg } }; - const res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssertA, infoA] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoA, 1, true); - await relayAll(link!); - const chainABalance = await chainA.client!.sign.getBalance( - receiver, - chainA.denom - ); - assert( - chainABalance.amount === transferAmount.amount, - "Balance is incorrect" - ); - } - ); - - step( - "should send chain A tokens from chain A to chain B using VFS symlink", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainB.definition.prefix); - const symlinkName = "chain-b-recipient"; - const symlink = `ibc://${chainB.name}/home/${receiver}`; - const splitterCodeId: number = await chainA.os.adodb!.query( - { code_id: { key: "splitter" } }, - chainA.client! - ); - const splitterInstMsg = { - kernel_address: chainA.os.kernel!.address, - recipients: [ - { - recipient: { - address: `/home/${chainA.client?.senderAddress}/${symlinkName}`, - }, - percent: "1", - }, - ], - }; - const splitter = await Contract.fromCodeId( - splitterCodeId, - splitterInstMsg, - chainA.client! - ); - - const vfs_msg = { - add_symlink: { - name: symlinkName, - symlink, - }, - }; - await chainA.os.vfs?.execute(vfs_msg, chainA.client!); - - state.logger.log( - "chain A tokens from chain A to chain B using splitter - Splitter address", - splitter.address - ); - state.logger.log( - "chain A tokens from chain A to chain B using splitter - Receiver address", - receiver - ); - - const transferAmount = { amount: "100", denom: chainA.denom }; - const msg = createAMPMsg(`${splitter.address}`, { send: {} }, [ - transferAmount, - ]); - const kernelMsg = { send: { message: msg } }; - const res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssertA, infoB] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoB, 1, true); - await relayAll(link!); - const chainBBalance = await chainB.client!.sign.getBalance( - receiver, - chainA.ibcDenom - ); - assert( - chainBBalance.amount === transferAmount.amount, - "Balance is incorrect" - ); - } - ); -}); - -describe("Cross Chain ADO Creation", async () => { - step( - "should create an ADO on chain B when sent to the kernel on chain A", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const splitterInstMsg = { - kernel_address: chainB.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainA.name}/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const message = { - create: { - ado_type: "splitter", - owner: receiver, - chain: chainB.name, - msg: toBinary(splitterInstMsg), - }, - }; - - const res = await chainA.os.kernel!.execute(message, chainA.client!); - assert(res.transactionHash); - - const [shouldAssertA, infoA] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoA, 1, true); - } - ); - - step( - "should create an app on chain A containing a splitter on chain A", - async () => { - const { chainA } = state; - const receiver = randomAddress(chainA.definition.prefix); - const splitterInstMsg = { - kernel_address: chainA.os.kernel!.address, - recipients: [ - { - recipient: { - address: `/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const appName = `${receiver.substring(0, 8)}-app`; - const appInstMsg = { - kernel_address: chainA.os.kernel!.address, - app_components: [ - { - name: "splitter-b", - ado_type: "splitter@0.2.3", - component_type: { - new: toBinary(splitterInstMsg), - }, - }, - ], - name: appName, - owner: receiver, - }; - - const kernel_msg = { - create: { - ado_type: "app-contract", - msg: toBinary(appInstMsg), - }, - }; - - const res = await chainA.os.kernel!.execute(kernel_msg, chainA.client!); - assert(res.transactionHash); - } - ); - - step( - "should create an app on chain B via the kernel on chain A", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const splitterInstMsg = { - kernel_address: chainB.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainA.name}/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const appName = `${receiver.substring(0, 8)}-app`; - const appInstMsg = { - kernel_address: chainB.os.kernel!.address, - app_components: [ - { - name: "splitter-b", - ado_type: "splitter", - component_type: { - new: toBinary(splitterInstMsg), - }, - }, - ], - name: appName, - owner: chainB.client!.senderAddress, - }; - - const kernel_msg = { - create: { - ado_type: "app-contract", - owner: chainB.client!.senderAddress, - msg: toBinary(appInstMsg), - chain: chainB.name, - }, - }; - - const res = await chainA.os.kernel!.execute(kernel_msg, chainA.client!); - assert(res.transactionHash); - - const [shouldAssertA, infoA] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoA, 1, true); - - const resp = await chainB.os.vfs!.query( - { - resolve_path: { - path: `/home/${chainB.client!.senderAddress}/${appName}`, - }, - }, - chainB.client! - ); - assert(resp); - } - ); - - step( - "should create an app on chain A containing a splitter on chain B", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const splitterInstMsg = { - kernel_address: chainB.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainA.name}/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const appName = `${receiver.substring(0, 8)}-app`; - const appInstMsg = { - kernel_address: chainA.os.kernel!.address, - app_components: [ - { - name: "splitter-b", - ado_type: "splitter", - component_type: { - cross_chain: { - chain: chainB.name, - instantiate_msg: toBinary(splitterInstMsg), - }, - }, - }, - ], - chain_info: [ - { - chain_name: chainB.name, - owner: receiver, - }, - ], - name: appName, - }; - - const appCodeId: number = await chainA.os.adodb!.query( - { code_id: { key: "app-contract" } }, - chainA.client! - ); - const app = await Contract.fromCodeId( - appCodeId, - appInstMsg, - chainA.client! - ); - assert(app.address); - - const [shouldAssertA, infoA] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoA, 1, true); - - const resp = await chainB.os.vfs!.query( - { - resolve_path: { - path: `/home/${receiver}/${appName}/splitter-b`, - }, - }, - chainB.client! - ); - assert(resp); - - const respTwo = await chainA.os.vfs!.query( - { - resolve_symlink: { - path: `/home/${chainA.client!.senderAddress}/${appName}/splitter-b`, - }, - }, - chainA.client! - ); - assert(respTwo); - - const sendMsg = createAMPMsg( - `/home/${chainA.client!.senderAddress}/${appName}/splitter-b`, - undefined, - [{ amount: "100", denom: chainA.denom }] - ); - const sendKernelMsg = { send: { message: sendMsg } }; - const res = await chainA.os.kernel!.execute( - sendKernelMsg, - chainA.client!, - [{ amount: "100", denom: chainA.denom }] - ); - - assert(res); - - const [shouldAssertATwo, infoATwo] = await relayAll(link!); - if (shouldAssertATwo) assertPacketsFromA(infoATwo, 1, true); - } - ); -}); - -describe("IBC Fund Recovery", async () => { - step( - "should recover funds on a failed IBC hooks message from chain A to chain B", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const recoveryAddr = chainA.client!.senderAddress; - const recoveryQuery = { - recoveries: { addr: recoveryAddr }, - }; - const splitterCodeId: number = await chainB.os.adodb!.query( - { code_id: { key: "splitter" } }, - chainB.client! - ); - const splitterInstMsg = { - kernel_address: chainB.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainA.name}/home/${receiver}`, - }, - percent: "1", - }, - ], - }; - const splitter = await Contract.fromCodeId( - splitterCodeId, - splitterInstMsg, - chainB.client! - ); - - state.logger.log( - "Chain A to B IBC Fail Recovery - Splitter address", - splitter.address - ); - state.logger.log( - "Chain A to B IBC Fail Recovery - Receiver address", - receiver - ); - - const transferAmount = { amount: "100", denom: chainA.denom }; - // ERROR HERE - const msg = createAMPMsg( - `ibc://${chainB.name}/home/${splitter.address}`, - { not_a_valid_message: {} }, - [transferAmount], - { - recovery_addr: recoveryAddr, - } - ); - const kernelMsg = { send: { message: msg } }; - const res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssertA, infoA] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoA, 1, false); - await relayAll(link!); - const recoveries: { amount: string; denom: string }[] = - await chainA.os.kernel!.query(recoveryQuery, chainA.client!); - assert(recoveries.length === 1, "No recovery found"); - assert( - recoveries[0].amount === transferAmount.amount, - "Incorrect amount" - ); - assert(recoveries[0].denom === transferAmount.denom, "Incorrect denom"); - - const recoveryRes = await chainA.os.kernel!.execute( - { recover: {} }, - chainA.client! - ); - assert(recoveryRes.transactionHash); - } - ); - - step( - "should recover funds on a failed IBC hooks message after sending from chain A to chain B and responding back to chain A", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const recoveryAddr = chainB.client!.senderAddress; - const splitterCodeId: number = await chainB.os.adodb!.query( - { code_id: { key: "splitter" } }, - chainB.client! - ); - // Will error with recipient as it is not a splitter contract - const splitterInstMsg = { - kernel_address: chainB.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainA.name}/home/${receiver}`, - msg: "eyJzZW5kIjp7fX0=", // { send: {} } encoded - ibc_recovery_address: recoveryAddr, - }, - percent: "1", - }, - ], - }; - const splitter = await Contract.fromCodeId( - splitterCodeId, - splitterInstMsg, - chainB.client! - ); - - state.logger.log( - "Chain A to B to Chain A IBC Fail Recovery - Splitter address", - splitter.address - ); - state.logger.log( - "Chain A to B to Chain A IBC Fail Recovery - Receiver address", - receiver - ); - - const transferAmount = { amount: "100", denom: chainA.denom }; - const msg = createAMPMsg( - `ibc://${chainB.name}/home/${splitter.address}`, - { send: {} }, - [transferAmount] - ); - const kernelMsg = { send: { message: msg } }; - const res = await chainA.os.kernel!.execute(kernelMsg, chainA.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssertA, infoA] = await relayAll(link!); - if (shouldAssertA) assertPacketsFromA(infoA, 1, true); - await relayAll(link!); - const recoveryQuery = { - recoveries: { addr: recoveryAddr }, - }; - const recoveries: { amount: string; denom: string }[] = - await chainB.os.kernel!.query(recoveryQuery, chainB.client!); - assert(recoveries.length === 1, "No recovery found"); - assert( - recoveries[0].amount === transferAmount.amount, - "Incorrect amount" - ); - assert(recoveries[0].denom === chainA.ibcDenom, "Incorrect denom"); - const recoveryRes = await chainB.os.kernel!.execute( - { recover: {} }, - chainB.client! - ); - assert(recoveryRes.transactionHash); - } - ); - - step( - "should assign the original sender as the recovery address in an AMP packet when none is provided", - async () => { - const { link, chainA, chainB } = state; - const receiver = randomAddress(chainA.definition.prefix); - const recoveryAddr = chainB.client!.senderAddress; - const splitterCodeId: number = await chainB.os.adodb!.query( - { code_id: { key: "splitter" } }, - chainB.client! - ); - // Will error with recipient as it is not a splitter contract - const splitterInstMsg = { - kernel_address: chainB.os.kernel!.address, - recipients: [ - { - recipient: { - address: `ibc://${chainA.name}/home/${receiver}`, - msg: "eyJzZW5kIjp7fX0=", // { send: {} } encoded - }, - percent: "1", - }, - ], - }; - const splitter = await Contract.fromCodeId( - splitterCodeId, - splitterInstMsg, - chainB.client! - ); - - const transferAmount = { amount: "100", denom: chainB.denom }; - const msg = createAMPMsg(splitter.address, { send: {} }, [ - transferAmount, - ]); - const kernelMsg = { send: { message: msg } }; - const res = await chainB.os.kernel!.execute(kernelMsg, chainB.client!, [ - transferAmount, - ]); - assert(res.transactionHash); - const [shouldAssertB, infoB] = await relayAll(link!); - if (shouldAssertB) assertPacketsFromB(infoB, 1, false); - const recoveryQuery = { - recoveries: { addr: recoveryAddr }, - }; - const recoveries: { amount: string; denom: string }[] = - await chainB.os.kernel!.query(recoveryQuery, chainB.client!); - assert(recoveries.length === 1, "No recovery found"); - assert( - recoveries[0].amount === transferAmount.amount, - "Incorrect amount" - ); - assert(recoveries[0].denom === transferAmount.denom, "Incorrect denom"); - const recoveryRes = await chainB.os.kernel!.execute( - { recover: {} }, - chainB.client! - ); - assert(recoveryRes.transactionHash); - } - ); -}); - -describe("User Registration", async () => { - step("should register a user on chain A", async () => { - const { chainA } = state; - const username = "user1"; - const msg = { - register_user: { - username, - }, - }; - - const res = await chainA.os.vfs!.execute(msg, chainA.client!); - assert(res.transactionHash); - }); - - step("should error on user registration on chain B", async () => { - const { chainB } = state; - const username = "user1"; - const msg = { - register_user: { - username, - }, - }; - - try { - await chainB.os.vfs!.execute(msg, chainB.client!); - throw new Error("Should have errored"); - } catch (error) { - const { message } = error as Error; - assert(!message.includes("Should have errored")); - } - }); - - step("should propagate the registered user to chain B", async () => { - const { chainA, chainB, link } = state; - const msg = { - register_user_cross_chain: { - address: chainB.client!.senderAddress, - chain: chainB.name, - }, - }; - - const res = await chainA.os.vfs!.execute(msg, chainA.client!); - assert(res.transactionHash); - - const [shouldAssert, info] = await relayAll(link!); - if (shouldAssert) assertPacketsFromA(info, 1, true); - - const userRes = await chainB.os.vfs!.query( - { resolve_path: { path: "~user1" } }, - chainB.client! - ); - assert(userRes === chainB.client!.senderAddress); - }); -}); diff --git a/andromeda-core/ibc-tests/test/logger.ts b/andromeda-core/ibc-tests/test/logger.ts deleted file mode 100644 index bdf9146..0000000 --- a/andromeda-core/ibc-tests/test/logger.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { appendFileSync, writeFileSync } from "fs"; - -import { Logger, LogMethod } from "@confio/relayer/build/lib/logger"; -import { SinonSpy, spy } from "sinon"; - -export class CustomLogger implements Logger { - readonly error: SinonSpy & LogMethod; - readonly warn: SinonSpy & LogMethod; - readonly info: SinonSpy & LogMethod; - readonly verbose: SinonSpy & LogMethod; - readonly debug: SinonSpy & LogMethod; - readonly child: () => CustomLogger; - readonly log: SinonSpy & LogMethod; - constructor() { - reset(); - const createSpy = (logFn: typeof logger, type: string) => { - return spy((...args) => { - logFn(`${type.toUpperCase()}::${new Date().toISOString()}`); - args.forEach((message) => { - if (message) logFn(message, "\n👉👉"); - }); - return this; - }).bind(this); - }; - this.error = createSpy(logger, "ERROR"); - this.warn = createSpy(logger, "WARN"); - this.info = createSpy(logger, "INFO"); - this.verbose = createSpy(logger, "VERBOSE"); - this.debug = createSpy(logger, "DEBUG"); - this.child = () => this; - this.log = createSpy(logger, "CUSTOM LOG"); - } -} - -const FILE_NAME = `./relayer.log.txt`; -async function logger(data: any, lineBreak = "\n📄") { - if (typeof data !== "string") data = JSON.stringify(data); - appendFileSync(FILE_NAME, lineBreak + "\t" + data); -} - -async function reset() { - writeFileSync(FILE_NAME, "Logger Starting now\n"); -} diff --git a/andromeda-core/ibc-tests/test/os.ts b/andromeda-core/ibc-tests/test/os.ts deleted file mode 100644 index 14eaa40..0000000 --- a/andromeda-core/ibc-tests/test/os.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { readFileSync, writeFileSync } from "fs"; - -import { CosmWasmSigner } from "@confio/relayer"; - -import { getADOPath, setupContracts } from "./utils"; - -export async function instantiateOs( - client: CosmWasmSigner, - codeIds: Record, - chainName: string -) { - const addresses: Record = {}; - const res = await client.sign.instantiate( - client.senderAddress, - codeIds["kernel"], - { chain_name: chainName }, - "Kernel", - "auto" - ); - addresses["kernel"] = res.contractAddress; - for (const name in codeIds) { - if (name === "kernel") { - continue; - } else { - const res = await client.sign.instantiate( - client.senderAddress, - codeIds[name], - { kernel_address: addresses["kernel"] }, - name, - "auto" - ); - addresses[name] = res.contractAddress; - } - } - - return addresses; -} - -async function assignKeyAddresses( - client: CosmWasmSigner, - addresses: Record -) { - const kernelAddress = addresses["kernel"]; - for (const name in addresses) { - if (name === "kernel") continue; - await client.sign.execute( - client.senderAddress, - kernelAddress, - { upsert_key_address: { key: name, value: addresses[name] } }, - "auto" - ); - } -} - -export async function setupOS(client: CosmWasmSigner, chainName: string) { - const chainId = await client.sign.getChainId(); - const osCache = await getChainCache(chainId); - const contracts: Record = { - kernel: getADOPath("kernel"), - adodb: getADOPath("adodb"), - vfs: getADOPath("vfs"), - economics: getADOPath("economics"), - }; - if (osCache?.OS && !Object.keys(contracts).some((k) => !osCache.OS[k])) { - console.debug(`Using cache for ${chainId}`); - return osCache.OS; - } - const codeIds = await setupContracts(client, contracts); - const addresses = await instantiateOs(client, codeIds, chainName); - await assignKeyAddresses(client, addresses); - await setChainCache(chainId, { - OS: addresses, - ALL_ADO: {}, - client: client.senderAddress, - }); - return addresses; -} - -export interface Cache { - OS: Record; - ALL_ADO: Record; - client: string; -} - -export async function getChainCache(chainId: string) { - try { - const cache = readFileSync(`./${chainId}.cache.json`, "utf8"); - return JSON.parse(cache) as Cache; - } catch (err) { - return undefined; - } -} - -export async function setChainCache(chainId: string, data: Cache) { - writeFileSync(`./${chainId}.cache.json`, JSON.stringify(data, undefined, 4)); -} diff --git a/andromeda-core/ibc-tests/test/relayer.ts b/andromeda-core/ibc-tests/test/relayer.ts deleted file mode 100644 index 0f7749c..0000000 --- a/andromeda-core/ibc-tests/test/relayer.ts +++ /dev/null @@ -1,26 +0,0 @@ -import axios from "axios"; - -const POLL_INTERVAL = 2000; -const MAX_POLL_COUNT = 60; - -async function sleep(timeout: number) { - return new Promise((resolve) => setTimeout(resolve, timeout)); -} - -export async function waitForChain(url: string) { - for (let i = 0; i < MAX_POLL_COUNT; i++) { - try { - await axios.get(`${url}/status`); - return; - } catch { - console.error( - `No response from ${url}, retrying in ${POLL_INTERVAL / 1000}s (${ - i + 1 - }/${MAX_POLL_COUNT})` - ); - await sleep(POLL_INTERVAL); - } - } - - throw new Error("Timeout reached while waiting for chain"); -} diff --git a/andromeda-core/ibc-tests/test/utils.ts b/andromeda-core/ibc-tests/test/utils.ts deleted file mode 100644 index 84b9541..0000000 --- a/andromeda-core/ibc-tests/test/utils.ts +++ /dev/null @@ -1,390 +0,0 @@ -// SOURCE CODE: https://github.com/confio/cw-ibc-demo/blob/main/tests/src/utils.ts -import { readdirSync, readFileSync } from "fs"; - -import { - AckWithMetadata, - CosmWasmSigner, - IbcClient, - Link, - RelayInfo, - testutils, -} from "@confio/relayer"; -import { IbcClientOptions } from "@confio/relayer/build/lib/ibcclient"; -import { SigningCosmWasmClientOptions } from "@cosmjs/cosmwasm-stargate"; -import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate"; -import { stringToPath } from "@cosmjs/crypto"; -import { fromBase64, fromUtf8 } from "@cosmjs/encoding"; -import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; -import { Coin, GasPrice } from "@cosmjs/stargate"; -import { assert } from "@cosmjs/utils"; -import axios from "axios"; - -import { ChainDefinition } from "./configs"; -import Contract from "./contract"; -import { getChainCache, setChainCache } from "./os"; - -function encode(data: unknown | string) { - return Buffer.from(JSON.stringify(data)).toString("base64"); -} - -const { generateMnemonic } = testutils; - -const mnemonic = - "bounce success option birth apple portion aunt rural episode solution hockey pencil lend session cause hedgehog slender journey system canvas decorate razor catch empty"; - -export const IbcVersion = "simple-ica-v2"; - -export async function awaitMulti(promises: Promise[]) { - return await Promise.all(promises); -} - -async function signingCosmWasmClient( - chain: ChainDefinition, - mnemonic: string -): Promise { - const hdPath = - chain.prefix === "terra" ? [stringToPath("m/44'/330'/0'/0/0")] : undefined; - const signer = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { - prefix: chain.prefix, - hdPaths: hdPath as any, - }); - const { address: senderAddress } = (await signer.getAccounts())[0]; - const options: SigningCosmWasmClientOptions = { - gasPrice: GasPrice.fromString(chain.minFee), - // This is just for tests - don't add this in production code - broadcastPollIntervalMs: 100, - broadcastTimeoutMs: 15000, - }; - const sign = await SigningCosmWasmClient.connectWithSigner( - chain.tendermintUrlHttp, - signer, - options - ); - - return { sign, senderAddress }; -} - -async function ibcClient( - chain: ChainDefinition, - clientMnemonic: string -): Promise { - const hdPath = - chain.prefix === "terra" ? [stringToPath("m/44'/330'/0'/0/0")] : undefined; - const signer = await DirectSecp256k1HdWallet.fromMnemonic(clientMnemonic, { - prefix: chain.prefix, - hdPaths: hdPath as any, - }); - const { address: senderAddress } = (await signer.getAccounts())[0]; - const options: IbcClientOptions = { - gasPrice: GasPrice.fromString(chain.minFee), - // This is just for tests - don't add this in production code - estimatedBlockTime: 1000, - estimatedIndexerTime: 500, - broadcastTimeoutMs: 15000, - broadcastPollIntervalMs: 100, - }; - const sign = await IbcClient.connectWithSigner( - chain.tendermintUrlHttp, - signer, - senderAddress, - options - ); - - return sign; -} - -export async function setupContracts( - cosmwasm: CosmWasmSigner, - contracts: Record -): Promise> { - const results: Record = {}; - for (const name in contracts) { - const path = contracts[name]; - const wasm = readFileSync(path); - const receipt = await cosmwasm.sign.upload( - cosmwasm.senderAddress, - wasm, - "auto", - `Upload ${name}` - ); - results[name] = receipt.codeId; - } - - return results; -} - -// This creates a client for the CosmWasm chain, that can interact with contracts -export async function setupChainClient( - chain: ChainDefinition, - _mnemonic?: string -): Promise { - _mnemonic = _mnemonic || mnemonic || generateMnemonic(); - const cosmwasm = await signingCosmWasmClient(chain, _mnemonic); - return cosmwasm; -} - -// throws error if not all are success -export function assertAckSuccess(acks: AckWithMetadata[]) { - for (const ack of acks) { - const parsed = JSON.parse(fromUtf8(ack.acknowledgement)); - if (parsed.error) { - throw new Error(`Unexpected error in ack: ${parsed.error}`); - } - if (!parsed.result) { - throw new Error(`Ack result unexpectedly empty`); - } - } -} - -// throws error if not all are errors -export function assertAckErrors(acks: AckWithMetadata[]) { - for (const ack of acks) { - const parsed = JSON.parse(fromUtf8(ack.acknowledgement)); - if (parsed.result) { - throw new Error(`Ack result unexpectedly set`); - } - if (!parsed.error) { - throw new Error(`Ack error unexpectedly empty`); - } - } -} - -export function assertPacketsFromA( - relay: RelayInfo, - count: number, - success: boolean -) { - if (relay.packetsFromA !== count) { - throw new Error(`Expected ${count} packets, got ${relay.packetsFromA}`); - } - if (relay.acksFromB.length !== count) { - throw new Error(`Expected ${count} acks, got ${relay.acksFromB.length}`); - } - if (success) { - assertAckSuccess(relay.acksFromB); - } else { - assertAckErrors(relay.acksFromB); - } -} - -export function assertPacketsFromB( - relay: RelayInfo, - count: number, - success: boolean -) { - if (relay.packetsFromB !== count) { - throw new Error(`Expected ${count} packets, got ${relay.packetsFromB}`); - } - if (relay.acksFromA.length !== count) { - throw new Error(`Expected ${count} acks, got ${relay.acksFromA.length}`); - } - if (success) { - assertAckSuccess(relay.acksFromA); - } else { - assertAckErrors(relay.acksFromA); - } -} - -export function parseAcknowledgementSuccess( - ack: AckWithMetadata -): Record { - const response = parseString(ack.acknowledgement); - assert(response.result); - return parseBinary(response.result as string); -} - -export function parseString(str: Uint8Array): Record { - return JSON.parse(fromUtf8(str)); -} - -export function parseBinary(bin: string): Record { - return JSON.parse(fromUtf8(fromBase64(bin))); -} - -export interface AMPIBCConfig { - recovery_addr?: string; -} - -export interface AMPMsg { - recipient: string; - message: string; - funds: { amount: string; denom: string }[]; - config: { - reply_on: "error" | "always" | "never" | "success"; - exit_at_error: boolean; - gas_limit?: number; - direct: boolean; - ibc_config?: AMPIBCConfig; - }; -} - -export function createAMPMsg( - recipient: string, - msg: Record | "" = "", - funds: { amount: string; denom: string }[] = [], - ibcConfig?: AMPIBCConfig -): AMPMsg { - return { - recipient, - message: msg === "" ? msg : encode(msg), - funds, - config: { - reply_on: "error", - exit_at_error: false, - direct: true, - ibc_config: ibcConfig, - }, - }; -} - -export function createAMPPacket(sender: string, messages: AMPMsg[]) { - return { - messages, - ctx: { - origin: sender, - previous_sender: sender, - id: 0, - }, - }; -} - -export async function setupRelayerInfo( - chainA: ChainDefinition, - chainB: ChainDefinition -) { - const newMnemonic = - "cream sport mango believe inhale text fish rely elegant below earth april wall rug ritual blossom cherry detail length blind digital proof identify ride"; - const info = [ - await ibcClient(chainA, newMnemonic), - await ibcClient(chainB, newMnemonic), - ]; - return info; -} - -export function getADOPath(name: string) { - const files = readdirSync("./contracts"); - const path = files.find((x) => x.includes(name.replace(/-/g, "_"))); - - return `./contracts/${path}`; -} - -export function getFileVersion(path: string) { - const split = path.split("@"); - return split[split.length - 1].replace(".wasm", ""); -} - -export function getFileName(path: string) { - const split = path.split("@"); - return split[0].replace("andromeda_", "").replace(/_/g, "-"); -} - -export function getAllADONames() { - const files = readdirSync("./contracts"); - return files.map((x) => getFileName(x)); -} - -export async function uploadADO( - name: string, - client: CosmWasmSigner, - adodb: Contract -) { - const chainId = await client.sign.getChainId(); - const cache = await getChainCache(chainId); - if (cache?.ALL_ADO?.[name]) return; - const path = getADOPath(name); - const version = getFileVersion(path); - - const { codeId } = await client.sign.upload( - client.senderAddress, - readFileSync(path), - "auto", - `Upload ${name}` - ); - const publishMsg = { - publish: { - code_id: codeId, - ado_type: name, - version, - }, - }; - - await adodb.execute(publishMsg, client); - if (cache) { - await setChainCache(chainId, { - ...cache, - ALL_ADO: { - ...cache.ALL_ADO, - [name]: codeId, - }, - }); - } -} - -export async function uploadAllADOs(client: CosmWasmSigner, adodb: Contract) { - const names = getAllADONames(); - for (const name of names) { - await uploadADO(name, client, adodb); - } -} - -async function sleep(timeout: number) { - return new Promise((resolve) => setTimeout(resolve, timeout)); -} -export async function relayAll(link: Link): Promise<[boolean, RelayInfo]> { - let counter = 0; - let err; - while (counter < 6) { - try { - const info = await link.relayAll(); - return [ - counter === 0 || - info.acksFromA.length > 0 || - info.acksFromB.length > 0 || - info.packetsFromA > 0 || - info.packetsFromB > 0, - info!, - ]; - } catch (error: unknown) { - err = error; - const { message } = error as Error; - if ( - message.includes("incorrect account sequence") || - message.includes("can't be greater than max height") - ) { - // Increase counter by 1 as this is expected error - counter = counter + 1; - } else { - // Increate counter by 2 as this is unexpected error - counter = counter + 2; - } - console.debug("Retrying relayAll"); - await sleep(1000); - } - } - - throw err || new Error("Unreachable"); -} - -export async function getBalances(chain: ChainDefinition, address: string) { - const balances = await axios - .get(`${chain.restUrl}/cosmos/bank/v1beta1/balances/${address}`) - .then((res) => res.data.balances); - console.log(address, balances); - return balances as Coin[]; -} - -export async function retryTill(cb: () => Promise | T, count = 5) { - let err; - while (count > 0) { - try { - const res = await cb(); - return res; - } catch (_err) { - err = _err; - console.debug("Retrying..."); - await sleep(100); - count--; - } - } - throw err; -} diff --git a/andromeda-core/ibc-tests/tests/validator_staking.rs b/andromeda-core/ibc-tests/tests/validator_staking.rs new file mode 100644 index 0000000..9e2d5e3 --- /dev/null +++ b/andromeda-core/ibc-tests/tests/validator_staking.rs @@ -0,0 +1,210 @@ +use andromeda_std::ado_base::MigrateMsg; +use cosmwasm_std::Uint128; +use cw_orch::environment::ChainKind; +use cw_orch::environment::NetworkInfo; +use cw_orch::interface; +use cw_orch::prelude::*; +use cw_orch_daemon::queriers::Staking; +use cw_orch_daemon::queriers::StakingBondStatus; +use cw_orch_daemon::Daemon; +use ibc_tests::contract_interface; + +// import messages +use andromeda_app::app; +use andromeda_finance::validator_staking; + +const TESTNET_MNEMONIC: &str = "across left ignore gold echo argue track joy hire release captain enforce hotel wide flash hotel brisk joke midnight duck spare drop chronic stool"; + +// define app contract interface +contract_interface!( + AppContract, + andromeda_app_contract, + app, + "andromeda_app_contract", + "app_contract" +); + +// include ados be tested +contract_interface!( + ValidatorStakingContract, + andromeda_validator_staking, + validator_staking, + "validator_staking_contract", + "validator_staking" +); + +pub const TERRA_NETWORK: NetworkInfo = NetworkInfo { + chain_name: "terra", + pub_address_prefix: "terra", + coin_type: 330u32, +}; + +pub const LOCAL_TERRA: ChainInfo = ChainInfo { + kind: ChainKind::Local, + chain_id: "localterraa-1", + gas_denom: "uluna", + gas_price: 0.15, + grpc_urls: &["http://localhost:20331"], + network_info: TERRA_NETWORK, + lcd_url: None, + fcd_url: None, +}; + +#[test] +fn test_validator_staking() { + let local_terra = LOCAL_TERRA; + let daemon = Daemon::builder(local_terra.clone()) // set the network to use + .mnemonic(TESTNET_MNEMONIC) + .build() + .unwrap(); + let denom = local_terra.gas_denom; + + let validator_staking_contract = ValidatorStakingContract::new(daemon.clone()); + validator_staking_contract.set_address(&Addr::unchecked( + "terra18cv7jca4dnsu8vuhu2t7fkwl23dxres8kpnhggdarf7f0dh4j4ysv3qhd7", + )); + + let staking_querier = Staking::new(&daemon); + let mut validators = daemon + .rt_handle + .block_on(async { staking_querier._validators(StakingBondStatus::Bonded).await }) + .unwrap(); + + while validators.is_empty() { + println!("================================waiting till bonded validators found================================"); + daemon.wait_seconds(10).unwrap(); + + validators = daemon + .rt_handle + .block_on(async { staking_querier._validators(StakingBondStatus::Bonded).await }) + .unwrap(); + } + + let default_validator = &validators[0]; + + let staking_query_msg = validator_staking::QueryMsg::StakedTokens { + validator: Some(Addr::unchecked(default_validator.address.to_string())), + }; + let _rewards_response: Option = validator_staking_contract + .query(&staking_query_msg) + .unwrap(); + + let claim_msg = validator_staking::ExecuteMsg::Claim { + validator: Some(Addr::unchecked(default_validator.address.to_string())), + }; + validator_staking_contract + .execute(&claim_msg, None) + .unwrap(); + + let unstake_msg = validator_staking::ExecuteMsg::Unstake { + validator: Some(Addr::unchecked(default_validator.address.to_string())), + amount: None, + }; + validator_staking_contract + .execute(&unstake_msg, None) + .unwrap(); + + daemon.wait_seconds(61).unwrap(); + + let withdraw_msg = validator_staking::ExecuteMsg::WithdrawFunds { + denom: Some(denom.to_string()), + recipient: None, + }; + validator_staking_contract + .execute(&withdraw_msg, None) + .unwrap(); + + let contract_balance = daemon + .balance( + validator_staking_contract.addr_str().unwrap(), + Some(denom.to_string()), + ) + .unwrap()[0] + .amount; + assert_eq!(contract_balance, Uint128::zero()); +} + +#[test] +fn test_kicked_validator() { + // Pause validator before running this test + let local_terra = LOCAL_TERRA; + let daemon = Daemon::builder(local_terra.clone()) // set the network to use + .mnemonic(TESTNET_MNEMONIC) + .build() + .unwrap(); + let denom = local_terra.gas_denom; + + let validator_staking_contract = ValidatorStakingContract::new(daemon.clone()); + validator_staking_contract.set_address(&Addr::unchecked( + "terra18cv7jca4dnsu8vuhu2t7fkwl23dxres8kpnhggdarf7f0dh4j4ysv3qhd7", + )); + + let staking_querier = Staking::new(&daemon); + let mut kicked_validators = daemon + .rt_handle + .block_on(async { + staking_querier + ._validators(StakingBondStatus::Unbonded) + .await + }) + .unwrap(); + + while kicked_validators.is_empty() { + println!("================================waiting till one validator is kicked================================"); + daemon.wait_seconds(10).unwrap(); + + kicked_validators = daemon + .rt_handle + .block_on(async { + staking_querier + ._validators(StakingBondStatus::Unbonded) + .await + }) + .unwrap(); + } + + let kicked_validator = &kicked_validators[0]; + + let contract_balance = daemon + .balance( + validator_staking_contract.addr_str().unwrap(), + Some(denom.to_string()), + ) + .unwrap()[0] + .amount; + assert_eq!(contract_balance, Uint128::zero()); + + let claim_msg = validator_staking::ExecuteMsg::Claim { + validator: Some(Addr::unchecked(kicked_validator.address.to_string())), + }; + validator_staking_contract + .execute(&claim_msg, None) + .unwrap(); + + let unstake_msg = validator_staking::ExecuteMsg::Unstake { + validator: Some(Addr::unchecked(kicked_validator.address.to_string())), + amount: None, + }; + validator_staking_contract + .execute(&unstake_msg, None) + .unwrap(); + + daemon.wait_seconds(61).unwrap(); + + let withdraw_msg = validator_staking::ExecuteMsg::WithdrawFunds { + denom: Some(denom.to_string()), + recipient: None, + }; + validator_staking_contract + .execute(&withdraw_msg, None) + .unwrap(); + + let contract_balance = daemon + .balance( + validator_staking_contract.addr_str().unwrap(), + Some(denom.to_string()), + ) + .unwrap()[0] + .amount; + assert_eq!(contract_balance, Uint128::zero()); +} diff --git a/andromeda-core/ibc-tests/tsconfig.json b/andromeda-core/ibc-tests/tsconfig.json deleted file mode 100644 index 4bd484a..0000000 --- a/andromeda-core/ibc-tests/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es6", - "lib": ["es2020"], - "moduleResolution": "node", - "incremental": true, - "tsBuildInfoFile": "build/.tsbuildinfo", - "inlineSourceMap": true, - "declaration": true, - "outDir": "build", - "rootDir": "test", - "strict": true, - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "noUnusedLocals": false, - "noUnusedParameters": true, - "esModuleInterop": true, - "resolveJsonModule": true, - "pretty": true, - }, - "include": ["test/**/*.ts"], - "exclude": ["node_modules/**/*", "build"] -} \ No newline at end of file diff --git a/andromeda-core/packages/andromeda-app/Cargo.toml b/andromeda-core/packages/andromeda-app/Cargo.toml index 519d136..bd45cc8 100644 --- a/andromeda-core/packages/andromeda-app/Cargo.toml +++ b/andromeda-core/packages/andromeda-app/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-app" -version = "0.1.0" +version = "1.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" +description = "Utility methods and message definitions for the Andromeda App Contract" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -12,7 +14,10 @@ backtraces = ["cosmwasm-std/backtraces"] crate-type = ["cdylib", "rlib"] [dependencies] -cosmwasm-std = { workspace = true } +cosmwasm-std = { workspace = true, features = ["cosmwasm_1_2"] } cosmwasm-schema = { workspace = true } serde = { workspace = true } andromeda-std = { workspace = true } + +[dev-dependencies] +cw-multi-test = { version = "1.0.0" } diff --git a/andromeda-core/packages/andromeda-app/src/app.rs b/andromeda-core/packages/andromeda-app/src/app.rs index 17d19a2..9ee9372 100644 --- a/andromeda-core/packages/andromeda-app/src/app.rs +++ b/andromeda-core/packages/andromeda-app/src/app.rs @@ -1,8 +1,32 @@ -use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query, error::ContractError}; +use andromeda_std::{ + amp::AndrAddr, + andr_exec, andr_instantiate, andr_query, + common::reply::ReplyId, + error::ContractError, + os::{ + aos_querier::AOSQuerier, + vfs::{convert_component_name, ExecuteMsg as VFSExecuteMsg}, + }, +}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{to_json_binary, Binary, Deps}; +use cosmwasm_std::{ + attr, ensure, instantiate2_address, to_json_binary, wasm_execute, Addr, Api, Binary, + CodeInfoResponse, Deps, Event, QuerierWrapper, SubMsg, WasmMsg, +}; use serde::Serialize; +pub fn get_chain_info(chain_name: String, chain_info: Option>) -> Option { + match chain_info { + Some(chain_info) => { + let idx = chain_info + .iter() + .position(|info| info.chain_name == chain_name)?; + Some(chain_info[idx].clone()) + } + None => None, + } +} + #[cw_serde] pub struct CrossChainComponent { pub instantiate_msg: Binary, @@ -13,6 +37,7 @@ pub struct CrossChainComponent { pub enum ComponentType { New(Binary), Symlink(AndrAddr), + #[serde(skip)] CrossChain(CrossChainComponent), } @@ -68,6 +93,18 @@ impl AppComponent { } } + pub fn symlink( + name: impl Into, + ado_type: impl Into, + symlink: impl Into, + ) -> AppComponent { + AppComponent { + ado_type: ado_type.into(), + name: name.into(), + component_type: ComponentType::Symlink(AndrAddr::from_string(symlink.into())), + } + } + pub fn verify(&self, _deps: &Deps) -> Result<(), ContractError> { if self.name.is_empty() { panic!("name cannot be empty"); @@ -78,6 +115,183 @@ impl AppComponent { self.component_type.verify()?; Ok(()) } + + #[inline] + pub fn get_salt(&self, _parent_addr: Addr) -> Binary { + Binary::from(self.name.as_bytes()) + } + + /// Generates an `Instantiate2` address for the component. + /// + /// Returns `None` for `Symlink` and `CrossChain` components. + pub fn get_new_addr( + &self, + api: &dyn Api, + adodb_addr: &Addr, + querier: &QuerierWrapper, + parent_addr: Addr, + ) -> Result, ContractError> { + if !matches!(self.component_type, ComponentType::New(..)) { + return Ok(None); + } + + let code_id = AOSQuerier::code_id_getter(querier, adodb_addr, &self.ado_type)?; + let CodeInfoResponse { checksum, .. } = querier.query_wasm_code_info(code_id)?; + + let salt = self.get_salt(parent_addr.clone()); + let creator = api.addr_canonicalize(parent_addr.as_str())?; + let new_addr = instantiate2_address(&checksum, &creator, &salt).unwrap(); + + // Instantiate 2 impl uses default cannonical address of 32 bytes (SHA 256). But as mentioned here - + // https://github.com/cosmos/cosmos-sdk/blob/v0.45.8/docs/architecture/adr-028-public-key-addresses.md + // chains can use different length for cannonical address, eg, injective uses 20 (eth based). + // Instead of having fallback for each chain we can use parent address, which itself is a contract. + // Slice the default 32 bytes canonical address to size of parent cannonical address + + let cannonical_parent_addr = api.addr_canonicalize(parent_addr.as_str())?; + let new_addr = new_addr + .as_slice() + .split_at(cannonical_parent_addr.len()) + .0 + .into(); + + Ok(Some(api.addr_humanize(&new_addr)?)) + } + + #[inline] + pub fn get_msg_binary(&self) -> Result { + match self.component_type.clone() { + ComponentType::New(msg) => Ok(msg), + _ => Err(ContractError::InvalidComponent { + name: self.name.clone(), + }), + } + } + + /// Generates a VFS registration message for the component. + pub fn generate_vfs_registration( + &self, + // New addr is provided to prevent duplicate queries + new_addr: Option, + _app_addr: &Addr, + app_name: &str, + chain_info: Option>, + _adodb_addr: &Addr, + vfs_addr: &Addr, + ) -> Result, ContractError> { + if self.name.starts_with('.') { + return Ok(None); + } + match self.component_type.clone() { + ComponentType::New(_) => { + let new_addr = new_addr.unwrap(); + let register_msg = wasm_execute( + vfs_addr.clone(), + &VFSExecuteMsg::AddPath { + name: convert_component_name(&self.name), + address: new_addr, + parent_address: None, + }, + vec![], + )?; + let register_submsg = + SubMsg::reply_always(register_msg, ReplyId::RegisterPath.repr()); + + Ok(Some(register_submsg)) + } + ComponentType::Symlink(symlink) => { + let msg = VFSExecuteMsg::AddSymlink { + name: self.name.clone(), + symlink, + parent_address: None, + }; + let cosmos_msg = wasm_execute(vfs_addr, &msg, vec![])?; + let sub_msg = SubMsg::reply_on_error(cosmos_msg, ReplyId::RegisterPath.repr()); + Ok(Some(sub_msg)) + } + ComponentType::CrossChain(CrossChainComponent { chain, .. }) => { + let curr_chain_info = get_chain_info(chain.clone(), chain_info.clone()); + ensure!( + curr_chain_info.is_some(), + ContractError::InvalidComponent { + name: self.name.clone() + } + ); + let owner_addr = curr_chain_info.unwrap().owner; + let name = self.name.clone(); + + // Register the component as a symlink for the receiving chain + let new_component = AppComponent { + name: name.clone(), + ado_type: self.ado_type.clone(), + component_type: ComponentType::Symlink(AndrAddr::from_string(format!( + "ibc://{chain}/home/{owner_addr}/{app_name}/{name}" + ))), + }; + new_component.generate_vfs_registration( + new_addr, + _app_addr, + app_name, + chain_info, + _adodb_addr, + vfs_addr, + ) + } + } + } + + /// Generates an instantiation message for the component. + /// + /// Returns `None` for `Symlink` and `CrossChain` components. + pub fn generate_instantiation_message( + &self, + querier: &QuerierWrapper, + adodb_addr: &Addr, + parent_addr: &Addr, + sender: &str, + idx: u64, + ) -> Result, ContractError> { + if let ComponentType::New(instantiate_msg) = self.component_type.clone() { + let code_id = AOSQuerier::code_id_getter(querier, adodb_addr, &self.ado_type)?; + let salt = self.get_salt(parent_addr.clone()); + let inst_msg = WasmMsg::Instantiate2 { + admin: Some(sender.to_string()), + code_id, + label: format!("Instantiate: {}", self.ado_type), + msg: instantiate_msg, + funds: vec![], + salt, + }; + Ok(Some(SubMsg::reply_always(inst_msg, idx))) + } else { + Ok(None) + } + } + + /// Generates an event for the app component. + /// + /// Includes the name and type of the component plus the following for each type: + /// - `New` - the address of the component + /// - `CrossChain` - the receiving chain of the component + /// - `Symlink` - the created symlink for the component + pub fn generate_event(&self, addr: Option) -> Event { + let mut ev = Event::new("add_app_component").add_attributes(vec![ + attr("name", self.name.clone()), + attr("ado_type", self.ado_type.clone()), + ]); + + match self.component_type.clone() { + ComponentType::New(_) => { + ev = ev.add_attribute("address", addr.unwrap().to_string()); + } + ComponentType::CrossChain(chain_component) => { + ev = ev.add_attribute("chain", chain_component.chain); + } + ComponentType::Symlink(link) => ev = ev.add_attribute("symlink", link), + } + + ev + } } #[cw_serde] @@ -116,9 +330,6 @@ pub enum ExecuteMsg { AssignAppToComponents {}, } -#[cw_serde] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] @@ -151,8 +362,3 @@ pub struct ComponentAddress { pub name: String, pub address: String, } - -#[cfg(test)] -mod tests { - // use super::*; -} diff --git a/andromeda-core/packages/andromeda-data-storage/Cargo.toml b/andromeda-core/packages/andromeda-data-storage/Cargo.toml index 7414811..0b19ac2 100644 --- a/andromeda-core/packages/andromeda-data-storage/Cargo.toml +++ b/andromeda-core/packages/andromeda-data-storage/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-data-storage" -version = "0.2.0" +version = "1.0.0" edition = "2018" -rust-version = "1.65.0" +rust-version = "1.75.0" +description = "Utility methods and message definitions for the Andromeda Data Storage Contracts" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -17,5 +19,4 @@ cosmwasm-schema = { workspace = true } serde = { version = "1.0.127", default-features = false, features = ["derive"] } cw-utils = { workspace = true } -andromeda-std = { workspace = true, features=["module_hooks"] } - +andromeda-std = { workspace = true, features = [] } diff --git a/andromeda-core/packages/andromeda-data-storage/src/boolean.rs b/andromeda-core/packages/andromeda-data-storage/src/boolean.rs new file mode 100644 index 0000000..11bb0a9 --- /dev/null +++ b/andromeda-core/packages/andromeda-data-storage/src/boolean.rs @@ -0,0 +1,43 @@ +use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query}; +use cosmwasm_schema::{cw_serde, QueryResponses}; + +#[andr_instantiate] +#[cw_serde] +pub struct InstantiateMsg { + pub restriction: BooleanRestriction, +} + +#[andr_exec] +#[cw_serde] +pub enum ExecuteMsg { + SetValue { value: bool }, + DeleteValue {}, + UpdateRestriction { restriction: BooleanRestriction }, +} + +#[andr_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(GetValueResponse)] + GetValue {}, + #[returns(GetDataOwnerResponse)] + GetDataOwner {}, +} + +#[cw_serde] +pub enum BooleanRestriction { + Private, + Public, + Restricted, +} + +#[cw_serde] +pub struct GetValueResponse { + pub value: bool, +} + +#[cw_serde] +pub struct GetDataOwnerResponse { + pub owner: AndrAddr, +} diff --git a/andromeda-core/packages/andromeda-data-storage/src/counter.rs b/andromeda-core/packages/andromeda-data-storage/src/counter.rs new file mode 100644 index 0000000..fbcb993 --- /dev/null +++ b/andromeda-core/packages/andromeda-data-storage/src/counter.rs @@ -0,0 +1,74 @@ +use andromeda_std::{andr_exec, andr_instantiate, andr_query}; +use cosmwasm_schema::{cw_serde, QueryResponses}; + +#[andr_instantiate] +#[cw_serde] +pub struct InstantiateMsg { + pub restriction: CounterRestriction, + pub initial_state: State, +} + +#[cw_serde] +pub struct State { + pub initial_amount: Option, + pub increase_amount: Option, + pub decrease_amount: Option, +} + +#[andr_exec] +#[cw_serde] +pub enum ExecuteMsg { + Increment {}, + Decrement {}, + Reset {}, + UpdateRestriction { restriction: CounterRestriction }, + SetIncreaseAmount { increase_amount: u64 }, + SetDecreaseAmount { decrease_amount: u64 }, +} + +#[andr_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(GetInitialAmountResponse)] + GetInitialAmount {}, + #[returns(GetCurrentAmountResponse)] + GetCurrentAmount {}, + #[returns(GetIncreaseAmountResponse)] + GetIncreaseAmount {}, + #[returns(GetDecreaseAmountResponse)] + GetDecreaseAmount {}, + #[returns(GetRestrictionResponse)] + GetRestriction {}, +} + +#[cw_serde] +pub enum CounterRestriction { + Private, + Public, +} + +#[cw_serde] +pub struct GetInitialAmountResponse { + pub initial_amount: u64, +} + +#[cw_serde] +pub struct GetCurrentAmountResponse { + pub current_amount: u64, +} + +#[cw_serde] +pub struct GetIncreaseAmountResponse { + pub increase_amount: u64, +} + +#[cw_serde] +pub struct GetDecreaseAmountResponse { + pub decrease_amount: u64, +} + +#[cw_serde] +pub struct GetRestrictionResponse { + pub restriction: CounterRestriction, +} diff --git a/andromeda-core/packages/andromeda-data-storage/src/lib.rs b/andromeda-core/packages/andromeda-data-storage/src/lib.rs index 2d8afe5..c85c564 100644 --- a/andromeda-core/packages/andromeda-data-storage/src/lib.rs +++ b/andromeda-core/packages/andromeda-data-storage/src/lib.rs @@ -1 +1,4 @@ +pub mod boolean; +pub mod counter; pub mod primitive; +pub mod string_storage; diff --git a/andromeda-core/packages/andromeda-data-storage/src/primitive.rs b/andromeda-core/packages/andromeda-data-storage/src/primitive.rs index 96bc332..e5100f6 100644 --- a/andromeda-core/packages/andromeda-data-storage/src/primitive.rs +++ b/andromeda-core/packages/andromeda-data-storage/src/primitive.rs @@ -1,6 +1,7 @@ -use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query}; -use cosmwasm_schema::{cw_serde, schemars::Map, QueryResponses}; -use cosmwasm_std::{Addr, Binary, Coin, Decimal, StdError, Uint128}; +use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query, error::ContractError}; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{ensure, Addr, Api, Binary, Coin, Decimal, StdError, Uint128}; +use std::fmt; #[andr_instantiate] #[cw_serde] @@ -25,16 +26,14 @@ pub enum ExecuteMsg { }, } -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { #[returns(GetValueResponse)] GetValue { key: Option }, + #[returns(GetTypeResponse)] + GetType { key: Option }, #[returns(Vec)] AllKeys {}, #[returns(Vec)] @@ -49,9 +48,59 @@ pub enum Primitive { Addr(Addr), String(String), Bool(bool), - Vec(Vec), Binary(Binary), - Object(Map), +} + +impl Primitive { + pub fn validate(&self, api: &dyn Api) -> Result<(), ContractError> { + match self { + Primitive::Uint128(number) => { + ensure!( + !number.to_string().is_empty(), + ContractError::EmptyString {} + ); + } + Primitive::Decimal(_) => {} + Primitive::Coin(coin) => { + ensure!( + !coin.denom.is_empty(), + ContractError::InvalidDenom { msg: None } + ); + } + Primitive::Addr(address) => { + api.addr_validate(address.as_str())?; + } + Primitive::String(string) => { + ensure!(!string.is_empty(), ContractError::EmptyString {}); + } + Primitive::Bool(_) => {} + Primitive::Binary(binary) => { + ensure!(!binary.is_empty(), ContractError::EmptyString {}); + } + } + Ok(()) + } +} + +impl From for String { + fn from(primitive: Primitive) -> Self { + match primitive { + Primitive::Uint128(_) => "Uint128".to_string(), + Primitive::Decimal(_) => "Decimal".to_string(), + Primitive::Coin(_) => "Coin".to_string(), + Primitive::Addr(_) => "Addr".to_string(), + Primitive::String(_) => "String".to_string(), + Primitive::Bool(_) => "Bool".to_string(), + Primitive::Binary(_) => "Binary".to_string(), + } + } +} + +impl fmt::Display for Primitive { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let variant_name: String = self.clone().into(); + write!(f, "{}", variant_name) + } } #[cw_serde] @@ -104,24 +153,12 @@ impl From for Primitive { } } -impl From> for Primitive { - fn from(value: Vec) -> Self { - Primitive::Vec(value) - } -} - impl From for Primitive { fn from(value: Binary) -> Self { Primitive::Binary(value) } } -impl From> for Primitive { - fn from(value: Map) -> Self { - Primitive::Object(value) - } -} - // These are methods to help the calling user quickly retreive the data in the Primitive as they // often already know what the type should be. impl Primitive { @@ -153,13 +190,6 @@ impl Primitive { } } - pub fn try_get_vec(&self) -> Result, StdError> { - match self { - Primitive::Vec(vector) => Ok(vector.to_vec()), - _ => Err(parse_error(String::from("Vec"))), - } - } - pub fn try_get_coin(&self) -> Result { match self { Primitive::Coin(coin) => Ok(coin.clone()), @@ -180,13 +210,6 @@ impl Primitive { _ => Err(parse_error(String::from("Binary"))), } } - - pub fn try_get_object(&self) -> Result, StdError> { - match self { - Primitive::Object(value) => Ok(value.clone()), - _ => Err(parse_error(String::from("Binary"))), - } - } } #[cw_serde] @@ -195,11 +218,123 @@ pub struct GetValueResponse { pub value: Primitive, } +#[cw_serde] +pub struct GetTypeResponse { + pub value_type: String, +} + #[cfg(test)] mod tests { use super::*; + use andromeda_std::testing::mock_querier::mock_dependencies_custom; use cosmwasm_std::to_json_binary; + struct TestValidate { + name: &'static str, + primitive: Primitive, + expected_error: Option, + } + + #[test] + fn test_from_string() { + let cases = vec![ + ( + Primitive::Uint128(Uint128::from(5_u128)), + "Uint128".to_string(), + ), + ( + Primitive::Decimal(Decimal::new(Uint128::one())), + "Decimal".to_string(), + ), + ( + Primitive::Coin(Coin { + amount: Uint128::new(100), + denom: "uatom".to_string(), + }), + "Coin".to_string(), + ), + ( + Primitive::Addr(Addr::unchecked("cosmos1...v937")), + "Addr".to_string(), + ), + ( + Primitive::String("Some string".to_string()), + "String".to_string(), + ), + (Primitive::Bool(true), "Bool".to_string()), + ( + Primitive::Binary(to_json_binary(&"data").unwrap()), + "Binary".to_string(), + ), + ]; + + for (value, expected_str) in cases.iter() { + assert_eq!(String::from(value.to_owned()), expected_str.to_owned()); + } + + let decimal_primitive = Primitive::Decimal(Decimal::new(Uint128::one())); + assert_eq!("Decimal".to_string(), String::from(decimal_primitive)); + } + + #[test] + fn test_validate() { + let test_cases = vec![ + TestValidate { + name: "Empty string", + primitive: Primitive::String("".to_string()), + expected_error: Some(ContractError::EmptyString {}), + }, + TestValidate { + name: "Valid string", + primitive: Primitive::String("string".to_string()), + expected_error: None, + }, + TestValidate { + name: "Empty Binary", + primitive: Primitive::Binary(Binary::default()), + expected_error: Some(ContractError::EmptyString {}), + }, + TestValidate { + name: "Valid Binary", + primitive: Primitive::Binary(to_json_binary(&"binary".to_string()).unwrap()), + expected_error: None, + }, + TestValidate { + name: "Invalid Coin Denom", + primitive: Primitive::Coin(Coin::new(0_u128, "".to_string())), + expected_error: Some(ContractError::InvalidDenom {msg: None}), + }, + TestValidate { + name: "Valid Coin Denom", + primitive: Primitive::Coin(Coin::new(0_u128, "valid".to_string())), + expected_error: None, + }, + TestValidate { + name: "Invalid Address", + primitive: Primitive::Addr(Addr::unchecked("wa".to_string())), + expected_error: Some(ContractError::Std(StdError::GenericErr { msg: "Invalid input: human address too short for this mock implementation (must be >= 3).".to_string() })), + }, + TestValidate { + name: "Valid Address", + primitive: Primitive::Addr(Addr::unchecked("andr1".to_string())), + expected_error: None, + }, + ]; + + for test in test_cases { + let deps = mock_dependencies_custom(&[]); + + let res = test.primitive.validate(&deps.api); + + if let Some(err) = test.expected_error { + assert_eq!(res.unwrap_err(), err, "{}", test.name); + continue; + } + + assert!(res.is_ok()); + } + } + #[test] fn test_parse_error() { assert_eq!( @@ -247,27 +382,6 @@ mod tests { ); } - #[test] - fn try_get_vec() { - let primitive = Primitive::Vec(vec![Primitive::Bool(true)]); - assert_eq!( - vec![Primitive::Bool(true)], - primitive.try_get_vec().unwrap() - ); - - let primitive = Primitive::Vec(vec![Primitive::Vec(vec![Primitive::Bool(true)])]); - assert_eq!( - vec![Primitive::Vec(vec![Primitive::Bool(true)])], - primitive.try_get_vec().unwrap() - ); - - let primitive = Primitive::String("String".to_string()); - assert_eq!( - parse_error("Vec".to_string()), - primitive.try_get_vec().unwrap_err() - ); - } - #[test] fn try_get_decimal() { let primitive = Primitive::Decimal(Decimal::zero()); @@ -294,12 +408,4 @@ mod tests { primitive.try_get_binary().unwrap_err() ); } - - #[test] - fn try_get_object() { - let mut map = Map::new(); - map.insert("key".to_string(), Primitive::Bool(true)); - let primitive = Primitive::Object(map.clone()); - assert_eq!(map.clone(), primitive.try_get_object().unwrap()); - } } diff --git a/andromeda-core/packages/andromeda-data-storage/src/string_storage.rs b/andromeda-core/packages/andromeda-data-storage/src/string_storage.rs new file mode 100644 index 0000000..34d36b9 --- /dev/null +++ b/andromeda-core/packages/andromeda-data-storage/src/string_storage.rs @@ -0,0 +1,138 @@ +use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query, error::ContractError}; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{ensure, StdError}; + +#[andr_instantiate] +#[cw_serde] +pub struct InstantiateMsg { + pub restriction: StringStorageRestriction, +} + +#[andr_exec] +#[cw_serde] +pub enum ExecuteMsg { + SetValue { + value: StringStorage, + }, + DeleteValue {}, + UpdateRestriction { + restriction: StringStorageRestriction, + }, +} + +#[andr_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(GetValueResponse)] + GetValue {}, + #[returns(GetDataOwnerResponse)] + GetDataOwner {}, +} + +#[cw_serde] +pub enum StringStorage { + String(String), +} + +impl StringStorage { + pub fn validate(&self) -> Result<(), ContractError> { + match self { + StringStorage::String(value) => { + ensure!(!value.to_string().is_empty(), ContractError::EmptyString {}); + } + } + Ok(()) + } +} + +impl From for String { + fn from(string_storage: StringStorage) -> Self { + match string_storage { + StringStorage::String(value) => value, + } + } +} + +impl From for StringStorage { + fn from(value: String) -> Self { + StringStorage::String(value) + } +} + +impl StringStorage { + pub fn try_get_value(&self) -> Result { + match self { + StringStorage::String(value) => Ok(value.to_string()), + } + } +} + +#[cw_serde] +pub enum StringStorageRestriction { + Private, + Public, + Restricted, +} + +#[cw_serde] +pub struct GetValueResponse { + pub value: String, +} + +#[cw_serde] +pub struct GetDataOwnerResponse { + pub owner: AndrAddr, +} + +#[cfg(test)] +mod tests { + use super::*; + + struct TestValidate { + name: &'static str, + string_storage: StringStorage, + expected_error: Option, + } + + #[test] + fn test_from_string() { + let cases = vec![( + StringStorage::String("String".to_string()), + "String".to_string(), + )]; + + for (value, expected_str) in cases.iter() { + assert_eq!(String::from(value.to_owned()), expected_str.to_owned()); + } + } + + #[test] + fn test_validate() { + let test_cases = vec![TestValidate { + name: "Empty string", + string_storage: StringStorage::String("".to_string()), + expected_error: Some(ContractError::EmptyString {}), + }]; + + for test in test_cases { + let res = test.string_storage.validate(); + + if let Some(err) = test.expected_error { + assert_eq!(res.unwrap_err(), err, "{}", test.name); + continue; + } + + assert!(res.is_ok()); + } + } + + #[test] + fn try_get_string() { + let string_storage = StringStorage::String("String".to_string()); + assert_eq!( + "String".to_string(), + string_storage.try_get_value().unwrap() + ); + } +} diff --git a/andromeda-core/packages/andromeda-ecosystem/Cargo.toml b/andromeda-core/packages/andromeda-ecosystem/Cargo.toml index 0ffe963..07e9f87 100644 --- a/andromeda-core/packages/andromeda-ecosystem/Cargo.toml +++ b/andromeda-core/packages/andromeda-ecosystem/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-ecosystem" -version = "0.1.0" +version = "1.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" +description = "Utility methods and message definitions for the Andromeda Ecosystem Contracts" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -19,5 +21,5 @@ serde = { workspace = true } schemars = "0.8.10" #astroport = "1.0.1" cw20 = { workspace = true } -cw-asset = { workspace = true } +cw-asset = { workspace = true } andromeda-std = { workspace = true } diff --git a/andromeda-core/packages/andromeda-ecosystem/src/vault.rs b/andromeda-core/packages/andromeda-ecosystem/src/vault.rs index 052a056..3601956 100644 --- a/andromeda-core/packages/andromeda-ecosystem/src/vault.rs +++ b/andromeda-core/packages/andromeda-ecosystem/src/vault.rs @@ -110,6 +110,16 @@ pub enum ExecuteMsg { strategy: StrategyType, address: AndrAddr, }, + // Originally was an Andromeda Msg + Withdraw { + recipient: Option, + tokens_to_withdraw: Option>, + }, + // Originally was an Andromeda Msg + Deposit { + recipient: Option<::andromeda_std::amp::AndrAddr>, + msg: Option<::cosmwasm_std::Binary>, + }, } #[andr_query] @@ -131,6 +141,3 @@ pub struct StrategyAddressResponse { pub strategy: StrategyType, pub address: String, } - -#[cw_serde] -pub struct MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-finance/Cargo.toml b/andromeda-core/packages/andromeda-finance/Cargo.toml index 0c965ef..7a21073 100644 --- a/andromeda-core/packages/andromeda-finance/Cargo.toml +++ b/andromeda-core/packages/andromeda-finance/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-finance" -version = "0.1.0" +version = "1.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" +description = "Utility methods and message definitions for the Andromeda Finance Contracts" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -12,7 +14,7 @@ backtraces = ["cosmwasm-std/backtraces"] crate-type = ["cdylib", "rlib"] [dependencies] -cosmwasm-std = { workspace = true, features= ["staking"] } +cosmwasm-std = { workspace = true, features = ["staking"] } cosmwasm-schema = { workspace = true } serde = { version = "1.0.127", default-features = false, features = ["derive"] } cw-utils = { workspace = true } @@ -21,4 +23,3 @@ cw721-base = { workspace = true } schemars = { version = "0.8.10" } andromeda-std = { workspace = true } - diff --git a/andromeda-core/packages/andromeda-finance/src/conditional_splitter.rs b/andromeda-core/packages/andromeda-finance/src/conditional_splitter.rs new file mode 100644 index 0000000..9d1edd8 --- /dev/null +++ b/andromeda-core/packages/andromeda-finance/src/conditional_splitter.rs @@ -0,0 +1,317 @@ +use andromeda_std::{ + andr_exec, andr_instantiate, andr_query, + common::{expiration::Expiry, MillisecondsDuration, MillisecondsExpiration}, + error::ContractError, +}; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{ensure, Decimal, Deps, Uint128}; +use std::collections::HashSet; + +use crate::splitter::AddressPercent; + +// The threshold has a min value and a vector of recipients, each having a respective percentage +#[cw_serde] +pub struct Threshold { + pub min: Uint128, + pub address_percent: Vec, +} +impl Threshold { + pub fn new(min: Uint128, address_percent: Vec) -> Self { + Self { + min, + address_percent, + } + } + // Checks if the funds sent are equal or greater than the min value + pub fn in_range(&self, num: Uint128) -> bool { + num >= self.min + } +} + +// To get the threshold that corresponds to the funds sent, we sort the thresholds by min value in decreasing order, and return first threshold where the funds and in range of its min value +pub fn get_threshold( + thresholds: &[Threshold], + amount: Uint128, +) -> Result { + let mut sorted_thresholds = thresholds.to_vec(); + // Sort the thresholds in decreasing order + sorted_thresholds.sort_by(|a, b| b.min.cmp(&a.min)); + + for threshold in sorted_thresholds.into_iter() { + // Return the first threshold that's in range of the given amount + if threshold.in_range(amount) { + return Ok(threshold); + } + } + Err(ContractError::InvalidAmount { + msg: "The amount sent does not meet any threshold".to_string(), + }) +} + +#[cw_serde] +/// A config struct for a `Conditional Splitter` contract. +pub struct ConditionalSplitter { + /// The vector of thresholds which assign a percentage for a certain range of received funds + pub thresholds: Vec, + /// The lock's expiration time + pub lock_time: MillisecondsExpiration, +} +impl ConditionalSplitter { + pub fn validate(&self, deps: Deps) -> Result<(), ContractError> { + validate_thresholds(deps, &self.thresholds) + } +} + +#[andr_instantiate] +#[cw_serde] +pub struct InstantiateMsg { + /// The vector of recipients for the contract. Anytime a `Send` execute message is + /// sent the amount sent will be divided amongst these recipients depending on their assigned percentage. + pub thresholds: Vec, + pub lock_time: Option, +} + +#[andr_exec] +#[cw_serde] +pub enum ExecuteMsg { + /// Update the thresholds. Only executable by the contract owner when the contract is not locked. + UpdateThresholds { thresholds: Vec }, + /// Used to lock/unlock the contract allowing the config to be updated. + UpdateLock { + // Milliseconds from current time + lock_time: MillisecondsDuration, + }, + /// Divides any attached funds to the message amongst the recipients list. + Send {}, +} + +#[andr_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// The current config of the Conditional Splitter contract + #[returns(GetConditionalSplitterConfigResponse)] + GetConditionalSplitterConfig {}, +} + +#[cw_serde] +pub struct GetConditionalSplitterConfigResponse { + pub config: ConditionalSplitter, +} + +/// Ensures that a given list of thresholds is valid: +/// * The list of thresholds is not empty +/// * Percentages of each threshold should not exceed 100 +/// * Each threshold must include at least one recipient +/// * The number of recipients for each threshold must not exceed 100 +/// * The recipient addresses must be unique for each threshold +/// * Make sure there are no duplicate min values between the thresholds +pub fn validate_thresholds(deps: Deps, thresholds: &Vec) -> Result<(), ContractError> { + ensure!( + !thresholds.is_empty(), + ContractError::EmptyThresholdsList {} + ); + let mut min_value_set = HashSet::new(); + for threshold in thresholds { + // Make sure the threshold has recipients + ensure!( + !threshold.address_percent.is_empty(), + ContractError::EmptyRecipientsList {} + ); + // Make sure the threshold's number of recipients doesn't exceed 100 + ensure!( + threshold.address_percent.len() <= 100, + ContractError::ReachedRecipientLimit {} + ); + + let mut total_percent = Decimal::zero(); + let mut recipient_address_set = HashSet::new(); + + for address_percent in &threshold.address_percent { + // Check for total percent exceeding 100 + total_percent = total_percent.checked_add(address_percent.percent)?; + ensure!( + total_percent <= Decimal::one(), + ContractError::AmountExceededHundredPrecent {} + ); + + // Checks for duplicate and invalid recipients + address_percent.recipient.validate(&deps)?; + let recipient_address = address_percent.recipient.address.get_raw_address(&deps)?; + ensure!( + !recipient_address_set.contains(&recipient_address), + ContractError::DuplicateRecipient {} + ); + recipient_address_set.insert(recipient_address); + } + + // Checks for duplicate minimum values + let min_value = threshold.min.u128(); + ensure!( + !min_value_set.contains(&min_value), + ContractError::DuplicateThresholds {} + ); + + min_value_set.insert(min_value); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use andromeda_std::amp::{AndrAddr, Recipient}; + use cosmwasm_std::testing::mock_dependencies; + + struct TestThresholdValidation { + name: &'static str, + thresholds: Vec, + expected_error: Option, + } + + #[test] + fn test_validate_thresholds() { + let test_cases = vec![ + TestThresholdValidation { + name: "Empty thresholds list", + thresholds: vec![], + expected_error: Some(ContractError::EmptyThresholdsList {}), + }, + TestThresholdValidation { + name: "Duplicate minimums between thresholds", + thresholds: vec![ + Threshold::new( + Uint128::zero(), + vec![AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::zero(), + )], + ), + Threshold::new( + Uint128::zero(), + vec![AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::zero(), + )], + ), + ], + expected_error: Some(ContractError::DuplicateThresholds {}), + }, + TestThresholdValidation { + name: "Duplicate recipients within the same threshold", + thresholds: vec![Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::zero(), + ), + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::zero(), + ), + ], + )], + expected_error: Some(ContractError::DuplicateRecipient {}), + }, + TestThresholdValidation { + name: "Sum of the threshold's percentage should not exceed 100", + thresholds: vec![Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::one(), + ), + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient2"), None), + Decimal::one(), + ), + ], + )], + expected_error: Some(ContractError::AmountExceededHundredPrecent {}), + }, + TestThresholdValidation { + name: "Threshold with no recipients", + thresholds: vec![Threshold::new(Uint128::zero(), vec![])], + expected_error: Some(ContractError::EmptyRecipientsList {}), + }, + TestThresholdValidation { + name: "Works with one threshold", + thresholds: vec![Threshold::new( + Uint128::zero(), + vec![AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::zero(), + )], + )], + expected_error: None, + }, + TestThresholdValidation { + name: "Works with two thresholds", + thresholds: vec![ + Threshold::new( + Uint128::zero(), + vec![ + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::zero(), + ), + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient2"), None), + Decimal::new(Uint128::new(20)), + ), + ], + ), + Threshold::new( + Uint128::one(), + vec![AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::one(), + )], + ), + ], + expected_error: None, + }, + TestThresholdValidation { + name: "Thresholds start above zero", + thresholds: vec![ + Threshold::new( + Uint128::new(20), + vec![ + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::zero(), + ), + AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient2"), None), + Decimal::new(Uint128::new(20)), + ), + ], + ), + Threshold::new( + Uint128::new(50), + vec![AddressPercent::new( + Recipient::new(AndrAddr::from_string("recipient"), None), + Decimal::one(), + )], + ), + ], + expected_error: None, + }, + ]; + + for test in test_cases { + let deps = mock_dependencies(); + + let res = validate_thresholds(deps.as_ref(), &test.thresholds); + + if let Some(err) = test.expected_error { + assert_eq!(res.unwrap_err(), err, "{}", test.name); + continue; + } else { + assert!(res.is_ok()) + } + } + } +} diff --git a/andromeda-core/packages/andromeda-finance/src/cross_chain_swap.rs b/andromeda-core/packages/andromeda-finance/src/cross_chain_swap.rs index af8c048..cc606ea 100644 --- a/andromeda-core/packages/andromeda-finance/src/cross_chain_swap.rs +++ b/andromeda-core/packages/andromeda-finance/src/cross_chain_swap.rs @@ -19,10 +19,6 @@ pub enum ExecuteMsg { }, } -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] diff --git a/andromeda-core/packages/andromeda-finance/src/lib.rs b/andromeda-core/packages/andromeda-finance/src/lib.rs index b3d4a14..dabe894 100644 --- a/andromeda-core/packages/andromeda-finance/src/lib.rs +++ b/andromeda-core/packages/andromeda-finance/src/lib.rs @@ -1,5 +1,7 @@ +pub mod conditional_splitter; pub mod cross_chain_swap; pub mod rate_limiting_withdrawals; +pub mod set_amount_splitter; pub mod splitter; pub mod timelock; pub mod validator_staking; diff --git a/andromeda-core/packages/andromeda-finance/src/rate_limiting_withdrawals.rs b/andromeda-core/packages/andromeda-finance/src/rate_limiting_withdrawals.rs index 9c7f999..6ef43b3 100644 --- a/andromeda-core/packages/andromeda-finance/src/rate_limiting_withdrawals.rs +++ b/andromeda-core/packages/andromeda-finance/src/rate_limiting_withdrawals.rs @@ -1,4 +1,4 @@ -use andromeda_std::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +use andromeda_std::{andr_exec, andr_instantiate, andr_query, common::MillisecondsDuration}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Timestamp, Uint128}; @@ -25,7 +25,7 @@ pub struct CoinAllowance { /// Sets the withdrawal limit in terms of amount pub limit: Uint128, /// Sets the minimum amount of time required between withdrawals in seconds - pub minimal_withdrawal_frequency: Uint128, + pub minimal_withdrawal_frequency: MillisecondsDuration, } #[cw_serde] @@ -35,7 +35,6 @@ pub struct ContractAndKey { } #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { pub allowed_coin: CoinAndLimit, @@ -44,22 +43,16 @@ pub struct InstantiateMsg { #[cw_serde] pub enum MinimumFrequency { - Time { time: Uint128 }, - AddressAndKey { address_and_key: ContractAndKey }, + Time { time: MillisecondsDuration }, } #[andr_exec] #[cw_serde] -//NOTE can't name Deposit and Withdraw while implementing andr_exec pub enum ExecuteMsg { - Deposits { recipient: Option }, - Withdraws { amount: Uint128 }, + Deposit { recipient: Option }, + Withdraw { amount: Uint128 }, } -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] diff --git a/andromeda-core/packages/andromeda-finance/src/set_amount_splitter.rs b/andromeda-core/packages/andromeda-finance/src/set_amount_splitter.rs new file mode 100644 index 0000000..71888b3 --- /dev/null +++ b/andromeda-core/packages/andromeda-finance/src/set_amount_splitter.rs @@ -0,0 +1,250 @@ +use std::collections::HashSet; + +use andromeda_std::{ + amp::recipient::Recipient, + andr_exec, andr_instantiate, andr_query, + common::{expiration::Expiry, MillisecondsDuration, MillisecondsExpiration}, + error::ContractError, +}; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{ensure, Coin, Deps}; + +#[cw_serde] +pub struct AddressAmount { + pub recipient: Recipient, + pub coins: Vec, +} + +impl AddressAmount { + pub fn new(recipient: Recipient, coins: Vec) -> Self { + Self { recipient, coins } + } +} + +#[cw_serde] +/// A config struct for a `Splitter` contract. +pub struct Splitter { + /// The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned amount. + pub recipients: Vec, + /// The lock's expiration time + pub lock: MillisecondsExpiration, +} + +#[andr_instantiate] +#[cw_serde] +pub struct InstantiateMsg { + /// The vector of recipients for the contract. Anytime a `Send` execute message is + /// sent the amount sent will be divided amongst these recipients depending on their assigned amount. + pub recipients: Vec, + pub lock_time: Option, +} + +impl InstantiateMsg { + pub fn validate(&self, deps: Deps) -> Result<(), ContractError> { + validate_recipient_list(deps, self.recipients.clone()) + } +} + +#[andr_exec] +#[cw_serde] +pub enum ExecuteMsg { + /// Update the recipients list. Only executable by the contract owner when the contract is not locked. + UpdateRecipients { recipients: Vec }, + /// Used to lock/unlock the contract allowing the config to be updated. + UpdateLock { + // Milliseconds from current time + lock_time: MillisecondsDuration, + }, + /// Divides any attached funds to the message amongst the recipients list. + Send {}, +} + +#[andr_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + /// The current config of the Splitter contract + #[returns(GetSplitterConfigResponse)] + GetSplitterConfig {}, +} + +#[cw_serde] +pub struct GetSplitterConfigResponse { + pub config: Splitter, +} + +/// Ensures that a given list of recipients for a `splitter` contract is valid: +/// +/// * Must include at least one recipient +/// * The number of recipients must not exceed 100 +/// * The recipient addresses must be unique +/// * The recipient amount must be above zero +/// * Each recipient can't have more than two coins assigned. +/// * No duplicate coins + +pub fn validate_recipient_list( + deps: Deps, + recipients: Vec, +) -> Result<(), ContractError> { + ensure!( + !recipients.is_empty(), + ContractError::EmptyRecipientsList {} + ); + + ensure!( + recipients.len() <= 100, + ContractError::ReachedRecipientLimit {} + ); + + let mut recipient_address_set = HashSet::new(); + + for rec in recipients { + ensure!( + rec.coins.len() == 1 || rec.coins.len() == 2, + ContractError::InvalidFunds { + msg: "A minimim of 1 and a maximum of 2 coins are allowed".to_string(), + } + ); + + let mut denom_set = HashSet::new(); + for coin in rec.coins { + ensure!(!coin.amount.is_zero(), ContractError::InvalidZeroAmount {}); + ensure!( + !denom_set.contains(&coin.denom), + ContractError::DuplicateCoinDenoms {} + ); + denom_set.insert(coin.denom); + } + + rec.recipient.validate(&deps)?; + + let recipient_address = rec.recipient.address.get_raw_address(&deps)?; + ensure!( + !recipient_address_set.contains(&recipient_address), + ContractError::DuplicateRecipient {} + ); + recipient_address_set.insert(recipient_address); + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use cosmwasm_std::{coin, coins, testing::mock_dependencies}; + + use super::*; + + #[test] + fn test_validate_recipient_list() { + let deps = mock_dependencies(); + let empty_recipients = vec![]; + let err = validate_recipient_list(deps.as_ref(), empty_recipients).unwrap_err(); + assert_eq!(err, ContractError::EmptyRecipientsList {}); + + let recipients_zero_amount = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("xyz")), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: coins(0_u128, "usdc"), + }, + ]; + let err = validate_recipient_list(deps.as_ref(), recipients_zero_amount).unwrap_err(); + assert_eq!(err, ContractError::InvalidZeroAmount {}); + + let recipients_zero_amount = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("xyz")), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: vec![ + coin(1_u128, "uandr"), + coin(12_u128, "usdc"), + coin(13_u128, "usdt"), + ], + }, + ]; + let err = validate_recipient_list(deps.as_ref(), recipients_zero_amount).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidFunds { + msg: "A minimim of 1 and a maximum of 2 coins are allowed".to_string(), + } + ); + let recipients_zero_amount = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("xyz")), + coins: vec![], + }, + AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: vec![ + coin(1_u128, "uandr"), + coin(12_u128, "usdc"), + coin(13_u128, "usdt"), + ], + }, + ]; + let err = validate_recipient_list(deps.as_ref(), recipients_zero_amount).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidFunds { + msg: "A minimim of 1 and a maximum of 2 coins are allowed".to_string(), + } + ); + + let recipients_zero_amount = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("xyz")), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: vec![coin(1_u128, "uandr"), coin(12_u128, "uandr")], + }, + ]; + let err = validate_recipient_list(deps.as_ref(), recipients_zero_amount).unwrap_err(); + assert_eq!(err, ContractError::DuplicateCoinDenoms {}); + + let duplicate_recipients = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: coins(1_u128, "denom"), + }, + AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: coins(1_u128, "uandr"), + }, + ]; + + let err = validate_recipient_list(deps.as_ref(), duplicate_recipients).unwrap_err(); + assert_eq!(err, ContractError::DuplicateRecipient {}); + + let valid_recipients = vec![ + AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: coins(1_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(String::from("xyz")), + coins: coins(1_u128, "denom"), + }, + ]; + + let res = validate_recipient_list(deps.as_ref(), valid_recipients); + assert!(res.is_ok()); + + let one_valid_recipient = vec![AddressAmount { + recipient: Recipient::from_string(String::from("abc")), + coins: coins(1_u128, "denom"), + }]; + + let res = validate_recipient_list(deps.as_ref(), one_valid_recipient); + assert!(res.is_ok()); + } +} diff --git a/andromeda-core/packages/andromeda-finance/src/splitter.rs b/andromeda-core/packages/andromeda-finance/src/splitter.rs index 9503daf..e385286 100644 --- a/andromeda-core/packages/andromeda-finance/src/splitter.rs +++ b/andromeda-core/packages/andromeda-finance/src/splitter.rs @@ -1,9 +1,13 @@ +use std::collections::HashSet; + use andromeda_std::{ - amp::recipient::Recipient, andr_exec, andr_instantiate, andr_query, error::ContractError, + amp::recipient::Recipient, + andr_exec, andr_instantiate, andr_query, + common::{expiration::Expiry, MillisecondsDuration, MillisecondsExpiration}, + error::ContractError, }; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{ensure, Decimal, ReplyOn}; -use cw_utils::Expiration; +use cosmwasm_std::{ensure, Decimal, Deps}; #[cw_serde] pub struct AddressPercent { @@ -22,8 +26,8 @@ impl AddressPercent { pub struct Splitter { /// The vector of recipients for the contract. Anytime a `Send` execute message is sent the amount sent will be divided amongst these recipients depending on their assigned percentage. pub recipients: Vec, - /// Whether or not the contract is currently locked. This restricts updating any config related fields. - pub lock: Expiration, + /// The lock's expiration time + pub lock: MillisecondsExpiration, } #[andr_instantiate] @@ -32,38 +36,29 @@ pub struct InstantiateMsg { /// The vector of recipients for the contract. Anytime a `Send` execute message is /// sent the amount sent will be divided amongst these recipients depending on their assigned percentage. pub recipients: Vec, - pub lock_time: Option, + pub lock_time: Option, } impl InstantiateMsg { - pub fn validate(&self) -> Result { - validate_recipient_list(self.recipients.clone())?; - Ok(true) + pub fn validate(&self, deps: Deps) -> Result<(), ContractError> { + validate_recipient_list(deps, self.recipients.clone()) } } -#[cw_serde] -pub struct ReplyGasExit { - pub reply_on: Option, - pub gas_limit: Option, - pub exit_at_error: Option, -} - #[andr_exec] #[cw_serde] pub enum ExecuteMsg { /// Update the recipients list. Only executable by the contract owner when the contract is not locked. UpdateRecipients { recipients: Vec }, /// Used to lock/unlock the contract allowing the config to be updated. - UpdateLock { lock_time: u64 }, + UpdateLock { + // Milliseconds from current time + lock_time: MillisecondsDuration, + }, /// Divides any attached funds to the message amongst the recipients list. Send {}, } -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] @@ -81,56 +76,99 @@ pub struct GetSplitterConfigResponse { /// Ensures that a given list of recipients for a `splitter` contract is valid: /// /// * Must include at least one recipient +/// * The number of recipients must not exceed 100 /// * The combined percentage of the recipients must not exceed 100 -pub fn validate_recipient_list(recipients: Vec) -> Result { +/// * The recipient addresses must be unique +pub fn validate_recipient_list( + deps: Deps, + recipients: Vec, +) -> Result<(), ContractError> { ensure!( !recipients.is_empty(), ContractError::EmptyRecipientsList {} ); + ensure!( + recipients.len() <= 100, + ContractError::ReachedRecipientLimit {} + ); + let mut percent_sum: Decimal = Decimal::zero(); + let mut recipient_address_set = HashSet::new(); + for rec in recipients { - // += operation is not supported for decimal. - percent_sum += rec.percent; + rec.recipient.validate(&deps)?; + percent_sum = percent_sum.checked_add(rec.percent)?; + ensure!( + percent_sum <= Decimal::one(), + ContractError::AmountExceededHundredPrecent {} + ); + + let recipient_address = rec.recipient.address.get_raw_address(&deps)?; + ensure!( + !recipient_address_set.contains(&recipient_address), + ContractError::DuplicateRecipient {} + ); + recipient_address_set.insert(recipient_address); } - ensure!( - percent_sum <= Decimal::one(), - ContractError::AmountExceededHundredPrecent {} - ); - - Ok(true) + Ok(()) } #[cfg(test)] mod tests { + use cosmwasm_std::testing::mock_dependencies; + use super::*; #[test] fn test_validate_recipient_list() { + let deps = mock_dependencies(); let empty_recipients = vec![]; - let res = validate_recipient_list(empty_recipients).unwrap_err(); + let res = validate_recipient_list(deps.as_ref(), empty_recipients).unwrap_err(); assert_eq!(res, ContractError::EmptyRecipientsList {}); let inadequate_recipients = vec![AddressPercent { - recipient: Recipient::from_string(String::from("Some Address")), + recipient: Recipient::from_string(String::from("abc")), percent: Decimal::percent(150), }]; - let res = validate_recipient_list(inadequate_recipients).unwrap_err(); + let res = validate_recipient_list(deps.as_ref(), inadequate_recipients).unwrap_err(); assert_eq!(res, ContractError::AmountExceededHundredPrecent {}); + let duplicate_recipients = vec![ + AddressPercent { + recipient: Recipient::from_string(String::from("abc")), + percent: Decimal::percent(50), + }, + AddressPercent { + recipient: Recipient::from_string(String::from("abc")), + percent: Decimal::percent(50), + }, + ]; + + let err = validate_recipient_list(deps.as_ref(), duplicate_recipients).unwrap_err(); + assert_eq!(err, ContractError::DuplicateRecipient {}); + let valid_recipients = vec![ AddressPercent { - recipient: Recipient::from_string(String::from("Some Address")), + recipient: Recipient::from_string(String::from("abc")), percent: Decimal::percent(50), }, AddressPercent { - recipient: Recipient::from_string(String::from("Some Address")), + recipient: Recipient::from_string(String::from("xyz")), percent: Decimal::percent(50), }, ]; - let res = validate_recipient_list(valid_recipients).unwrap(); - assert!(res); + let res = validate_recipient_list(deps.as_ref(), valid_recipients); + assert!(res.is_ok()); + + let one_valid_recipient = vec![AddressPercent { + recipient: Recipient::from_string(String::from("abc")), + percent: Decimal::percent(50), + }]; + + let res = validate_recipient_list(deps.as_ref(), one_valid_recipient); + assert!(res.is_ok()); } } diff --git a/andromeda-core/packages/andromeda-finance/src/timelock.rs b/andromeda-core/packages/andromeda-finance/src/timelock.rs index eecfd64..9dafe0e 100644 --- a/andromeda-core/packages/andromeda-finance/src/timelock.rs +++ b/andromeda-core/packages/andromeda-finance/src/timelock.rs @@ -1,16 +1,17 @@ use andromeda_std::{ - amp::recipient::Recipient, andr_exec, andr_instantiate, andr_instantiate_modules, andr_query, - common::merge_coins, error::ContractError, + amp::recipient::Recipient, + andr_exec, andr_instantiate, andr_query, + common::{expiration::Expiry, merge_coins}, + error::ContractError, }; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ensure, Api, BlockInfo, Coin}; -use cw_utils::Expiration; #[cw_serde] /// Enum used to specify the condition which must be met in order for the Escrow to unlock. pub enum EscrowCondition { - /// Requires a given time or block height to be reached. - Expiration(Expiration), + /// Requires a given time + Expiration(Expiry), /// Requires a minimum amount of funds to be deposited. MinimumFunds(Vec), } @@ -38,7 +39,7 @@ impl Escrow { ensure!( !self.coins.is_empty(), ContractError::InvalidFunds { - msg: "ensure! at least one coin to be sent".to_string(), + msg: "At least one coin should be sent".to_string(), } ); ensure!( @@ -79,11 +80,9 @@ impl Escrow { match &self.condition { None => Ok(false), Some(condition) => match condition { - EscrowCondition::Expiration(expiration) => match expiration { - Expiration::AtTime(t) => Ok(t > &block.time), - Expiration::AtHeight(h) => Ok(h > &block.height), - _ => Err(ContractError::ExpirationNotSpecified {}), - }, + EscrowCondition::Expiration(expiration) => { + Ok(!expiration.get_time(block).is_expired(block)) + } EscrowCondition::MinimumFunds(funds) => { Ok(!self.min_funds_deposited(funds.clone())) } @@ -112,12 +111,11 @@ impl Escrow { /// /// Returns nothing as it is done in place. pub fn add_funds(&mut self, coins_to_add: Vec) { - merge_coins(&mut self.coins, coins_to_add); + self.coins = merge_coins(self.coins.to_vec(), coins_to_add); } } #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg {} @@ -140,10 +138,6 @@ pub enum ExecuteMsg { recipient_addr: Option, }, } -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] @@ -174,15 +168,16 @@ pub struct GetLockedFundsForRecipientResponse { #[cfg(test)] mod tests { + use super::*; + use andromeda_std::common::Milliseconds; use cosmwasm_std::testing::mock_dependencies; use cosmwasm_std::{coin, Timestamp}; - use super::*; - #[test] fn test_validate() { let deps = mock_dependencies(); - let condition = EscrowCondition::Expiration(Expiration::AtHeight(1500)); + let condition = + EscrowCondition::Expiration(Expiry::FromNow(Milliseconds::from_seconds(101))); let coins = vec![coin(100u128, "uluna")]; let recipient = Recipient::from_string("owner"); @@ -194,7 +189,7 @@ mod tests { }; let block = BlockInfo { height: 1000, - time: Timestamp::from_seconds(4444), + time: Timestamp::from_seconds(100), chain_id: "foo".to_string(), }; valid_escrow.validate(deps.as_ref().api, &block).unwrap(); @@ -236,32 +231,22 @@ mod tests { .unwrap_err(); assert_eq!( ContractError::InvalidFunds { - msg: "ensure! at least one coin to be sent".to_string() + msg: "At least one coin should be sent".to_string() }, resp ); - let invalid_condition_escrow = Escrow { - recipient: recipient.clone(), - coins: coins.clone(), - condition: Some(EscrowCondition::Expiration(Expiration::Never {})), - recipient_addr: "owner".to_string(), - }; - - let resp = invalid_condition_escrow - .validate(deps.as_ref().api, &block) - .unwrap_err(); - assert_eq!(ContractError::ExpirationNotSpecified {}, resp); - let invalid_time_escrow = Escrow { - recipient: recipient.clone(), - coins: coins.clone(), - condition: Some(EscrowCondition::Expiration(Expiration::AtHeight(10))), + recipient, + coins, + condition: Some(EscrowCondition::Expiration(Expiry::AtTime( + Milliseconds::from_seconds(0), + ))), recipient_addr: "owner".to_string(), }; let block = BlockInfo { height: 1000, - time: Timestamp::from_seconds(4444), + time: Timestamp::from_seconds(1), chain_id: "foo".to_string(), }; assert_eq!( @@ -270,21 +255,6 @@ mod tests { .validate(deps.as_ref().api, &block) .unwrap_err() ); - - let invalid_time_escrow = Escrow { - recipient, - coins, - condition: Some(EscrowCondition::Expiration(Expiration::AtTime( - Timestamp::from_seconds(100), - ))), - recipient_addr: "owner".to_string(), - }; - assert_eq!( - ContractError::ExpirationInPast {}, - invalid_time_escrow - .validate(deps.as_ref().api, &block) - .unwrap_err() - ); } #[test] diff --git a/andromeda-core/packages/andromeda-finance/src/validator_staking.rs b/andromeda-core/packages/andromeda-finance/src/validator_staking.rs index fd83119..e3fbd34 100644 --- a/andromeda-core/packages/andromeda-finance/src/validator_staking.rs +++ b/andromeda-core/packages/andromeda-finance/src/validator_staking.rs @@ -1,6 +1,6 @@ use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query, error::ContractError}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, Coin, DepsMut, FullDelegation, Timestamp}; +use cosmwasm_std::{Addr, Coin, DepsMut, Timestamp, Uint128}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -18,12 +18,18 @@ pub enum ExecuteMsg { }, Unstake { validator: Option, + amount: Option, }, Claim { validator: Option, + }, + WithdrawFunds { + denom: Option, recipient: Option, }, - WithdrawFunds {}, + UpdateDefaultValidator { + validator: Addr, + }, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] @@ -36,7 +42,7 @@ pub struct UnstakingTokens { #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(Option)] + #[returns(Option<::cosmwasm_std::FullDelegation>)] StakedTokens { validator: Option }, #[returns(Option>)] diff --git a/andromeda-core/packages/andromeda-finance/src/vesting.rs b/andromeda-core/packages/andromeda-finance/src/vesting.rs index c8201e5..b2c15e5 100644 --- a/andromeda-core/packages/andromeda-finance/src/vesting.rs +++ b/andromeda-core/packages/andromeda-finance/src/vesting.rs @@ -1,13 +1,11 @@ use andromeda_std::{ - amp::Recipient, andr_exec, andr_instantiate, andr_instantiate_modules, andr_query, - common::withdraw::WithdrawalType, + amp::Recipient, andr_exec, andr_instantiate, andr_query, common::withdraw::WithdrawalType, }; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Uint128, VoteOption}; +use cosmwasm_std::Uint128; use cw_utils::Duration; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { /// The recipient of all funds locked in this contract. @@ -45,30 +43,7 @@ pub enum ExecuteMsg { /// Specifies how much is to be released after each `release_unit`. If /// it is a percentage, it would be the percentage of the original amount. release_amount: WithdrawalType, - /// The validator to delegate to. If specified, funds will be delegated to it. - validator_to_delegate_to: Option, }, - /// Delegates the given amount of tokens, or all if not specified. - Delegate { - amount: Option, - validator: String, - }, - /// Redelegates the given amount of tokens, or all from the `from` validator to the `to` - /// validator. - Redelegate { - amount: Option, - from: String, - to: String, - }, - /// Undelegates the given amount of tokens, or all if not specified. - Undelegate { - amount: Option, - validator: String, - }, - /// Withdraws rewards from all delegations to the sender. - WithdrawRewards {}, - /// Votes on the specified proposal with the specified vote. - Vote { proposal_id: u64, vote: VoteOption }, } #[andr_query] @@ -97,8 +72,6 @@ pub struct Config { pub is_multi_batch_enabled: bool, /// The denom of the coin being vested. pub denom: String, - /// The unbonding duration of the native staking module. - pub unbonding_duration: Duration, } #[cw_serde] @@ -123,7 +96,3 @@ pub struct BatchResponse { /// The time at which the last claim took place in seconds. pub last_claimed_release_time: u64, } - -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-finance/src/weighted_splitter.rs b/andromeda-core/packages/andromeda-finance/src/weighted_splitter.rs index 52ede69..a4acd1c 100644 --- a/andromeda-core/packages/andromeda-finance/src/weighted_splitter.rs +++ b/andromeda-core/packages/andromeda-finance/src/weighted_splitter.rs @@ -1,6 +1,4 @@ -use andromeda_std::{ - amp::recipient::Recipient, andr_exec, andr_instantiate, andr_instantiate_modules, andr_query, -}; +use andromeda_std::{amp::recipient::Recipient, andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; use cw_utils::Expiration; @@ -21,7 +19,6 @@ pub struct Splitter { } #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { /// The vector of recipients for the contract. Anytime a `Send` execute message is @@ -47,10 +44,6 @@ pub enum ExecuteMsg { Send {}, } -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] diff --git a/andromeda-core/packages/andromeda-fungible-tokens/Cargo.toml b/andromeda-core/packages/andromeda-fungible-tokens/Cargo.toml index 9a8737b..613562d 100644 --- a/andromeda-core/packages/andromeda-fungible-tokens/Cargo.toml +++ b/andromeda-core/packages/andromeda-fungible-tokens/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-fungible-tokens" -version = "0.1.0" +version = "1.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" +description = "Utility methods and message definitions for the Andromeda Fungible Tokens Contracts" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -22,4 +24,3 @@ cw-asset = { workspace = true } andromeda-std = { workspace = true } - diff --git a/andromeda-core/packages/andromeda-fungible-tokens/src/airdrop.rs b/andromeda-core/packages/andromeda-fungible-tokens/src/airdrop.rs index 1b644e6..76db7df 100644 --- a/andromeda-core/packages/andromeda-fungible-tokens/src/airdrop.rs +++ b/andromeda-core/packages/andromeda-fungible-tokens/src/airdrop.rs @@ -1,14 +1,14 @@ -use andromeda_std::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +use andromeda_std::{ + andr_exec, andr_instantiate, andr_query, + common::{denom::Asset, expiration::Expiry, MillisecondsExpiration}, +}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; -use cw_asset::{AssetInfo, AssetInfoUnchecked}; -use cw_utils::Expiration; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { - pub asset_info: AssetInfoUnchecked, + pub asset_info: Asset, } #[andr_exec] @@ -17,7 +17,7 @@ pub enum ExecuteMsg { RegisterMerkleRoot { /// MerkleRoot is hex-encoded merkle root. merkle_root: String, - expiration: Option, + expiration: Option, total_amount: Option, }, /// Claim does not check if contract has enough funds, owner must ensure it. @@ -50,7 +50,7 @@ pub enum QueryMsg { #[cw_serde] #[serde(rename_all = "snake_case")] pub struct ConfigResponse { - pub asset_info: AssetInfo, + pub asset_info: Asset, } #[cw_serde] @@ -58,7 +58,7 @@ pub struct MerkleRootResponse { pub stage: u8, /// MerkleRoot is hex-encoded merkle root. pub merkle_root: String, - pub expiration: Expiration, + pub expiration: Option, pub total_amount: Uint128, } @@ -76,6 +76,3 @@ pub struct IsClaimedResponse { pub struct TotalClaimedResponse { pub total_claimed: Uint128, } - -#[cw_serde] -pub struct MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-fungible-tokens/src/cw20.rs b/andromeda-core/packages/andromeda-fungible-tokens/src/cw20.rs index 3833a1b..9422fa6 100644 --- a/andromeda-core/packages/andromeda-fungible-tokens/src/cw20.rs +++ b/andromeda-core/packages/andromeda-fungible-tokens/src/cw20.rs @@ -1,4 +1,4 @@ -use andromeda_std::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Binary, Uint128}; use cw20::{Cw20Coin, Logo, MinterResponse}; @@ -9,7 +9,6 @@ use cw20_base::msg::{ use cw_utils::Expiration; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { pub name: String, @@ -37,13 +36,16 @@ impl From for Cw20InstantiateMsg { #[cw_serde] pub enum ExecuteMsg { /// Transfer is a base message to move tokens to another account without triggering actions - Transfer { recipient: String, amount: Uint128 }, + Transfer { + recipient: AndrAddr, + amount: Uint128, + }, /// Burn is a base message to destroy tokens forever Burn { amount: Uint128 }, /// Send is a base message to transfer tokens to a contract and trigger an action /// on the receiving contract. Send { - contract: String, + contract: AndrAddr, amount: Uint128, msg: Binary, }, @@ -67,14 +69,14 @@ pub enum ExecuteMsg { /// if `env.sender` has sufficient pre-approval. TransferFrom { owner: String, - recipient: String, + recipient: AndrAddr, amount: Uint128, }, /// Only with "approval" extension. Sends amount tokens from owner -> contract /// if `env.sender` has sufficient pre-approval. SendFrom { owner: String, - contract: String, + contract: AndrAddr, amount: Uint128, msg: Binary, }, @@ -101,16 +103,17 @@ pub enum ExecuteMsg { impl From for Cw20ExecuteMsg { fn from(msg: ExecuteMsg) -> Self { match msg { - ExecuteMsg::Transfer { recipient, amount } => { - Cw20ExecuteMsg::Transfer { recipient, amount } - } + ExecuteMsg::Transfer { recipient, amount } => Cw20ExecuteMsg::Transfer { + recipient: recipient.to_string(), + amount, + }, ExecuteMsg::Burn { amount } => Cw20ExecuteMsg::Burn { amount }, ExecuteMsg::Send { contract, amount, msg, } => Cw20ExecuteMsg::Send { - contract, + contract: contract.to_string(), amount, msg, }, @@ -138,7 +141,7 @@ impl From for Cw20ExecuteMsg { amount, } => Cw20ExecuteMsg::TransferFrom { owner, - recipient, + recipient: recipient.to_string(), amount, }, ExecuteMsg::SendFrom { @@ -148,7 +151,7 @@ impl From for Cw20ExecuteMsg { msg, } => Cw20ExecuteMsg::SendFrom { owner, - contract, + contract: contract.to_string(), amount, msg, }, @@ -169,10 +172,6 @@ impl From for Cw20ExecuteMsg { } } -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] @@ -225,14 +224,14 @@ pub enum QueryMsg { /// Return type: DownloadLogoResponse. #[returns(cw20::DownloadLogoResponse)] DownloadLogo {}, + #[returns(cw20::BalanceResponse)] + Balance { address: String }, } impl From for Cw20QueryMsg { fn from(msg: QueryMsg) -> Self { match msg { - QueryMsg::Balance { address } => Cw20QueryMsg::Balance { - address: address.to_string(), - }, + QueryMsg::Balance { address } => Cw20QueryMsg::Balance { address }, QueryMsg::TokenInfo {} => Cw20QueryMsg::TokenInfo {}, QueryMsg::Minter {} => Cw20QueryMsg::Minter {}, QueryMsg::Allowance { owner, spender } => Cw20QueryMsg::Allowance { owner, spender }, diff --git a/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_exchange.rs b/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_exchange.rs index b41a38e..a1ed81d 100644 --- a/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_exchange.rs +++ b/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_exchange.rs @@ -1,15 +1,15 @@ use andromeda_std::{ - amp::AndrAddr, andr_exec, andr_instantiate, andr_instantiate_modules, andr_query, + amp::AndrAddr, + andr_exec, andr_instantiate, andr_query, + common::{expiration::Expiry, MillisecondsDuration}, }; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; use cw20::Cw20ReceiveMsg; use cw_asset::AssetInfo; use cw_utils::Expiration; -use serde::{Deserialize, Serialize}; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { /// Address of the CW20 token to be sold @@ -44,7 +44,7 @@ pub struct Sale { pub start_amount: Uint128, } -#[derive(Deserialize, Serialize)] +#[cw_serde] pub enum Cw20HookMsg { /// Starts a sale StartSale { @@ -55,8 +55,8 @@ pub enum Cw20HookMsg { /// The recipient of the sale proceeds /// Sender is used if `None` provided recipient: Option, - start_time: Option, - duration: Option, + start_time: Option, + duration: Option, }, /// Purchases tokens Purchase { @@ -98,6 +98,3 @@ pub struct TokenAddressResponse { /// The address of the token being sold pub address: String, } - -#[cw_serde] -pub struct MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_staking.rs b/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_staking.rs index 0849488..e9c6330 100644 --- a/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_staking.rs +++ b/andromeda-core/packages/andromeda-fungible-tokens/src/cw20_staking.rs @@ -1,7 +1,8 @@ use andromeda_std::amp::addresses::AndrAddr; -use andromeda_std::common::expiration::MILLISECONDS_TO_NANOSECONDS_RATIO; +use andromeda_std::common::expiration::{Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}; +use andromeda_std::common::{Milliseconds, MillisecondsDuration, MillisecondsExpiration}; use andromeda_std::error::ContractError; -use andromeda_std::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +use andromeda_std::{andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{ensure, Api, BlockInfo, Decimal, Decimal256, Uint128}; use cw20::Cw20ReceiveMsg; @@ -9,7 +10,6 @@ use cw_asset::{AssetInfo, AssetInfoUnchecked}; use std::fmt; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { /// The cw20 token that can be staked. @@ -26,6 +26,16 @@ pub enum ExecuteMsg { AddRewardToken { reward_token: RewardTokenUnchecked, }, + /// Remove `reward_token`. Owner only. + RemoveRewardToken { + reward_token: String, + }, + /// Replace `reward_token` as another reward token. Owner only. + ReplaceRewardToken { + origin_reward_token: String, + reward_token: RewardTokenUnchecked, + }, + /// Unstakes the specified amount of assets, or all if not specified. The user's pending /// rewards and indexes are updated for each additional reward token. UnstakeTokens { @@ -70,9 +80,6 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, - /// Queries the current timestamp. - #[returns(u64)] - Timestamp {}, } #[cw_serde] @@ -92,6 +99,7 @@ pub struct State { #[cw_serde] pub struct RewardTokenUnchecked { pub asset_info: AssetInfoUnchecked, + pub init_timestamp: Expiry, pub allocation_config: Option, } @@ -103,21 +111,21 @@ impl RewardTokenUnchecked { block_info: &BlockInfo, api: &dyn Api, ) -> Result { - //TODO replace unwrap() with ? once cw-asset is integrated in error.rs - let checked_asset_info = self.asset_info.check(api, None).unwrap(); + let checked_asset_info = self.asset_info.check(api, None)?; let reward_type = match self.allocation_config { None => RewardType::NonAllocated { previous_reward_balance: Uint128::zero(), + init_timestamp: self.init_timestamp.get_time(block_info), }, Some(allocation_config) => { - let init_timestamp = allocation_config.init_timestamp; - let till_timestamp = allocation_config.till_timestamp; + let init_timestamp = self.init_timestamp.clone(); + let till_timestamp = allocation_config.clone().till_timestamp; let cycle_duration = allocation_config.cycle_duration; let cycle_rewards = allocation_config.cycle_rewards; let reward_increase = allocation_config.reward_increase; ensure!( - init_timestamp >= block_info.time.seconds(), + init_timestamp.get_time(block_info).seconds() >= block_info.time.seconds(), ContractError::StartTimeInThePast { current_block: block_info.height, current_time: block_info.time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO, @@ -125,11 +133,14 @@ impl RewardTokenUnchecked { ); ensure!( - init_timestamp < till_timestamp, + init_timestamp.get_time(block_info) < till_timestamp.get_time(block_info), ContractError::StartTimeAfterEndTime {} ); - ensure!(cycle_duration > 0, ContractError::InvalidCycleDuration {}); + ensure!( + !cycle_duration.is_zero(), + ContractError::InvalidCycleDuration {} + ); if let Some(reward_increase) = reward_increase { ensure!( @@ -143,8 +154,9 @@ impl RewardTokenUnchecked { allocation_state: AllocationState { current_cycle: 0, current_cycle_rewards: cycle_rewards, - last_distributed: init_timestamp, + last_distributed: init_timestamp.get_time(block_info), }, + init_timestamp: self.init_timestamp.get_time(block_info), } } }; @@ -153,6 +165,7 @@ impl RewardTokenUnchecked { asset_info: checked_asset_info, reward_type, index: Decimal256::zero(), + is_active: true, }) } } @@ -162,9 +175,11 @@ pub enum RewardType { Allocated { allocation_config: AllocationConfig, allocation_state: AllocationState, + init_timestamp: MillisecondsExpiration, }, NonAllocated { previous_reward_balance: Uint128, + init_timestamp: MillisecondsExpiration, }, } @@ -173,6 +188,7 @@ pub struct RewardToken { pub asset_info: AssetInfo, pub index: Decimal256, pub reward_type: RewardType, + pub is_active: bool, } impl fmt::Display for RewardToken { @@ -191,14 +207,12 @@ pub struct AllocationInfo { #[cw_serde] pub struct AllocationConfig { - /// Timestamp from which Rewards will start getting accrued against the staked LP tokens - pub init_timestamp: u64, /// Timestamp till which Rewards will be accrued. No staking rewards are accrued beyond this timestamp - pub till_timestamp: u64, + pub till_timestamp: Expiry, /// Rewards distributed during the 1st cycle. pub cycle_rewards: Uint128, /// Cycle duration in timestamps - pub cycle_duration: u64, + pub cycle_duration: MillisecondsDuration, /// Percent increase in Rewards per cycle pub reward_increase: Option, } @@ -210,7 +224,7 @@ pub struct AllocationState { /// Number of tokens to be distributed during the current cycle pub current_cycle_rewards: Uint128, /// Timestamp at which the global_reward_index was last updated - pub last_distributed: u64, + pub last_distributed: Milliseconds, } #[cw_serde] @@ -224,6 +238,3 @@ pub struct StakerResponse { /// The staker's pending rewards represented as [(token_1, amount_1), ..., (token_n, amount_n)] pub pending_rewards: Vec<(String, Uint128)>, } - -#[cw_serde] -pub enum MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-fungible-tokens/src/lockdrop.rs b/andromeda-core/packages/andromeda-fungible-tokens/src/lockdrop.rs index 269c187..490dd02 100644 --- a/andromeda-core/packages/andromeda-fungible-tokens/src/lockdrop.rs +++ b/andromeda-core/packages/andromeda-fungible-tokens/src/lockdrop.rs @@ -1,23 +1,24 @@ -use andromeda_std::andr_instantiate_modules; +use andromeda_std::amp::AndrAddr; +use andromeda_std::common::expiration::Expiry; +use andromeda_std::common::{Milliseconds, MillisecondsDuration, MillisecondsExpiration}; use andromeda_std::{andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Decimal, Uint128}; +use cosmwasm_std::Uint128; use cw20::Cw20ReceiveMsg; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { /// The bootsrap contract to be used in the second phase. // pub bootstrap_contract: Option, /// Timestamp till when deposits can be made - pub init_timestamp: u64, - /// Number of seconds for which lockup deposits will be accepted - pub deposit_window: u64, - /// Number of seconds for which lockup withdrawals will be allowed - pub withdrawal_window: u64, + pub init_timestamp: Expiry, + /// Number of milliseconds for which lockup deposits will be accepted + pub deposit_window: MillisecondsDuration, + /// Number of milliseconds for which lockup withdrawals will be allowed + pub withdrawal_window: MillisecondsDuration, /// The token being given as incentive. - pub incentive_token: String, + pub incentive_token: AndrAddr, /// The native token being deposited. pub native_denom: String, } @@ -37,11 +38,11 @@ pub enum ExecuteMsg { ClaimRewards {}, /// Called by the bootstrap contract when liquidity is added to the TOKEN-NATIVE Pool to enable TOKEN withdrawals by users. EnableClaims {}, - /// Called by the owner after the phase is over to withdraw all of the NATIVE token to the - /// given recipient, or themselves if not specified. - WithdrawProceeds { - recipient: Option, - }, + // Called by the owner after the phase is over to withdraw all of the NATIVE token to the + // given recipient, or themselves if not specified. + // WithdrawProceeds { + // recipient: Option, + // }, } #[cw_serde] @@ -64,9 +65,9 @@ pub enum QueryMsg { #[returns(UserInfoResponse)] UserInfo { address: String }, /// Gets the withdrawal percent allowed given the timestamp, or the current time if not - /// specified. - #[returns(Decimal)] - WithdrawalPercentAllowed { timestamp: Option }, + /// specified. Timestamp is in seconds. + #[returns(::cosmwasm_std::Decimal)] + WithdrawalPercentAllowed { timestamp: Option }, } #[cw_serde] @@ -74,15 +75,15 @@ pub struct ConfigResponse { /// Bootstrap Contract address to which tokens can be delegated to for bootstrapping TOKEN-NATIVE Pool. // pub bootstrap_contract_address: Option, /// Timestamp till when deposits can be made. - pub init_timestamp: u64, + pub init_timestamp: MillisecondsExpiration, /// Number of seconds for which lockup deposits will be accepted. - pub deposit_window: u64, + pub deposit_window: MillisecondsDuration, /// Number of seconds for which lockup withdrawals will be allowed. - pub withdrawal_window: u64, + pub withdrawal_window: MillisecondsDuration, /// Total token lockdrop incentives to be distributed among the users. pub lockdrop_incentives: Uint128, /// The token being given as incentive. - pub incentive_token: String, + pub incentive_token: AndrAddr, /// The native token being deposited. pub native_denom: String, } @@ -102,6 +103,3 @@ pub struct UserInfoResponse { pub is_lockdrop_claimed: bool, pub withdrawal_flag: bool, } - -#[cw_serde] -pub struct MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-modules/Cargo.toml b/andromeda-core/packages/andromeda-modules/Cargo.toml index df8dbf3..ef52b85 100644 --- a/andromeda-core/packages/andromeda-modules/Cargo.toml +++ b/andromeda-core/packages/andromeda-modules/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-modules" -version = "0.1.0" +version = "2.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" +description = "Utility methods and message definitions for the Andromeda Module Contracts" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -19,4 +21,4 @@ cw-utils = { workspace = true } cw721 = { workspace = true } cw721-base = { workspace = true } -andromeda-std = { workspace = true, features=["module_hooks"] } +andromeda-std = { workspace = true, features = ["rates"] } diff --git a/andromeda-core/packages/andromeda-modules/README.md b/andromeda-core/packages/andromeda-modules/README.md index 8803b9e..dcc3981 100644 --- a/andromeda-core/packages/andromeda-modules/README.md +++ b/andromeda-core/packages/andromeda-modules/README.md @@ -10,3 +10,45 @@ This package contains structs related to each Andromeda ADO contract: - [andromeda_splitter](https://github.com/andromedaprotocol/andromeda-contracts/blob/main/packages/andromeda_protocol/src/splitter.rs) - [andromeda_timelock](https://github.com/andromedaprotocol/andromeda-contracts/blob/main/packages/andromeda_protocol/src/timelock.rs) - [andromeda_receipt](https://github.com/andromedaprotocol/andromeda-contracts/blob/main/packages/andromeda_protocol/src/receipt.rs) + +# Address-List As Part of Permissioning +## Getting Started +The first step is to save the desired actor to permission pair in the address-list contract's +```rust +pub const PERMISSIONS: Map<&Addr, Permission> = Map::new("permissioning") +``` +Note that `Permission` of type `Contract` isn't allowed in the address-list contract. + +Apply `ExecuteMsg::PermissionActors { actor, permission }` to the ADO you want. +To involve the address-list contract, set the Permission to be of type Contract, and input the address-list's contract address. `Permission::Contract(address_list_address)`. +Make sure that the `actor` is the same as the one set in the address-list contract. + + +The completion of the aforementioned steps will enable permissioning on the ADO of your choice. + +# Rates Module as a Feature +## Implementation +Rates are now stored directly in your ADO without the need of a rates contract, though referring to one is still possible. + +You can store rates in your ADO by calling +```rust +ExecuteMsg::Rates(RatesMessage::SetRate {action: String, rate: Rate} +``` + +or remove rates by calling + +```rust +ExecuteMsg::Rates(RatesMessage::RemoveRate { action: String } +``` + +## Types of Rates +There are two types: + +`Local` which doesn't involve calling a rates contract. It's also the only allowed `Rate` type to be stored in the rates contract. + +`Contract` which fetches a `LocalRate` from a verified rates contract. +## Compatiblity +The `rates` feature has been enabled on the following ADOs: CW721, CW20, Auction, Crowdfund, and Marketplace. + +## How Rates Work +Details about the Rates' workings can be found on https://docs.andromedaprotocol.io/andromeda/andromeda-digital-objects/rates diff --git a/andromeda-core/packages/andromeda-modules/src/address_list.rs b/andromeda-core/packages/andromeda-modules/src/address_list.rs index 45af044..864d4d7 100644 --- a/andromeda-core/packages/andromeda-modules/src/address_list.rs +++ b/andromeda-core/packages/andromeda-modules/src/address_list.rs @@ -1,35 +1,42 @@ -use andromeda_std::{andr_exec, andr_instantiate, andr_query}; +use andromeda_std::{ + ado_base::permissioning::LocalPermission, amp::AndrAddr, andr_exec, andr_instantiate, + andr_query, +}; use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Addr; #[andr_instantiate] #[cw_serde] pub struct InstantiateMsg { - pub is_inclusive: bool, + pub actor_permission: Option, +} +// Struct used to bundle actor and permission +#[cw_serde] +pub struct ActorPermission { + pub actors: Vec, + pub permission: LocalPermission, } #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - /// Add an address to the address list - AddAddress { address: String }, - /// Remove an address from the address list - RemoveAddress { address: String }, - /// Add multiple addresses to the address list - AddAddresses { addresses: Vec }, + /// Adds an actor key and a permission value + PermissionActors { + actors: Vec, + permission: LocalPermission, + }, + /// Removes actor alongisde his permission + RemovePermissions { actors: Vec }, } -#[cw_serde] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - /// Query if address is included - #[returns(IncludesAddressResponse)] - IncludesAddress { address: String }, - #[returns(IsInclusiveResponse)] - IsInclusive {}, + #[returns(IncludesActorResponse)] + IncludesActor { actor: Addr }, + #[returns(ActorPermissionResponse)] + ActorPermission { actor: Addr }, } #[cw_serde] pub struct IsInclusiveResponse { @@ -37,7 +44,12 @@ pub struct IsInclusiveResponse { } #[cw_serde] -pub struct IncludesAddressResponse { - /// Whether the address is included in the address list +pub struct IncludesActorResponse { + /// Whether the actor is included in the permissions pub included: bool, } + +#[cw_serde] +pub struct ActorPermissionResponse { + pub permission: LocalPermission, +} diff --git a/andromeda-core/packages/andromeda-modules/src/date_time.rs b/andromeda-core/packages/andromeda-modules/src/date_time.rs new file mode 100644 index 0000000..89ded88 --- /dev/null +++ b/andromeda-core/packages/andromeda-modules/src/date_time.rs @@ -0,0 +1,66 @@ +use andromeda_std::{andr_exec, andr_instantiate, andr_query}; +use cosmwasm_schema::{cw_serde, QueryResponses}; + +#[andr_instantiate] +#[cw_serde] +pub struct InstantiateMsg {} + +#[andr_exec] +#[cw_serde] +pub enum ExecuteMsg {} + +#[andr_query] +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(GetDateTimeResponse)] + GetDateTime { timezone: Option }, +} + +#[cw_serde] +pub struct GetDateTimeResponse { + pub day_of_week: String, + pub date_time: String, +} + +#[cw_serde] +pub enum Timezone { + UtcMinus12 = -1200, + UtcMinus11 = -1100, + UtcMinus10 = -1000, + UtcMinus9_30 = -950, + UtcMinus9 = -900, + UtcMinus8 = -800, + UtcMinus7 = -700, + UtcMinus6 = -600, + UtcMinus5 = -500, + UtcMinus4 = -400, + UtcMinus3 = -300, + UtcMinus2_30 = -250, + UtcMinus2 = -200, + UtcMinus1 = -100, + Utc = 0, + UtcPlus1 = 100, + UtcPlus2 = 200, + UtcPlus3 = 300, + UtcPlus3_30 = 350, + UtcPlus4 = 400, + UtcPlus4_30 = 450, + UtcPlus5 = 500, + UtcPlus5_45 = 575, + UtcPlus5_30 = 550, + UtcPlus6 = 600, + UtcPlus6_30 = 650, + UtcPlus7 = 700, + UtcPlus8 = 800, + UtcPlus8_45 = 875, + UtcPlus9 = 900, + UtcPlus9_30 = 950, + UtcPlus10 = 1000, + UtcPlus10_30 = 1050, + UtcPlus11 = 1100, + UtcPlus12 = 1200, + UtcPlus12_45 = 1275, + UtcPlus13 = 1300, + UtcPlus14 = 1400, +} diff --git a/andromeda-core/packages/andromeda-modules/src/lib.rs b/andromeda-core/packages/andromeda-modules/src/lib.rs index 6f71686..becf453 100644 --- a/andromeda-core/packages/andromeda-modules/src/lib.rs +++ b/andromeda-core/packages/andromeda-modules/src/lib.rs @@ -1,3 +1,4 @@ pub mod address_list; +pub mod date_time; pub mod rates; pub mod shunting; diff --git a/andromeda-core/packages/andromeda-modules/src/rates.rs b/andromeda-core/packages/andromeda-modules/src/rates.rs index 6189121..2406d08 100644 --- a/andromeda-core/packages/andromeda-modules/src/rates.rs +++ b/andromeda-core/packages/andromeda-modules/src/rates.rs @@ -1,210 +1,29 @@ -use andromeda_std::{ - amp::recipient::Recipient, andr_exec, andr_instantiate, andr_query, error::ContractError, -}; +use andromeda_std::{ado_base::rates::LocalRate, andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{ensure, Coin, Decimal, Fraction, QuerierWrapper}; #[andr_instantiate] #[cw_serde] pub struct InstantiateMsg { - pub rates: Vec, + pub action: String, + pub rate: LocalRate, } #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - UpdateRates { rates: Vec }, + SetRate { action: String, rate: LocalRate }, + RemoveRate { action: String }, } -#[cw_serde] -pub struct MigrateMsg {} - #[andr_query] #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { - #[returns(PaymentsResponse)] - Payments {}, -} - -#[cw_serde] -pub struct PaymentsResponse { - pub payments: Vec, + #[returns(RateResponse)] + Rate { action: String }, } #[cw_serde] -pub struct RateInfo { - pub rate: Rate, - pub is_additive: bool, - pub description: Option, - pub recipients: Vec, -} - -#[cw_serde] -/// An enum used to define various types of fees -pub enum Rate { - /// A flat rate fee - Flat(Coin), - /// A percentage fee - Percent(PercentRate), - // External(PrimitivePointer), -} - -#[cw_serde] // This is added such that both Rate::Flat and Rate::Percent have the same level of nesting which - // makes it easier to work with on the frontend. -pub struct PercentRate { - pub percent: Decimal, -} - -impl From for Rate { - fn from(decimal: Decimal) -> Self { - Rate::Percent(PercentRate { percent: decimal }) - } -} - -impl Rate { - /// Validates that a given rate is non-zero. It is expected that the Rate is not an - /// External Rate. - pub fn is_non_zero(&self) -> Result { - match self { - Rate::Flat(coin) => Ok(!coin.amount.is_zero()), - Rate::Percent(PercentRate { percent }) => Ok(!percent.is_zero()), - // Rate::External(_) => Err(ContractError::UnexpectedExternalRate {}), - } - } - - /// Validates `self` and returns an "unwrapped" version of itself wherein if it is an External - /// Rate, the actual rate value is retrieved from the Primitive Contract. - pub fn validate(&self, querier: &QuerierWrapper) -> Result { - let rate = self.clone().get_rate(querier)?; - ensure!(rate.is_non_zero()?, ContractError::InvalidRate {}); - - if let Rate::Percent(PercentRate { percent }) = rate { - ensure!(percent <= Decimal::one(), ContractError::InvalidRate {}); - } - - Ok(rate) - } - - /// If `self` is Flat or Percent it returns itself. Otherwise it queries the primitive contract - /// and retrieves the actual Flat or Percent rate. - fn get_rate(self, _querier: &QuerierWrapper) -> Result { - match self { - Rate::Flat(_) => Ok(self), - Rate::Percent(_) => Ok(self), - // Rate::External(primitive_pointer) => { - // let primitive = primitive_pointer.into_value(querier)?; - // match primitive { - // None => Err(ContractError::ParsingError { - // err: "Stored primitive is None".to_string(), - // }), - // Some(primitive) => match primitive { - // Primitive::Coin(coin) => Ok(Rate::Flat(coin)), - // Primitive::Decimal(value) => Ok(Rate::from(value)), - // _ => Err(ContractError::ParsingError { - // err: "Stored rate is not a coin or Decimal".to_string(), - // }), - // }, - // } - // } - } - } -} - -/// An attribute struct used for any events that involve a payment -pub struct PaymentAttribute { - /// The amount paid - pub amount: Coin, - /// The address the payment was made to - pub receiver: String, -} - -impl ToString for PaymentAttribute { - fn to_string(&self) -> String { - format!("{}<{}", self.receiver, self.amount) - } -} - -/// Calculates a fee amount given a `Rate` and payment amount. -/// -/// ## Arguments -/// * `fee_rate` - The `Rate` of the fee to be paid -/// * `payment` - The amount used to calculate the fee -/// -/// Returns the fee amount in a `Coin` struct. -pub fn calculate_fee(fee_rate: Rate, payment: &Coin) -> Result { - match fee_rate { - Rate::Flat(rate) => Ok(Coin::new(rate.amount.u128(), rate.denom)), - Rate::Percent(PercentRate { percent }) => { - // [COM-03] Make sure that fee_rate between 0 and 100. - ensure!( - // No need for rate >=0 due to type limits (Question: Should add or remove?) - percent <= Decimal::one() && !percent.is_zero(), - ContractError::InvalidRate {} - ); - let mut fee_amount = payment.amount * percent; - - // Always round any remainder up and prioritise the fee receiver. - // Inverse of percent will always exist. - let reversed_fee = fee_amount * percent.inv().unwrap(); - if payment.amount > reversed_fee { - // [COM-1] Added checked add to fee_amount rather than direct increment - fee_amount = fee_amount.checked_add(1u128.into())?; - } - Ok(Coin::new(fee_amount.u128(), payment.denom.clone())) - } // Rate::External(_) => Err(ContractError::UnexpectedExternalRate {}), - } -} - -#[cfg(test)] -mod tests { - - use cosmwasm_std::{coin, Uint128}; - - use super::*; - - // #[test] - // fn test_validate_external_rate() { - // let deps = mock_dependencies_custom(&[]); - - // let rate = Rate::External(PrimitivePointer { - // address: MOCK_PRIMITIVE_CONTRACT.to_owned(), - - // key: Some("percent".to_string()), - // }); - // let validated_rate = rate.validate(&deps.as_ref().querier).unwrap(); - // let expected_rate = Rate::from(Decimal::percent(1)); - // assert_eq!(expected_rate, validated_rate); - - // let rate = Rate::External(PrimitivePointer { - // address: MOCK_PRIMITIVE_CONTRACT.to_owned(), - // key: Some("flat".to_string()), - // }); - // let validated_rate = rate.validate(&deps.as_ref().querier).unwrap(); - // let expected_rate = Rate::Flat(coin(1u128, "uusd")); - // assert_eq!(expected_rate, validated_rate); - // } - - #[test] - fn test_calculate_fee() { - let payment = coin(101, "uluna"); - let expected = Ok(coin(5, "uluna")); - let fee = Rate::from(Decimal::percent(4)); - - let received = calculate_fee(fee, &payment); - - assert_eq!(expected, received); - - assert_eq!(expected, received); - - let payment = coin(125, "uluna"); - let fee = Rate::Flat(Coin { - amount: Uint128::from(5_u128), - denom: "uluna".to_string(), - }); - - let received = calculate_fee(fee, &payment); - - assert_eq!(expected, received); - } +pub struct RateResponse { + pub rate: LocalRate, } diff --git a/andromeda-core/packages/andromeda-non-fungible-tokens/Cargo.toml b/andromeda-core/packages/andromeda-non-fungible-tokens/Cargo.toml index 6297490..a734126 100644 --- a/andromeda-core/packages/andromeda-non-fungible-tokens/Cargo.toml +++ b/andromeda-core/packages/andromeda-non-fungible-tokens/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-non-fungible-tokens" -version = "0.1.0" +version = "1.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" +description = "Message definitions and utility methods for Andromeda non-fungible token contracts" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -18,6 +20,6 @@ serde = { version = "1.0.127", default-features = false, features = ["derive"] } cw-utils = { workspace = true } cw721 = { workspace = true } cw721-base = { workspace = true } +cw20 = { workspace = true } andromeda-std = { workspace = true } - diff --git a/andromeda-core/packages/andromeda-non-fungible-tokens/src/auction.rs b/andromeda-core/packages/andromeda-non-fungible-tokens/src/auction.rs index 344763c..81788e5 100644 --- a/andromeda-core/packages/andromeda-non-fungible-tokens/src/auction.rs +++ b/andromeda-core/packages/andromeda-non-fungible-tokens/src/auction.rs @@ -1,19 +1,27 @@ -use andromeda_std::common::OrderBy; -use andromeda_std::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +use andromeda_std::amp::{AndrAddr, Recipient}; +use andromeda_std::common::denom::Asset; +use andromeda_std::common::expiration::Expiry; +use andromeda_std::common::{MillisecondsExpiration, OrderBy}; +use andromeda_std::{andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, Timestamp, Uint128}; +use cosmwasm_std::{Addr, Uint128}; +use cw20::Cw20ReceiveMsg; use cw721::{Cw721ReceiveMsg, Expiration}; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] -pub struct InstantiateMsg {} +pub struct InstantiateMsg { + pub authorized_token_addresses: Option>, + pub authorized_cw20_address: Option, +} #[andr_exec] #[cw_serde] pub enum ExecuteMsg { ReceiveNft(Cw721ReceiveMsg), + // for cw20 + Receive(Cw20ReceiveMsg), /// Places a bid on the current auction for the given token_id. The previous largest bid gets /// automatically sent back to the bidder when they are outbid. PlaceBid { @@ -28,16 +36,27 @@ pub enum ExecuteMsg { UpdateAuction { token_id: String, token_address: String, - start_time: u64, - duration: u64, - coin_denom: String, + start_time: Option, + end_time: Expiry, + coin_denom: Asset, whitelist: Option>, min_bid: Option, + min_raise: Option, + recipient: Option, }, CancelAuction { token_id: String, token_address: String, }, + /// Restricted to owner + AuthorizeTokenContract { + addr: AndrAddr, + expiration: Option, + }, + /// Restricted to owner + DeauthorizeTokenContract { + addr: AndrAddr, + }, } #[cw_serde] @@ -46,14 +65,24 @@ pub enum Cw721HookMsg { /// has started but is immutable after that. StartAuction { /// Start time in milliseconds since epoch - start_time: u64, + start_time: Option, /// Duration in milliseconds - duration: u64, - coin_denom: String, + end_time: Expiry, + coin_denom: Asset, min_bid: Option, + min_raise: Option, whitelist: Option>, + recipient: Option, + }, +} +#[cw_serde] +pub enum Cw20HookMsg { + PlaceBid { + token_id: String, + token_address: String, }, } + #[andr_query] #[cw_serde] #[derive(QueryResponses)] @@ -81,6 +110,14 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + /// Gets all of the authorized addresses for the auction + #[returns(AuthorizedAddressesResponse)] + AuthorizedAddresses { + start_after: Option, + limit: Option, + order_by: Option, + }, + /// Gets the bids for the given auction id. Start_after starts indexing at 0. #[returns(BidsResponse)] Bids { @@ -136,11 +173,14 @@ impl From for AuctionStateResponse { high_bidder_addr: token_auction_state.high_bidder_addr.to_string(), high_bidder_amount: token_auction_state.high_bidder_amount, coin_denom: token_auction_state.coin_denom, + uses_cw20: token_auction_state.uses_cw20, auction_id: token_auction_state.auction_id, whitelist: token_auction_state.whitelist, is_cancelled: token_auction_state.is_cancelled, min_bid: token_auction_state.min_bid, + min_raise: token_auction_state.min_raise, owner: token_auction_state.owner, + recipient: token_auction_state.recipient, } } } @@ -155,17 +195,20 @@ pub struct TokenAuctionState { pub auction_id: Uint128, pub whitelist: Option>, pub min_bid: Option, + pub min_raise: Option, pub owner: String, pub token_id: String, pub token_address: String, pub is_cancelled: bool, + pub uses_cw20: bool, + pub recipient: Option, } #[cw_serde] pub struct Bid { pub bidder: String, pub amount: Uint128, - pub timestamp: Timestamp, + pub timestamp: MillisecondsExpiration, } #[cw_serde] @@ -176,10 +219,18 @@ pub struct AuctionStateResponse { pub high_bidder_amount: Uint128, pub auction_id: Uint128, pub coin_denom: String, + pub uses_cw20: bool, pub whitelist: Option>, pub min_bid: Option, + pub min_raise: Option, pub is_cancelled: bool, pub owner: String, + pub recipient: Option, +} + +#[cw_serde] +pub struct AuthorizedAddressesResponse { + pub addresses: Vec, } #[cw_serde] diff --git a/andromeda-core/packages/andromeda-non-fungible-tokens/src/crowdfund.rs b/andromeda-core/packages/andromeda-non-fungible-tokens/src/crowdfund.rs index fc55f73..51af10e 100644 --- a/andromeda-core/packages/andromeda-non-fungible-tokens/src/crowdfund.rs +++ b/andromeda-core/packages/andromeda-non-fungible-tokens/src/crowdfund.rs @@ -1,112 +1,271 @@ -use crate::cw721::TokenExtension; -use andromeda_std::amp::{addresses::AndrAddr, recipient::Recipient}; -use andromeda_std::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +use andromeda_std::amp::addresses::AndrAddr; +use andromeda_std::amp::Recipient; +use andromeda_std::common::denom::Asset; +use andromeda_std::common::{MillisecondsExpiration, OrderBy}; +use andromeda_std::error::ContractError; +use andromeda_std::{andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Coin, Uint128}; -use cw_utils::Expiration; +use cosmwasm_std::{ensure, Addr, DepsMut, Env, Uint128, Uint64}; +use cw20::Cw20ReceiveMsg; + +use crate::cw721::TokenExtension; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { - pub token_address: AndrAddr, - pub can_mint_after_sale: bool, + /// The configuration for the campaign + pub campaign_config: CampaignConfig, + /// The tiers for the campaign + pub tiers: Vec, } #[andr_exec] #[cw_serde] pub enum ExecuteMsg { - /// Mints a new token to be sold in a future sale. Only possible when the sale is not ongoing. - Mint(Vec), - /// Starts the sale if one is not already ongoing. - StartSale { - /// When the sale ends. - expiration: Expiration, - /// The price per token. - price: Coin, - /// The minimum amount of tokens sold to go through with the sale. - min_tokens_sold: Uint128, - /// The amount of tokens a wallet can purchase, default is 1. - max_amount_per_wallet: Option, - /// The recipient of the funds if the sale met the minimum sold. - recipient: Recipient, + /// Add a tier + AddTier { tier: Tier }, + /// Update an existing tier + UpdateTier { tier: Tier }, + /// Remove a tier + RemoveTier { level: Uint64 }, + /// Start the campaign + StartCampaign { + start_time: Option, + end_time: MillisecondsExpiration, + presale: Option>, }, - /// Puchases tokens in an ongoing sale. - Purchase { number_of_tokens: Option }, - /// Purchases the token with the given id. - PurchaseByTokenId { token_id: String }, - /// Allow a user to claim their own refund if the minimum number of tokens are not sold. - ClaimRefund {}, - /// Ends the ongoing sale by completing `limit` number of operations depending on if the minimum number - /// of tokens was sold. - EndSale { limit: Option }, + /// Purchase tiers + PurchaseTiers { orders: Vec }, + /// Purchase tiers with cw20 + Receive(Cw20ReceiveMsg), + /// End the campaign + EndCampaign {}, + /// Claim tiers or get refunded based on the campaign result + Claim {}, + /// Discard the campaign + DiscardCampaign {}, } -#[andr_query] #[cw_serde] -#[derive(QueryResponses)] -pub enum QueryMsg { - #[returns(State)] - State {}, - #[returns(Config)] - Config {}, - #[returns(Vec)] - AvailableTokens { - start_after: Option, - limit: Option, - }, - #[returns(IsTokenAvailableResponse)] - IsTokenAvailable { id: String }, +pub enum Cw20HookMsg { + PurchaseTiers { orders: Vec }, +} + +#[cw_serde] +pub struct CampaignConfig { + /// Title of the campaign. Maximum length is 64. + pub title: Option, + /// Short description about the campaign. + pub description: Option, + /// URL for the banner of the campaign + pub banner: Option, + /// Official website of the campaign + pub url: Option, + /// The address of the tier contract whose tokens are being distributed + pub token_address: AndrAddr, + /// The denom of the token that is being accepted by the campaign + pub denom: Asset, + /// Recipient that is upposed to receive the funds gained by the campaign + pub withdrawal_recipient: Recipient, + /// The minimum amount of funding to be sold for the successful fundraising + pub soft_cap: Option, + /// The maximum amount of funding to be sold for the fundraising + pub hard_cap: Option, +} + +impl CampaignConfig { + pub fn validate(&self, deps: DepsMut, env: &Env) -> Result<(), ContractError> { + // validate addresses + self.token_address.validate(deps.api)?; + self.withdrawal_recipient.validate(&deps.as_ref())?; + let _ = self + .denom + .get_verified_asset(deps, env.clone()) + .map_err(|_| ContractError::InvalidAsset { + asset: self.denom.to_string(), + })?; + + // validate meta info + ensure!( + self.title.clone().unwrap_or_default().len() <= 64, + ContractError::InvalidParameter { + error: Some("Title length can be 64 at maximum".to_string()) + } + ); + + // validate target capital + ensure!( + (self.soft_cap).map_or(true, |soft_cap| soft_cap + < self.hard_cap.unwrap_or(soft_cap + Uint128::new(1))), + ContractError::InvalidParameter { + error: Some("soft_cap can not exceed hard_cap".to_string()) + } + ); + Ok(()) + } } #[cw_serde] -pub struct IsTokenAvailableResponse { - pub is_token_available: bool, +pub enum CampaignStage { + /// Stage when all necessary environment is set to start campaign + READY, + /// Stage when campaign is being carried out + ONGOING, + /// Stage when campaign is finished successfully + SUCCESS, + /// Stage when campaign failed to meet the target cap before expiration + FAILED, +} + +impl ToString for CampaignStage { + #[inline] + fn to_string(&self) -> String { + match self { + Self::READY => "READY".to_string(), + Self::ONGOING => "ONGOING".to_string(), + Self::SUCCESS => "SUCCESS".to_string(), + Self::FAILED => "FAILED".to_string(), + } + } } #[cw_serde] -pub struct Config { - /// The address of the token contract whose tokens are being sold. - pub token_address: AndrAddr, - /// Whether or not the owner can mint additional tokens after the sale has been conducted. - pub can_mint_after_sale: bool, +pub struct Tier { + pub level: Uint64, + pub label: String, + pub price: Uint128, + pub limit: Option, // None for no limit + pub metadata: TierMetaData, } #[cw_serde] -pub struct State { - /// The expiration denoting when the sale ends. - pub expiration: Expiration, - /// The price of each token. - pub price: Coin, - /// The minimum number of tokens sold for the sale to go through. - pub min_tokens_sold: Uint128, - /// The max number of tokens allowed per wallet. - pub max_amount_per_wallet: u32, - /// Number of tokens sold. - pub amount_sold: Uint128, - /// The amount of funds to send to recipient if sale successful. This already - /// takes into account the royalties and taxes. - pub amount_to_send: Uint128, - /// Number of tokens transferred to purchasers if sale was successful. - pub amount_transferred: Uint128, - /// The recipient of the raised funds if the sale is successful. - pub recipient: Recipient, +pub struct TierOrder { + pub orderer: Addr, + pub level: Uint64, + pub amount: Uint128, + pub is_presale: bool, } +// Used for presale #[cw_serde] -pub struct CrowdfundMintMsg { - /// Unique ID of the NFT - pub token_id: String, - /// The owner of the newly minter NFT - pub owner: Option, - /// Universal resource identifier for this NFT - /// Should point to a JSON file that conforms to the ERC721 +pub struct PresaleTierOrder { + pub level: Uint64, + pub amount: Uint128, + pub orderer: Addr, +} + +impl From for TierOrder { + fn from(val: PresaleTierOrder) -> Self { + TierOrder { + level: val.level, + amount: val.amount, + orderer: val.orderer, + is_presale: true, + } + } +} + +// Used when the orderer is defined +#[cw_serde] +pub struct SimpleTierOrder { + pub level: Uint64, + pub amount: Uint128, +} + +impl Tier { + pub fn validate(&self) -> Result<(), ContractError> { + ensure!( + !self.price.is_zero(), + ContractError::InvalidTier { + operation: "all".to_string(), + msg: "Price can not be zero".to_string() + } + ); + ensure!( + !self.label.is_empty() && self.label.len() <= 64, + ContractError::InvalidTier { + operation: "all".to_string(), + msg: "Label should be no-empty and its length can be 64 at maximum".to_string() + } + ); + + Ok(()) + } +} +#[cw_serde] +pub struct TierMetaData { + /// Universal resource identifier for the tier + /// Should point to a JSON file that conforms to the CW721 /// Metadata JSON Schema pub token_uri: Option, /// Any custom extension used by this contract pub extension: TokenExtension, } +#[andr_query] #[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} +#[derive(QueryResponses)] +pub enum QueryMsg { + /// Query to get summary about the campaign. + #[returns(CampaignSummaryResponse)] + CampaignSummary {}, + /// Query to get TierOrders for a specific orderer. + /// + /// - orderer: The address of the orderer. + /// - start_after: Optional parameter to indicate the starting point for pagination, based on the level of the TierOrder. + /// - limit: Optional parameter to limit the number of results. + /// - order_by: Optional parameter to specify the ordering of the results. + #[returns(TierOrdersResponse)] + TierOrders { + orderer: String, + start_after: Option, + limit: Option, + order_by: Option, + }, + /// Query to get Tiers used for the campaign. + /// + /// - start_after: Optional parameter to indicate the starting point for pagination, based on the level of the Tier. + /// - limit: Optional parameter to limit the number of results. + /// - order_by: Optional parameter to specify the ordering of the results. + #[returns(TiersResponse)] + Tiers { + start_after: Option, + limit: Option, + order_by: Option, + }, +} + +#[cw_serde] +pub struct CampaignSummaryResponse { + // Campaign configuration + pub title: Option, + pub description: Option, + pub banner: Option, + pub url: Option, + pub token_address: AndrAddr, + pub denom: Asset, + pub withdrawal_recipient: Recipient, + pub soft_cap: Option, + pub hard_cap: Option, + pub start_time: Option, + pub end_time: MillisecondsExpiration, + // Current Status + pub current_stage: String, + pub current_capital: u128, +} + +#[cw_serde] +pub struct TierOrdersResponse { + pub orders: Vec, +} + +#[cw_serde] +pub struct TiersResponse { + pub tiers: Vec, +} + +#[cw_serde] +pub struct TierResponseItem { + pub tier: Tier, + pub sold_amount: Uint128, +} diff --git a/andromeda-core/packages/andromeda-non-fungible-tokens/src/cw721.rs b/andromeda-core/packages/andromeda-non-fungible-tokens/src/cw721.rs index 8cfc564..90d0f4d 100644 --- a/andromeda-core/packages/andromeda-non-fungible-tokens/src/cw721.rs +++ b/andromeda-core/packages/andromeda-non-fungible-tokens/src/cw721.rs @@ -1,6 +1,4 @@ -use andromeda_std::{ - amp::addresses::AndrAddr, andr_exec, andr_instantiate, andr_instantiate_modules, andr_query, -}; +use andromeda_std::{amp::addresses::AndrAddr, andr_exec, andr_instantiate, andr_query}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Binary, Coin, CustomMsg}; @@ -9,7 +7,6 @@ use cw721::Expiration; use cw721_base::{ExecuteMsg as Cw721ExecuteMsg, QueryMsg as Cw721QueryMsg}; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] pub struct InstantiateMsg { /// Name of the NFT contract @@ -85,12 +82,12 @@ pub enum ExecuteMsg { }, /// Transfers ownership of a token TransferNft { - recipient: String, + recipient: AndrAddr, token_id: String, }, /// Sends a token to another contract SendNft { - contract: String, + contract: AndrAddr, token_id: String, msg: Binary, }, @@ -102,39 +99,25 @@ pub enum ExecuteMsg { expires: Option, }, /// Remove previously granted Approval - Revoke { - spender: String, - token_id: String, - }, + Revoke { spender: String, token_id: String }, /// Approves an address for all tokens owned by the sender ApproveAll { operator: String, expires: Option, }, /// Remove previously granted ApproveAll permission - RevokeAll { - operator: String, - }, + RevokeAll { operator: String }, /// Burns a token, removing all data related to it. The ID of the token is still reserved. - Burn { - token_id: String, - }, + Burn { token_id: String }, /// Archives a token, causing it to be immutable but readable - Archive { - token_id: String, - }, + Archive { token_id: String }, /// Assigns a `TransferAgreement` for a token TransferAgreement { token_id: String, agreement: Option, }, /// Mint multiple tokens at a time - BatchMint { - tokens: Vec, - }, - Extension { - msg: Box, - }, + BatchMint { tokens: Vec }, } impl From for Cw721ExecuteMsg { @@ -144,7 +127,7 @@ impl From for Cw721ExecuteMsg { recipient, token_id, } => Cw721ExecuteMsg::TransferNft { - recipient, + recipient: recipient.to_string(), token_id, }, ExecuteMsg::SendNft { @@ -152,7 +135,7 @@ impl From for Cw721ExecuteMsg { token_id, msg, } => Cw721ExecuteMsg::SendNft { - contract, + contract: contract.to_string(), token_id, msg, }, @@ -184,7 +167,6 @@ impl From for Cw721ExecuteMsg { owner, }, ExecuteMsg::Burn { token_id } => Cw721ExecuteMsg::Burn { token_id }, - ExecuteMsg::Extension { msg } => Cw721ExecuteMsg::Extension { msg: *msg }, _ => panic!("Unsupported message"), } } @@ -242,8 +224,6 @@ pub enum QueryMsg { /// The current config of the contract #[returns(cw721::ContractInfoResponse)] ContractInfo {}, - #[returns(TokenExtension)] - Extension { msg: Box }, #[returns(cw721_base::MinterResponse)] Minter {}, #[returns(cw721::ApprovalResponse)] @@ -308,7 +288,6 @@ impl From for Cw721QueryMsg { QueryMsg::AllTokens { start_after, limit } => { Cw721QueryMsg::AllTokens { start_after, limit } } - QueryMsg::Extension { msg } => Cw721QueryMsg::Extension { msg: *msg }, QueryMsg::Minter {} => Cw721QueryMsg::Minter {}, QueryMsg::Approval { token_id, @@ -330,7 +309,3 @@ impl From for Cw721QueryMsg { } } } - -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-non-fungible-tokens/src/marketplace.rs b/andromeda-core/packages/andromeda-non-fungible-tokens/src/marketplace.rs index 8e5d9d4..d68c2e5 100644 --- a/andromeda-core/packages/andromeda-non-fungible-tokens/src/marketplace.rs +++ b/andromeda-core/packages/andromeda-non-fungible-tokens/src/marketplace.rs @@ -1,19 +1,28 @@ -use andromeda_std::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +use andromeda_std::{ + amp::{AndrAddr, Recipient}, + andr_exec, andr_instantiate, andr_query, + common::expiration::Expiry, + common::{denom::Asset, MillisecondsDuration}, +}; use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::Uint128; -use cw721::Cw721ReceiveMsg; +use cw20::Cw20ReceiveMsg; +use cw721::{Cw721ReceiveMsg, Expiration}; use std::fmt::{Display, Formatter, Result}; #[andr_instantiate] -#[andr_instantiate_modules] #[cw_serde] #[serde(rename_all = "snake_case")] -pub struct InstantiateMsg {} +pub struct InstantiateMsg { + pub authorized_cw20_address: Option, + pub authorized_token_addresses: Option>, +} #[andr_exec] #[cw_serde] pub enum ExecuteMsg { ReceiveNft(Cw721ReceiveMsg), + Receive(Cw20ReceiveMsg), /// Transfers NFT to buyer and sends funds to seller Buy { token_id: String, @@ -24,7 +33,8 @@ pub enum ExecuteMsg { token_id: String, token_address: String, price: Uint128, - coin_denom: String, + coin_denom: Asset, + recipient: Option, }, CancelSale { token_id: String, @@ -38,11 +48,21 @@ pub enum Cw721HookMsg { /// has started but is immutable after that. StartSale { price: Uint128, - coin_denom: String, - start_time: Option, - duration: Option, + start_time: Option, + coin_denom: Asset, + duration: Option, + recipient: Option, + }, +} + +#[cw_serde] +pub enum Cw20HookMsg { + Buy { + token_id: String, + token_address: String, }, } + #[cw_serde] pub enum Status { Open, @@ -103,13 +123,12 @@ pub struct SaleStateResponse { pub coin_denom: String, pub price: Uint128, pub status: Status, + pub start_time: Expiration, + pub end_time: Expiration, + pub recipient: Option, } #[cw_serde] pub struct SaleIdsResponse { pub sale_ids: Vec, } - -#[cw_serde] -#[serde(rename_all = "snake_case")] -pub struct MigrateMsg {} diff --git a/andromeda-core/packages/andromeda-testing-e2e/Cargo.toml b/andromeda-core/packages/andromeda-testing-e2e/Cargo.toml new file mode 100644 index 0000000..54fc56a --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "andromeda-testing-e2e" +version = "1.0.0" +authors = ["Albert Hu "] +edition = "2018" +description = "E2E Testing utilities for Andromeda Digital Object Contracts" +license = "MIT" + +[features] +backtraces = ["cosmwasm-std/backtraces"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw721 = { workspace = true } +cw20 = { workspace = true } +anyhow = "1.0.79" + +andromeda-non-fungible-tokens = { workspace = true } +andromeda-app = { version = "1.0.0", path = "../andromeda-app" } +andromeda-modules = { version = "2.0.0", path = "../andromeda-modules" } +andromeda-adodb = { version = "1.0.0", path = "../../contracts/os/andromeda-adodb", features = [ + "testing", +] } +andromeda-kernel = { version = "1.0.0", path = "../../contracts/os/andromeda-kernel", features = [ + "testing", +] } +andromeda-vfs = { version = "1.0.0", path = "../../contracts/os/andromeda-vfs", features = [ + "testing", +] } +andromeda-economics = { version = "1.0.0", path = "../../contracts/os/andromeda-economics", features = [ + "testing", + "library", +] } +andromeda-std = { workspace = true } +serde = { workspace = true } +secp256k1 = "0.29.0" +cosmrs = "0.18.0" + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +cw-multi-test = { workspace = true } +anyhow = "1.0.79" +reqwest = { version = "0.12.5", features = ["json"] } +tokio = "1.39.2" +cw-orch-daemon = "0.24.3" +cw-orch = "0.24.1" diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/adodb.rs b/andromeda-core/packages/andromeda-testing-e2e/src/adodb.rs new file mode 100644 index 0000000..fba2b23 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/adodb.rs @@ -0,0 +1,39 @@ +use crate::contract_interface; +use andromeda_std::ado_base::MigrateMsg; +use cw_orch::interface; +use cw_orch::prelude::*; + +use andromeda_std::os::adodb; +use cw_orch_daemon::DaemonBase; +use cw_orch_daemon::Wallet; + +contract_interface!( + AdodbContract, + andromeda_adodb, + adodb, + "adodb_contract", + "adodb" +); +impl AdodbContract> { + pub fn init(self, kernel_address: String) { + let msg = adodb::InstantiateMsg { + kernel_address, + owner: None, + }; + self.instantiate(&msg, None, None).unwrap(); + } + + pub fn execute_publish(self, code_id: u64, ado_type: String, version: String) { + self.execute( + &adodb::ExecuteMsg::Publish { + code_id, + ado_type, + action_fees: None, + version, + publisher: None, + }, + None, + ) + .unwrap(); + } +} diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/economics.rs b/andromeda-core/packages/andromeda-testing-e2e/src/economics.rs new file mode 100644 index 0000000..58f4500 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/economics.rs @@ -0,0 +1,25 @@ +use crate::contract_interface; +use andromeda_std::ado_base::MigrateMsg; +use cw_orch::interface; +use cw_orch::prelude::*; + +use andromeda_std::os::economics; +use cw_orch_daemon::DaemonBase; +use cw_orch_daemon::Wallet; + +contract_interface!( + EconomicsContract, + andromeda_economics, + economics, + "economics_contract", + "economics" +); +impl EconomicsContract> { + pub fn init(self, kernel_address: String) { + let msg = economics::InstantiateMsg { + kernel_address, + owner: None, + }; + self.instantiate(&msg, None, None).unwrap(); + } +} diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/faucet.rs b/andromeda-core/packages/andromeda-testing-e2e/src/faucet.rs new file mode 100644 index 0000000..da66dc8 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/faucet.rs @@ -0,0 +1,18 @@ +use cosmwasm_std::coins; +use cw_orch::prelude::ChainInfo; +use cw_orch_daemon::{DaemonBase, Wallet}; +const FAUCET_MNEMONIC: &str = "increase bread alpha rigid glide amused approve oblige print asset idea enact lawn proof unfold jeans rabbit audit return chuckle valve rather cactus great"; + +pub fn fund(daemon: &DaemonBase, chain_info: &ChainInfo, amount: u128) { + let target_addr = daemon.sender().pub_addr_str(); + + let faucet_daemon = daemon.rebuild().mnemonic(FAUCET_MNEMONIC).build().unwrap(); + let rt = faucet_daemon.rt_handle.clone(); + let wallet = faucet_daemon.sender(); + + rt.block_on(wallet.bank_send( + &target_addr, + coins(amount, chain_info.gas_denom.to_string()), + )) + .unwrap(); +} diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/interface_macro.rs b/andromeda-core/packages/andromeda-testing-e2e/src/interface_macro.rs new file mode 100644 index 0000000..462e401 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/interface_macro.rs @@ -0,0 +1,26 @@ +#[macro_export] +macro_rules! contract_interface { + ($contract_name:ident, $module_path:ident, $package_path:ident, $contract_id:expr, $wasm_path:expr) => { + #[interface($package_path::InstantiateMsg, $package_path::ExecuteMsg, $package_path::QueryMsg, MigrateMsg, id = $contract_id)] + pub struct $contract_name; + + impl Uploadable for $contract_name { + fn wrapper() -> Box> { + Box::new( + ContractWrapper::new_with_empty( + $module_path::contract::execute, + $module_path::contract::instantiate, + $module_path::contract::query, + ) + .with_migrate($module_path::contract::migrate), + ) + } + + fn wasm(_chain: &ChainInfoOwned) -> WasmPath { + artifacts_dir_from_workspace!() + .find_wasm_path($wasm_path) + .unwrap() + } + } + }; +} diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/kernel.rs b/andromeda-core/packages/andromeda-testing-e2e/src/kernel.rs new file mode 100644 index 0000000..ebf375e --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/kernel.rs @@ -0,0 +1,31 @@ +use crate::contract_interface; +use andromeda_std::ado_base::MigrateMsg; +use cw_orch::interface; +use cw_orch::prelude::*; + +use andromeda_std::os::kernel; +use cw_orch_daemon::DaemonBase; +use cw_orch_daemon::Wallet; + +contract_interface!( + KernelContract, + andromeda_kernel, + kernel, + "kernel_contract", + "kernel" +); + +impl KernelContract> { + pub fn init(self, chain_name: String) { + let msg = kernel::InstantiateMsg { + chain_name, + owner: None, + }; + self.instantiate(&msg, None, None).unwrap(); + } + + pub fn execute_store_key_address(self, key: String, value: String) { + self.execute(&kernel::ExecuteMsg::UpsertKeyAddress { key, value }, None) + .unwrap(); + } +} diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/lib.rs b/andromeda-core/packages/andromeda-testing-e2e/src/lib.rs new file mode 100644 index 0000000..e96f910 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/lib.rs @@ -0,0 +1,20 @@ +#[cfg(not(target_arch = "wasm32"))] +pub mod faucet; + +#[cfg(not(target_arch = "wasm32"))] +pub mod interface_macro; + +#[cfg(not(target_arch = "wasm32"))] +pub mod mock; + +#[cfg(not(target_arch = "wasm32"))] +pub mod kernel; + +#[cfg(not(target_arch = "wasm32"))] +pub mod adodb; + +#[cfg(not(target_arch = "wasm32"))] +pub mod vfs; + +#[cfg(not(target_arch = "wasm32"))] +pub mod economics; diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/mock.rs b/andromeda-core/packages/andromeda-testing-e2e/src/mock.rs new file mode 100644 index 0000000..1d6d68b --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/mock.rs @@ -0,0 +1,92 @@ +use cw_orch::prelude::*; +use cw_orch_daemon::{Daemon, DaemonBase, Wallet}; + +use crate::{ + adodb::AdodbContract, economics::EconomicsContract, faucet::fund, kernel::KernelContract, + vfs::VfsContract, +}; + +pub fn mock_app(chain: ChainInfo, mnemonic: &str) -> DaemonBase { + let daemon = Daemon::builder(chain.clone()) // set the network to use + .mnemonic(mnemonic) + .build() + .unwrap(); + + fund(&daemon, &chain, 10000000000000); + + daemon +} + +pub struct MockAndromeda { + pub kernel_contract: KernelContract>, + pub adodb_contract: AdodbContract>, + pub vfs_contract: VfsContract>, + pub economics_contract: EconomicsContract>, +} + +impl MockAndromeda { + pub fn new(daemon: &DaemonBase) -> MockAndromeda { + let chain_name: String = daemon.chain_info().network_info.chain_name.to_string(); + + // Upload and instantiate os ADOs + let kernel_contract = KernelContract::new(daemon.clone()); + kernel_contract.upload().unwrap(); + kernel_contract.clone().init(chain_name); + + let adodb_contract = AdodbContract::new(daemon.clone()); + adodb_contract.upload().unwrap(); + adodb_contract + .clone() + .init(kernel_contract.addr_str().unwrap()); + + let vfs_contract = VfsContract::new(daemon.clone()); + vfs_contract.upload().unwrap(); + vfs_contract + .clone() + .init(kernel_contract.addr_str().unwrap()); + + let economics_contract = EconomicsContract::new(daemon.clone()); + economics_contract.upload().unwrap(); + economics_contract + .clone() + .init(kernel_contract.addr_str().unwrap()); + + // register code ids in ado db + adodb_contract.clone().execute_publish( + adodb_contract.code_id().unwrap(), + "adodb".to_string(), + "0.1.0".to_string(), + ); + + adodb_contract.clone().execute_publish( + vfs_contract.code_id().unwrap(), + "vfs".to_string(), + "0.1.0".to_string(), + ); + + adodb_contract.clone().execute_publish( + kernel_contract.code_id().unwrap(), + "kernel".to_string(), + "0.1.0".to_string(), + ); + + // update kernel + kernel_contract + .clone() + .execute_store_key_address("adodb".to_string(), adodb_contract.addr_str().unwrap()); + kernel_contract + .clone() + .execute_store_key_address("vfs".to_string(), vfs_contract.addr_str().unwrap()); + kernel_contract.clone().execute_store_key_address( + "economics".to_string(), + economics_contract.addr_str().unwrap(), + ); + + MockAndromeda { + kernel_contract, + adodb_contract, + vfs_contract, + economics_contract, + } + } +} diff --git a/andromeda-core/packages/andromeda-testing-e2e/src/vfs.rs b/andromeda-core/packages/andromeda-testing-e2e/src/vfs.rs new file mode 100644 index 0000000..6e29963 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing-e2e/src/vfs.rs @@ -0,0 +1,19 @@ +use crate::contract_interface; +use andromeda_std::ado_base::MigrateMsg; +use cw_orch::interface; +use cw_orch::prelude::*; + +use andromeda_std::os::vfs; +use cw_orch_daemon::DaemonBase; +use cw_orch_daemon::Wallet; + +contract_interface!(VfsContract, andromeda_vfs, vfs, "vfs_contract", "vfs"); +impl VfsContract> { + pub fn init(self, kernel_address: String) { + let msg = vfs::InstantiateMsg { + kernel_address, + owner: None, + }; + self.instantiate(&msg, None, None).unwrap(); + } +} diff --git a/andromeda-core/packages/andromeda-testing/Cargo.toml b/andromeda-core/packages/andromeda-testing/Cargo.toml index 3b6a6ad..8051191 100644 --- a/andromeda-core/packages/andromeda-testing/Cargo.toml +++ b/andromeda-core/packages/andromeda-testing/Cargo.toml @@ -1,8 +1,10 @@ [package] name = "andromeda-testing" -version = "0.1.0" +version = "1.0.0" authors = ["Connor Barr "] edition = "2018" +description = "Testing utilities for Andromeda Digital Object Contracts" +license = "MIT" [features] backtraces = ["cosmwasm-std/backtraces"] @@ -16,21 +18,25 @@ cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } cw721 = { workspace = true } cw20 = { workspace = true } -prost = "0.9.0" +anyhow = "1.0.79" -andromeda-non-fungible-tokens = { version = "0.1.0", path = "../andromeda-non-fungible-tokens" } -andromeda-app = { version = "0.1.0", path = "../andromeda-app" } -andromeda-modules = { version = "0.1.0", path = "../andromeda-modules" } -andromeda-adodb = { version = "0.2.1", path = "../../contracts/os/andromeda-adodb", features = [ +andromeda-non-fungible-tokens = { workspace = true } +andromeda-app = { version = "1.0.0", path = "../andromeda-app" } +andromeda-modules = { version = "2.0.0", path = "../andromeda-modules" } +andromeda-adodb = { version = "1.0.0", path = "../../contracts/os/andromeda-adodb", features = [ + "testing", +] } +andromeda-kernel = { version = "1.0.0", path = "../../contracts/os/andromeda-kernel", features = [ "testing", ] } -andromeda-kernel = { version = "0.2.15", path = "../../contracts/os/andromeda-kernel", features = [ +andromeda-vfs = { version = "1.0.0", path = "../../contracts/os/andromeda-vfs", features = [ "testing", ] } -andromeda-vfs = { version = "0.2.2", path = "../../contracts/os/andromeda-vfs", features = [ +andromeda-economics = { version = "1.0.0", path = "../../contracts/os/andromeda-economics", features = [ "testing", + "library", ] } -andromeda-economics = { version = "0.2.0", path = "../../contracts/os/andromeda-economics", features = [ +andromeda-ibc-registry = { version = "1.0.0", path = "../../contracts/os/andromeda-ibc-registry", features = [ "testing", "library", ] } diff --git a/andromeda-core/packages/andromeda-testing/README.md b/andromeda-core/packages/andromeda-testing/README.md index 6b6a44c..43ff9af 100644 --- a/andromeda-core/packages/andromeda-testing/README.md +++ b/andromeda-core/packages/andromeda-testing/README.md @@ -37,7 +37,7 @@ let andr = mock_andromeda(); andr.store_ado(&mut router, mock_andromeda_app(), "app"); ``` -Here the second parameter is a `cw-multi-test` [mock contract](https://docs.rs/cw-multi-test/latest/cw_multi_test/trait.Contract.html) and the third is a name for the ADO. This can be used to access the code id by calling `andr.get_code_id(&router, "app")`. Repeat this process for any ADOs you wish to add (including your own). +Here the second parameter is a `cw-multi-test` [mock contract](https://docs.rs/cw-multi-test/latest/cw_multi_test/trait.Contract.html) and the third is a name for the ADO. This can be used to access the code id by calling `andr.get_code_id(&router, "app-contract")`. Repeat this process for any ADOs you wish to add (including your own). ## Creating a Mock Contract @@ -63,3 +63,62 @@ Once this is done you can either create the contract directly or you can create ``` Mock structs have been provided for most ADOs however they are still a work in progress. + +## Test Scaffolding + +To help with setting up a testing environment using aOS we can use the `MockAndromedaBuilder` struct. This allows definition of what wallets and contracts you would like to use while testing: + +```rust +use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder}; + +let mut router = mock_app(None); +let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(1000, "uandr")]), + ("user1", vec![]), + ]) + .with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("app-contract", mock_andromeda_app()), + ]) + .build(&mut router); +``` + +In the above example we specify a few things: + +```rust +MockAndromedaBuilder::new(&mut router, "admin") +``` + +Here we set the wallet **name** that has admin privileges over the aOS, in this case `"admin"`. Next up we define a few extra wallets: + +```rust +.with_wallets(vec![ + ("owner", vec![coin(1000, "uandr")]), + ("user1", vec![]), +]) +``` + +This generates two wallets (`"owner"` and `"user1"`) and assigns 1000 uandr to the `"owner"` wallet. Here the provided names **are not addresses** but are simply names. These can be accessed using: + +```rust +let owner = andr.get_wallet("owner"); +let user1 = andr.get_wallet("user1"); +``` + +Next we include the contracts we would like to use: + +```rust +.with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("app-contract", mock_andromeda_app()), +]) +``` + +In this case we would like to use the CW721 contract and the App contract, the provided names can also be version (e.g. `"cw721@0.1.0"`). The stored code IDs for these can be accessed via their names like so: + +```rust +let app_code_id = andr.get_code_id("cw721"); +``` + +The rest of the integration test should continue as usual. diff --git a/andromeda-core/packages/andromeda-testing/src/adodb.rs b/andromeda-core/packages/andromeda-testing/src/adodb.rs index 2fc3815..5a36143 100644 --- a/andromeda-core/packages/andromeda-testing/src/adodb.rs +++ b/andromeda-core/packages/andromeda-testing/src/adodb.rs @@ -1,15 +1,15 @@ -use crate::{mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; +use crate::{mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; use andromeda_adodb::mock::*; use andromeda_std::os::adodb::{ActionFee, ExecuteMsg, QueryMsg}; use cosmwasm_std::Addr; -use cw_multi_test::{App, Executor}; +use cw_multi_test::Executor; pub struct MockADODB(Addr); mock_ado!(MockADODB, ExecuteMsg, QueryMsg); impl MockADODB { pub fn instantiate( - app: &mut App, + app: &mut MockApp, code_id: u64, sender: Addr, owner: Option, @@ -31,7 +31,7 @@ impl MockADODB { #[allow(clippy::too_many_arguments)] pub fn execute_publish( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, code_id: u64, ado_type: impl Into, @@ -44,7 +44,7 @@ impl MockADODB { self.execute(app, &msg, sender, &[]) } - pub fn query_code_id(&self, app: &mut App, key: impl Into) -> u64 { + pub fn query_code_id(&self, app: &mut MockApp, key: impl Into) -> u64 { let msg = mock_get_code_id_msg(key.into()); let res: u64 = self.query(app, msg); diff --git a/andromeda-core/packages/andromeda-testing/src/economics.rs b/andromeda-core/packages/andromeda-testing/src/economics.rs index c4063e0..af7b91a 100644 --- a/andromeda-core/packages/andromeda-testing/src/economics.rs +++ b/andromeda-core/packages/andromeda-testing/src/economics.rs @@ -4,16 +4,16 @@ use andromeda_std::{ os::economics::{ExecuteMsg, QueryMsg}, }; use cosmwasm_std::{Addr, Coin, Uint128}; -use cw_multi_test::{App, Executor}; +use cw_multi_test::Executor; -use crate::{mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; +use crate::{mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; pub struct MockEconomics(Addr); mock_ado!(MockEconomics, ExecuteMsg, QueryMsg); impl MockEconomics { pub fn instantiate( - app: &mut App, + app: &mut MockApp, code_id: u64, sender: Addr, owner: Option, @@ -34,7 +34,7 @@ impl MockEconomics { pub fn execute_deposit( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, address: Option, funds: &[Coin], @@ -46,7 +46,7 @@ impl MockEconomics { pub fn execute_withdraw( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, asset: impl Into, amount: Option, @@ -58,7 +58,7 @@ impl MockEconomics { pub fn query_balance( &self, - app: &mut App, + app: &mut MockApp, address: AndrAddr, asset: impl Into, ) -> Uint128 { diff --git a/andromeda-core/packages/andromeda-testing/src/economics_msg.rs b/andromeda-core/packages/andromeda-testing/src/economics_msg.rs new file mode 100644 index 0000000..4025d41 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing/src/economics_msg.rs @@ -0,0 +1,17 @@ +use andromeda_std::{common::reply::ReplyId, os::economics::ExecuteMsg as EconomicsExecuteMsg}; +use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, SubMsg, WasmMsg}; + +pub fn generate_economics_message(payee: &str, action: &str) -> SubMsg { + SubMsg::reply_on_error( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: "economics_contract".to_string(), + msg: to_json_binary(&EconomicsExecuteMsg::PayFee { + payee: Addr::unchecked(payee), + action: action.to_string(), + }) + .unwrap(), + funds: vec![], + }), + ReplyId::PayFee.repr(), + ) +} diff --git a/andromeda-core/packages/andromeda-testing/src/faucet.rs b/andromeda-core/packages/andromeda-testing/src/faucet.rs new file mode 100644 index 0000000..099aa4d --- /dev/null +++ b/andromeda-core/packages/andromeda-testing/src/faucet.rs @@ -0,0 +1,30 @@ +use cw_orch::prelude::ChainInfo; +use serde::{Deserialize, Serialize}; +use tokio::runtime::Runtime; + +#[derive(Serialize, Deserialize, Debug)] +pub struct AirdropRequest { + /// Address of the address asking for funds + pub address: String, + /// Denom asked for + pub denom: String, +} +async fn airdrop(addr: String, chain: &ChainInfo) { + let client = reqwest::Client::new(); + let url = chain.fcd_url.unwrap_or("http://localhost:8001"); + let url = format!("{}/credit", url); + client + .post(url) + .json(&AirdropRequest { + address: addr.to_string(), + denom: chain.gas_denom.to_string(), + }) + .send() + .await + .unwrap(); +} + +pub fn fund(addr: String, chain_info: &ChainInfo) { + let rt_handle = Runtime::new().unwrap(); + rt_handle.block_on(airdrop(addr, chain_info)); +} diff --git a/andromeda-core/packages/andromeda-testing/src/ibc_registry.rs b/andromeda-core/packages/andromeda-testing/src/ibc_registry.rs new file mode 100644 index 0000000..d3ef0d0 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing/src/ibc_registry.rs @@ -0,0 +1,86 @@ +use crate::{mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; +use andromeda_std::amp::AndrAddr; +use andromeda_std::os::ibc_registry::{ + AllDenomInfoResponse, DenomInfoResponse, ExecuteMsg, IBCDenomInfo, InstantiateMsg, QueryMsg, +}; +use cosmwasm_std::{Addr, Coin}; +use cw_multi_test::Executor; + +pub struct MockIbcRegistry(Addr); +mock_ado!(MockIbcRegistry, ExecuteMsg, QueryMsg); + +impl MockIbcRegistry { + pub fn instantiate( + app: &mut MockApp, + code_id: u64, + sender: Addr, + owner: Option, + kernel_address: String, + service_address: AndrAddr, + ) -> MockIbcRegistry { + let msg = mock_ibc_registry_instantiate_msg( + Addr::unchecked(kernel_address), + owner, + service_address, + ); + let addr = app + .instantiate_contract( + code_id, + sender.clone(), + &msg, + &[], + "IBC Registry Contract", + Some(sender.to_string()), + ) + .unwrap(); + MockIbcRegistry(Addr::unchecked(addr)) + } + + pub fn execute_execute_store_denom_info( + &self, + app: &mut MockApp, + sender: Addr, + funds: Option, + ibc_denom_info: Vec, + ) -> ExecuteResult { + let msg = mock_execute_store_denom_info_msg(ibc_denom_info); + if let Some(funds) = funds { + app.execute_contract(sender, self.addr().clone(), &msg, &[funds]) + } else { + app.execute_contract(sender, self.addr().clone(), &msg, &[]) + } + } + + pub fn query_denom_info(&self, app: &mut MockApp, denom: String) -> DenomInfoResponse { + let msg = QueryMsg::DenomInfo { denom }; + let res: DenomInfoResponse = self.query(app, msg); + res + } + + pub fn query_all_denom_info( + &self, + app: &mut MockApp, + limit: Option, + start_after: Option, + ) -> AllDenomInfoResponse { + let msg = QueryMsg::AllDenomInfo { limit, start_after }; + let res: AllDenomInfoResponse = self.query(app, msg); + res + } +} + +pub fn mock_ibc_registry_instantiate_msg( + kernel_address: Addr, + owner: Option, + service_address: AndrAddr, +) -> InstantiateMsg { + InstantiateMsg { + kernel_address, + owner, + service_address, + } +} + +pub fn mock_execute_store_denom_info_msg(ibc_denom_info: Vec) -> ExecuteMsg { + ExecuteMsg::StoreDenomInfo { ibc_denom_info } +} diff --git a/andromeda-core/packages/andromeda-testing/src/kernel.rs b/andromeda-core/packages/andromeda-testing/src/kernel.rs index 49bbf12..234c7af 100644 --- a/andromeda-core/packages/andromeda-testing/src/kernel.rs +++ b/andromeda-core/packages/andromeda-testing/src/kernel.rs @@ -1,10 +1,11 @@ +use crate::mock::MockApp; use crate::mock_contract::ExecuteResult; use andromeda_kernel::mock::*; use andromeda_std::amp::{messages::AMPMsgConfig, AndrAddr}; use andromeda_std::os::kernel::{ExecuteMsg, QueryMsg}; use cosmwasm_std::{Addr, Coin}; -use cw_multi_test::{App, Executor}; +use cw_multi_test::Executor; use serde::Serialize; use super::{mock_ado, MockADO, MockContract}; @@ -14,7 +15,7 @@ mock_ado!(MockKernel, ExecuteMsg, QueryMsg); impl MockKernel { pub fn instantiate( - app: &mut App, + app: &mut MockApp, code_id: u64, sender: Addr, admin: Option, @@ -35,7 +36,7 @@ impl MockKernel { pub fn execute_store_key_address( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, key: impl Into, value: impl Into, @@ -47,7 +48,7 @@ impl MockKernel { pub fn execute_create( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, ado_type: impl Into, msg: impl Serialize, @@ -61,7 +62,7 @@ impl MockKernel { pub fn execute_send( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, recipient: impl Into, msg: impl Serialize, @@ -73,7 +74,7 @@ impl MockKernel { self.execute(app, &msg, sender, &funds) } - pub fn query_key_address(&self, app: &App, key: impl Into) -> String { + pub fn query_key_address(&self, app: &MockApp, key: impl Into) -> String { let msg = mock_get_key_address(key); self.query(app, msg) diff --git a/andromeda-core/packages/andromeda-testing/src/lib.rs b/andromeda-core/packages/andromeda-testing/src/lib.rs index df90f8e..8de3394 100644 --- a/andromeda-core/packages/andromeda-testing/src/lib.rs +++ b/andromeda-core/packages/andromeda-testing/src/lib.rs @@ -1,23 +1,34 @@ -mod adodb; -mod economics; -mod kernel; -mod vfs; +pub mod economics_msg; +// pub mod reply; +// pub mod testing; +#[cfg(not(target_arch = "wasm32"))] +pub mod adodb; +#[cfg(not(target_arch = "wasm32"))] +pub mod economics; +#[cfg(not(target_arch = "wasm32"))] +pub mod ibc_registry; +#[cfg(not(target_arch = "wasm32"))] +pub mod kernel; +#[cfg(not(target_arch = "wasm32"))] +pub mod mock_builder; +#[cfg(not(target_arch = "wasm32"))] +pub mod vfs; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub mod mock; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub mod mock_contract; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub use adodb::MockADODB; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub use economics::MockEconomics; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub use kernel::MockKernel; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub use mock::MockAndromeda; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub use mock_contract::MockADO; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub use mock_contract::MockContract; -#[cfg(all(not(target_arch = "wasm32")))] +#[cfg(not(target_arch = "wasm32"))] pub use vfs::MockVFS; diff --git a/andromeda-core/packages/andromeda-testing/src/mock.rs b/andromeda-core/packages/andromeda-testing/src/mock.rs index e4c9142..e28cde9 100644 --- a/andromeda-core/packages/andromeda-testing/src/mock.rs +++ b/andromeda-core/packages/andromeda-testing/src/mock.rs @@ -1,37 +1,133 @@ -#![cfg(all(not(target_arch = "wasm32")))] +#![cfg(not(target_arch = "wasm32"))] +use std::collections::HashMap; use andromeda_adodb::mock::mock_andromeda_adodb; use andromeda_economics::mock::mock_andromeda_economics; +use andromeda_ibc_registry::mock::mock_andromeda_ibc_registry; use andromeda_kernel::mock::mock_andromeda_kernel; +use andromeda_std::{amp::AndrAddr, os::adodb::ADOVersion}; use andromeda_vfs::mock::mock_andromeda_vfs; -use cosmwasm_std::{Addr, Empty}; -use cw_multi_test::{App, Contract}; +use cosmwasm_std::{coin, Addr, BlockInfo, Coin, Decimal, Timestamp, Validator}; +use cw_multi_test::{ + App, AppBuilder, BankKeeper, Executor, MockAddressGenerator, MockApiBech32, WasmKeeper, +}; -use crate::{mock_contract::MockContract, MockADODB, MockEconomics, MockKernel, MockVFS}; +use crate::{ + ibc_registry::MockIbcRegistry, mock_contract::MockContract, MockADODB, MockEconomics, + MockKernel, MockVFS, +}; pub const ADMIN_USERNAME: &str = "am"; +pub type MockApp = App; + +pub fn mock_app(denoms: Option>) -> MockApp { + let denoms = denoms.unwrap_or(vec!["uandr", "uusd"]); + AppBuilder::new() + .with_api(MockApiBech32::new("andr")) + .with_wasm(WasmKeeper::new().with_address_generator(MockAddressGenerator)) + .build(|router, api, storage| { + router + .bank + .init_balance( + storage, + &Addr::unchecked("bank"), + denoms + .iter() + .map(|d| coin(u128::MAX, *d)) + .collect::>(), + ) + .unwrap(); + + router + .staking + .add_validator( + api, + storage, + &BlockInfo { + height: 0, + time: Timestamp::default(), + chain_id: "andromeda".to_string(), + }, + Validator { + address: MockApiBech32::new("andr") + .addr_make("validator1") + .to_string(), + commission: Decimal::zero(), + max_commission: Decimal::percent(20), + max_change_rate: Decimal::percent(1), + }, + ) + .unwrap(); + + router + .staking + .add_validator( + api, + storage, + &BlockInfo { + height: 0, + time: Timestamp::default(), + chain_id: "andromeda-1".to_string(), + }, + Validator { + address: MockApiBech32::new("andr") + .addr_make("validator2") + .to_string(), + commission: Decimal::zero(), + max_commission: Decimal::percent(20), + max_change_rate: Decimal::percent(1), + }, + ) + .unwrap(); + }) +} + +pub fn init_balances(app: &mut MockApp, balances: Vec<(Addr, &[Coin])>) { + for (addr, coins) in balances { + app.send_tokens(Addr::unchecked("bank"), addr, coins) + .unwrap(); + } +} + pub struct MockAndromeda { pub admin_address: Addr, pub kernel: MockKernel, pub adodb: MockADODB, pub economics: MockEconomics, pub vfs: MockVFS, + pub ibc_registry: MockIbcRegistry, + pub wallets: HashMap, } - impl MockAndromeda { - pub fn new(app: &mut App, admin_address: &Addr) -> MockAndromeda { + pub fn new(app: &mut MockApp, admin_name: &str) -> MockAndromeda { + let mut wallets = HashMap::new(); + let admin_address = app.api().addr_make(admin_name); + let service_address = app.api().addr_make("service_address"); + wallets + .entry(admin_name.to_string()) + .and_modify(|_| { + panic!("Wallet already exists"); + }) + .or_insert(admin_address.clone()); + // Store contract codes let adodb_code_id = app.store_code(mock_andromeda_adodb()); let kernel_code_id = app.store_code(mock_andromeda_kernel()); let vfs_code_id = app.store_code(mock_andromeda_vfs()); let economics_code_id = app.store_code(mock_andromeda_economics()); + let ibc_registry_code_id = app.store_code(mock_andromeda_ibc_registry()); // Init Kernel - let kernel = - MockKernel::instantiate(app, kernel_code_id, admin_address.clone(), None, None); + let kernel = MockKernel::instantiate( + app, + kernel_code_id, + admin_address.clone(), + Some(admin_address.to_string()), + None, + ); - // Init ADO DB + // Init ADODB let adodb = MockADODB::instantiate( app, adodb_code_id, @@ -40,7 +136,17 @@ impl MockAndromeda { kernel.addr().to_string(), ); - //Init Economics + // Init IBC Registry + let ibc_registry = MockIbcRegistry::instantiate( + app, + ibc_registry_code_id, + admin_address.clone(), + None, + kernel.addr().to_string(), + AndrAddr::from_string(service_address), + ); + + // Init Economics let economics = MockEconomics::instantiate( app, economics_code_id, @@ -57,8 +163,6 @@ impl MockAndromeda { None, kernel.addr().to_string(), ); - vfs.execute_register_user(app, admin_address.clone(), ADMIN_USERNAME.to_string()) - .unwrap(); // Add Code IDs adodb @@ -72,6 +176,17 @@ impl MockAndromeda { None, ) .unwrap(); + adodb + .execute_publish( + app, + admin_address.clone(), + ibc_registry_code_id, + "ibc-registry", + "0.1.0", + None, + None, + ) + .unwrap(); adodb .execute_publish( app, @@ -108,44 +223,64 @@ impl MockAndromeda { economics.addr().clone(), ) .unwrap(); - + kernel + .execute_store_key_address( + app, + admin_address.clone(), + "ibc-registry", + ibc_registry.addr().clone(), + ) + .unwrap(); MockAndromeda { - admin_address: admin_address.clone(), + admin_address, kernel, adodb, economics, vfs, + ibc_registry, + wallets, } } /// Stores a given Code ID under the given key in the ADO DB contract - pub fn store_code_id(&self, app: &mut App, key: &str, code_id: u64) { + pub fn store_code_id(&self, router: &mut MockApp, key: &str, code_id: u64) { + let ado_version = ADOVersion::from_string(key); + let version = + if !ado_version.get_version().is_empty() && ado_version.get_version() != "latest" { + ado_version.get_version() + } else { + "0.1.0".to_string() + }; self.adodb .execute_publish( - app, + router, self.admin_address.clone(), code_id, - key, - "0.1.0", + ado_version.get_type(), + version, Some(self.admin_address.to_string()), None, ) .unwrap(); } - pub fn store_ado( - &self, - app: &mut App, - contract: Box>, - ado_type: impl Into, - ) -> u64 { - let code_id = app.store_code(contract); - self.store_code_id(app, ado_type.into().as_str(), code_id); - code_id - } - /// Gets the Code ID for a given key from the ADO DB contract - pub fn get_code_id(&self, app: &mut App, key: impl Into) -> u64 { + pub fn get_code_id(&self, app: &mut MockApp, key: impl Into) -> u64 { self.adodb.query_code_id(app, key) } + + pub fn add_wallet(&mut self, router: &mut MockApp, name: &str) -> Addr { + let addr = router.api().addr_make(name); + self.wallets + .entry(name.to_string()) + .and_modify(|_| { + panic!("Wallet already exists"); + }) + .or_insert(addr.clone()); + addr + } + + pub fn get_wallet(&self, name: &str) -> &Addr { + self.wallets.get(name).unwrap() + } } diff --git a/andromeda-core/packages/andromeda-testing/src/mock_builder.rs b/andromeda-core/packages/andromeda-testing/src/mock_builder.rs new file mode 100644 index 0000000..0fc9153 --- /dev/null +++ b/andromeda-core/packages/andromeda-testing/src/mock_builder.rs @@ -0,0 +1,62 @@ +use cosmwasm_std::{Addr, Coin, Empty}; +use cw_multi_test::{Contract, Executor}; + +use crate::{mock::MockApp, MockAndromeda}; + +pub struct MockAndromedaBuilder { + contracts: Vec<(&'static str, Box>)>, + andr: MockAndromeda, + wallets: Vec<(&'static str, Vec)>, + raw_balances: Vec<(Addr, Vec)>, +} + +impl MockAndromedaBuilder { + pub fn new(app: &mut MockApp, admin_wallet_name: &'static str) -> Self { + let andr = MockAndromeda::new(app, admin_wallet_name); + Self { + contracts: vec![], + andr, + raw_balances: vec![], + wallets: vec![], + } + } + + pub fn with_wallets(self, wallets: Vec<(&'static str, Vec)>) -> Self { + Self { wallets, ..self } + } + + pub fn with_balances(self, raw_balances: &[(Addr, Vec)]) -> Self { + Self { + raw_balances: raw_balances.to_vec(), + ..self + } + } + + pub fn with_contracts(self, contracts: Vec<(&'static str, Box>)>) -> Self { + Self { contracts, ..self } + } + + pub fn build(mut self, app: &mut MockApp) -> MockAndromeda { + for (version, contract) in self.contracts { + let code_id = app.store_code(contract); + self.andr.store_code_id(app, version, code_id); + } + + for (wallet, balance) in self.wallets { + let addr = self.andr.add_wallet(app, wallet); + if !balance.is_empty() { + app.send_tokens(Addr::unchecked("bank"), addr, &balance) + .unwrap(); + } + } + + for (addr, balance) in self.raw_balances { + if !balance.is_empty() { + app.send_tokens(Addr::unchecked("bank"), addr, &balance) + .unwrap(); + } + } + + self.andr + } +} diff --git a/andromeda-core/packages/andromeda-testing/src/mock_contract.rs b/andromeda-core/packages/andromeda-testing/src/mock_contract.rs index 05bb54f..56e1f91 100644 --- a/andromeda-core/packages/andromeda-testing/src/mock_contract.rs +++ b/andromeda-core/packages/andromeda-testing/src/mock_contract.rs @@ -1,12 +1,22 @@ use core::fmt; -use andromeda_std::ado_base::{ownership::ContractOwnerResponse, AndromedaQuery}; +use andromeda_std::{ + ado_base::{ + ownership::{ContractOwnerResponse, OwnershipMessage}, + permissioning::{Permission, PermissioningMessage}, + AndromedaMsg, AndromedaQuery, + }, + amp::AndrAddr, +}; + use cosmwasm_std::{Addr, Coin}; -use cw_multi_test::{App, AppResponse, Executor}; +use cw_multi_test::{AppResponse, Executor}; use serde::{de::DeserializeOwned, Serialize}; pub use anyhow::Result as AnyResult; +use crate::mock::MockApp; + pub type ExecuteResult = AnyResult; pub trait MockContract { @@ -14,7 +24,7 @@ pub trait MockContract { fn execute( &self, - app: &mut App, + app: &mut MockApp, msg: &E, sender: Addr, funds: &[Coin], @@ -22,7 +32,7 @@ pub trait MockContract { app.execute_contract(sender, self.addr().clone(), &msg, funds) } - fn query(&self, app: &App, msg: Q) -> T { + fn query(&self, app: &MockApp, msg: Q) -> T { app.wrap() .query_wasm_smart::(self.addr().clone(), &msg) .unwrap() @@ -32,12 +42,41 @@ pub trait MockContract { pub trait MockADO: MockContract { - fn query_owner(&self, app: &App) -> String { + fn query_owner(&self, app: &MockApp) -> String { app.wrap() .query_wasm_smart::(self.addr(), &AndromedaQuery::Owner {}) .unwrap() .owner } + + fn accept_ownership(&self, app: &mut MockApp, sender: Addr) -> AnyResult { + app.execute_contract( + sender, + self.addr().clone(), + &AndromedaMsg::Ownership(OwnershipMessage::AcceptOwnership {}), + &[], + ) + } + + fn execute_set_permissions( + &self, + app: &mut MockApp, + sender: Addr, + actors: Vec, + action: impl Into, + permission: Permission, + ) -> ExecuteResult { + app.execute_contract( + sender, + self.addr().clone(), + &AndromedaMsg::Permissioning(PermissioningMessage::SetPermission { + actors, + action: action.into(), + permission, + }), + &[], + ) + } } #[macro_export] diff --git a/andromeda-core/packages/andromeda-testing/src/vfs.rs b/andromeda-core/packages/andromeda-testing/src/vfs.rs index e653d04..94e7368 100644 --- a/andromeda-core/packages/andromeda-testing/src/vfs.rs +++ b/andromeda-core/packages/andromeda-testing/src/vfs.rs @@ -1,15 +1,15 @@ -use crate::{mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; +use crate::{mock::MockApp, mock_ado, mock_contract::ExecuteResult, MockADO, MockContract}; use andromeda_std::os::vfs::{ExecuteMsg, QueryMsg}; use andromeda_vfs::mock::*; use cosmwasm_std::Addr; -use cw_multi_test::{App, Executor}; +use cw_multi_test::Executor; pub struct MockVFS(Addr); mock_ado!(MockVFS, ExecuteMsg, QueryMsg); impl MockVFS { pub fn instantiate( - app: &mut App, + app: &mut MockApp, code_id: u64, sender: Addr, owner: Option, @@ -30,7 +30,7 @@ impl MockVFS { pub fn execute_register_user( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, username: String, ) -> ExecuteResult { @@ -41,7 +41,7 @@ impl MockVFS { pub fn execute_add_path( &self, - app: &mut App, + app: &mut MockApp, sender: Addr, name: impl Into, address: Addr, @@ -51,9 +51,9 @@ impl MockVFS { self.execute(app, &msg, sender, &[]) } - pub fn query_resolve_path(&self, app: &mut App, path: String) -> String { + pub fn query_resolve_path(&self, app: &mut MockApp, path: String) -> Addr { let msg = mock_resolve_path_query(path); - let res: String = self.query(app, msg); + let res: Addr = self.query(app, msg); res } diff --git a/andromeda-core/packages/std/Cargo.toml b/andromeda-core/packages/std/Cargo.toml index 700de56..192914f 100644 --- a/andromeda-core/packages/std/Cargo.toml +++ b/andromeda-core/packages/std/Cargo.toml @@ -1,38 +1,41 @@ [package] name = "andromeda-std" -version = "0.1.0" +version = "1.2.3" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" description = "The standard library for creating an Andromeda Digital Object" license = "MIT" [features] -withdraw = ["andromeda-macros/withdraw"] primitive = [] -modules = ["andromeda-macros/modules"] -module_hooks = ["andromeda-macros/module_hooks"] instantiate = [] +rates = ["andromeda-macros/rates"] [lib] crate-type = ["cdylib", "rlib"] [dependencies] -cosmwasm-std = { workspace=true, features = ["ibc3"] } +cosmwasm-std = { workspace = true, features = ["ibc3", "cosmwasm_1_2"] } cosmwasm-schema = { workspace = true } cw-storage-plus = { workspace = true } schemars = "0.8.10" serde = { version = "1.0.127", default-features = false, features = ["derive"] } semver = { workspace = true } -cw20 = { version = "1.0.1"} +cw20 = { version = "1.0.1" } cw20-base = { workspace = true, features = ["library"] } cw721-base = { workspace = true } cw-utils = { workspace = true } +cw2 = { workspace = true } cw-asset = { version = "3.0.0" } thiserror = { version = "1.0.21" } lazy_static = "1" hex = "0.4" -regex = { version = "1.9.1", default-features = false} +regex = { version = "1.9.1", default-features = false } andromeda-macros = { workspace = true } strum_macros = { workspace = true } cw721 = { workspace = true } serde-json-wasm = "0.5.0" +enum-repr = { workspace = true } + +[dev-dependencies] +cw-multi-test = { version = "1.0.0" } diff --git a/andromeda-core/packages/std/README.md b/andromeda-core/packages/std/README.md new file mode 100644 index 0000000..24c25fc --- /dev/null +++ b/andromeda-core/packages/std/README.md @@ -0,0 +1,29 @@ +# Andromeda STD + +This crate defines how a smart contract can be integrated in to the aOS and also provides several methods to aid in doing so. + +## Usage + +### ADO Base + +This module contains all the message and struct definitions used by the base aOS contracts and ADOs. The primary struct provided by this module are the `AndromedaMsg`, `AndromedaQuery`and `InstantiateMsg` structs. + +There are also several response structs to the provided queries available through this crate. + +### ADO Contract + +This module contains the base logic of an ADO, primarily provided via the `ADOContract` struct. + +### AMP + +This module contains packet and message structs used to define how the Andromeda Message Protocol can be utilised, there are three primary structs: + +Using these a contract can easily make use of the Andromeda Messaging protocol. + +### Common + +Contains several utility methods and structs to help with consistency across our ADOs. + +### OS + +This module contains the message definitions and a few utility methods for the core of the aOS. \ No newline at end of file diff --git a/andromeda-core/packages/std/macros/Cargo.toml b/andromeda-core/packages/std/macros/Cargo.toml index 5711aa4..78b431d 100644 --- a/andromeda-core/packages/std/macros/Cargo.toml +++ b/andromeda-core/packages/std/macros/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "andromeda-macros" -version = "0.1.0" +version = "1.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" description = "Macros for Andromeda Digital Objects" license = "MIT" @@ -10,12 +10,10 @@ license = "MIT" proc-macro = true [features] -modules = [] withdraw = [] -module_hooks = [] +rates = [] [dependencies] -syn = { version = "1.0.0", features = ["derive"]} +syn = { version = "1.0.0", features = ["derive"] } proc-macro2 = "1.0" -quote="1.0" - +quote = "1.0" diff --git a/andromeda-core/packages/std/macros/src/lib.rs b/andromeda-core/packages/std/macros/src/lib.rs index 9e413bf..73455e9 100644 --- a/andromeda-core/packages/std/macros/src/lib.rs +++ b/andromeda-core/packages/std/macros/src/lib.rs @@ -44,67 +44,26 @@ pub fn andr_exec(_args: TokenStream, input: TokenStream) -> TokenStream { enum Right { #[serde(rename="amp_receive")] AMPReceive(::andromeda_std::amp::messages::AMPPkt), - UpdateOwner { - address: String, - }, - UpdateOperators { - operators: Vec, + Ownership(::andromeda_std::ado_base::ownership::OwnershipMessage), + UpdateKernelAddress { + address: ::cosmwasm_std::Addr, }, UpdateAppContract { address: String, }, - SetPermission { - actor: ::andromeda_std::amp::AndrAddr, - action: String, - permission: ::andromeda_std::ado_base::permissioning::Permission, - }, - RemovePermission { - action: String, - actor: ::andromeda_std::amp::AndrAddr, - }, - PermissionAction { - action: String - }, + Permissioning(::andromeda_std::ado_base::permissioning::PermissioningMessage), } } .into(), ); - #[cfg(feature = "modules")] - { - merged = merge_variants( - merged, - quote! { - enum Right { - RegisterModule { - module: ::andromeda_std::ado_base::Module, - }, - DeregisterModule { - module_idx: ::cosmwasm_std::Uint64, - }, - AlterModule { - module_idx: ::cosmwasm_std::Uint64, - module: ::andromeda_std::ado_base::Module, - }, - } - } - .into(), - ) - } - #[cfg(feature = "withdraw")] + #[cfg(feature = "rates")] { merged = merge_variants( merged, quote! { enum Right { - Deposit { - recipient: Option<::andromeda_std::amp::AndrAddr>, - msg: Option<::cosmwasm_std::Binary>, - }, - Withdraw { - recipient: Option<::andromeda_std::amp::Recipient>, - tokens_to_withdraw: Option>, - }, + Rates(::andromeda_std::ado_base::rates::RatesMessage) } } .into(), @@ -133,7 +92,6 @@ fn andr_exec_derive(input: DeriveInput) -> DeriveInput { /// Includes: /// 1. Kernel Address for interacting with aOS /// 2. Owner of the ADO (optional, assumed to be sender otherwise) -/// 3. Modules (optional, requires `modules` feature) #[proc_macro_attribute] pub fn andr_instantiate(_args: TokenStream, input: TokenStream) -> TokenStream { let mut ast = parse_macro_input!(input as DeriveInput); @@ -161,29 +119,6 @@ pub fn andr_instantiate(_args: TokenStream, input: TokenStream) -> TokenStream { } } -#[proc_macro_attribute] -pub fn andr_instantiate_modules(_args: TokenStream, input: TokenStream) -> TokenStream { - let mut ast = parse_macro_input!(input as DeriveInput); - match &mut ast.data { - syn::Data::Struct(ref mut struct_data) => { - if let syn::Fields::Named(fields) = &mut struct_data.fields { - fields.named.push( - syn::Field::parse_named - .parse2( - quote! { pub modules: Option> }, - ) - .unwrap(), - ); - } - quote! { - #ast - } - .into() - } - _ => panic!("Macro only works with structs"), - } -} - #[proc_macro_attribute] /// Attaches all relevant ADO messages to a set of Query messages for a given contract. /// @@ -196,24 +131,22 @@ pub fn andr_query(_metadata: TokenStream, input: TokenStream) -> TokenStream { enum Right { #[returns(andromeda_std::ado_base::ownership::ContractOwnerResponse)] Owner {}, - #[returns(andromeda_std::ado_base::operators::OperatorsResponse)] - Operators {}, + #[returns(andromeda_std::ado_base::ownership::ContractPotentialOwnerResponse)] + OwnershipRequest {}, #[returns(andromeda_std::ado_base::ado_type::TypeResponse)] Type {}, #[returns(andromeda_std::ado_base::kernel_address::KernelAddressResponse)] KernelAddress {}, + #[returns(andromeda_std::ado_base::app_contract::AppContractResponse)] + AppContract {}, #[returns(andromeda_std::ado_base::ownership::PublisherResponse)] OriginalPublisher {}, #[returns(andromeda_std::ado_base::block_height::BlockHeightResponse)] BlockHeightUponCreation {}, - #[returns(andromeda_std::ado_base::operators::IsOperatorResponse)] - IsOperator { address: String }, #[returns(andromeda_std::ado_base::version::VersionResponse)] Version {}, - #[returns(::cosmwasm_std::BalanceResponse)] - Balance { - address: ::andromeda_std::amp::AndrAddr, - }, + #[returns(andromeda_std::ado_base::version::ADOBaseVersionResponse)] + ADOBaseVersion {}, #[returns(Vec<::andromeda_std::ado_base::permissioning::PermissionInfo>)] Permissions { actor: String, limit: Option, start_after: Option }, #[returns(Vec)] @@ -222,35 +155,20 @@ pub fn andr_query(_metadata: TokenStream, input: TokenStream) -> TokenStream { } .into(), ); - - #[cfg(feature = "modules")] + #[cfg(feature = "rates")] { merged = merge_variants( merged, quote! { enum Right { - #[returns(andromeda_std::ado_base::Module)] - Module { id: ::cosmwasm_std::Uint64 }, - #[returns(Vec)] - ModuleIds {}, + #[returns(Option<::andromeda_std::ado_base::rates::Rate>)] + Rates {action: String}, + #[returns(::andromeda_std::ado_base::rates::AllRatesResponse)] + AllRates {} } } .into(), - ); - } - #[cfg(feature = "module_hooks")] - { - merged = merge_variants( - merged, - quote! { - enum Right { - #[returns(::cosmwasm_std::Binary)] - AndrHook(::andromeda_std::ado_base::hooks::AndromedaHook), - } - } - .into(), - ); + ) } - merged } diff --git a/andromeda-core/packages/std/src/ado_base/app_contract.rs b/andromeda-core/packages/std/src/ado_base/app_contract.rs new file mode 100644 index 0000000..25053dd --- /dev/null +++ b/andromeda-core/packages/std/src/ado_base/app_contract.rs @@ -0,0 +1,7 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::Addr; + +#[cw_serde] +pub struct AppContractResponse { + pub app_contract: Addr, +} diff --git a/andromeda-core/packages/std/src/ado_base/hooks.rs b/andromeda-core/packages/std/src/ado_base/hooks.rs deleted file mode 100644 index 2d742a6..0000000 --- a/andromeda-core/packages/std/src/ado_base/hooks.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::common::Funds; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{Binary, Coin, Event, SubMsg}; - -#[cw_serde] -pub enum AndromedaHook { - OnExecute { - sender: String, - payload: Binary, - }, - OnFundsTransfer { - sender: String, - payload: Binary, - amount: Funds, - }, - OnTokenTransfer { - token_id: String, - sender: String, - recipient: String, - }, -} - -#[cw_serde] -pub struct OnFundsTransferResponse { - pub msgs: Vec, - pub events: Vec, - pub leftover_funds: Funds, -} - -impl Default for OnFundsTransferResponse { - fn default() -> Self { - Self { - msgs: Vec::new(), - events: Vec::new(), - leftover_funds: Funds::Native(Coin::default()), - } - } -} - -/// Helper enum for serialization -#[cw_serde] -pub enum HookMsg { - AndrHook(AndromedaHook), -} diff --git a/andromeda-core/packages/std/src/ado_base/mod.rs b/andromeda-core/packages/std/src/ado_base/mod.rs index 787c3cd..27c5e83 100644 --- a/andromeda-core/packages/std/src/ado_base/mod.rs +++ b/andromeda-core/packages/std/src/ado_base/mod.rs @@ -1,86 +1,48 @@ pub mod ado_type; +pub mod app_contract; pub mod block_height; -#[cfg(any(feature = "module_hooks", feature = "modules"))] -pub mod hooks; pub mod kernel_address; pub mod modules; -pub mod operators; pub mod ownership; pub mod permissioning; +#[cfg(feature = "rates")] +pub mod rates; pub mod version; pub mod withdraw; -#[cfg(feature = "withdraw")] -use crate::ado_base::withdraw::Withdrawal; -#[cfg(feature = "withdraw")] -use crate::amp::recipient::Recipient; -use crate::{ - ado_base::permissioning::Permission, - amp::{messages::AMPPkt, AndrAddr}, -}; +use crate::amp::{messages::AMPPkt, AndrAddr}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::Binary; -pub use modules::Module; +use cosmwasm_std::Addr; -#[cfg(feature = "modules")] -use cosmwasm_std::Uint64; +use self::ownership::OwnershipMessage; +use self::permissioning::PermissioningMessage; #[cw_serde] pub struct InstantiateMsg { pub ado_type: String, pub ado_version: String, - pub operators: Option>, pub kernel_address: String, pub owner: Option, } +#[cw_serde] +#[serde(rename_all = "snake_case")] +pub struct MigrateMsg {} + #[cw_serde] pub enum AndromedaMsg { - UpdateOwner { - address: String, - }, - UpdateOperators { - operators: Vec, - }, + Ownership(OwnershipMessage), UpdateAppContract { address: String, }, - #[cfg(feature = "withdraw")] - Withdraw { - recipient: Option, - tokens_to_withdraw: Option>, - }, - #[cfg(feature = "modules")] - RegisterModule { - module: Module, - }, - #[cfg(feature = "modules")] - DeregisterModule { - module_idx: Uint64, - }, - #[cfg(feature = "modules")] - AlterModule { - module_idx: Uint64, - module: Module, - }, - Deposit { - recipient: Option, - msg: Option, + UpdateKernelAddress { + address: Addr, }, + #[cfg(feature = "rates")] + Rates(self::rates::RatesMessage), #[serde(rename = "amp_receive")] AMPReceive(AMPPkt), - SetPermission { - actor: AndrAddr, - action: String, - permission: Permission, - }, - RemovePermission { - action: String, - actor: AndrAddr, - }, - PermissionAction { - action: String, - }, + Permissioning(PermissioningMessage), } #[cw_serde] @@ -88,8 +50,8 @@ pub enum AndromedaMsg { pub enum AndromedaQuery { #[returns(self::ownership::ContractOwnerResponse)] Owner {}, - #[returns(self::operators::OperatorsResponse)] - Operators {}, + #[returns(self::ownership::ContractPotentialOwnerResponse)] + OwnershipRequest {}, #[returns(self::ado_type::TypeResponse)] Type {}, #[returns(self::kernel_address::KernelAddressResponse)] @@ -98,27 +60,26 @@ pub enum AndromedaQuery { OriginalPublisher {}, #[returns(self::block_height::BlockHeightResponse)] BlockHeightUponCreation {}, - #[returns(self::operators::IsOperatorResponse)] - IsOperator { address: String }, #[returns(self::version::VersionResponse)] Version {}, - #[returns(Option<::cosmwasm_std::Addr>)] + #[returns(self::version::ADOBaseVersionResponse)] + ADOBaseVersion {}, + #[returns(self::app_contract::AppContractResponse)] AppContract {}, - #[cfg(feature = "modules")] - #[returns(Module)] - Module { id: Uint64 }, - #[cfg(feature = "modules")] - #[returns(Vec)] - ModuleIds {}, - #[cfg(feature = "withdraw")] - #[returns(::cosmwasm_std::BalanceResponse)] - Balance { address: AndrAddr }, #[returns(Vec)] Permissions { actor: AndrAddr, limit: Option, start_after: Option, }, - #[returns(Vec)] + #[returns(Vec)] PermissionedActions {}, + + #[cfg(feature = "rates")] + #[returns(Option)] + Rates { action: String }, + + #[cfg(feature = "rates")] + #[returns(self::rates::AllRatesResponse)] + AllRates {}, } diff --git a/andromeda-core/packages/std/src/ado_base/modules.rs b/andromeda-core/packages/std/src/ado_base/modules.rs index 026b784..9329c58 100644 --- a/andromeda-core/packages/std/src/ado_base/modules.rs +++ b/andromeda-core/packages/std/src/ado_base/modules.rs @@ -1,9 +1,9 @@ use crate::amp::addresses::AndrAddr; -#[cfg(feature = "modules")] + use crate::error::ContractError; use cosmwasm_schema::cw_serde; -#[cfg(feature = "modules")] + use cosmwasm_std::ensure; /// A struct describing a token module, provided with the instantiation message this struct is used to record the info about the module and how/if it should be instantiated @@ -14,7 +14,6 @@ pub struct Module { pub is_mutable: bool, } -#[cfg(feature = "modules")] impl Module { pub fn new(name: impl Into, address: impl Into, is_mutable: bool) -> Module { Module { @@ -52,11 +51,11 @@ impl Module { #[cfg(test)] mod tests { - #[cfg(feature = "modules")] + use super::*; #[test] - #[cfg(feature = "modules")] + fn test_validate_uniqueness() { let module1 = Module::new("module", "addr1", false); let module2 = Module::new("module", "addr2", false); diff --git a/andromeda-core/packages/std/src/ado_base/operators.rs b/andromeda-core/packages/std/src/ado_base/operators.rs deleted file mode 100644 index e480725..0000000 --- a/andromeda-core/packages/std/src/ado_base/operators.rs +++ /dev/null @@ -1,11 +0,0 @@ -use cosmwasm_schema::cw_serde; - -#[cw_serde] -pub struct IsOperatorResponse { - pub is_operator: bool, -} - -#[cw_serde] -pub struct OperatorsResponse { - pub operators: Vec, -} diff --git a/andromeda-core/packages/std/src/ado_base/ownership.rs b/andromeda-core/packages/std/src/ado_base/ownership.rs index 1664017..311a6e0 100644 --- a/andromeda-core/packages/std/src/ado_base/ownership.rs +++ b/andromeda-core/packages/std/src/ado_base/ownership.rs @@ -1,11 +1,31 @@ use cosmwasm_schema::cw_serde; +use cosmwasm_std::Addr; + +use crate::common::{expiration::Expiry, MillisecondsExpiration}; #[cw_serde] pub struct ContractOwnerResponse { pub owner: String, } +#[cw_serde] +pub struct ContractPotentialOwnerResponse { + pub potential_owner: Option, + pub expiration: Option, +} + #[cw_serde] pub struct PublisherResponse { pub original_publisher: String, } + +#[cw_serde] +pub enum OwnershipMessage { + UpdateOwner { + new_owner: Addr, + expiration: Option, + }, + RevokeOwnershipOffer, + AcceptOwnership, + Disown, +} diff --git a/andromeda-core/packages/std/src/ado_base/permissioning.rs b/andromeda-core/packages/std/src/ado_base/permissioning.rs index 4650a72..49142ee 100644 --- a/andromeda-core/packages/std/src/ado_base/permissioning.rs +++ b/andromeda-core/packages/std/src/ado_base/permissioning.rs @@ -2,7 +2,31 @@ use core::fmt; use cosmwasm_schema::cw_serde; use cosmwasm_std::Env; -use cw_utils::Expiration; + +use crate::{ + amp::AndrAddr, + common::{expiration::Expiry, MillisecondsExpiration}, + error::ContractError, +}; + +#[cw_serde] +pub enum PermissioningMessage { + SetPermission { + actors: Vec, + action: String, + permission: Permission, + }, + RemovePermission { + action: String, + actors: Vec, + }, + PermissionAction { + action: String, + }, + DisableActionPermissioning { + action: String, + }, +} #[cw_serde] pub struct PermissionInfo { @@ -11,6 +35,11 @@ pub struct PermissionInfo { pub actor: String, } +#[cw_serde] +pub struct PermissionedActionsResponse { + pub actions: Vec, +} + /// An enum to represent a user's permission for an action /// /// - **Blacklisted** - The user cannot perform the action until after the provided expiration @@ -19,31 +48,31 @@ pub struct PermissionInfo { /// /// Expiration defaults to `Never` if not provided #[cw_serde] -pub enum Permission { - Blacklisted(Option), +pub enum LocalPermission { + Blacklisted(Option), Limited { - expiration: Option, + expiration: Option, uses: u32, }, - Whitelisted(Option), + Whitelisted(Option), } -impl std::default::Default for Permission { +impl std::default::Default for LocalPermission { fn default() -> Self { Self::Whitelisted(None) } } -impl Permission { - pub fn blacklisted(expiration: Option) -> Self { +impl LocalPermission { + pub fn blacklisted(expiration: Option) -> Self { Self::Blacklisted(expiration) } - pub fn whitelisted(expiration: Option) -> Self { + pub fn whitelisted(expiration: Option) -> Self { Self::Whitelisted(expiration) } - pub fn limited(expiration: Option, uses: u32) -> Self { + pub fn limited(expiration: Option, uses: u32) -> Self { Self::Limited { expiration, uses } } @@ -51,15 +80,15 @@ impl Permission { match self { Self::Blacklisted(expiration) => { if let Some(expiration) = expiration { - if expiration.is_expired(&env.block) { - return true; + if expiration.get_time(&env.block).is_expired(&env.block) { + return !strict; } } false } Self::Limited { expiration, uses } => { if let Some(expiration) = expiration { - if expiration.is_expired(&env.block) { + if expiration.get_time(&env.block).is_expired(&env.block) { return !strict; } } @@ -70,7 +99,7 @@ impl Permission { } Self::Whitelisted(expiration) => { if let Some(expiration) = expiration { - if expiration.is_expired(&env.block) { + if expiration.get_time(&env.block).is_expired(&env.block) { return !strict; } } @@ -79,22 +108,30 @@ impl Permission { } } - pub fn get_expiration(&self) -> Expiration { + pub fn get_expiration(&self, env: Env) -> MillisecondsExpiration { match self { - Self::Blacklisted(expiration) => expiration.unwrap_or_default(), - Self::Limited { expiration, .. } => expiration.unwrap_or_default(), - Self::Whitelisted(expiration) => expiration.unwrap_or_default(), + Self::Blacklisted(expiration) => { + expiration.clone().unwrap_or_default().get_time(&env.block) + } + Self::Limited { expiration, .. } => { + expiration.clone().unwrap_or_default().get_time(&env.block) + } + Self::Whitelisted(expiration) => { + expiration.clone().unwrap_or_default().get_time(&env.block) + } } } - pub fn consume_use(&mut self) { + pub fn consume_use(&mut self) -> Result<(), ContractError> { if let Self::Limited { uses, .. } = self { - *uses -= 1 + *uses = uses.saturating_sub(1); } + + Ok(()) } } -impl fmt::Display for Permission { +impl fmt::Display for LocalPermission { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let self_as_string = match self { Self::Blacklisted(expiration) => { @@ -122,3 +159,19 @@ impl fmt::Display for Permission { write!(f, "{self_as_string}") } } + +#[cw_serde] +pub enum Permission { + Local(LocalPermission), + Contract(AndrAddr), +} + +impl fmt::Display for Permission { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let self_as_string = match self { + Self::Local(local_permission) => local_permission.to_string(), + Self::Contract(address_list) => address_list.to_string(), + }; + write!(f, "{self_as_string}") + } +} diff --git a/andromeda-core/packages/std/src/ado_base/rates.rs b/andromeda-core/packages/std/src/ado_base/rates.rs new file mode 100644 index 0000000..b957242 --- /dev/null +++ b/andromeda-core/packages/std/src/ado_base/rates.rs @@ -0,0 +1,252 @@ +use crate::{ + ado_contract::ADOContract, + amp::{AndrAddr, Recipient}, + common::{deduct_funds, Funds}, + error::ContractError, + os::{adodb::ADOVersion, aos_querier::AOSQuerier}, +}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ensure, has_coins, Coin, Decimal, Deps, Event, Fraction, SubMsg}; +use cw20::Cw20Coin; + +#[cw_serde] +pub struct RatesResponse { + pub msgs: Vec, + pub events: Vec, + pub leftover_funds: Funds, +} + +impl Default for RatesResponse { + fn default() -> Self { + Self { + msgs: Vec::new(), + events: Vec::new(), + leftover_funds: Funds::Native(Coin::default()), + } + } +} + +#[cw_serde] +pub enum RatesMessage { + SetRate { action: String, rate: Rate }, + RemoveRate { action: String }, +} + +#[cw_serde] +pub enum RatesQueryMessage { + GetRate { action: String }, +} + +/// An attribute struct used for any events that involve a payment +pub struct PaymentAttribute { + /// The amount paid + pub amount: Coin, + /// The address the payment was made to + pub receiver: String, +} + +impl ToString for PaymentAttribute { + fn to_string(&self) -> String { + format!("{}<{}", self.receiver, self.amount) + } +} + +#[cw_serde] +pub enum LocalRateType { + Additive, + Deductive, +} +impl LocalRateType { + pub fn is_additive(&self) -> bool { + self == &LocalRateType::Additive + } + pub fn create_event(&self) -> Event { + if self.is_additive() { + Event::new("tax") + } else { + Event::new("royalty") + } + } +} + +#[cw_serde] +pub enum LocalRateValue { + // Percent fee + Percent(PercentRate), + // Flat fee + Flat(Coin), +} +impl LocalRateValue { + pub fn validate(&self) -> Result<(), ContractError> { + match self { + // If it's a coin, make sure it's non-zero + LocalRateValue::Flat(coin) => { + ensure!(!coin.amount.is_zero(), ContractError::InvalidRate {}); + } + // If it's a percentage, make sure it's greater than zero and less than or equal to 1 of type decimal (which represents 100%) + LocalRateValue::Percent(percent_rate) => { + ensure!( + !percent_rate.percent.is_zero() && percent_rate.percent <= Decimal::one(), + ContractError::InvalidRate {} + ); + } + } + Ok(()) + } + pub fn is_flat(&self) -> bool { + match self { + LocalRateValue::Percent(_) => false, + LocalRateValue::Flat(_) => true, + } + } +} + +#[cw_serde] +pub struct LocalRate { + pub rate_type: LocalRateType, + pub recipients: Vec, + pub value: LocalRateValue, + pub description: Option, +} +// Created this because of the very complex return value warning. +type LocalRateResponse = (Vec, Vec, Vec); + +impl LocalRate { + pub fn generate_response( + &self, + deps: Deps, + coin: Coin, + is_native: bool, + ) -> Result { + let mut msgs: Vec = vec![]; + let mut events: Vec = vec![]; + let mut leftover_funds = vec![coin.clone()]; + // Tax event if the rate type is additive, or Royalty event if the rate type is deductive. + let mut event = self.rate_type.create_event(); + + if let Some(desc) = &self.description { + event = event.add_attribute("description", desc); + } + let fee = calculate_fee(self.value.clone(), &coin)?; + for receiver in self.recipients.iter() { + // If the rate type is deductive + if !self.rate_type.is_additive() { + deduct_funds(&mut leftover_funds, &fee)?; + event = event.add_attribute("deducted", fee.to_string()); + } + event = event.add_attribute( + "payment", + PaymentAttribute { + receiver: receiver.get_addr(), + amount: fee.clone(), + } + .to_string(), + ); + let msg = if is_native { + receiver.generate_direct_msg(&deps, vec![fee.clone()])? + } else { + receiver.generate_msg_cw20( + &deps, + Cw20Coin { + amount: fee.amount, + address: fee.denom.to_string(), + }, + )? + }; + msgs.push(msg); + } + events.push(event); + Ok((msgs, events, leftover_funds)) + } +} + +#[cw_serde] +pub enum Rate { + Local(LocalRate), + Contract(AndrAddr), +} + +impl Rate { + // Makes sure that the contract address is that of a Rates contract verified by the ADODB and validates the local rate value + pub fn validate_rate(&self, deps: Deps) -> Result<(), ContractError> { + match self { + Rate::Contract(address) => { + let raw_address = address.get_raw_address(&deps)?; + let contract_info = deps.querier.query_wasm_contract_info(raw_address)?; + let adodb_addr = + ADOContract::default().get_adodb_address(deps.storage, &deps.querier)?; + let ado_type = AOSQuerier::ado_type_getter_smart( + &deps.querier, + &adodb_addr, + contract_info.code_id, + )?; + match ado_type { + Some(ado_type) => { + let ado_type = ADOVersion::from_string(ado_type).get_type(); + ensure!(ado_type == "rates", ContractError::InvalidAddress {}); + Ok(()) + } + None => Err(ContractError::InvalidAddress {}), + } + } + Rate::Local(local_rate) => { + // Validate the local rate value + local_rate.value.validate()?; + Ok(()) + } + } + } + pub fn is_local(&self) -> bool { + match self { + Rate::Contract(_) => false, + Rate::Local(_) => true, + } + } +} +// This is added such that both Rate::Flat and Rate::Percent have the same level of nesting which makes it easier to work with on the frontend. +#[cw_serde] +pub struct PercentRate { + pub percent: Decimal, +} + +/// Calculates a fee amount given a `Rate` and payment amount. +/// +/// ## Arguments +/// * `fee_rate` - The `Rate` of the fee to be paid +/// * `payment` - The amount used to calculate the fee +/// +/// Returns the fee amount in a `Coin` struct. +pub fn calculate_fee(fee_rate: LocalRateValue, payment: &Coin) -> Result { + match fee_rate { + LocalRateValue::Flat(rate) => { + ensure!( + has_coins(&[payment.clone()], &rate), + ContractError::InsufficientFunds {} + ); + Ok(Coin::new(rate.amount.u128(), rate.denom)) + } + LocalRateValue::Percent(percent_rate) => { + // [COM-03] Make sure that fee_rate between 0 and 100. + ensure!( + // No need for rate >=0 due to type limits (Question: Should add or remove?) + percent_rate.percent <= Decimal::one() && !percent_rate.percent.is_zero(), + ContractError::InvalidRate {} + ); + let mut fee_amount = payment.amount * percent_rate.percent; + + // Always round any remainder up and prioritise the fee receiver. + // Inverse of percent will always exist. + let reversed_fee = fee_amount * percent_rate.percent.inv().unwrap(); + if payment.amount > reversed_fee { + // [COM-1] Added checked add to fee_amount rather than direct increment + fee_amount = fee_amount.checked_add(1u128.into())?; + } + Ok(Coin::new(fee_amount.u128(), payment.denom.clone())) + } // Rate::External(_) => Err(ContractError::UnexpectedExternalRate {}), + } +} + +#[cw_serde] +pub struct AllRatesResponse { + pub all_rates: Vec<(String, Rate)>, +} diff --git a/andromeda-core/packages/std/src/ado_base/version.rs b/andromeda-core/packages/std/src/ado_base/version.rs index 310da62..46a2121 100644 --- a/andromeda-core/packages/std/src/ado_base/version.rs +++ b/andromeda-core/packages/std/src/ado_base/version.rs @@ -4,3 +4,9 @@ use cosmwasm_schema::cw_serde; pub struct VersionResponse { pub version: String, } + +#[cw_serde] +pub struct ADOBaseVersionResponse { + // andromeda-std version in semver format + pub version: String, +} diff --git a/andromeda-core/packages/std/src/ado_contract/app.rs b/andromeda-core/packages/std/src/ado_contract/app.rs index 8678707..de24377 100644 --- a/andromeda-core/packages/std/src/ado_contract/app.rs +++ b/andromeda-core/packages/std/src/ado_contract/app.rs @@ -31,6 +31,13 @@ impl<'a> ADOContract<'a> { self.app_contract .save(deps.storage, &deps.api.addr_validate(&address)?)?; self.validate_andr_addresses(&deps.as_ref(), addresses.unwrap_or_default())?; + #[cfg(feature = "modules")] + { + let modules = self.load_modules(deps.storage)?; + for module in modules { + self.validate_module_address(&deps.as_ref(), &module)?; + } + } Ok(Response::new() .add_attribute("action", "update_app_contract") .add_attribute("address", address)) diff --git a/andromeda-core/packages/std/src/ado_contract/execute.rs b/andromeda-core/packages/std/src/ado_contract/execute.rs index 9a53640..3972365 100644 --- a/andromeda-core/packages/std/src/ado_contract/execute.rs +++ b/andromeda-core/packages/std/src/ado_contract/execute.rs @@ -2,19 +2,23 @@ use crate::ado_contract::ADOContract; use crate::amp::addresses::AndrAddr; use crate::amp::messages::AMPPkt; use crate::common::context::ExecuteContext; +use crate::common::reply::ReplyId; +use crate::error::from_semver; use crate::os::{aos_querier::AOSQuerier, economics::ExecuteMsg as EconomicsExecuteMsg}; use crate::{ ado_base::{AndromedaMsg, InstantiateMsg}, error::ContractError, }; use cosmwasm_std::{ - attr, from_json, to_json_binary, Addr, Api, CosmosMsg, Deps, DepsMut, Env, MessageInfo, - QuerierWrapper, Response, Storage, SubMsg, WasmMsg, + attr, ensure, from_json, to_json_binary, Addr, Api, ContractInfoResponse, CosmosMsg, Deps, + DepsMut, Env, MessageInfo, QuerierWrapper, Response, StdError, Storage, SubMsg, WasmMsg, }; +use cw2::{get_contract_version, set_contract_version}; +use semver::Version; use serde::de::DeserializeOwned; use serde::Serialize; -type ExecuteContextFunction = fn(ExecuteContext, E) -> Result; +type ExecuteContextFunction = fn(ExecuteContext, M) -> Result; impl<'a> ADOContract<'a> { pub fn instantiate( @@ -22,20 +26,61 @@ impl<'a> ADOContract<'a> { storage: &mut dyn Storage, env: Env, api: &dyn Api, + querier: &QuerierWrapper, info: MessageInfo, msg: InstantiateMsg, ) -> Result { - self.owner.save( - storage, - &api.addr_validate(&msg.owner.unwrap_or(info.sender.to_string()))?, - )?; + let ado_type = if msg.ado_type.starts_with("crates.io:andromeda-") { + msg.ado_type.strip_prefix("crates.io:andromeda-").unwrap() + } else if msg.ado_type.starts_with("crates.io:") { + msg.ado_type.strip_prefix("crates.io:").unwrap() + } else { + &msg.ado_type + }; + cw2::set_contract_version(storage, ado_type, msg.ado_version)?; + let mut owner = api.addr_validate(&msg.owner.unwrap_or(info.sender.to_string()))?; self.original_publisher.save(storage, &info.sender)?; self.block_height.save(storage, &env.block.height)?; - self.ado_type.save(storage, &msg.ado_type)?; - self.version.save(storage, &msg.ado_version)?; + self.ado_type.save(storage, &ado_type.to_string())?; self.kernel_address .save(storage, &api.addr_validate(&msg.kernel_address)?)?; - let attributes = [attr("method", "instantiate"), attr("type", &msg.ado_type)]; + let mut attributes = vec![ + attr("method", "instantiate"), + attr("type", ado_type), + attr("kernel_address", msg.kernel_address), + ]; + + // We do not want to store app contracts for the kernel, exit early if current contract is kernel + let is_kernel_contract = ado_type.contains("kernel"); + if is_kernel_contract { + self.owner.save(storage, &owner)?; + attributes.push(attr("owner", owner)); + return Ok(Response::new().add_attributes(attributes)); + } + + // Check if the sender is an app contract to allow for automatic storage of app contrcat reference + let maybe_contract_info = querier.query_wasm_contract_info(info.sender.clone()); + let is_sender_contract = maybe_contract_info.is_ok(); + if is_sender_contract { + let ContractInfoResponse { code_id, .. } = maybe_contract_info?; + let sender_ado_type = AOSQuerier::ado_type_getter( + querier, + &self.get_adodb_address(storage, querier)?, + code_id, + )?; + let is_sender_app = Some("app-contract".to_string()) == sender_ado_type; + // Automatically save app contract reference if creator is an app contract + if is_sender_app { + self.app_contract + .save(storage, &Addr::unchecked(info.sender.to_string()))?; + let app_owner = AOSQuerier::ado_owner_getter(querier, &info.sender)?; + owner = app_owner; + attributes.push(attr("app_contract", info.sender.to_string())); + } + } + + self.owner.save(storage, &owner)?; + attributes.push(attr("owner", owner)); Ok(Response::new().add_attributes(attributes)) } @@ -48,57 +93,61 @@ impl<'a> ADOContract<'a> { let msg = to_json_binary(&msg)?; match from_json::(&msg) { Ok(msg) => match msg { - AndromedaMsg::UpdateOwner { address } => { - self.execute_update_owner(ctx.deps, ctx.info, address) - } - AndromedaMsg::UpdateOperators { operators } => { - self.execute_update_operators(ctx.deps, ctx.info, operators) + AndromedaMsg::Ownership(msg) => { + self.execute_ownership(ctx.deps, ctx.env, ctx.info, msg) } AndromedaMsg::UpdateAppContract { address } => { self.execute_update_app_contract(ctx.deps, ctx.info, address, None) } - #[cfg(feature = "withdraw")] - AndromedaMsg::Withdraw { - recipient, - tokens_to_withdraw, - } => self.execute_withdraw(ctx, recipient, tokens_to_withdraw), - #[cfg(feature = "modules")] - AndromedaMsg::RegisterModule { module } => { - self.validate_module_address(&ctx.deps.as_ref(), &module)?; - self.execute_register_module( - ctx.deps.storage, - ctx.info.sender.as_str(), - module, - true, - ) - } - #[cfg(feature = "modules")] - AndromedaMsg::DeregisterModule { module_idx } => { - self.execute_deregister_module(ctx.deps, ctx.info, module_idx) - } - #[cfg(feature = "modules")] - AndromedaMsg::AlterModule { module_idx, module } => { - self.validate_module_address(&ctx.deps.as_ref(), &module)?; - self.execute_alter_module(ctx.deps, ctx.info, module_idx, module) - } - AndromedaMsg::SetPermission { - actor, - action, - permission, - } => self.execute_set_permission(ctx, actor, action, permission), - AndromedaMsg::RemovePermission { action, actor } => { - self.execute_remove_permission(ctx, actor, action) - } - AndromedaMsg::PermissionAction { action } => { - self.execute_permission_action(ctx, action) + #[cfg(feature = "rates")] + AndromedaMsg::Rates(rates_message) => self.execute_rates(ctx, rates_message), + AndromedaMsg::UpdateKernelAddress { address } => { + self.update_kernel_address(ctx.deps, ctx.info, address) } + AndromedaMsg::Permissioning(msg) => self.execute_permissioning(ctx, msg), AndromedaMsg::AMPReceive(_) => panic!("AMP Receive should be handled separately"), - AndromedaMsg::Deposit { .. } => Err(ContractError::NotImplemented { msg: None }), }, _ => Err(ContractError::NotImplemented { msg: None }), } } + pub fn migrate( + &self, + deps: DepsMut, + contract_name: &str, + contract_version: &str, + ) -> Result { + // New version + let version: Version = contract_version.parse().map_err(from_semver)?; + + // Old version + let stored = get_contract_version(deps.storage)?; + let storage_version: Version = stored.version.parse().map_err(from_semver)?; + let contract_name = if contract_name.starts_with("crates.io:andromeda-") { + contract_name.strip_prefix("crates.io:andromeda-").unwrap() + } else if contract_name.starts_with("crates.io:") { + contract_name.strip_prefix("crates.io:").unwrap() + } else { + contract_name + }; + ensure!( + stored.contract == contract_name, + ContractError::CannotMigrate { + previous_contract: stored.contract, + } + ); + + // New version has to be newer/greater than the old version + ensure!( + storage_version < version, + ContractError::CannotMigrate { + previous_contract: stored.version, + } + ); + + set_contract_version(deps.storage, contract_name, contract_version)?; + Ok(Response::default()) + } /// Validates all provided `AndrAddr` addresses. /// /// Requires the VFS address to be set if any address is a VFS path. @@ -111,16 +160,6 @@ impl<'a> ADOContract<'a> { let vfs_address = self.get_vfs_address(deps.storage, &deps.querier); match vfs_address { Ok(vfs_address) => { - #[cfg(feature = "modules")] - { - let mut addresses = addresses.clone(); - let modules = self.load_modules(deps.storage)?; - if !modules.is_empty() { - let andr_addresses: Vec = - modules.into_iter().map(|m| m.address).collect(); - addresses.extend(andr_addresses); - } - } for address in addresses { self.validate_andr_address(deps, address, vfs_address.clone())?; } @@ -128,7 +167,7 @@ impl<'a> ADOContract<'a> { } Err(_) => { for address in addresses { - address.is_addr(deps.api); + ensure!(address.is_addr(deps.api), ContractError::InvalidAddress {}); } Ok(()) } @@ -142,7 +181,6 @@ impl<'a> ADOContract<'a> { address: AndrAddr, vfs_address: Addr, ) -> Result<(), ContractError> { - // Validate address string is valid address.validate(deps.api)?; if !address.is_addr(deps.api) { address.get_raw_address_from_vfs(deps, vfs_address)?; @@ -179,36 +217,30 @@ impl<'a> ADOContract<'a> { AOSQuerier::adodb_address_getter(querier, &kernel_address) } - #[inline] - /// Updates the current version of the contract. - pub fn execute_update_version(&self, deps: DepsMut) -> Result { - self.version - .save(deps.storage, &env!("CARGO_PKG_VERSION").to_string())?; - Ok(Response::new() - .add_attribute("action", "update_version") - .add_attribute("version", env!("CARGO_PKG_VERSION").to_string())) - } - /// Handles receiving and verifies an AMPPkt from the Kernel before executing the appropriate messages. /// /// Calls the provided handler with the AMP packet attached within the context. - pub fn execute_amp_receive( + pub fn execute_amp_receive( &self, ctx: ExecuteContext, mut packet: AMPPkt, - handler: ExecuteContextFunction, - ) -> Result { + handler: ExecuteContextFunction, + ) -> Result + where + E: From + From, + { packet.verify_origin(&ctx.info, &ctx.deps.as_ref())?; let ctx = ctx.with_ctx(packet.clone()); let msg_opt = packet.messages.pop(); if let Some(msg_opt) = msg_opt { - let msg: E = from_json(msg_opt.message)?; + let msg: M = from_json(msg_opt.message)?; let response = handler(ctx, msg)?; Ok(response) } else { Err(ContractError::InvalidPacket { error: Some("AMP Packet received with no messages".to_string()), - }) + } + .into()) } } @@ -238,107 +270,37 @@ impl<'a> ADOContract<'a> { msg: to_json_binary(&economics_msg)?, funds: vec![], }), - 9999, + ReplyId::PayFee.repr(), ); Ok(msg) } + + /// Updates the current kernel address used by the ADO + /// Requires the sender to be the owner of the ADO + pub fn update_kernel_address( + &self, + deps: DepsMut, + info: MessageInfo, + address: Addr, + ) -> Result { + ensure!( + self.is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + self.kernel_address.save(deps.storage, &address)?; + Ok(Response::new() + .add_attribute("action", "update_kernel_address") + .add_attribute("address", address)) + } } #[cfg(test)] -#[cfg(feature = "modules")] + mod tests { use super::*; - use crate::ado_base::modules::Module; - use crate::testing::mock_querier::{ - mock_dependencies_custom, MOCK_APP_CONTRACT, MOCK_KERNEL_CONTRACT, - }; - use cosmwasm_std::{ - testing::{mock_dependencies, mock_env, mock_info}, - Addr, Uint64, - }; - - #[test] - fn test_register_module_invalid_identifier() { - let contract = ADOContract::default(); - let mut deps = mock_dependencies_custom(&[]); - - let info = mock_info("owner", &[]); - let deps_mut = deps.as_mut(); - contract - .instantiate( - deps_mut.storage, - mock_env(), - deps_mut.api, - info.clone(), - InstantiateMsg { - ado_type: "type".to_string(), - operators: None, - ado_version: "version".to_string(), - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - owner: None, - }, - ) - .unwrap(); - - contract - .app_contract - .save(deps_mut.storage, &Addr::unchecked(MOCK_APP_CONTRACT)) - .unwrap(); - - let module = Module::new("module".to_owned(), "z".to_string(), false); - - let msg = AndromedaMsg::RegisterModule { module }; - - let res = contract.execute(ExecuteContext::new(deps.as_mut(), info, mock_env()), msg); - assert!(res.is_err()) - } - - #[test] - fn test_alter_module_invalid_identifier() { - let contract = ADOContract::default(); - let mut deps = mock_dependencies_custom(&[]); - - let info = mock_info("owner", &[]); - let deps_mut = deps.as_mut(); - contract - .instantiate( - deps_mut.storage, - mock_env(), - deps_mut.api, - info.clone(), - InstantiateMsg { - ado_type: "type".to_string(), - ado_version: "version".to_string(), - operators: None, - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - owner: None, - }, - ) - .unwrap(); - contract - .register_modules( - info.sender.as_str(), - deps_mut.storage, - Some(vec![Module::new("module", "cosmos1...".to_string(), false)]), - ) - .unwrap(); - - contract - .app_contract - .save(deps_mut.storage, &Addr::unchecked(MOCK_APP_CONTRACT)) - .unwrap(); - - let module = Module::new("/m".to_owned(), "z".to_string(), false); - - let msg = AndromedaMsg::AlterModule { - module_idx: Uint64::new(1), - module, - }; - - let res = contract.execute(ExecuteContext::new(deps.as_mut(), info, mock_env()), msg); - assert!(res.is_err()) - } + use crate::testing::mock_querier::MOCK_KERNEL_CONTRACT; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; #[test] fn test_update_app_contract() { @@ -352,11 +314,12 @@ mod tests { deps_mut.storage, mock_env(), deps_mut.api, + &deps_mut.querier, info.clone(), InstantiateMsg { ado_type: "type".to_string(), ado_version: "version".to_string(), - operators: None, + kernel_address: MOCK_KERNEL_CONTRACT.to_string(), owner: None, }, @@ -380,36 +343,4 @@ mod tests { res ); } - - #[test] - #[cfg(feature = "modules")] - fn test_update_app_contract_invalid_module() { - let contract = ADOContract::default(); - let mut deps = mock_dependencies_custom(&[]); - - let info = mock_info("owner", &[]); - let deps_mut = deps.as_mut(); - contract - .instantiate( - deps_mut.storage, - mock_env(), - deps_mut.api, - info.clone(), - InstantiateMsg { - ado_type: "type".to_string(), - ado_version: "version".to_string(), - owner: None, - operators: None, - kernel_address: MOCK_KERNEL_CONTRACT.to_string(), - }, - ) - .unwrap(); - contract - .register_modules( - info.sender.as_str(), - deps_mut.storage, - Some(vec![Module::new("module", "cosmos1...".to_string(), false)]), - ) - .unwrap(); - } } diff --git a/andromeda-core/packages/std/src/ado_contract/instantiate.rs b/andromeda-core/packages/std/src/ado_contract/instantiate.rs deleted file mode 100644 index bd2fadc..0000000 --- a/andromeda-core/packages/std/src/ado_contract/instantiate.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::ado_contract::ADOContract; -use crate::error::ContractError; -use crate::os::aos_querier::AOSQuerier; -use crate::os::kernel::QueryMsg as KernelQueryMsg; -use cosmwasm_std::{Addr, Binary, CosmosMsg, QuerierWrapper, ReplyOn, Storage, SubMsg, WasmMsg}; - -impl<'a> ADOContract<'a> { - pub fn generate_instantiate_msg( - &self, - storage: &mut dyn Storage, - querier: &QuerierWrapper, - msg_id: u64, - msg: Binary, - ado_type: String, - sender: String, - ) -> Result { - match self.get_code_id(storage, querier, &ado_type) { - Err(_) => Err(ContractError::InvalidModule { - msg: Some(String::from( - "ADO type provided does not have a valid Code Id", - )), - }), - Ok(code_id) => Ok(SubMsg { - id: msg_id, - reply_on: ReplyOn::Always, - msg: CosmosMsg::Wasm(WasmMsg::Instantiate { - admin: Some(sender), - code_id, - msg, - funds: vec![], - label: format!("Instantiate: {ado_type}"), - }), - gas_limit: None, - }), - } - } - - /// Gets the address for `contract` stored in the primitive contract. - pub fn get_address_from_kernel( - &self, - storage: &dyn Storage, - querier: &QuerierWrapper, - contract: &str, - ) -> Result { - let kernel_address = self.kernel_address.load(storage)?; - let query = KernelQueryMsg::KeyAddress { - key: contract.to_string(), - }; - let address: Addr = querier.query_wasm_smart(kernel_address, &query)?; - - Ok(address) - } - - fn get_code_id( - &self, - storage: &mut dyn Storage, - querier: &QuerierWrapper, - name: &str, - ) -> Result { - // Do we want to cache the factory address? - let adodb_addr = self.get_adodb_address(storage, querier)?; - let code_id: u64 = AOSQuerier::code_id_getter(querier, &adodb_addr, name)?; - Ok(code_id) - } -} diff --git a/andromeda-core/packages/std/src/ado_contract/mod.rs b/andromeda-core/packages/std/src/ado_contract/mod.rs index 142a436..898d156 100644 --- a/andromeda-core/packages/std/src/ado_contract/mod.rs +++ b/andromeda-core/packages/std/src/ado_contract/mod.rs @@ -1,17 +1,14 @@ pub mod app; mod execute; -#[cfg(feature = "instantiate")] -mod instantiate; - -#[cfg(feature = "modules")] -pub mod modules; mod ownership; pub mod permissioning; mod query; + +#[cfg(feature = "rates")] +pub mod rates; + pub mod state; -#[cfg(feature = "withdraw")] -pub mod withdraw; pub use crate::ado_contract::state::ADOContract; diff --git a/andromeda-core/packages/std/src/ado_contract/modules/execute.rs b/andromeda-core/packages/std/src/ado_contract/modules/execute.rs deleted file mode 100644 index 9a38f8c..0000000 --- a/andromeda-core/packages/std/src/ado_contract/modules/execute.rs +++ /dev/null @@ -1,80 +0,0 @@ -use super::ADOContract; -use crate::{ado_base::modules::Module, error::ContractError}; -use cosmwasm_std::{ensure, DepsMut, MessageInfo, Response, Storage, Uint64}; - -impl<'a> ADOContract<'a> { - /// Registers all modules within the ADO contract - pub fn instantiate_modules( - &self, - storage: &mut dyn Storage, - modules: Vec, - ) -> Result { - let mut resp = Response::default(); - for module in modules { - let idx = self.register_module(storage, &module)?; - resp = resp.add_attribute("module_idx", idx.to_string()); - } - Ok(resp) - } - - /// An execute wrapper for `fn register_module`. The parameters are "extracted" from `DepsMut` to be able to - /// execute this in a loop without cloning. - pub(crate) fn execute_register_module( - &self, - storage: &mut dyn Storage, - sender: &str, - module: Module, - should_validate: bool, - ) -> Result { - ensure!( - self.is_owner_or_operator(storage, sender)?, - ContractError::Unauthorized {} - ); - let resp = Response::default(); - let idx = self.register_module(storage, &module)?; - if should_validate { - self.validate_modules(&self.load_modules(storage)?)?; - } - Ok(resp - .add_attribute("action", "register_module") - .add_attribute("module_idx", idx.to_string())) - } - - /// An execute wrapper for `fn alter_module`. - pub(crate) fn execute_alter_module( - &self, - deps: DepsMut, - info: MessageInfo, - module_idx: Uint64, - module: Module, - ) -> Result { - let addr = info.sender.as_str(); - ensure!( - self.is_owner_or_operator(deps.storage, addr)?, - ContractError::Unauthorized {} - ); - self.alter_module(deps.storage, module_idx, &module)?; - self.validate_modules(&self.load_modules(deps.storage)?)?; - Ok(Response::default() - .add_attribute("action", "alter_module") - .add_attribute("module_idx", module_idx)) - } - - /// A wrapper for `fn deregister_module`. - pub(crate) fn execute_deregister_module( - &self, - deps: DepsMut, - info: MessageInfo, - module_idx: Uint64, - ) -> Result { - let addr = info.sender.as_str(); - ensure!( - self.is_owner_or_operator(deps.storage, addr)?, - ContractError::Unauthorized {} - ); - self.deregister_module(deps.storage, module_idx)?; - Ok(Response::default() - .add_attribute("action", "deregister_module") - .add_attribute("module_idx", module_idx)) - } -} diff --git a/andromeda-core/packages/std/src/ado_contract/modules/mod.rs b/andromeda-core/packages/std/src/ado_contract/modules/mod.rs index b1ce232..c35dd29 100644 --- a/andromeda-core/packages/std/src/ado_contract/modules/mod.rs +++ b/andromeda-core/packages/std/src/ado_contract/modules/mod.rs @@ -6,11 +6,12 @@ use crate::{ common::Funds, }; use cosmwasm_std::{ - Binary, Deps, Event, Order, QuerierWrapper, Response, StdError, Storage, SubMsg, Uint64, + ensure, Binary, Deps, Event, Order, QuerierWrapper, Response, StdError, Storage, SubMsg, Uint64, }; use cw_storage_plus::Bound; use serde::de::DeserializeOwned; +use crate::os::kernel::QueryMsg as KernelQueryMsg; use crate::{ado_base::modules::Module, error::ContractError}; pub mod execute; @@ -42,7 +43,22 @@ impl<'a> ADOContract<'a> { deps: &Deps, module: &Module, ) -> Result<(), ContractError> { - self.validate_andr_addresses(deps, vec![module.address.to_owned()])?; + // Validate module is an ADO + let addr = module.address.get_raw_address(deps)?; + let query = KernelQueryMsg::VerifyAddress { + address: addr.to_string(), + }; + let kernel_addr = self.get_kernel_address(deps.storage)?; + let res: bool = deps.querier.query_wasm_smart(kernel_addr, &query)?; + ensure!( + res, + ContractError::InvalidModule { + msg: Some(format!( + "Module {} is not a valid ADO", + module.name.clone().unwrap_or(module.address.to_string()) + )) + } + ); Ok(()) } @@ -50,18 +66,16 @@ impl<'a> ADOContract<'a> { &self, sender: &str, storage: &mut dyn Storage, - modules: Option>, ) -> Result { let mut resp = Response::new(); - if let Some(modules) = modules { - self.validate_modules(&modules)?; - for module in modules { - let register_response = - self.execute_register_module(storage, sender, module, false)?; - resp = resp - .add_attributes(register_response.attributes) - .add_submessages(register_response.messages) - } + let modules = modules.unwrap_or_default(); + + self.validate_modules(&modules)?; + for module in modules { + let register_response = self.execute_register_module(storage, sender, module, false)?; + resp = resp + .add_attributes(register_response.attributes) + .add_submessages(register_response.messages) } Ok(resp) @@ -132,6 +146,9 @@ impl<'a> ADOContract<'a> { /// Loads all registered modules in Vector form pub(crate) fn load_modules(&self, storage: &dyn Storage) -> Result, ContractError> { + // if !self.module_idx.may_load(storage)?.is_some() { + // return Ok(Vec::new()); + // } let module_idx = self.module_idx.may_load(storage)?.unwrap_or(1); let min = Some(Bound::inclusive("1")); let modules: Vec = self @@ -164,6 +181,12 @@ impl<'a> ADOContract<'a> { /// Validates all modules. fn validate_modules(&self, modules: &[Module]) -> Result<(), ContractError> { + ensure!( + modules.len() <= 100, + ContractError::InvalidModules { + msg: "Cannot have more than 100 modules".to_string() + } + ); for module in modules { module.validate(modules)?; } @@ -248,7 +271,7 @@ mod tests { use crate::testing::mock_querier::{mock_dependencies_custom, MOCK_APP_CONTRACT}; use cosmwasm_std::{ testing::{mock_dependencies, mock_info}, - Addr, + to_json_binary, Addr, Coin, }; #[test] @@ -511,6 +534,9 @@ mod tests { fn test_load_module_addresses() { let mut deps = mock_dependencies_custom(&[]); let contract = ADOContract::default(); + + let resp = contract.load_module_addresses(&deps.as_ref()).unwrap(); + assert!(resp.is_empty()); contract .app_contract .save(deps.as_mut().storage, &Addr::unchecked(MOCK_APP_CONTRACT)) @@ -558,4 +584,52 @@ mod tests { res ); } + + #[test] + fn test_validate_modules() { + let mut modules = vec![]; + + let mut i = 0; + while i < 101 { + modules.push(Module::new(i.to_string(), i.to_string(), true)); + i += 1; + } + + let err = ADOContract::default() + .validate_modules(&modules) + .unwrap_err(); + assert_eq!( + err, + ContractError::InvalidModules { + msg: "Cannot have more than 100 modules".to_string() + } + ); + + modules.clear(); + modules.push(Module::new("address_list", "address", true)); + modules.push(Module::new("receipt", "address", true)); + modules.push(Module::new("auction", "address", true)); + + let res = ADOContract::default().validate_modules(&modules); + assert!(res.is_ok()); + } + + #[test] + fn test_module_hook() { + let deps = mock_dependencies_custom(&[]); + let contract = ADOContract::default(); + + let resp: Vec = contract + .module_hook( + &deps.as_ref(), + AndromedaHook::OnFundsTransfer { + payload: to_json_binary(&true).unwrap(), + sender: "sender".to_string(), + amount: Funds::Native(Coin::new(100u128, "uandr")), + }, + ) + .unwrap(); + + assert!(resp.is_empty()); + } } diff --git a/andromeda-core/packages/std/src/ado_contract/modules/query.rs b/andromeda-core/packages/std/src/ado_contract/modules/query.rs deleted file mode 100644 index 42d5ae4..0000000 --- a/andromeda-core/packages/std/src/ado_contract/modules/query.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::ado_contract::{modules::Module, ADOContract}; -use crate::error::ContractError; -use cosmwasm_std::{Deps, Order, Uint64}; -use cw_storage_plus::Bound; - -impl<'a> ADOContract<'a> { - /// Queries a module by its id. - pub fn query_module(&self, deps: Deps, id: Uint64) -> Result { - let id = id.to_string(); - let module = self.module_info.load(deps.storage, &id)?; - Ok(module) - } - - /// Queries all of the module ids. - pub fn query_module_ids(&self, deps: Deps) -> Result, ContractError> { - let module_idx = self.module_idx.may_load(deps.storage)?.unwrap_or(1); - let min = Some(Bound::inclusive("1")); - let module_ids: Result, _> = self - .module_info - .keys(deps.storage, min, None, Order::Ascending) - .take(module_idx as usize) - .collect(); - Ok(module_ids?) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::ado_contract::modules::Module; - use cosmwasm_std::{testing::mock_dependencies, Addr}; - - #[test] - fn test_query_module() { - let contract = ADOContract::default(); - let mut deps = mock_dependencies(); - - contract - .owner - .save(deps.as_mut().storage, &Addr::unchecked("owner")) - .unwrap(); - - let module1 = Module::new("module_name1", "address1", true); - - let module2 = Module::new("module_name2", "address2", true); - - contract - .module_info - .save(deps.as_mut().storage, "1", &module1) - .unwrap(); - - contract - .module_info - .save(deps.as_mut().storage, "2", &module2) - .unwrap(); - - contract.module_idx.save(deps.as_mut().storage, &2).unwrap(); - - let res = contract - .query_module(deps.as_ref(), Uint64::from(1u64)) - .unwrap(); - - assert_eq!(module1, res); - - let res = contract - .query_module(deps.as_ref(), Uint64::from(2u64)) - .unwrap(); - - assert_eq!(module2, res); - - let res = contract.query_module_ids(deps.as_ref()).unwrap(); - assert_eq!(vec![String::from("1"), String::from("2")], res); - } -} diff --git a/andromeda-core/packages/std/src/ado_contract/ownership.rs b/andromeda-core/packages/std/src/ado_contract/ownership.rs index 4ab0b71..9f92800 100644 --- a/andromeda-core/packages/std/src/ado_contract/ownership.rs +++ b/andromeda-core/packages/std/src/ado_contract/ownership.rs @@ -1,21 +1,62 @@ -use crate::ado_contract::ADOContract; +use crate::common::expiration::Expiry; +use crate::common::MillisecondsExpiration; use crate::error::ContractError; -use cosmwasm_std::{attr, ensure, DepsMut, MessageInfo, Response, Storage}; +use crate::{ + ado_base::ownership::{ContractPotentialOwnerResponse, OwnershipMessage}, + ado_contract::ADOContract, +}; +use cosmwasm_std::{attr, ensure, Addr, DepsMut, Env, MessageInfo, Response, Storage}; +use cw_storage_plus::Item; + +const POTENTIAL_OWNER: Item = Item::new("andr_potential_owner"); +const POTENTIAL_OWNER_EXPIRATION: Item = + Item::new("andr_potential_owner_expiration"); impl<'a> ADOContract<'a> { + pub fn execute_ownership( + &self, + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: OwnershipMessage, + ) -> Result { + match msg { + OwnershipMessage::UpdateOwner { + new_owner, + expiration, + } => self.update_owner(deps, env, info, new_owner, expiration), + OwnershipMessage::RevokeOwnershipOffer => self.revoke_ownership_offer(deps, info), + OwnershipMessage::AcceptOwnership => self.accept_ownership(deps, env, info), + OwnershipMessage::Disown => self.disown(deps, info), + } + } + /// Updates the current contract owner. **Only executable by the current contract owner.** - pub fn execute_update_owner( + pub fn update_owner( &self, deps: DepsMut, + env: Env, info: MessageInfo, - new_owner: String, + new_owner: Addr, + expiration: Option, ) -> Result { ensure!( self.is_contract_owner(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); - let new_owner_addr = deps.api.addr_validate(&new_owner)?; - self.owner.save(deps.storage, &new_owner_addr)?; + ensure!( + !self.is_contract_owner(deps.storage, new_owner.as_str())?, + ContractError::Unauthorized {} + ); + let new_owner_addr = deps.api.addr_validate(new_owner.as_ref())?; + POTENTIAL_OWNER.save(deps.storage, &new_owner_addr)?; + + if let Some(exp) = expiration { + POTENTIAL_OWNER_EXPIRATION.save(deps.storage, &exp.get_time(&env.block))?; + } else { + // In case an offer is already pending + POTENTIAL_OWNER_EXPIRATION.remove(deps.storage); + } Ok(Response::new().add_attributes(vec![ attr("action", "update_owner"), @@ -23,30 +64,63 @@ impl<'a> ADOContract<'a> { ])) } - /// Updates the current contract operators. **Only executable by the current contract owner.** - pub fn execute_update_operators( + /// Revokes the ownership offer. **Only executable by the current contract owner.** + pub fn revoke_ownership_offer( &self, deps: DepsMut, info: MessageInfo, - operators: Vec, ) -> Result { ensure!( self.is_contract_owner(deps.storage, info.sender.as_str())?, ContractError::Unauthorized {} ); - self.operators.clear(deps.storage); - for op in operators.iter() { - self.operators.save(deps.storage, op, &true)?; + POTENTIAL_OWNER.remove(deps.storage); + POTENTIAL_OWNER_EXPIRATION.remove(deps.storage); + Ok(Response::new().add_attributes(vec![attr("action", "revoke_ownership_offer")])) + } + + /// Accepts the ownership of the contract. **Only executable by the new contract owner.** + pub fn accept_ownership( + &self, + deps: DepsMut, + env: Env, + info: MessageInfo, + ) -> Result { + let new_owner_addr = POTENTIAL_OWNER.load(deps.storage)?; + ensure!( + info.sender == new_owner_addr, + ContractError::Unauthorized {} + ); + let expiration = POTENTIAL_OWNER_EXPIRATION.may_load(deps.storage)?; + if let Some(exp) = expiration { + ensure!(!exp.is_expired(&env.block), ContractError::Unauthorized {}); } - Ok(Response::new().add_attributes(vec![attr("action", "update_operators")])) + self.owner.save(deps.storage, &new_owner_addr)?; + POTENTIAL_OWNER.remove(deps.storage); + POTENTIAL_OWNER_EXPIRATION.remove(deps.storage); + Ok(Response::new().add_attributes(vec![ + attr("action", "accept_ownership"), + attr("value", new_owner_addr.to_string()), + ])) + } + + /// Disowns the contract. **Only executable by the current contract owner.** + pub fn disown(&self, deps: DepsMut, info: MessageInfo) -> Result { + ensure!( + self.is_contract_owner(deps.storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + self.owner.save(deps.storage, &Addr::unchecked("null"))?; + Ok(Response::new().add_attributes(vec![attr("action", "disown")])) } - /// Helper function to query if a given address is a operator. + /// Helper function to query if a given address is the current contract owner. /// - /// Returns a boolean value indicating if the given address is a operator. - pub fn is_operator(&self, storage: &dyn Storage, addr: &str) -> bool { - self.operators.has(storage, addr) + /// Returns a boolean value indicating if the given address is the contract owner. + pub fn owner(&self, storage: &dyn Storage) -> Result { + let owner = self.owner.load(storage)?; + Ok(owner) } /// Helper function to query if a given address is the current contract owner. @@ -69,6 +143,146 @@ impl<'a> ADOContract<'a> { storage: &dyn Storage, addr: &str, ) -> Result { - Ok(self.is_contract_owner(storage, addr)? || self.is_operator(storage, addr)) + self.is_contract_owner(storage, addr) + } + + pub fn ownership_request( + &self, + storage: &dyn Storage, + ) -> Result { + let potential_owner = POTENTIAL_OWNER.may_load(storage)?; + let expiration = POTENTIAL_OWNER_EXPIRATION.may_load(storage)?; + Ok(ContractPotentialOwnerResponse { + potential_owner, + expiration, + }) + } +} + +#[cfg(test)] +mod test { + use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info}, + Addr, DepsMut, + }; + + use crate::{ + ado_contract::{ + ownership::{POTENTIAL_OWNER, POTENTIAL_OWNER_EXPIRATION}, + ADOContract, + }, + common::MillisecondsExpiration, + }; + + fn init(deps: DepsMut, owner: impl Into) { + ADOContract::default() + .owner + .save(deps.storage, &Addr::unchecked(owner)) + .unwrap(); + } + + #[test] + fn test_update_owner() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let contract = ADOContract::default(); + let new_owner = Addr::unchecked("new_owner"); + init(deps.as_mut(), "owner"); + + let res = contract.update_owner( + deps.as_mut(), + env.clone(), + mock_info("owner", &[]), + new_owner.clone(), + None, + ); + assert!(res.is_ok()); + let saved_new_owner = POTENTIAL_OWNER.load(deps.as_ref().storage).unwrap(); + assert_eq!(saved_new_owner, new_owner); + + let res = contract.update_owner( + deps.as_mut(), + env.clone(), + mock_info("owner", &[]), + Addr::unchecked("owner"), + None, + ); + assert!(res.is_err()); + let res = contract.update_owner( + deps.as_mut(), + env, + mock_info("new_owner", &[]), + new_owner, + None, + ); + assert!(res.is_err()); + } + + #[test] + fn test_revoke_ownership_offer() { + let mut deps = mock_dependencies(); + let contract = ADOContract::default(); + init(deps.as_mut(), "owner"); + + let res = contract.revoke_ownership_offer(deps.as_mut(), mock_info("owner", &[])); + assert!(res.is_ok()); + let saved_new_owner = POTENTIAL_OWNER.may_load(deps.as_ref().storage).unwrap(); + assert!(saved_new_owner.is_none()); + } + + #[test] + fn test_accept_ownership() { + let mut deps = mock_dependencies(); + let contract = ADOContract::default(); + let new_owner = Addr::unchecked("new_owner"); + init(deps.as_mut(), "owner"); + POTENTIAL_OWNER + .save(deps.as_mut().storage, &new_owner) + .unwrap(); + + let res = contract.accept_ownership(deps.as_mut(), mock_env(), mock_info("owner", &[])); + assert!(res.is_err()); + let res = contract.accept_ownership(deps.as_mut(), mock_env(), mock_info("new_owner", &[])); + assert!(res.is_ok()); + let saved_owner = contract.owner.load(deps.as_ref().storage).unwrap(); + assert_eq!(saved_owner, new_owner); + let saved_new_owner = POTENTIAL_OWNER.may_load(deps.as_ref().storage).unwrap(); + assert!(saved_new_owner.is_none()); + } + + #[test] + fn test_accept_ownership_expired() { + let mut deps = mock_dependencies(); + let contract = ADOContract::default(); + let new_owner = Addr::unchecked("new_owner"); + init(deps.as_mut(), "owner"); + POTENTIAL_OWNER + .save(deps.as_mut().storage, &new_owner) + .unwrap(); + POTENTIAL_OWNER_EXPIRATION + .save( + deps.as_mut().storage, + &MillisecondsExpiration::from_nanos(1), + ) + .unwrap(); + + let mut env = mock_env(); + env.block.time = MillisecondsExpiration::from_nanos(2).into(); + let res = contract.accept_ownership(deps.as_mut(), env, mock_info("new_owner", &[])); + assert!(res.is_err()); + let saved_owner = contract.owner.load(deps.as_ref().storage).unwrap(); + assert_eq!(saved_owner, Addr::unchecked("owner")); + } + + #[test] + fn test_disown() { + let mut deps = mock_dependencies(); + let contract = ADOContract::default(); + init(deps.as_mut(), "owner"); + + let res = contract.disown(deps.as_mut(), mock_info("owner", &[])); + assert!(res.is_ok()); + let saved_owner = contract.owner.load(deps.as_ref().storage).unwrap(); + assert_eq!(saved_owner, Addr::unchecked("null")); } } diff --git a/andromeda-core/packages/std/src/ado_contract/permissioning.rs b/andromeda-core/packages/std/src/ado_contract/permissioning.rs index 7afff66..eea1dc7 100644 --- a/andromeda-core/packages/std/src/ado_contract/permissioning.rs +++ b/andromeda-core/packages/std/src/ado_contract/permissioning.rs @@ -1,10 +1,12 @@ +use crate::ado_base::permissioning::LocalPermission; +use crate::os::aos_querier::AOSQuerier; use crate::{ - ado_base::permissioning::{Permission, PermissionInfo}, + ado_base::permissioning::{Permission, PermissionInfo, PermissioningMessage}, amp::{messages::AMPPkt, AndrAddr}, - common::context::ExecuteContext, + common::{context::ExecuteContext, OrderBy}, error::ContractError, }; -use cosmwasm_std::{ensure, Deps, Env, MessageInfo, Order, Response, Storage}; +use cosmwasm_std::{ensure, Deps, DepsMut, Env, MessageInfo, Order, Response, Storage}; use cw_storage_plus::{Bound, Index, IndexList, IndexedMap, MultiIndex}; use super::ADOContract; @@ -16,12 +18,13 @@ pub struct PermissionsIndices<'a> { /// PK: action + actor /// /// Secondary key: actor - pub permissions: MultiIndex<'a, String, PermissionInfo, String>, + pub actor: MultiIndex<'a, String, PermissionInfo, String>, + pub action: MultiIndex<'a, String, PermissionInfo, String>, } impl<'a> IndexList for PermissionsIndices<'a> { fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.permissions]; + let v: Vec<&dyn Index> = vec![&self.action, &self.actor]; Box::new(v.into_iter()) } } @@ -31,18 +34,45 @@ impl<'a> IndexList for PermissionsIndices<'a> { /// Permissions are stored in a multi-indexed map with the primary key being the action and actor pub fn permissions<'a>() -> IndexedMap<'a, &'a str, PermissionInfo, PermissionsIndices<'a>> { let indexes = PermissionsIndices { - permissions: MultiIndex::new(|_pk: &[u8], r| r.actor.clone(), "andr_permissions", "actor"), + actor: MultiIndex::new(|_pk: &[u8], r| r.actor.clone(), "andr_permissions", "actor"), + action: MultiIndex::new( + |_pk: &[u8], r| r.action.clone(), + "andr_permissions", + "action", + ), }; IndexedMap::new("andr_permissions", indexes) } impl<'a> ADOContract<'a> { + pub fn execute_permissioning( + &self, + ctx: ExecuteContext, + msg: PermissioningMessage, + ) -> Result { + match msg { + PermissioningMessage::SetPermission { + actors, + action, + permission, + } => self.execute_set_permission(ctx, actors, action, permission), + PermissioningMessage::RemovePermission { action, actors } => { + self.execute_remove_permission(ctx, actors, action) + } + PermissioningMessage::PermissionAction { action } => { + self.execute_permission_action(ctx, action) + } + PermissioningMessage::DisableActionPermissioning { action } => { + self.execute_disable_action_permission(ctx, action) + } + } + } /// Determines if the provided actor is authorised to perform the given action /// /// Returns an error if the given action is not permissioned for the given actor pub fn is_permissioned( &self, - store: &mut dyn Storage, + deps: DepsMut, env: Env, action: impl Into, actor: impl Into, @@ -51,36 +81,57 @@ impl<'a> ADOContract<'a> { let action_string: String = action.into(); let actor_string: String = actor.into(); - if self.is_contract_owner(store, actor_string.as_str())? { + if self.is_contract_owner(deps.as_ref().storage, actor_string.as_str())? { return Ok(()); } - let permission = Self::get_permission(store, action_string.clone(), actor_string.clone())?; + let permission = Self::get_permission( + deps.as_ref().storage, + action_string.clone(), + actor_string.clone(), + )?; let permissioned_action = self .permissioned_actions - .may_load(store, action_string.clone())? + .may_load(deps.storage, action_string.clone())? .unwrap_or(false); match permission { - Some(mut permission) => { - ensure!( - permission.is_permissioned(&env, permissioned_action), - ContractError::Unauthorized {} - ); - - // Consume a use for a limited permission - if let Permission::Limited { .. } = permission { - permission.consume_use(); - permissions().save( - store, - (action_string.clone() + actor_string.as_str()).as_str(), - &PermissionInfo { - action: action_string, - actor: actor_string, - permission, - }, - )?; - } - + Some(mut some_permission) => { + match some_permission { + Permission::Local(ref mut local_permission) => { + ensure!( + local_permission.is_permissioned(&env, permissioned_action), + ContractError::Unauthorized {} + ); + + // Consume a use for a limited permission + if let LocalPermission::Limited { .. } = local_permission { + // Only consume a use if the action is permissioned + if permissioned_action { + local_permission.consume_use()?; + permissions().save( + deps.storage, + (action_string.clone() + actor_string.as_str()).as_str(), + &PermissionInfo { + action: action_string, + actor: actor_string, + permission: some_permission, + }, + )?; + } + } + } + Permission::Contract(contract_address) => { + // Query contract that we'll be referencing the permissions from + let addr = contract_address.get_raw_address(&deps.as_ref())?; + let local_permission = + AOSQuerier::get_permission(&deps.querier, &addr, &actor_string)?; + + ensure!( + local_permission.is_permissioned(&env, permissioned_action), + ContractError::Unauthorized {} + ); + } + }; Ok(()) } None => { @@ -97,7 +148,7 @@ impl<'a> ADOContract<'a> { /// Returns an error if the permission has expired or if no permission exists for a restricted ADO pub fn is_permissioned_strict( &self, - store: &mut dyn Storage, + deps: DepsMut, env: Env, action: impl Into, actor: impl Into, @@ -106,32 +157,46 @@ impl<'a> ADOContract<'a> { let action_string: String = action.into(); let actor_string: String = actor.into(); - if self.is_contract_owner(store, actor_string.as_str())? { + if self.is_contract_owner(deps.storage, actor_string.as_str())? { return Ok(()); } - let permission = Self::get_permission(store, action_string.clone(), actor_string.clone())?; + let permission = + Self::get_permission(deps.storage, action_string.clone(), actor_string.clone())?; match permission { - Some(mut permission) => { - ensure!( - permission.is_permissioned(&env, true), - ContractError::Unauthorized {} - ); - - // Consume a use for a limited permission - if let Permission::Limited { .. } = permission { - permission.consume_use(); - permissions().save( - store, - (action_string.clone() + actor_string.as_str()).as_str(), - &PermissionInfo { - action: action_string, - actor: actor_string, - permission, - }, - )?; + Some(mut some_permission) => { + match some_permission { + Permission::Local(ref mut local_permission) => { + ensure!( + local_permission.is_permissioned(&env, true), + ContractError::Unauthorized {} + ); + + // Consume a use for a limited permission + if let LocalPermission::Limited { .. } = local_permission { + // Always consume a use due to strict setting + local_permission.consume_use()?; + permissions().save( + deps.storage, + (action_string.clone() + actor_string.as_str()).as_str(), + &PermissionInfo { + action: action_string, + actor: actor_string, + permission: some_permission, + }, + )?; + } + } + Permission::Contract(ref contract_address) => { + let addr = contract_address.get_raw_address(&deps.as_ref())?; + let local_permission = + AOSQuerier::get_permission(&deps.querier, &addr, &actor_string)?; + ensure!( + local_permission.is_permissioned(&env, true), + ContractError::Unauthorized {} + ); + } } - Ok(()) } None => Err(ContractError::Unauthorized {}), @@ -193,48 +258,81 @@ impl<'a> ADOContract<'a> { /// /// **Whitelisted/Limited permissions will only work for permissioned actions** /// - /// TODO: Add permission for execute context pub fn execute_set_permission( &self, ctx: ExecuteContext, - actor: AndrAddr, + actors: Vec, action: impl Into, permission: Permission, ) -> Result { - Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?; - let actor_addr = actor.get_raw_address(&ctx.deps.as_ref())?; + ensure!( + Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?, + ContractError::Unauthorized {} + ); + ensure!(!actors.is_empty(), ContractError::NoActorsProvided {}); let action = action.into(); - Self::set_permission( - ctx.deps.storage, - action.clone(), - actor_addr.clone(), - permission.clone(), - )?; + + let mut actor_addrs = Vec::new(); + + for actor in actors { + let actor_addr = actor.get_raw_address(&ctx.deps.as_ref())?; + actor_addrs.push(actor_addr); + } + + for actor_addr in actor_addrs.clone() { + Self::set_permission( + ctx.deps.storage, + action.clone(), + actor_addr.clone(), + permission.clone(), + )?; + } + + let actor_strs = actor_addrs + .iter() + .map(|addr| addr.as_str()) + .collect::>() + .join(", "); Ok(Response::default().add_attributes(vec![ ("action", "set_permission"), - ("actor", actor_addr.as_str()), + ("actors", &actor_strs), ("action", action.as_str()), ("permission", permission.to_string().as_str()), ])) } /// Execute handler for setting permission - /// TODO: Add permission for execute context pub fn execute_remove_permission( &self, ctx: ExecuteContext, - actor: AndrAddr, + actors: Vec, action: impl Into, ) -> Result { - Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?; - let actor_addr = actor.get_raw_address(&ctx.deps.as_ref())?; + ensure!( + Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?, + ContractError::Unauthorized {} + ); + ensure!(!actors.is_empty(), ContractError::NoActorsProvided {}); + let action = action.into(); - Self::remove_permission(ctx.deps.storage, action.clone(), actor_addr.clone())?; + let mut actor_addrs = Vec::new(); + + for actor in actors { + let actor_addr = actor.get_raw_address(&ctx.deps.as_ref())?; + actor_addrs.push(actor_addr.clone()); + Self::remove_permission(ctx.deps.storage, action.clone(), actor_addr)?; + } + + let actor_strs = actor_addrs + .iter() + .map(|addr| addr.as_str()) + .collect::>() + .join(", "); Ok(Response::default().add_attributes(vec![ ("action", "remove_permission"), - ("actor", actor_addr.as_str()), + ("actors", &actor_strs), ("action", action.as_str()), ])) } @@ -261,7 +359,10 @@ impl<'a> ADOContract<'a> { action: impl Into, ) -> Result { let action_string: String = action.into(); - Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?; + ensure!( + Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?, + ContractError::Unauthorized {} + ); self.permission_action(action_string.clone(), ctx.deps.storage)?; Ok(Response::default().add_attributes(vec![ ("action", "permission_action"), @@ -275,7 +376,10 @@ impl<'a> ADOContract<'a> { action: impl Into, ) -> Result { let action_string: String = action.into(); - Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?; + ensure!( + Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?, + ContractError::Unauthorized {} + ); Self::disable_action_permission(self, action_string.clone(), ctx.deps.storage); Ok(Response::default().add_attributes(vec![ ("action", "disable_action_permission"), @@ -296,7 +400,7 @@ impl<'a> ADOContract<'a> { let limit = limit.unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize; let permissions = permissions() .idx - .permissions + .actor .prefix(actor) .range(deps.storage, min, None, Order::Ascending) .take(limit) @@ -313,6 +417,42 @@ impl<'a> ADOContract<'a> { .collect::>(); Ok(actions) } + + pub fn query_permissioned_actors( + &self, + deps: Deps, + action: impl Into, + start_after: Option, + limit: Option, + order_by: Option, + ) -> Result, ContractError> { + let action_string: String = action.into(); + let order_by = match order_by { + Some(OrderBy::Desc) => Order::Descending, + _ => Order::Ascending, + }; + + let actors = permissions() + .idx + .action + .prefix(action_string.clone()) + .keys( + deps.storage, + start_after.map(Bound::inclusive), + None, + order_by, + ) + .take((limit).unwrap_or(DEFAULT_QUERY_LIMIT).min(MAX_QUERY_LIMIT) as usize) + .map(|p| { + p.unwrap() + .strip_prefix(action_string.as_str()) + .unwrap() + .to_string() + }) + .collect::>(); + + Ok(actors) + } } /// Checks if the provided context is authorised to perform the provided action. @@ -321,7 +461,7 @@ impl<'a> ADOContract<'a> { /// - The context does not contain any AMP context and the **sender** is the actor /// - The context contains AMP context and the **previous sender** or **origin** are considered the actor pub fn is_context_permissioned( - storage: &mut dyn Storage, + deps: &mut DepsMut, info: &MessageInfo, env: &Env, ctx: &Option, @@ -333,21 +473,24 @@ pub fn is_context_permissioned( Some(amp_ctx) => { let action: String = action.into(); let is_origin_permissioned = contract.is_permissioned( - storage, + deps.branch(), env.clone(), action.clone(), amp_ctx.ctx.get_origin().as_str(), ); + if is_origin_permissioned.is_ok() { + return Ok(true); + } let is_previous_sender_permissioned = contract.is_permissioned( - storage, + deps.branch(), env.clone(), action, amp_ctx.ctx.get_previous_sender().as_str(), ); - Ok(is_origin_permissioned.is_ok() || is_previous_sender_permissioned.is_ok()) + Ok(is_previous_sender_permissioned.is_ok()) } None => Ok(contract - .is_permissioned(storage, env.clone(), action, info.sender.to_string()) + .is_permissioned(deps.branch(), env.clone(), action, info.sender.to_string()) .is_ok()), } } @@ -358,7 +501,7 @@ pub fn is_context_permissioned( /// - The context does not contain any AMP context and the **sender** is the actor /// - The context contains AMP context and the **previous sender** or **origin** are considered the actor pub fn is_context_permissioned_strict( - storage: &mut dyn Storage, + mut deps: DepsMut, info: &MessageInfo, env: &Env, ctx: &Option, @@ -370,21 +513,24 @@ pub fn is_context_permissioned_strict( Some(amp_ctx) => { let action: String = action.into(); let is_origin_permissioned = contract.is_permissioned_strict( - storage, + deps.branch(), env.clone(), action.clone(), amp_ctx.ctx.get_origin().as_str(), ); + if is_origin_permissioned.is_ok() { + return Ok(true); + } let is_previous_sender_permissioned = contract.is_permissioned_strict( - storage, + deps.branch(), env.clone(), action, amp_ctx.ctx.get_previous_sender().as_str(), ); - Ok(is_origin_permissioned.is_ok() || is_previous_sender_permissioned.is_ok()) + Ok(is_previous_sender_permissioned.is_ok()) } None => Ok(contract - .is_permissioned_strict(storage, env.clone(), action, info.sender.to_string()) + .is_permissioned_strict(deps.branch(), env.clone(), action, info.sender.to_string()) .is_ok()), } } @@ -395,9 +541,12 @@ mod tests { testing::{mock_dependencies, mock_env, mock_info}, Addr, }; - use cw_utils::Expiration; - use crate::amp::messages::AMPPkt; + use crate::{ + ado_base::AndromedaMsg, + amp::messages::AMPPkt, + common::{expiration::Expiry, MillisecondsExpiration}, + }; use super::*; @@ -418,40 +567,52 @@ mod tests { .unwrap(); // Test Whitelisting - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_err()); - let permission = Permission::whitelisted(None); + let permission = Permission::Local(LocalPermission::Whitelisted(None)); ADOContract::set_permission(deps.as_mut().storage, action, actor, permission).unwrap(); - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_ok()); ADOContract::remove_permission(deps.as_mut().storage, action, actor).unwrap(); // Test Limited - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_err()); - let permission = Permission::limited(None, 1); + let permission = Permission::Local(LocalPermission::Limited { + expiration: None, + uses: 1, + }); ADOContract::set_permission(deps.as_mut().storage, action, actor, permission).unwrap(); - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_ok()); // Ensure use is consumed - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_err()); + ADOContract::default().disable_action_permission(action, deps.as_mut().storage); + + // Ensure limited use does not interfere with non-permissioned action + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); + assert!(res.is_ok()); + ADOContract::remove_permission(deps.as_mut().storage, action, actor).unwrap(); + ADOContract::default() + .permission_action(action, deps.as_mut().storage) + .unwrap(); // Test Blacklisted - let permission = Permission::blacklisted(None); + let permission = Permission::Local(LocalPermission::Blacklisted(None)); ADOContract::set_permission(deps.as_mut().storage, action, actor, permission).unwrap(); - let res = contract.is_permissioned(deps.as_mut().storage, env, action, actor); + let res = contract.is_permissioned(deps.as_mut(), env, action, actor); assert!(res.is_err()); } @@ -473,10 +634,10 @@ mod tests { .unwrap(); // Test Blacklisted - let permission = Permission::blacklisted(None); + let permission = Permission::Local(LocalPermission::Blacklisted(None)); ADOContract::set_permission(deps.as_mut().storage, action, actor, permission).unwrap(); - let res = contract.is_permissioned(deps.as_mut().storage, env, action, actor); + let res = contract.is_permissioned(deps.as_mut(), env, action, actor); assert!(res.is_err()); } @@ -493,14 +654,13 @@ mod tests { .save(deps.as_mut().storage, &Addr::unchecked("owner")) .unwrap(); - let res = - contract.is_permissioned_strict(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned_strict(deps.as_mut(), env.clone(), action, actor); assert!(res.is_err()); - let permission = Permission::whitelisted(None); + let permission = Permission::Local(LocalPermission::Whitelisted(None)); ADOContract::set_permission(deps.as_mut().storage, action, actor, permission).unwrap(); - let res = contract.is_permissioned_strict(deps.as_mut().storage, env, action, actor); + let res = contract.is_permissioned_strict(deps.as_mut(), env, action, actor); assert!(res.is_ok()); } @@ -516,14 +676,92 @@ mod tests { .save(deps.as_mut().storage, &Addr::unchecked(actor)) .unwrap(); - let res = - contract.is_permissioned_strict(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned_strict(deps.as_mut(), env.clone(), action, actor); assert!(res.is_ok()); - let res = contract.is_permissioned(deps.as_mut().storage, env, action, actor); + let res = contract.is_permissioned(deps.as_mut(), env, action, actor); assert!(res.is_ok()); } + #[test] + fn test_set_permission_unauthorized() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let contract = ADOContract::default(); + contract + .owner + .save(deps.as_mut().storage, &Addr::unchecked("owner")) + .unwrap(); + let msg = AndromedaMsg::Permissioning(PermissioningMessage::SetPermission { + actors: vec![AndrAddr::from_string("actor")], + action: "action".to_string(), + permission: Permission::Local(LocalPermission::Whitelisted(None)), + }); + let ctx = ExecuteContext::new(deps.as_mut(), mock_info("attacker", &[]), env); + let res = contract.execute(ctx, msg); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::Unauthorized {}); + } + + #[test] + fn test_permission_action_unauthorized() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let contract = ADOContract::default(); + contract + .owner + .save(deps.as_mut().storage, &Addr::unchecked("owner")) + .unwrap(); + let msg = AndromedaMsg::Permissioning(PermissioningMessage::PermissionAction { + action: "action".to_string(), + }); + let ctx = ExecuteContext::new(deps.as_mut(), mock_info("attacker", &[]), env); + let res = contract.execute(ctx, msg); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::Unauthorized {}); + } + + #[test] + fn test_disable_permissioning_unauthorized() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let contract = ADOContract::default(); + contract + .owner + .save(deps.as_mut().storage, &Addr::unchecked("owner")) + .unwrap(); + let msg = AndromedaMsg::Permissioning(PermissioningMessage::DisableActionPermissioning { + action: "action".to_string(), + }); + let ctx = ExecuteContext::new(deps.as_mut(), mock_info("attacker", &[]), env); + let res = contract.execute(ctx, msg); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::Unauthorized {}); + } + + #[test] + fn test_remove_permission_unauthorized() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let contract = ADOContract::default(); + contract + .owner + .save(deps.as_mut().storage, &Addr::unchecked("owner")) + .unwrap(); + let msg = AndromedaMsg::Permissioning(PermissioningMessage::RemovePermission { + action: "action".to_string(), + actors: vec![AndrAddr::from_string("actor")], + }); + let ctx = ExecuteContext::new(deps.as_mut(), mock_info("attacker", &[]), env); + let res = contract.execute(ctx, msg); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::Unauthorized {}); + } + #[test] fn test_permission_expiration() { let mut deps = mock_dependencies(); @@ -532,8 +770,10 @@ mod tests { let action = "action"; let actor = "actor"; let contract = ADOContract::default(); - let block = 100; - let expiration = Expiration::AtHeight(block); + let time = 2; + let expiration = Expiry::AtTime(MillisecondsExpiration::from_seconds(time)); + + env.block.time = MillisecondsExpiration::from_seconds(0).into(); contract .owner .save(deps.as_mut().storage, &Addr::unchecked("owner")) @@ -543,33 +783,40 @@ mod tests { .permission_action(action, deps.as_mut().storage) .unwrap(); - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_err()); // Test Whitelist - let permission = Permission::Whitelisted(Some(expiration)); + let permission = Permission::Local(LocalPermission::Whitelisted(Some(expiration.clone()))); ADOContract::set_permission(deps.as_mut().storage, action, actor, permission).unwrap(); - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_ok()); - env.block.height = block + 1; + env.block.time = MillisecondsExpiration::from_seconds(time + 1).into(); - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); assert!(res.is_err()); - env.block.height = 0; + env.block.time = MillisecondsExpiration::from_seconds(0).into(); // Test Blacklist - let permission = Permission::Blacklisted(Some(expiration)); + let permission = Permission::Local(LocalPermission::Blacklisted(Some(expiration.clone()))); ADOContract::set_permission(deps.as_mut().storage, action, actor, permission).unwrap(); - let res = contract.is_permissioned(deps.as_mut().storage, env.clone(), action, actor); + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); + assert!(res.is_err()); + + env.block.time = MillisecondsExpiration::from_seconds(time + 1).into(); + + let res = contract.is_permissioned(deps.as_mut(), env.clone(), action, actor); + //Action is still permissioned so this should error assert!(res.is_err()); - env.block.height = block + 1; + ADOContract::default().disable_action_permission(action, deps.as_mut().storage); - let res = contract.is_permissioned(deps.as_mut().storage, env, action, actor); + // Action is no longer permissioned so this should pass + let res = contract.is_permissioned(deps.as_mut(), env, action, actor); assert!(res.is_ok()); } @@ -581,7 +828,7 @@ mod tests { let info = mock_info(actor, &[]); let action = "action"; - let context = ExecuteContext::new(deps.as_mut(), info.clone(), env.clone()); + let mut context = ExecuteContext::new(deps.as_mut(), info.clone(), env.clone()); let contract = ADOContract::default(); contract @@ -590,7 +837,7 @@ mod tests { .unwrap(); assert!(is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -598,13 +845,13 @@ mod tests { ) .unwrap()); - let context = ExecuteContext::new(deps.as_mut(), info.clone(), env.clone()); + let mut context = ExecuteContext::new(deps.as_mut(), info.clone(), env.clone()); ADOContract::default() .permission_action(action, context.deps.storage) .unwrap(); assert!(!is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -612,12 +859,12 @@ mod tests { ) .unwrap()); - let context = ExecuteContext::new(deps.as_mut(), info, env.clone()); - let permission = Permission::whitelisted(None); + let mut context = ExecuteContext::new(deps.as_mut(), info.clone(), env.clone()); + let permission = Permission::Local(LocalPermission::Whitelisted(None)); ADOContract::set_permission(context.deps.storage, action, actor, permission).unwrap(); assert!(is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -626,10 +873,10 @@ mod tests { .unwrap()); let unauth_info = mock_info("mock_actor", &[]); - let context = ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()); + let mut context = ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()); assert!(!is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -638,11 +885,11 @@ mod tests { .unwrap()); let amp_ctx = AMPPkt::new("mock_actor", actor, vec![]); - let context = + let mut context = ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()).with_ctx(amp_ctx); assert!(is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -651,11 +898,11 @@ mod tests { .unwrap()); let amp_ctx = AMPPkt::new(actor, "mock_actor", vec![]); - let context = + let mut context = ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()).with_ctx(amp_ctx); assert!(is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -664,11 +911,11 @@ mod tests { .unwrap()); let amp_ctx = AMPPkt::new("mock_actor", "mock_actor", vec![]); - let context = + let mut context = ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()).with_ctx(amp_ctx); assert!(!is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -677,11 +924,11 @@ mod tests { .unwrap()); let amp_ctx = AMPPkt::new("owner", "mock_actor", vec![]); - let context = + let mut context = ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()).with_ctx(amp_ctx); assert!(is_context_permissioned( - context.deps.storage, + &mut context.deps, &context.info, &context.env, &context.amp_ctx, @@ -690,16 +937,50 @@ mod tests { .unwrap()); let amp_ctx = AMPPkt::new("mock_actor", "owner", vec![]); - let context = ExecuteContext::new(deps.as_mut(), unauth_info, env).with_ctx(amp_ctx); + let mut context = + ExecuteContext::new(deps.as_mut(), unauth_info, env.clone()).with_ctx(amp_ctx); assert!(is_context_permissioned( + &mut context.deps, + &context.info, + &context.env, + &context.amp_ctx, + action + ) + .unwrap()); + + let previous_sender = "previous_sender"; + let mut context = ExecuteContext::new(deps.as_mut(), info.clone(), env.clone()) + .with_ctx(AMPPkt::new(info.sender, previous_sender, vec![])); + let permission = Permission::Local(LocalPermission::limited(None, 1)); + ADOContract::set_permission(context.deps.storage, action, actor, permission.clone()) + .unwrap(); + ADOContract::set_permission( context.deps.storage, + action, + previous_sender, + permission.clone(), + ) + .unwrap(); + + assert!(is_context_permissioned( + &mut context.deps, &context.info, &context.env, &context.amp_ctx, action ) .unwrap()); + + let actor_permission = + ADOContract::get_permission(context.deps.storage, action, actor).unwrap(); + let previous_sender_permission = + ADOContract::get_permission(context.deps.storage, action, previous_sender).unwrap(); + assert_eq!(previous_sender_permission, Some(permission)); + assert_eq!( + actor_permission, + Some(Permission::Local(LocalPermission::limited(None, 0))) + ); } #[test] @@ -719,7 +1000,7 @@ mod tests { .unwrap(); assert!(!is_context_permissioned_strict( - context.deps.storage, + context.deps, &context.info, &context.env, &context.amp_ctx, @@ -728,11 +1009,11 @@ mod tests { .unwrap()); let context = ExecuteContext::new(deps.as_mut(), info, env.clone()); - let permission = Permission::whitelisted(None); + let permission = Permission::Local(LocalPermission::Whitelisted(None)); ADOContract::set_permission(context.deps.storage, action, actor, permission).unwrap(); assert!(is_context_permissioned_strict( - context.deps.storage, + context.deps, &context.info, &context.env, &context.amp_ctx, @@ -744,7 +1025,7 @@ mod tests { let context = ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()); assert!(!is_context_permissioned_strict( - context.deps.storage, + context.deps, &context.info, &context.env, &context.amp_ctx, @@ -757,7 +1038,7 @@ mod tests { ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()).with_ctx(amp_ctx); assert!(is_context_permissioned_strict( - context.deps.storage, + context.deps, &context.info, &context.env, &context.amp_ctx, @@ -770,7 +1051,7 @@ mod tests { ExecuteContext::new(deps.as_mut(), unauth_info.clone(), env.clone()).with_ctx(amp_ctx); assert!(is_context_permissioned_strict( - context.deps.storage, + context.deps, &context.info, &context.env, &context.amp_ctx, @@ -782,7 +1063,7 @@ mod tests { let context = ExecuteContext::new(deps.as_mut(), unauth_info, env).with_ctx(amp_ctx); assert!(!is_context_permissioned_strict( - context.deps.storage, + context.deps, &context.info, &context.env, &context.amp_ctx, @@ -802,7 +1083,7 @@ mod tests { assert!(permissions.is_empty()); - let permission = Permission::whitelisted(None); + let permission = Permission::Local(LocalPermission::Whitelisted(None)); let action = "action"; ADOContract::set_permission(deps.as_mut().storage, action, actor, permission.clone()) @@ -817,10 +1098,22 @@ mod tests { assert_eq!(permissions[0].permission, permission); let multi_permissions = vec![ - ("action2".to_string(), Permission::blacklisted(None)), - ("action3".to_string(), Permission::whitelisted(None)), - ("action4".to_string(), Permission::blacklisted(None)), - ("action5".to_string(), Permission::whitelisted(None)), + ( + "action2".to_string(), + Permission::Local(LocalPermission::Blacklisted(None)), + ), + ( + "action3".to_string(), + Permission::Local(LocalPermission::Whitelisted(None)), + ), + ( + "action4".to_string(), + Permission::Local(LocalPermission::Blacklisted(None)), + ), + ( + "action5".to_string(), + Permission::Local(LocalPermission::Whitelisted(None)), + ), ]; for (action, permission) in multi_permissions { @@ -867,4 +1160,41 @@ mod tests { assert_eq!(actions.len(), 1); assert_eq!(actions[0], "action"); } + + #[test] + fn test_query_permissioned_actors() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let info = mock_info("owner", &[]); + let ctx = ExecuteContext { + deps: deps.as_mut(), + env, + info: info.clone(), + amp_ctx: None, + }; + + let contract = ADOContract::default(); + + contract.owner.save(ctx.deps.storage, &info.sender).unwrap(); + + let actor = "actor"; + let action = "action"; + ADOContract::default() + .execute_permission_action(ctx, action) + .unwrap(); + + ADOContract::set_permission( + deps.as_mut().storage, + action, + actor, + Permission::Local(LocalPermission::default()), + ) + .unwrap(); + let actors = ADOContract::default() + .query_permissioned_actors(deps.as_ref(), action, None, None, None) + .unwrap(); + + assert_eq!(actors.len(), 1); + assert_eq!(actors[0], actor); + } } diff --git a/andromeda-core/packages/std/src/ado_contract/query.rs b/andromeda-core/packages/std/src/ado_contract/query.rs index bed8b14..4b7b754 100644 --- a/andromeda-core/packages/std/src/ado_contract/query.rs +++ b/andromeda-core/packages/std/src/ado_contract/query.rs @@ -1,10 +1,10 @@ +use crate::ado_base::version::ADOBaseVersionResponse; use crate::ado_contract::state::ADOContract; use crate::{ ado_base::{ ado_type::TypeResponse, block_height::BlockHeightResponse, kernel_address::KernelAddressResponse, - operators::{IsOperatorResponse, OperatorsResponse}, ownership::{ContractOwnerResponse, PublisherResponse}, version::VersionResponse, AndromedaQuery, @@ -12,7 +12,8 @@ use crate::{ common::encode_binary, error::ContractError, }; -use cosmwasm_std::{from_json, to_json_binary, Binary, Deps, Env, Order}; +use cosmwasm_std::{from_json, to_json_binary, Binary, Deps, Env}; +use cw2::get_contract_version; use serde::Serialize; impl<'a> ADOContract<'a> { @@ -28,7 +29,6 @@ impl<'a> ADOContract<'a> { match from_json::(&msg) { Ok(msg) => match msg { AndromedaQuery::Owner {} => encode_binary(&self.query_contract_owner(deps)?), - AndromedaQuery::Operators {} => encode_binary(&self.query_operators(deps)?), AndromedaQuery::OriginalPublisher {} => { encode_binary(&self.query_original_publisher(deps)?) } @@ -36,17 +36,14 @@ impl<'a> ADOContract<'a> { AndromedaQuery::BlockHeightUponCreation {} => { encode_binary(&self.query_block_height_upon_creation(deps)?) } - AndromedaQuery::IsOperator { address } => { - encode_binary(&self.query_is_operator(deps, &address)?) - } AndromedaQuery::KernelAddress {} => { encode_binary(&self.query_kernel_address(deps)?) } AndromedaQuery::Version {} => encode_binary(&self.query_version(deps)?), - #[cfg(feature = "modules")] - AndromedaQuery::Module { id } => encode_binary(&self.query_module(deps, id)?), - #[cfg(feature = "modules")] - AndromedaQuery::ModuleIds {} => encode_binary(&self.query_module_ids(deps)?), + AndromedaQuery::ADOBaseVersion {} => encode_binary(&self.query_ado_base_version()?), + AndromedaQuery::OwnershipRequest {} => { + encode_binary(&self.ownership_request(deps.storage)?) + } AndromedaQuery::AppContract {} => { encode_binary(&self.get_app_contract(deps.storage)?) } @@ -58,6 +55,12 @@ impl<'a> ADOContract<'a> { AndromedaQuery::PermissionedActions {} => { encode_binary(&self.query_permissioned_actions(deps)?) } + #[cfg(feature = "rates")] + AndromedaQuery::Rates { action } => encode_binary(&self.get_rates(deps, action)?), + + #[cfg(feature = "rates")] + AndromedaQuery::AllRates {} => encode_binary(&self.get_all_rates(deps)?), + _ => Err(ContractError::UnsupportedOperation {}), }, Err(_) => Err(ContractError::UnsupportedOperation {}), @@ -75,34 +78,12 @@ impl<'a> ADOContract<'a> { }) } - #[inline] - pub fn query_is_operator( - &self, - deps: Deps, - addr: &str, - ) -> Result { - Ok(IsOperatorResponse { - is_operator: self.operators.has(deps.storage, addr), - }) - } - #[inline] pub fn query_kernel_address(&self, deps: Deps) -> Result { let kernel_address = self.kernel_address.load(deps.storage)?; Ok(KernelAddressResponse { kernel_address }) } - #[inline] - pub fn query_operators(&self, deps: Deps) -> Result { - let operators: Result, _> = self - .operators - .keys(deps.storage, None, None, Order::Ascending) - .collect(); - Ok(OperatorsResponse { - operators: operators?, - }) - } - #[inline] pub fn query_original_publisher(&self, deps: Deps) -> Result { let original_publisher = self.original_publisher.load(deps.storage)?.to_string(); @@ -126,7 +107,17 @@ impl<'a> ADOContract<'a> { #[inline] pub fn query_version(&self, deps: Deps) -> Result { - let version = self.version.load(deps.storage)?; - Ok(VersionResponse { version }) + let contract_version = get_contract_version(deps.storage)?; + Ok(VersionResponse { + version: contract_version.version, + }) + } + + #[inline] + pub fn query_ado_base_version(&self) -> Result { + let ado_base_version: &str = env!("CARGO_PKG_VERSION"); + Ok(ADOBaseVersionResponse { + version: ado_base_version.to_string(), + }) } } diff --git a/andromeda-core/packages/std/src/ado_contract/rates.rs b/andromeda-core/packages/std/src/ado_contract/rates.rs new file mode 100644 index 0000000..e8c47e5 --- /dev/null +++ b/andromeda-core/packages/std/src/ado_contract/rates.rs @@ -0,0 +1,244 @@ +use crate::ado_base::rates::{AllRatesResponse, Rate, RatesMessage, RatesResponse}; +use crate::amp::Recipient; +use crate::common::{context::ExecuteContext, Funds}; +use crate::error::ContractError; +use crate::os::aos_querier::AOSQuerier; +use cosmwasm_std::{coin as create_coin, ensure, Coin, Deps, Response, Storage}; +use cw20::Cw20Coin; +use cw_storage_plus::Map; + +use super::ADOContract; + +pub fn rates<'a>() -> Map<'a, &'a str, Rate> { + Map::new("rates") +} + +impl<'a> ADOContract<'a> { + /// Sets rates + pub fn set_rates( + &self, + store: &mut dyn Storage, + action: impl Into, + rate: Rate, + ) -> Result<(), ContractError> { + let action: String = action.into(); + self.rates.save(store, &action, &rate)?; + Ok(()) + } + pub fn execute_rates( + &self, + ctx: ExecuteContext, + rates_message: RatesMessage, + ) -> Result { + match rates_message { + RatesMessage::SetRate { action, rate } => self.execute_set_rates(ctx, action, rate), + RatesMessage::RemoveRate { action } => self.execute_remove_rates(ctx, action), + } + } + pub fn execute_set_rates( + &self, + ctx: ExecuteContext, + action: impl Into, + mut rate: Rate, + ) -> Result { + ensure!( + Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?, + ContractError::Unauthorized {} + ); + let action: String = action.into(); + // Validate rates + rate.validate_rate(ctx.deps.as_ref())?; + + let rate = match rate { + Rate::Local(ref mut local_rate) => { + if local_rate.recipients.is_empty() { + local_rate.recipients = vec![Recipient::new(ctx.info.sender, None)]; + Rate::Local(local_rate.clone()) + } else { + rate + } + } + Rate::Contract(_) => rate, + }; + self.set_rates(ctx.deps.storage, action, rate)?; + + Ok(Response::default().add_attributes(vec![("action", "set_rates")])) + } + pub fn remove_rates( + &self, + store: &mut dyn Storage, + action: impl Into, + ) -> Result<(), ContractError> { + let action: String = action.into(); + self.rates.remove(store, &action); + Ok(()) + } + pub fn execute_remove_rates( + &self, + ctx: ExecuteContext, + action: impl Into, + ) -> Result { + ensure!( + Self::is_contract_owner(self, ctx.deps.storage, ctx.info.sender.as_str())?, + ContractError::Unauthorized {} + ); + let action: String = action.into(); + self.remove_rates(ctx.deps.storage, action.clone())?; + + Ok(Response::default().add_attributes(vec![ + ("action", "remove_rates"), + ("removed_action", &action), + ])) + } + + pub fn get_rates( + &self, + deps: Deps, + action: impl Into, + ) -> Result, ContractError> { + let action: String = action.into(); + Ok(rates().may_load(deps.storage, &action)?) + } + + pub fn get_all_rates(&self, deps: Deps) -> Result { + // Initialize a vector to hold all rates + let mut all_rates: Vec<(String, Rate)> = Vec::new(); + + // Iterate over all keys and load the corresponding rate + rates() + .range(deps.storage, None, None, cosmwasm_std::Order::Ascending) + .for_each(|item| { + if let Ok((action, rate)) = item { + all_rates.push((action, rate)); + } + }); + + Ok(AllRatesResponse { all_rates }) + } + + pub fn query_deducted_funds( + self, + deps: Deps, + action: impl Into, + funds: Funds, + ) -> Result, ContractError> { + let action: String = action.into(); + let rate = self.rates.may_load(deps.storage, &action)?; + match rate { + Some(rate) => { + let (coin, is_native): (Coin, bool) = match funds { + Funds::Native(coin) => { + ensure!( + !coin.amount.is_zero(), + ContractError::InvalidFunds { + msg: "Zero amounts are prohibited".to_string() + } + ); + (coin, true) + } + Funds::Cw20(cw20_coin) => { + ensure!( + !cw20_coin.amount.is_zero(), + ContractError::InvalidFunds { + msg: "Zero amounts are prohibited".to_string() + } + ); + ( + create_coin(cw20_coin.amount.u128(), cw20_coin.address), + false, + ) + } + }; + let (msgs, events, leftover_funds) = match rate { + Rate::Local(local_rate) => { + local_rate.generate_response(deps, coin.clone(), is_native)? + } + Rate::Contract(rates_address) => { + // Query rates contract + let addr = rates_address.get_raw_address(&deps)?; + let rate = AOSQuerier::get_rate(&deps.querier, &addr, &action)?; + rate.generate_response(deps, coin.clone(), is_native)? + } + }; + + Ok(Some(RatesResponse { + msgs, + leftover_funds: if is_native { + Funds::Native(leftover_funds[0].clone()) + } else { + Funds::Cw20(Cw20Coin { + amount: leftover_funds[0].amount, + address: coin.denom, + }) + }, + events, + })) + } + None => Ok(None), + } + } +} +#[cfg(test)] +#[cfg(feature = "rates")] + +mod tests { + + use cosmwasm_std::{ + coin, + testing::{mock_dependencies, mock_env}, + Addr, + }; + + use crate::{ + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue}, + amp::{AndrAddr, Recipient}, + }; + + use super::*; + #[test] + fn test_rates_crud() { + let mut deps = mock_dependencies(); + let _env = mock_env(); + let contract = ADOContract::default(); + contract + .owner + .save(deps.as_mut().storage, &Addr::unchecked("owner")) + .unwrap(); + + let expected_rate = Rate::Local(LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient { + address: AndrAddr::from_string("owner".to_string()), + msg: None, + ibc_recovery_address: None, + }], + value: LocalRateValue::Flat(coin(100_u128, "uandr")), + description: None, + }); + + let action = "deposit"; + // set rates + ADOContract::set_rates(&contract, &mut deps.storage, action, expected_rate.clone()) + .unwrap(); + + let rate = ADOContract::default() + .rates + .load(&deps.storage, action) + .unwrap(); + + assert_eq!(rate, expected_rate); + + // get rates + let rate = ADOContract::default() + .get_rates(deps.as_ref(), action) + .unwrap(); + assert_eq!(expected_rate, rate.unwrap()); + + // remove rates + ADOContract::remove_rates(&contract, &mut deps.storage, action).unwrap(); + let rate = ADOContract::default() + .get_rates(deps.as_ref(), action) + .unwrap(); + assert!(rate.is_none()); + } +} diff --git a/andromeda-core/packages/std/src/ado_contract/state.rs b/andromeda-core/packages/std/src/ado_contract/state.rs index 1dcc983..c3f8ab9 100644 --- a/andromeda-core/packages/std/src/ado_contract/state.rs +++ b/andromeda-core/packages/std/src/ado_contract/state.rs @@ -1,26 +1,19 @@ -#[cfg(feature = "modules")] -use crate::ado_base::modules::Module; +#[cfg(feature = "rates")] +use crate::ado_base::rates::Rate; use cosmwasm_std::Addr; -#[cfg(feature = "withdraw")] -use cw_asset::AssetInfo; use cw_storage_plus::{Item, Map}; pub struct ADOContract<'a> { pub(crate) owner: Item<'a, Addr>, pub(crate) original_publisher: Item<'a, Addr>, pub(crate) block_height: Item<'a, u64>, - pub(crate) operators: Map<'a, &'a str, bool>, pub(crate) ado_type: Item<'a, String>, - pub(crate) version: Item<'a, String>, pub(crate) app_contract: Item<'a, Addr>, pub(crate) kernel_address: Item<'a, Addr>, pub(crate) permissioned_actions: Map<'a, String, bool>, - #[cfg(feature = "modules")] - pub(crate) module_info: Map<'a, &'a str, Module>, - #[cfg(feature = "modules")] - pub(crate) module_idx: Item<'a, u64>, - #[cfg(feature = "withdraw")] - pub withdrawable_tokens: Map<'a, &'a str, AssetInfo>, + #[cfg(feature = "rates")] + /// Mapping of action to rate + pub rates: Map<'a, &'a str, Rate>, } impl<'a> Default for ADOContract<'a> { @@ -29,18 +22,12 @@ impl<'a> Default for ADOContract<'a> { owner: Item::new("owner"), original_publisher: Item::new("original_publisher"), block_height: Item::new("block_height"), - operators: Map::new("operators"), ado_type: Item::new("ado_type"), - version: Item::new("version"), app_contract: Item::new("app_contract"), kernel_address: Item::new("kernel_address"), permissioned_actions: Map::new("andr_permissioned_actions"), - #[cfg(feature = "modules")] - module_info: Map::new("andr_modules"), - #[cfg(feature = "modules")] - module_idx: Item::new("andr_module_idx"), - #[cfg(feature = "withdraw")] - withdrawable_tokens: Map::new("withdrawable_tokens"), + #[cfg(feature = "rates")] + rates: Map::new("rates"), } } } diff --git a/andromeda-core/packages/std/src/ado_contract/withdraw.rs b/andromeda-core/packages/std/src/ado_contract/withdraw.rs index 0656230..50f592f 100644 --- a/andromeda-core/packages/std/src/ado_contract/withdraw.rs +++ b/andromeda-core/packages/std/src/ado_contract/withdraw.rs @@ -1,34 +1,47 @@ use crate::ado_contract::ADOContract; use crate::common::context::ExecuteContext; use crate::{ado_base::withdraw::Withdrawal, amp::recipient::Recipient, error::ContractError}; -use cosmwasm_std::{coin, ensure, Order, Response, StdError, Storage, SubMsg}; +use cosmwasm_std::{coin, ensure, MessageInfo, Order, Response, StdError, Storage, SubMsg}; use cw20::Cw20Coin; use cw_asset::AssetInfo; impl<'a> ADOContract<'a> { + /// Add a withdrawable token to self.withdrawable_tokens. Can only be called by the contract's owner or operator. pub fn add_withdrawable_token( &self, storage: &mut dyn Storage, + info: MessageInfo, name: &str, asset_info: &AssetInfo, ) -> Result<(), ContractError> { + ensure!( + self.is_owner_or_operator(storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); if !self.withdrawable_tokens.has(storage, name) { self.withdrawable_tokens.save(storage, name, asset_info)?; } Ok(()) } + /// Remove a withdrawable token from self.withdrawable_tokens. Can only be called by the contract's owner or operator. pub fn remove_withdrawable_token( &self, storage: &mut dyn Storage, + info: MessageInfo, name: &str, ) -> Result<(), ContractError> { + ensure!( + self.is_owner_or_operator(storage, info.sender.as_str())?, + ContractError::Unauthorized {} + ); + self.withdrawable_tokens.remove(storage, name); Ok(()) } - /// Withdraw all tokens in self.withdrawable_tokens with non-zero balance to the given recipient. + /// Withdraw all tokens in self.withdrawable_tokens with non-zero balance to the given recipient. Can only be called by the contract's owner or operator pub fn execute_withdraw( &self, ctx: ExecuteContext, @@ -207,16 +220,11 @@ mod tests { #[test] fn test_execute_withdraw_cw20() { let mut deps = mock_dependencies_custom(&[]); - let operator = "operator"; ADOContract::default() .owner .save(deps.as_mut().storage, &Addr::unchecked("owner")) .unwrap(); - ADOContract::default() - .operators - .save(deps.as_mut().storage, operator, &true) - .unwrap(); - let info = mock_info(operator, &[]); + let info = mock_info("owner", &[]); ADOContract::default() .withdrawable_tokens .save( diff --git a/andromeda-core/packages/std/src/amp/README.md b/andromeda-core/packages/std/src/amp/README.md new file mode 100644 index 0000000..19d230c --- /dev/null +++ b/andromeda-core/packages/std/src/amp/README.md @@ -0,0 +1,77 @@ +# Andromeda Messaging Protocol + +The primary use of this crate is to define the Andromeda Messaging Protocol; a simple wrapper around contract communication that allows for simpler message routing and a larger context. + +## Usage + +There are two core components to the Andromeda Messaging Protocol the [`AndrAddr`](https://docs.andromedaprotocol.io/andromeda/platform-and-framework/common-types#andraddr) struct and the `AMPPkt` struct: + +```rust +// Found in addresses.rs +pub struct AndrAddr(String); + +// Found in messages.rs +pub struct AMPPkt { + /// Any messages associated with the packet + pub messages: Vec, + pub ctx: AMPCtx, +} +``` + +### Andromeda Addresses + +The `AndrAddr` struct is a wrapper around a `String` to allow a user to define with a standard human readable address or a valid VFS path. This struct provides a lot of utility methods to help with validating and resolving these paths. The primary logic for validation is to assume the provided `String` is an address and validate it like so. If this fails we validate that it is a correct VFS path. An example use of this would be: + +```rust +let user_andr_addr = AndrAddr::from_string("~user1/app1/component"); +let addr = user_andr_addr.get_raw_address(&deps)?; + +let raw_andr_addr = AndrAddr::from_string("andr1someaddress123"); +let addr = raw_andr_addr.get_raw_address(&deps)?; +``` + +In the first case we provide a VFS path, this will query the VFS contract that is registered with the kernel to resolve the address. The second is validated as a human readable address and returned straight away. + +### AMP Packet + +An AMP (Andromeda Messaging Protocol) Packet allows a user to specify several messages to be routed via the kernel. The benefit of this is to allow VFS routing (including IBC) and also to allow the receiving contract access to `AMPCtx`: + +```rust +#[cw_serde] +pub struct AMPCtx { + origin: String, + pub previous_sender: String, + pub id: u64, +} +``` + +This provides the `origin` field similar to a smart contract written in Solidity. The `origin` field specifies the original sender of the message (not the current sub message). However, as this is a security risk this context struct is only provided when one of three conditions are met upon the packet reaching the kernel: + +1. The origin field is equivalent to the message sender +2. The sender is a valid ADO +3. The sender is the kernel (Only applicable when an ADO receives the packet) + +The other benefit to using AMP is the use of `AndrAddr` in the messages: + +```rust +pub struct AMPMsg { + /// The message recipient, can be a contract/wallet address or a namespaced URI + pub recipient: AndrAddr, + /// The message to be sent to the recipient + pub message: Binary, + /// Any funds to be attached to the message, defaults to an empty vector + pub funds: Vec, + /// When the message should reply, defaults to Always + pub config: AMPMsgConfig, +} +``` + +Here the `recipient` field is using an Andromeda Address, when the kernel receives this address it is resolved and routed accordingly. The rest of the struct is extremely similar to a standard `WasmMsg` with the exception of `message`. When `Binary::default()` is provided as the message then the kernel assumes the provided message is a `BankMsg::Send` and routes accordingly. + +For more advanced users `AndrAddr` can be used via the kernel to route messages over IBC: + +```rust +let ibc_addr = AndrAddr::from_string("ibc://terra/home/terra-user/terra-app/terra-component"); +``` + +Our kernel will receive this address and route the message accordingly (to the Terra blockchain in this example). \ No newline at end of file diff --git a/andromeda-core/packages/std/src/amp/addresses.rs b/andromeda-core/packages/std/src/amp/addresses.rs index d29edf1..0616c88 100644 --- a/andromeda-core/packages/std/src/amp/addresses.rs +++ b/andromeda-core/packages/std/src/amp/addresses.rs @@ -1,11 +1,26 @@ use std::fmt::{Display, Formatter, Result as FMTResult}; use crate::error::ContractError; -use crate::os::vfs::vfs_resolve_symlink; +use crate::os::vfs::{vfs_resolve_symlink, PATH_REGEX, PROTOCOL_PATH_REGEX}; use crate::{ado_contract::ADOContract, os::vfs::vfs_resolve_path}; +use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Api, Deps, QuerierWrapper, Storage}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use lazy_static::lazy_static; + +lazy_static! { + static ref ANDR_ADDR_REGEX: String = format!( + // Combine all valid regex for ANDR_ADDR schema validations + "({re1})|({re2})|({re3})|({re4})", + // Protocol regex + re1 = PROTOCOL_PATH_REGEX, + // Path regex + re2 = PATH_REGEX, + // Raw address + re3 = r"^[a-z0-9]{2,}$", + // Local path + re4 = r"^\.(/[A-Za-z0-9.\-_]{2,40}?)*(/)?$", + ); +} /// An address that can be used within the Andromeda ecosystem. /// Inspired by the cosmwasm-std `Addr` type. https://github.com/CosmWasm/cosmwasm/blob/2a1c698520a1aacedfe3f4803b0d7d653892217a/packages/std/src/addresses.rs#L33 @@ -17,10 +32,8 @@ use serde::{Deserialize, Serialize}; /// VFS paths can be local in the case of an app and can be done by referencing `./component` they can also contain protocols for cross chain communication. A VFS path is usually structured as so: /// /// `:///` or `ibc://cosmoshub-4/user/app/component` -#[derive( - Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, JsonSchema, -)] -pub struct AndrAddr(String); +#[cw_serde] +pub struct AndrAddr(#[schemars(regex = "ANDR_ADDR_REGEX")] String); impl AndrAddr { #[inline] @@ -43,6 +56,11 @@ impl AndrAddr { AndrAddr(addr.into()) } + #[inline] + pub fn to_lowercase(&self) -> AndrAddr { + AndrAddr(self.0.to_lowercase()) + } + /// Validates an `AndrAddr`, to be valid the given address must either be a human readable address or a valid VFS path. /// /// **The existence of the provided path is not validated.** @@ -88,13 +106,20 @@ impl AndrAddr { let valid_vfs_path = self.local_path_to_vfs_path(deps.storage, &deps.querier, vfs_contract.clone())?; let vfs_addr = Addr::unchecked(vfs_contract); - vfs_resolve_path(valid_vfs_path, vfs_addr, &deps.querier) + vfs_resolve_path(valid_vfs_path.clone(), vfs_addr, &deps.querier) + .ok() + .ok_or(ContractError::InvalidPathname { + error: Some(format!( + "{:?} does not exist in the file system", + valid_vfs_path.0 + )), + }) } } } /// Converts a local path to a valid VFS path by replacing `./` with the app contract address - fn local_path_to_vfs_path( + pub fn local_path_to_vfs_path( &self, storage: &dyn Storage, querier: &QuerierWrapper, @@ -106,8 +131,7 @@ impl AndrAddr { match app_contract { None => Err(ContractError::AppContractNotSpecified {}), Some(app_contract) => { - let replaced = - AndrAddr(self.0.replace("./", &format!("/home/{app_contract}/"))); + let replaced = AndrAddr(self.0.replace("./", &format!("~{app_contract}/"))); vfs_resolve_symlink(replaced, vfs_contract, querier) } } @@ -267,8 +291,14 @@ impl From<&AndrAddr> for String { #[cfg(test)] mod tests { use cosmwasm_std::testing::mock_dependencies; + use regex::Regex; use super::*; + struct ValidateRegexTestCase { + name: &'static str, + input: &'static str, + should_err: bool, + } #[test] fn test_validate() { @@ -294,6 +324,9 @@ mod tests { let addr = AndrAddr("/home/user/app/component".to_string()); assert!(addr.is_vfs_path()); + let addr = AndrAddr("./user/app/component".to_string()); + assert!(addr.is_vfs_path()); + let addr = AndrAddr("ibc://chain/home/user/app/component".to_string()); assert!(addr.is_vfs_path()); @@ -342,11 +375,11 @@ mod tests { let addr = AndrAddr("cosmos1...".to_string()); assert_eq!(addr.get_raw_path(), "cosmos1..."); - let addr = AndrAddr("ibc://chain/user/app/component".to_string()); - assert_eq!(addr.get_raw_path(), "/user/app/component"); + let addr = AndrAddr("ibc://chain/home/app/component".to_string()); + assert_eq!(addr.get_raw_path(), "/home/app/component"); - let addr = AndrAddr("/chain/user/app/component".to_string()); - assert_eq!(addr.get_raw_path(), "/chain/user/app/component"); + let addr = AndrAddr("/chain/home/app/component".to_string()); + assert_eq!(addr.get_raw_path(), "/chain/home/app/component"); } #[test] @@ -369,4 +402,55 @@ mod tests { let addr = AndrAddr("./home/user1".to_string()); assert_eq!(addr.get_root_dir(), "./home/user1"); } + + #[test] + fn test_schemars_regex() { + let test_cases: Vec = vec![ + ValidateRegexTestCase { + name: "Normal Path", + input: "/home/user", + should_err: false, + }, + ValidateRegexTestCase { + name: "Path with tilde", + input: "~user/dir", + should_err: false, + }, + ValidateRegexTestCase { + name: "Wrong path with tilde", + input: "~/user/dir", + should_err: true, + }, + ValidateRegexTestCase { + name: "Valid protocol", + input: "ibc://chain/home/user/dir", + should_err: false, + }, + ValidateRegexTestCase { + name: "Valid protocol with tilde", + input: "ibc://chain/~user/dir", + should_err: false, + }, + ValidateRegexTestCase { + name: "Valid Raw Address", + input: "cosmos1234567", + should_err: false, + }, + ValidateRegexTestCase { + name: "Valid Local", + input: "./dir/file", + should_err: false, + }, + ValidateRegexTestCase { + name: "Invalid Local", + input: "../dir/file", + should_err: true, + }, + ]; + let re = Regex::new(&ANDR_ADDR_REGEX).unwrap(); + for test in test_cases { + let res = re.is_match(test.input); + assert_eq!(!res, test.should_err, "Test case: {}", test.name); + } + } } diff --git a/andromeda-core/packages/std/src/amp/messages.rs b/andromeda-core/packages/std/src/amp/messages.rs index a7e7ba2..0d8b80d 100644 --- a/andromeda-core/packages/std/src/amp/messages.rs +++ b/andromeda-core/packages/std/src/amp/messages.rs @@ -2,11 +2,11 @@ use crate::ado_contract::ADOContract; use crate::common::encode_binary; use crate::error::ContractError; use crate::os::aos_querier::AOSQuerier; -use crate::os::{kernel::ExecuteMsg as KernelExecuteMsg, kernel::QueryMsg as KernelQueryMsg}; +use crate::os::kernel::ExecuteMsg as KernelExecuteMsg; use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Coin, ContractInfoResponse, CosmosMsg, Deps, MessageInfo, - QueryRequest, ReplyOn, SubMsg, WasmMsg, WasmQuery, + to_json_binary, wasm_execute, Addr, Binary, Coin, ContractInfoResponse, CosmosMsg, Deps, Empty, + MessageInfo, QueryRequest, ReplyOn, SubMsg, WasmMsg, WasmQuery, }; use super::addresses::AndrAddr; @@ -150,6 +150,15 @@ impl AMPMsg { }) } + pub fn generate_sub_msg_direct(&self, addr: Addr, id: u64) -> SubMsg { + SubMsg { + id, + reply_on: self.config.reply_on.clone(), + gas_limit: self.config.gas_limit, + msg: CosmosMsg::Wasm(wasm_execute(addr, &self.message, self.funds.to_vec()).unwrap()), + } + } + pub fn to_ibc_hooks_memo(&self, contract_addr: String, callback_addr: String) -> String { #[derive(::serde::Serialize)] struct IbcHooksWasmMsg { @@ -279,8 +288,8 @@ impl AMPPkt { pub fn get_messages_for_recipient(&self, recipient: String) -> Vec { self.messages .iter() - .cloned() .filter(|msg| msg.recipient == recipient.clone()) + .cloned() .collect() } @@ -294,16 +303,13 @@ impl AMPPkt { /// If the sender is not valid, an error is returned pub fn verify_origin(&self, info: &MessageInfo, deps: &Deps) -> Result<(), ContractError> { let kernel_address = ADOContract::default().get_kernel_address(deps.storage)?; - if info.sender == self.ctx.origin || info.sender == kernel_address { + if (info.sender == self.ctx.origin && info.sender == self.ctx.previous_sender) + || info.sender == kernel_address + { Ok(()) } else { let adodb_address: Addr = - deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: kernel_address.to_string(), - msg: to_json_binary(&KernelQueryMsg::KeyAddress { - key: ADO_DB_KEY.to_string(), - })?, - }))?; + AOSQuerier::kernel_address_getter(&deps.querier, &kernel_address, ADO_DB_KEY)?; // Get the sender's Code ID let contract_info: ContractInfoResponse = @@ -495,9 +501,15 @@ mod tests { let res = pkt.verify_origin(&info, &deps.as_ref()); assert!(res.is_err()); - let offchain_pkt = AMPPkt::new(INVALID_CONTRACT, INVALID_CONTRACT, vec![msg]); - let res = offchain_pkt.verify_origin(&info, &deps.as_ref()); + // Previous sender and origin set correctly + let direct_pkt_valid = AMPPkt::new(INVALID_CONTRACT, INVALID_CONTRACT, vec![msg.clone()]); + let res = direct_pkt_valid.verify_origin(&info, &deps.as_ref()); assert!(res.is_ok()); + + // Previous sender and origin set incorrectly + let direct_pkt_invalid = AMPPkt::new(INVALID_CONTRACT, "notvalid", vec![msg]); + let res = direct_pkt_invalid.verify_origin(&info, &deps.as_ref()); + assert!(res.is_err()); } #[test] diff --git a/andromeda-core/packages/std/src/amp/recipient.rs b/andromeda-core/packages/std/src/amp/recipient.rs index 8956555..8797cbc 100644 --- a/andromeda-core/packages/std/src/amp/recipient.rs +++ b/andromeda-core/packages/std/src/amp/recipient.rs @@ -1,5 +1,5 @@ use super::{addresses::AndrAddr, messages::AMPMsg}; -use crate::{common::encode_binary, error::ContractError}; +use crate::{ado_contract::ADOContract, common::encode_binary, error::ContractError}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{to_json_binary, BankMsg, Binary, Coin, CosmosMsg, Deps, SubMsg, WasmMsg}; use cw20::{Cw20Coin, Cw20ExecuteMsg}; @@ -27,6 +27,20 @@ impl Recipient { } } + /// Validates a recipient by validating its address and recovery address (if it is provided) + pub fn validate(&self, deps: &Deps) -> Result<(), ContractError> { + self.address.validate(deps.api)?; + self.address.get_raw_address(deps)?; + + // Validate the recovery address if it is providedReci + if let Some(ibc_recovery_address) = self.ibc_recovery_address.clone() { + ibc_recovery_address.validate(deps.api)?; + ibc_recovery_address.get_raw_address(deps)?; + } + + Ok(()) + } + /// Creates a Recipient from the given string with no attached message pub fn from_string(addr: impl Into) -> Recipient { Recipient { @@ -98,13 +112,22 @@ impl Recipient { /// Generates an AMP message from the given Recipient. /// /// This can be attached to an AMP Packet for execution via the aOS. - pub fn generate_amp_msg(&self, funds: Option>) -> AMPMsg { - AMPMsg::new( - self.address.to_string(), + pub fn generate_amp_msg( + &self, + deps: &Deps, + funds: Option>, + ) -> Result { + let mut address = self.address.clone(); + if address.is_local_path() { + let vfs_addr = ADOContract::default().get_vfs_address(deps.storage, &deps.querier)?; + address = address.local_path_to_vfs_path(deps.storage, &deps.querier, vfs_addr)?; + } + Ok(AMPMsg::new( + address.to_string(), self.msg.clone().unwrap_or_default(), funds, ) - .with_ibc_recovery(self.ibc_recovery_address.clone()) + .with_ibc_recovery(self.ibc_recovery_address.clone())) } /// Adds an IBC recovery address to the recipient @@ -126,7 +149,9 @@ impl Recipient { #[cfg(test)] mod test { - use cosmwasm_std::{from_json, testing::mock_dependencies, Uint128}; + use cosmwasm_std::{from_json, testing::mock_dependencies, Addr, Uint128}; + + use crate::testing::mock_querier::{mock_dependencies_custom, MOCK_APP_CONTRACT}; use super::*; @@ -229,13 +254,14 @@ mod test { #[test] fn test_generate_amp_msg() { let recipient = Recipient::from_string("test"); - let msg = recipient.generate_amp_msg(None); + let mut deps = mock_dependencies_custom(&[]); + let msg = recipient.generate_amp_msg(&deps.as_ref(), None).unwrap(); assert_eq!(msg.recipient, "test"); assert_eq!(msg.message, Binary::default()); assert_eq!(msg.funds, vec![] as Vec); let recipient = Recipient::new("test", Some(Binary::from(b"test".to_vec()))); - let msg = recipient.generate_amp_msg(None); + let msg = recipient.generate_amp_msg(&deps.as_ref(), None).unwrap(); assert_eq!(msg.recipient, "test"); assert_eq!(msg.message, Binary::from(b"test".to_vec())); assert_eq!(msg.funds, vec![] as Vec); @@ -245,9 +271,26 @@ mod test { amount: Uint128::from(100u128), }]; let recipient = Recipient::from_string("test"); - let msg = recipient.generate_amp_msg(Some(funds.clone())); + let msg = recipient + .generate_amp_msg(&deps.as_ref(), Some(funds.clone())) + .unwrap(); assert_eq!(msg.recipient, "test"); assert_eq!(msg.message, Binary::default()); assert_eq!(msg.funds, funds); + + ADOContract::default() + .app_contract + .save(deps.as_mut().storage, &Addr::unchecked(MOCK_APP_CONTRACT)) + .unwrap(); + let recipient = Recipient::from_string("./test"); + let msg = recipient + .generate_amp_msg(&deps.as_ref(), Some(funds.clone())) + .unwrap(); + assert_eq!( + msg.recipient.to_string(), + format!("~{MOCK_APP_CONTRACT}/test") + ); + assert_eq!(msg.message, Binary::default()); + assert_eq!(msg.funds, funds); } } diff --git a/andromeda-core/packages/std/src/common/actions.rs b/andromeda-core/packages/std/src/common/actions.rs new file mode 100644 index 0000000..04f4284 --- /dev/null +++ b/andromeda-core/packages/std/src/common/actions.rs @@ -0,0 +1,30 @@ +use crate::{ + ado_contract::{permissioning::is_context_permissioned, ADOContract}, + amp::messages::AMPPkt, + error::ContractError, +}; +use cosmwasm_std::{ensure, DepsMut, Env, MessageInfo, Response}; + +pub fn call_action( + deps: &mut DepsMut, + info: &MessageInfo, + env: &Env, + amp_ctx: &Option, + action: &str, +) -> Result { + ensure!( + is_context_permissioned(deps, info, env, amp_ctx, action)?, + ContractError::Unauthorized {} + ); + + let payee = if let Some(amp_ctx) = amp_ctx.clone() { + deps.api.addr_validate(amp_ctx.ctx.get_origin().as_str())? + } else { + info.sender.clone() + }; + + let fee_msg = + ADOContract::default().pay_fee(deps.storage, &deps.querier, action.to_owned(), payee)?; + + Ok(Response::default().add_submessage(fee_msg)) +} diff --git a/andromeda-core/packages/std/src/common/denom.rs b/andromeda-core/packages/std/src/common/denom.rs new file mode 100644 index 0000000..d1eb85c --- /dev/null +++ b/andromeda-core/packages/std/src/common/denom.rs @@ -0,0 +1,113 @@ +use std::fmt::{Display, Formatter, Result as StdResult}; + +use crate::{ado_contract::ADOContract, amp::AndrAddr, error::ContractError}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ + coin, ensure, to_json_binary, wasm_execute, BankMsg, Deps, DepsMut, Env, QueryRequest, SubMsg, + Uint128, WasmQuery, +}; +use cw20::{Cw20ExecuteMsg, Cw20QueryMsg, TokenInfoResponse}; +pub const SEND_CW20_ACTION: &str = "SEND_CW20"; +pub const SEND_NFT_ACTION: &str = "SEND_NFT"; + +#[cw_serde] +pub enum Asset { + Cw20Token(AndrAddr), + NativeToken(String), +} + +impl Display for Asset { + fn fmt(&self, f: &mut Formatter) -> StdResult { + match self { + Asset::NativeToken(addr) => f.write_str(&format!("native:{addr}")), + Asset::Cw20Token(addr) => f.write_str(&format!("cw20:{addr}")), + } + } +} + +impl Asset { + pub fn get_verified_asset( + &self, + deps: DepsMut, + env: Env, + ) -> Result<(String, bool), ContractError> { + match self { + Asset::Cw20Token(cw20_token) => { + let cw20_token = cw20_token.get_raw_address(&deps.as_ref())?; + let token_info_query: TokenInfoResponse = + deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: cw20_token.to_string(), + msg: to_json_binary(&Cw20QueryMsg::TokenInfo {})?, + }))?; + ensure!( + !token_info_query.total_supply.is_zero(), + ContractError::InvalidZeroAmount {} + ); + let valid_cw20_auction = ADOContract::default() + .is_permissioned(deps, env, SEND_CW20_ACTION, cw20_token.clone()) + .is_ok(); + ensure!( + valid_cw20_auction, + ContractError::InvalidFunds { + msg: format!("Non-permissioned CW20 asset '{}' set as denom.", cw20_token) + } + ); + Ok((cw20_token.to_string(), true)) + } + Asset::NativeToken(native) => { + validate_denom(deps.as_ref(), native.clone())?; + Ok((native.to_string(), false)) + } + } + } + pub fn transfer( + &self, + deps: &Deps, + to_address: impl Into, + amount: Uint128, + ) -> Result { + let to_address: String = to_address.into(); + + Ok(match self { + Asset::NativeToken(denom) => SubMsg::new(BankMsg::Send { + to_address, + amount: vec![coin(amount.u128(), denom)], + }), + Asset::Cw20Token(denom) => { + let denom = denom.get_raw_address(deps)?; + let transfer_msg = Cw20ExecuteMsg::Transfer { + recipient: to_address, + amount, + }; + let wasm_msg = wasm_execute(denom, &transfer_msg, vec![])?; + SubMsg::new(wasm_msg) + } + }) + } + + pub fn burn(&self, deps: &Deps, amount: Uint128) -> Result { + Ok(match self { + Asset::NativeToken(denom) => SubMsg::new(BankMsg::Burn { + amount: vec![coin(amount.u128(), denom)], + }), + Asset::Cw20Token(denom) => { + let denom = denom.get_raw_address(deps)?; + let burn_msg = Cw20ExecuteMsg::Burn { amount }; + let wasm_msg = wasm_execute(denom, &burn_msg, vec![])?; + SubMsg::new(wasm_msg) + } + }) + } +} + +pub fn validate_denom(deps: Deps, denom: String) -> Result<(), ContractError> { + let potential_supply = deps.querier.query_supply(denom.clone())?; + let non_empty_denom = !denom.is_empty(); + let non_zero_supply = !potential_supply.amount.is_zero(); + ensure!( + non_empty_denom && non_zero_supply, + ContractError::InvalidAsset { asset: denom } + ); + + Ok(()) +} diff --git a/andromeda-core/packages/std/src/common/expiration.rs b/andromeda-core/packages/std/src/common/expiration.rs index 3950186..f33ff95 100644 --- a/andromeda-core/packages/std/src/common/expiration.rs +++ b/andromeda-core/packages/std/src/common/expiration.rs @@ -1,26 +1,72 @@ -use cosmwasm_std::{ensure, BlockInfo, Timestamp}; +use std::fmt::{self, Display}; + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{ensure, BlockInfo, Env, Timestamp}; use cw_utils::Expiration; use crate::error::ContractError; +use super::Milliseconds; + pub const MILLISECONDS_TO_NANOSECONDS_RATIO: u64 = 1_000_000; +/// The Expiry type is used to define an expiry time using milliseconds +/// +/// There are two types: +/// 1. FromNow(Milliseconds) - The expiry time is relative to the current time +/// 2. AtTime(Milliseconds) - The expiry time is absolute +#[cw_serde] +pub enum Expiry { + FromNow(Milliseconds), + AtTime(Milliseconds), +} + +impl Expiry { + /// Gets the expected expiry time provided the given block + pub fn get_time(&self, block: &BlockInfo) -> Milliseconds { + match self { + Expiry::FromNow(milliseconds) => { + // Get current time from block + let current_time = Milliseconds::from_nanos(block.time.nanos()); + // Add the expected expiry time from now + current_time.plus_milliseconds(*milliseconds) + } + // Given time is absolute + Expiry::AtTime(milliseconds) => *milliseconds, + } + } +} + +/// Expiry defaults to an absolute time of 0 +impl Default for Expiry { + fn default() -> Self { + Expiry::AtTime(Milliseconds::default()) + } +} + +impl Display for Expiry { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Expiry::FromNow(milliseconds) => write!(f, "{} milliseconds from now", milliseconds), + Expiry::AtTime(milliseconds) => write!(f, "At time: {}", milliseconds), + } + } +} + /// Creates a CosmWasm Expiration struct given a time in milliseconds /// # Arguments /// /// * `time` - The expiration time in milliseconds since the Epoch /// /// Returns a `cw_utils::Expiration::AtTime` struct with the given expiration time -pub fn expiration_from_milliseconds(time: u64) -> Result { +pub fn expiration_from_milliseconds(time: Milliseconds) -> Result { // Make sure that multiplying by above ratio does not exceed u64 limit ensure!( - time <= u64::MAX / MILLISECONDS_TO_NANOSECONDS_RATIO, + time.milliseconds() <= u64::MAX / MILLISECONDS_TO_NANOSECONDS_RATIO, ContractError::InvalidExpirationTime {} ); - Ok(Expiration::AtTime(Timestamp::from_nanos( - time * MILLISECONDS_TO_NANOSECONDS_RATIO, - ))) + Ok(Expiration::AtTime(Timestamp::from_nanos(time.nanos()))) } pub fn block_to_expiration(block: &BlockInfo, model: Expiration) -> Option { @@ -31,6 +77,32 @@ pub fn block_to_expiration(block: &BlockInfo, model: Expiration) -> Option, +) -> Result<(Expiration, Milliseconds), ContractError> { + let current_time = Milliseconds::from_nanos(env.block.time.nanos()).milliseconds(); + + let start_expiration = if let Some(start_time) = start_time { + expiration_from_milliseconds(start_time.get_time(&env.block))? + } else { + // Set as current time + 1 so that it isn't expired from the very start + expiration_from_milliseconds(Milliseconds(current_time + 1))? + }; + + // Validate start time + let block_time = block_to_expiration(&env.block, start_expiration).unwrap(); + ensure!( + start_expiration.gt(&block_time), + ContractError::StartTimeInThePast { + current_time, + current_block: env.block.height, + } + ); + + Ok((start_expiration, Milliseconds(current_time))) +} + #[cfg(test)] mod tests { use super::*; @@ -38,14 +110,26 @@ mod tests { #[test] fn test_expiration_from_milliseconds() { let time = u64::MAX; - let result = expiration_from_milliseconds(time).unwrap_err(); + let result = expiration_from_milliseconds(Milliseconds(time)).unwrap_err(); assert_eq!(result, ContractError::InvalidExpirationTime {}); let valid_time = 100; - let result = expiration_from_milliseconds(valid_time).unwrap(); + let result = expiration_from_milliseconds(Milliseconds(valid_time)).unwrap(); assert_eq!( Expiration::AtTime(Timestamp::from_nanos(100000000u64)), result ) } + + #[test] + fn test_expiry_from_now() { + let block = BlockInfo { + height: 100, + time: Timestamp::from_nanos(100000000u64), + chain_id: "test-chain".to_string(), + }; + + let expiry = Expiry::FromNow(Milliseconds(100)); + assert_eq!(expiry.get_time(&block), Milliseconds(200)); + } } diff --git a/andromeda-core/packages/std/src/common/migration.rs b/andromeda-core/packages/std/src/common/migration.rs new file mode 100644 index 0000000..f754e0b --- /dev/null +++ b/andromeda-core/packages/std/src/common/migration.rs @@ -0,0 +1,35 @@ +use cosmwasm_std::{ensure, Deps}; +use cw2::get_contract_version; +use semver::Version; + +use crate::error::{from_semver, ContractError}; +/// Ensure compatibility when migrating from the previous version. +/// +/// min_version specifies the oldest version that is still compatible. +/// If the original version is older than min_version, the migration should fail. +pub fn ensure_compatibility(deps: &Deps, min_version: &str) -> Result<(), ContractError> { + let prev = get_contract_version(deps.storage)?; + let prev: Version = prev.version.parse().map_err(from_semver)?; + let min_version: Version = min_version.parse().unwrap(); + + ensure!( + prev >= min_version, + ContractError::InvalidMigration { + prev: prev.to_string() + } + ); + Ok(()) +} + +#[test] +fn test_ensure_compatibility() { + let mut deps = crate::testing::mock_querier::mock_dependencies_custom(&[]); + cw2::set_contract_version(&mut deps.storage, "crowdfund", "1.0.0").unwrap(); + let res = ensure_compatibility(&deps.as_ref(), "1.1.0").unwrap_err(); + assert_eq!( + res, + ContractError::InvalidMigration { + prev: "1.0.0".to_string() + } + ) +} diff --git a/andromeda-core/packages/std/src/common/milliseconds.rs b/andromeda-core/packages/std/src/common/milliseconds.rs new file mode 100644 index 0000000..36859c2 --- /dev/null +++ b/andromeda-core/packages/std/src/common/milliseconds.rs @@ -0,0 +1,173 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{BlockInfo, Timestamp}; +use cw20::Expiration; + +#[cw_serde] +#[derive(Default, Eq, PartialOrd, Copy)] +/// Represents time in milliseconds. +pub struct Milliseconds(pub u64); +pub type MillisecondsDuration = Milliseconds; +pub type MillisecondsExpiration = Milliseconds; + +impl Milliseconds { + pub fn is_expired(&self, block: &BlockInfo) -> bool { + let time = Self::from_nanos(block.time.nanos()); + self.0 <= time.0 + } + + pub fn is_in_past(&self, block: &BlockInfo) -> bool { + let time = Self::from_nanos(block.time.nanos()); + self.0 < time.0 + } + + #[inline] + pub fn zero() -> Milliseconds { + Milliseconds(0) + } + + #[inline] + pub fn is_zero(&self) -> bool { + self.0 == 0 + } + + #[inline] + pub fn from_seconds(seconds: u64) -> Milliseconds { + if seconds > u64::MAX / 1000 { + panic!("Overflow: Cannot convert seconds to milliseconds") + } + + Milliseconds(seconds * 1000) + } + + #[inline] + pub fn from_nanos(nanos: u64) -> Milliseconds { + Milliseconds(nanos / 1000000) + } + + #[inline] + pub fn milliseconds(&self) -> u64 { + self.0 + } + + #[inline] + pub fn seconds(&self) -> u64 { + self.0 / 1000 + } + + #[inline] + pub fn nanos(&self) -> u64 { + if self.0 > u64::MAX / 1000000 { + panic!("Overflow: Cannot convert milliseconds time to nanoseconds") + } + self.0 * 1000000 + } + + pub fn add_milliseconds(&mut self, milliseconds: Milliseconds) { + self.0 += milliseconds.0; + } + + pub fn subtract_milliseconds(&mut self, milliseconds: Milliseconds) { + self.0 -= milliseconds.0; + } + + pub fn plus_milliseconds(self, milliseconds: Milliseconds) -> Milliseconds { + Milliseconds(self.0 + milliseconds.0) + } + + pub fn minus_milliseconds(self, milliseconds: Milliseconds) -> Milliseconds { + Milliseconds(self.0 - milliseconds.0) + } + + pub fn add_seconds(&mut self, seconds: u64) { + self.0 += seconds * 1000; + } + + pub fn subtract_seconds(&mut self, seconds: u64) { + if seconds > self.0 / 1000 { + panic!("Overflow: Cannot subtract seconds from milliseconds") + } + + self.0 -= seconds * 1000; + } + + pub fn plus_seconds(self, seconds: u64) -> Milliseconds { + Milliseconds(self.0 + seconds * 1000) + } + + pub fn minus_seconds(self, seconds: u64) -> Milliseconds { + Milliseconds(self.0 - seconds * 1000) + } +} + +impl From for String { + fn from(time: Milliseconds) -> String { + time.0.to_string() + } +} + +impl From for Timestamp { + fn from(time: Milliseconds) -> Timestamp { + Timestamp::from_nanos(time.nanos()) + } +} + +impl From for Expiration { + fn from(time: Milliseconds) -> Expiration { + Expiration::AtTime(time.into()) + } +} + +impl std::fmt::Display for Milliseconds { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +#[cfg(test)] +mod test { + use cosmwasm_std::testing::mock_env; + + use super::*; + + struct IsExpiredTestCase { + name: &'static str, + input: u64, + curr_time: u64, + is_expired: bool, + } + + #[test] + fn test_is_expired() { + let test_cases: Vec = vec![ + IsExpiredTestCase { + name: "valid expiration time (expired)", + input: 0, + curr_time: 1, + is_expired: true, + }, + IsExpiredTestCase { + name: "valid expiration time (not expired)", + input: 1, + curr_time: 0, + is_expired: false, + }, + IsExpiredTestCase { + name: "same time (expired)", + input: 0, + curr_time: 0, + is_expired: true, + }, + ]; + + for test in test_cases { + let input = Milliseconds(test.input); + let curr_time = Milliseconds(test.curr_time); + let mut env = mock_env(); + env.block.time = curr_time.into(); + + let output = input.is_expired(&env.block); + + assert_eq!(test.is_expired, output, "Test failed: {}", test.name) + } + } +} diff --git a/andromeda-core/packages/std/src/common/mod.rs b/andromeda-core/packages/std/src/common/mod.rs index 12a4121..350c38f 100644 --- a/andromeda-core/packages/std/src/common/mod.rs +++ b/andromeda-core/packages/std/src/common/mod.rs @@ -1,17 +1,23 @@ +pub mod actions; pub mod context; +pub mod denom; pub mod expiration; -pub mod queries; +pub mod migration; +pub mod milliseconds; pub mod rates; +pub mod reply; pub mod response; pub mod withdraw; +pub use milliseconds::*; + use crate::error::ContractError; use cosmwasm_std::{ - ensure, from_json, to_json_binary, BankMsg, Binary, Coin, CosmosMsg, QuerierWrapper, SubMsg, + ensure, has_coins, to_json_binary, BankMsg, Binary, Coin, CosmosMsg, SubMsg, Uint128, }; use cw20::Cw20Coin; -use serde::{de::DeserializeOwned, Serialize}; +use serde::Serialize; use std::collections::BTreeMap; use cosmwasm_schema::cw_serde; @@ -21,24 +27,6 @@ pub enum OrderBy { Desc, } -pub fn parse_struct(val: &Binary) -> Result -where - T: DeserializeOwned, -{ - let data_res = from_json(val); - match data_res { - Ok(data) => Ok(data), - Err(err) => Err(ContractError::ParsingError { - err: err.to_string(), - }), - } -} - -pub fn parse_message(data: &Option) -> Result { - let data = unwrap_or_err(data, ContractError::MissingRequiredMessageData {})?; - parse_struct::(data) -} - pub fn encode_binary(val: &T) -> Result where T: Serialize, @@ -49,24 +37,6 @@ where } } -pub fn unwrap_or_err(val_opt: &Option, err: ContractError) -> Result<&T, ContractError> { - match val_opt { - Some(val) => Ok(val), - None => Err(err), - } -} - -pub fn query_primitive( - _querier: QuerierWrapper, - _contract_address: String, - _key: Option, -) -> Result -where - T: DeserializeOwned, -{ - todo!() -} - #[cw_serde] pub enum Funds { Native(Coin), @@ -83,6 +53,14 @@ impl Funds { }), } } + pub fn try_get_cw20_coin(&self) -> Result { + match self { + Funds::Cw20(cw20_coin) => Ok(cw20_coin.clone()), + Funds::Native(_) => Err(ContractError::ParsingError { + err: "Native funds were sent while CW20 funds were expected".to_string(), + }), + } + } } /// Merges bank messages to the same recipient to a single bank message. Any sub messages @@ -102,9 +80,14 @@ pub fn merge_sub_msgs(msgs: Vec) -> Vec { for msg in msgs.into_iter() { match msg.msg { CosmosMsg::Bank(BankMsg::Send { to_address, amount }) => { - let current_coins = map.get_mut(&to_address); + let current_coins = map.get(&to_address); match current_coins { - Some(current_coins) => merge_coins(current_coins, amount), + Some(current_coins) => { + map.insert( + to_address.to_owned(), + merge_coins(current_coins.to_vec(), amount), + ); + } None => { map.insert(to_address.to_owned(), amount); } @@ -133,21 +116,46 @@ pub fn merge_sub_msgs(msgs: Vec) -> Vec { /// same denom /// /// Returns nothing as it is done in place. -pub fn merge_coins(coins: &mut Vec, coins_to_add: Vec) { +pub fn merge_coins(coins: Vec, coins_to_add: Vec) -> Vec { + let mut new_coins: Vec = if !coins.is_empty() { + merge_coins(vec![], coins.to_vec()) + } else { + vec![] + }; // Not the most efficient algorithm (O(n * m)) but we don't expect to deal with very large arrays of Coin, // typically at most 2 denoms. Even in the future there are not that many Terra native coins // where this will be a problem. - for coin in coins.iter_mut() { - let same_denom_coin = coins_to_add.iter().find(|&c| c.denom == coin.denom); - if let Some(same_denom_coin) = same_denom_coin { - coin.amount += same_denom_coin.amount; + + for coin in coins_to_add { + let mut same_denom_coins = new_coins.iter_mut().filter(|c| c.denom == coin.denom); + if let Some(same_denom_coin) = same_denom_coins.next() { + same_denom_coin.amount += coin.amount + } else { + new_coins.push(coin); } } - for coin_to_add in coins_to_add.iter() { - if !coins.iter().any(|c| c.denom == coin_to_add.denom) { - coins.push(coin_to_add.clone()); - } + + new_coins +} + +/// Checks if the required funds can be covered by merging the provided coins. +/// +/// ## Arguments +/// * `coins` - The vector of `Coin` structs representing the available coins +/// * `required` - The vector of `Coin` structs representing the required funds +/// +/// Returns true if the required funds can be covered by merging the available coins, false otherwise. +pub fn has_coins_merged(coins: &[Coin], required: &[Coin]) -> bool { + let merged_coins = merge_coins(vec![], coins.to_vec()); + let merged_required = merge_coins(vec![], required.to_vec()); + + for required_funds in merged_required { + if !has_coins(&merged_coins, &required_funds) { + return false; + }; } + + true } /// Deducts a given amount from a vector of `Coin` structs. Alters the given vector, does not return a new vector. @@ -155,25 +163,34 @@ pub fn merge_coins(coins: &mut Vec, coins_to_add: Vec) { /// ## Arguments /// * `coins` - The vector of `Coin` structs from which to deduct the given funds /// * `funds` - The amount to deduct -pub fn deduct_funds(coins: &mut [Coin], funds: &Coin) -> Result { - let coin_amount = coins.iter_mut().find(|c| c.denom.eq(&funds.denom)); - - match coin_amount { - Some(c) => { - ensure!( - c.amount >= funds.amount, - ContractError::InsufficientFunds {} - ); - c.amount -= funds.amount; - Ok(true) +pub fn deduct_funds(coins: &mut [Coin], funds: &Coin) -> Result<(), ContractError> { + let coin_amount: Vec<&mut Coin> = coins + .iter_mut() + .filter(|c| c.denom.eq(&funds.denom)) + .collect(); + + let mut remainder = funds.amount; + for same_coin in coin_amount { + if same_coin.amount > remainder { + same_coin.amount = same_coin.amount.checked_sub(remainder)?; + return Ok(()); + } else { + remainder = remainder.checked_sub(same_coin.amount)?; + same_coin.amount = Uint128::zero(); } - None => Err(ContractError::InsufficientFunds {}), } + + ensure!( + remainder == Uint128::zero(), + ContractError::InsufficientFunds {} + ); + + Ok(()) } #[cfg(test)] mod test { - use cosmwasm_std::{coin, to_json_binary, Uint128, WasmMsg}; + use cosmwasm_std::{coin, Uint128, WasmMsg}; use cw20::Expiration; use super::*; @@ -184,32 +201,22 @@ mod test { expiration: Expiration, } - #[test] - fn test_parse_struct() { - let valid_json = to_json_binary(&TestStruct { - name: "John Doe".to_string(), - expiration: Expiration::AtHeight(123), - }) - .unwrap(); - - let test_struct: TestStruct = parse_struct(&valid_json).unwrap(); - assert_eq!(test_struct.name, "John Doe"); - assert_eq!(test_struct.expiration, Expiration::AtHeight(123)); - - let invalid_json = to_json_binary("notavalidteststruct").unwrap(); - - assert!(parse_struct::(&invalid_json).is_err()) - } - #[test] fn test_merge_coins() { - let mut coins = vec![coin(100, "uusd"), coin(100, "uluna")]; - let funds_to_add = vec![coin(25, "uluna"), coin(50, "uusd"), coin(100, "ucad")]; + let coins = vec![coin(100, "uusd"), coin(100, "uluna")]; + let funds_to_add = vec![ + coin(25, "uluna"), + coin(50, "uusd"), + coin(100, "ucad"), + coin(50, "uluna"), + coin(100, "uluna"), + coin(100, "ucad"), + ]; - merge_coins(&mut coins, funds_to_add); + let res = merge_coins(coins, funds_to_add); assert_eq!( - vec![coin(150, "uusd"), coin(125, "uluna"), coin(100, "ucad")], - coins + vec![coin(150, "uusd"), coin(275, "uluna"), coin(200, "ucad")], + res ); } @@ -264,20 +271,45 @@ mod test { #[test] fn test_deduct_funds() { - let mut funds: Vec = vec![coin(100, "uluna")]; + let mut funds: Vec = vec![coin(5, "uluna"), coin(100, "uusd"), coin(100, "uluna")]; deduct_funds(&mut funds, &coin(10, "uluna")).unwrap(); - assert_eq!(Uint128::from(90_u64), funds[0].amount); + assert_eq!(Uint128::zero(), funds[0].amount); assert_eq!(String::from("uluna"), funds[0].denom); + assert_eq!(Uint128::from(95u128), funds[2].amount); + assert_eq!(String::from("uluna"), funds[2].denom); let mut funds: Vec = vec![Coin { denom: String::from("uluna"), - amount: Uint128::from(5_u64), + amount: Uint128::from(5u64), }]; let e = deduct_funds(&mut funds, &coin(10, "uluna")).unwrap_err(); assert_eq!(ContractError::InsufficientFunds {}, e); } + #[test] + fn test_has_coins_merged() { + let available_coins: Vec = vec![ + coin(50, "uluna"), + coin(200, "uusd"), + coin(50, "ukrw"), + coin(25, "uluna"), + coin(25, "uluna"), + ]; + let required_funds: Vec = vec![ + coin(50, "uluna"), + coin(100, "uusd"), + coin(50, "ukrw"), + coin(50, "uluna"), + ]; + + assert!(has_coins_merged(&available_coins, &required_funds)); + + let insufficient_funds: Vec = + vec![coin(10, "uluna"), coin(100, "uusd"), coin(50, "ukrw")]; + + assert!(!has_coins_merged(&insufficient_funds, &required_funds)); + } } diff --git a/andromeda-core/packages/std/src/common/queries.rs b/andromeda-core/packages/std/src/common/queries.rs deleted file mode 100644 index 22aff90..0000000 --- a/andromeda-core/packages/std/src/common/queries.rs +++ /dev/null @@ -1,14 +0,0 @@ -use cosmwasm_std::QuerierWrapper; - -use crate::error::ContractError; - -/// Queries contract info for a given address. -/// If the query errors the assumption is that the address is not a contract, if not then the address must be a contract. -/// -/// Returns a result containing a boolean as to whether the given address is a contract or not -pub fn is_contract(querier: QuerierWrapper, addr: &String) -> Result { - match querier.query_wasm_contract_info(addr) { - Ok(_) => Ok(true), - Err(_) => Ok(false), - } -} diff --git a/andromeda-core/packages/std/src/common/rates.rs b/andromeda-core/packages/std/src/common/rates.rs index d67ed7d..5108fa6 100644 --- a/andromeda-core/packages/std/src/common/rates.rs +++ b/andromeda-core/packages/std/src/common/rates.rs @@ -1,4 +1,5 @@ -use cosmwasm_std::{BankMsg, CosmosMsg, SubMsg, Uint128}; +use cosmwasm_std::{from_json, BankMsg, CosmosMsg, SubMsg, Uint128, WasmMsg}; +use cw20::Cw20ExecuteMsg; /// Gets the amount of tax paid by iterating over the `msgs` and comparing it to the /// difference between the base amount and the amount left over after royalties. @@ -31,3 +32,23 @@ pub fn get_tax_amount( .unwrap_or_else(Uint128::zero) - deducted_amount } + +pub fn get_tax_amount_cw20( + msgs: &[SubMsg], + base_amount: Uint128, + remaining_amount_after_royalties: Uint128, +) -> Uint128 { + let deducted_amount = base_amount - remaining_amount_after_royalties; + msgs.iter() + .map(|msg| { + if let CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) = &msg.msg { + if let Ok(Cw20ExecuteMsg::Transfer { amount, .. }) = from_json(msg) { + return amount; + } + } + Uint128::zero() + }) + .reduce(|total, amount| total + amount) + .unwrap_or_else(Uint128::zero) + - deducted_amount +} diff --git a/andromeda-core/packages/std/src/common/reply.rs b/andromeda-core/packages/std/src/common/reply.rs new file mode 100644 index 0000000..5a2cd21 --- /dev/null +++ b/andromeda-core/packages/std/src/common/reply.rs @@ -0,0 +1,20 @@ +use enum_repr::EnumRepr; + +#[EnumRepr(type = "u64")] +pub enum ReplyId { + // Kernel + AMPMsg = 100, + CreateADO = 101, + UpdateOwnership = 102, + IBCHooksPacketSend = 103, + Recovery = 104, + RegisterUsername = 105, + // App + ClaimOwnership = 200, + AssignApp = 201, + RegisterPath = 202, + CrossChainCreate = 203, + // Economics + Cw20WithdrawMsg = 300, + PayFee = 301, +} diff --git a/andromeda-core/packages/std/src/common/withdraw.rs b/andromeda-core/packages/std/src/common/withdraw.rs index 014fe2d..40e8720 100644 --- a/andromeda-core/packages/std/src/common/withdraw.rs +++ b/andromeda-core/packages/std/src/common/withdraw.rs @@ -17,9 +17,9 @@ pub enum WithdrawalType { impl Withdrawal { /// Calculates the amount to withdraw given the withdrawal type and passed in `balance`. - pub fn get_amount(&self, balance: Uint128) -> Result { + pub fn get_amount(&self, balance: Uint128) -> Result { match self.withdrawal_type.clone() { - None => Ok(balance), + None => Ok(Decimal::from_ratio(balance, Uint128::one())), Some(withdrawal_type) => withdrawal_type.get_amount(balance), } } @@ -27,13 +27,16 @@ impl Withdrawal { impl WithdrawalType { /// Calculates the amount to withdraw given the withdrawal type and passed in `balance`. - pub fn get_amount(&self, balance: Uint128) -> Result { + pub fn get_amount(&self, balance: Uint128) -> Result { match self { WithdrawalType::Percentage(percent) => { ensure!(*percent <= Decimal::one(), ContractError::InvalidRate {}); - Ok(balance * *percent) + Ok(Decimal::from_ratio(balance, Uint128::one()).checked_mul(*percent)?) } - WithdrawalType::Amount(amount) => Ok(cmp::min(*amount, balance)), + WithdrawalType::Amount(amount) => Ok(cmp::min( + Decimal::from_ratio(*amount, Uint128::one()), + Decimal::from_ratio(balance, Uint128::one()), + )), } } @@ -57,7 +60,10 @@ mod tests { withdrawal_type: None, }; let balance = Uint128::from(100u128); - assert_eq!(balance, withdrawal.get_amount(balance).unwrap()); + assert_eq!( + Decimal::from_ratio(balance, Uint128::one()), + withdrawal.get_amount(balance).unwrap() + ); } #[test] @@ -67,7 +73,10 @@ mod tests { withdrawal_type: Some(WithdrawalType::Percentage(Decimal::percent(10))), }; let balance = Uint128::from(100u128); - assert_eq!(10u128, withdrawal.get_amount(balance).unwrap().u128()); + assert_eq!( + Decimal::from_ratio(Uint128::from(10u128), Uint128::one()), + withdrawal.get_amount(balance).unwrap() + ); } #[test] @@ -90,7 +99,10 @@ mod tests { withdrawal_type: Some(WithdrawalType::Amount(5u128.into())), }; let balance = Uint128::from(10u128); - assert_eq!(5u128, withdrawal.get_amount(balance).unwrap().u128()); + assert_eq!( + Decimal::from_ratio(Uint128::from(5u128), Uint128::one()), + withdrawal.get_amount(balance).unwrap() + ); } #[test] @@ -100,6 +112,9 @@ mod tests { token: "token".to_string(), withdrawal_type: Some(WithdrawalType::Amount(balance + Uint128::from(1u128))), }; - assert_eq!(10, withdrawal.get_amount(balance).unwrap().u128()); + assert_eq!( + Decimal::from_ratio(Uint128::from(10u128), Uint128::one()), + withdrawal.get_amount(balance).unwrap() + ); } } diff --git a/andromeda-core/packages/std/src/error.rs b/andromeda-core/packages/std/src/error.rs index 9a4d7e9..a3fd2ae 100644 --- a/andromeda-core/packages/std/src/error.rs +++ b/andromeda-core/packages/std/src/error.rs @@ -1,14 +1,16 @@ -use cosmwasm_std::{OverflowError, StdError}; +use cosmwasm_std::{Addr, OverflowError, StdError}; use cw20_base::ContractError as Cw20ContractError; use cw721_base::ContractError as Cw721ContractError; use cw_asset::AssetError; -use cw_utils::{Expiration, ParseReplyError, PaymentError}; +use cw_utils::{ParseReplyError, PaymentError}; use hex::FromHexError; use std::convert::From; use std::str::{ParseBoolError, Utf8Error}; use std::string::FromUtf8Error; use thiserror::Error; +use crate::common::Milliseconds; + #[derive(Error, Debug, PartialEq)] pub enum ContractError { #[error("{0}")] @@ -26,6 +28,18 @@ pub enum ContractError { #[error("Unauthorized")] Unauthorized {}, + /// Used by external developers in case they don't find their desired error message + #[error("CustomError: {msg}")] + CustomError { msg: String }, + + #[error("ActionNotFound")] + ActionNotFound {}, + #[error("UnpublishedCodeID")] + UnpublishedCodeID {}, + + #[error("UnpublishedVersion")] + UnpublishedVersion {}, + #[error("ContractLocked")] ContractLocked {}, @@ -38,11 +52,25 @@ pub enum ContractError { #[error("InvalidOrigin")] InvalidOrigin {}, + #[error("EmptyDenom")] + EmptyDenom {}, + + #[error("NoDenomInfoProvided")] + NoDenomInfoProvided {}, + + #[error("InvalidAmount: {msg}")] + InvalidAmount { msg: String }, + + #[error("OverlappingRanges")] + OverlappingRanges {}, + #[error("Invalid {operation} Operation with {validator}")] InvalidValidatorOperation { operation: String, validator: String, }, + #[error("Invalid Campaign Operation: {operation} on {stage}")] + InvalidCampaignOperation { operation: String, stage: String }, #[error("No Staking Reward")] InvalidClaim {}, @@ -53,6 +81,9 @@ pub enum ContractError { #[error("InvalidValidator")] InvalidValidator {}, + #[error("NoActorsProvided")] + NoActorsProvided {}, + #[error("InvalidDelegation")] InvalidDelegation {}, @@ -74,9 +105,15 @@ pub enum ContractError { #[error("only unordered channels are supported")] OrderedChannel {}, + #[error("Invalid Expiration Time")] + InvalidExpirationTime {}, + #[error("invalid IBC channel version - got ({actual}), expected ({expected})")] InvalidVersion { actual: String, expected: String }, + #[error("CrossChainComponentsCurrentlyDisabled")] + CrossChainComponentsCurrentlyDisabled {}, + #[error("tokenId list has different length than tokenUri list")] TokenInfoLenMissmatch {}, @@ -89,7 +126,10 @@ pub enum ContractError { #[error("EmptyOptional")] EmptyOptional {}, - #[error("EmptyOptional")] + #[error("EmptyString")] + EmptyString {}, + + #[error("EmptyClassId")] EmptyClassId {}, #[error("NoTokens")] @@ -137,6 +177,9 @@ pub enum ContractError { #[error("InsufficientBondedTime")] InsufficientBondedTime {}, + #[error("ThresholdsPercentagesDiscrepancy: {msg}")] + ThresholdsPercentagesDiscrepancy { msg: String }, + #[error("LockTimeTooShort")] LockTimeTooShort {}, @@ -188,6 +231,9 @@ pub enum ContractError { #[error("EmptyRecipientsList")] EmptyRecipientsList {}, + #[error("EmptyThresholdsList")] + EmptyThresholdsList {}, + #[error("AmountExceededHundredPrecent")] AmountExceededHundredPrecent {}, @@ -227,9 +273,15 @@ pub enum ContractError { #[error("NoReceivingAddress")] NoReceivingAddress {}, + #[error("TemporarilyDisabled")] + TemporarilyDisabled {}, + #[error("AccountNotFound")] AccountNotFound {}, + #[error("ActorNotFound")] + ActorNotFound {}, + #[error("ModuleDiscriptionTooLong: {msg}")] ModuleDiscriptionTooLong { msg: String }, @@ -263,6 +315,15 @@ pub enum ContractError { #[error("AuctionEnded")] AuctionEnded {}, + #[error("CampaignNotStarted")] + CampaignNotStarted {}, + + #[error("CampaignEnded")] + CampaignEnded {}, + + #[error("Campaign is not expired yet")] + CampaignNotExpired {}, + #[error("SaleNotStarted")] SaleNotStarted {}, @@ -296,6 +357,9 @@ pub enum ContractError { #[error("Overflow")] Overflow {}, + #[error("Underflow")] + Underflow {}, + #[error("CannotWithdrawHighestBid")] CannotWithdrawHighestBid {}, @@ -323,9 +387,18 @@ pub enum ContractError { #[error("InvalidFunds: {msg}")] InvalidFunds { msg: String }, + #[error("InvalidPermission: {msg}")] + InvalidPermission { msg: String }, + #[error("InvalidADOVersion: {msg:?}")] InvalidADOVersion { msg: Option }, + #[error("InvalidCodeID: {msg:?}")] + InvalidCodeID { msg: Option }, + + #[error("InvalidADOType: {msg:?}")] + InvalidADOType { msg: Option }, + #[error("AuctionRewardAlreadyClaimed")] AuctionAlreadyClaimed {}, @@ -368,6 +441,12 @@ pub enum ContractError { #[error("DuplicateCoinDenoms")] DuplicateCoinDenoms {}, + #[error("DuplicateDenoms: {denom}")] + DuplicateDenoms { denom: String }, + + #[error("DuplicateThresholds")] + DuplicateThresholds {}, + #[error("DuplicateRecipient")] DuplicateRecipient {}, @@ -381,6 +460,9 @@ pub enum ContractError { #[error("Invalid zero amount")] InvalidZeroAmount {}, + #[error("Invalid Denom")] + InvalidDenom { msg: Option }, + #[error("Allowance is expired")] Expired {}, @@ -393,12 +475,18 @@ pub enum ContractError { #[error("Logo binary data exceeds 5KB limit")] LogoTooBig {}, + #[error("Invalid migration. Unable to migrate from version {prev}")] + InvalidMigration { prev: String }, + #[error("Invalid xml preamble for SVG")] InvalidXmlPreamble {}, #[error("Invalid png header")] InvalidPngHeader {}, + #[error("Instantiate2 Address Mistmatch: expected: {expected}, received: {received}")] + Instantiate2AddressMismatch { expected: Addr, received: Addr }, + #[error("Duplicate initial balance addresses")] DuplicateInitialBalanceAddresses {}, @@ -460,9 +548,6 @@ pub enum ContractError { #[error("TooManyAppComponents")] TooManyAppComponents {}, - #[error("TooManyComponents")] - TooManyComponents {}, - #[error("InvalidLtvRatio: {msg}")] InvalidLtvRatio { msg: String }, @@ -481,6 +566,9 @@ pub enum ContractError { #[error("Min sales exceeded")] MinSalesExceeded {}, + #[error("MinRaiseUnmet")] + MinRaiseUnmet {}, + #[error("Limit must not be zero")] LimitMustNotBeZero {}, @@ -509,10 +597,10 @@ pub enum ContractError { InvalidWithdrawal { msg: Option }, #[error("Airdrop stage {stage} expired at {expiration}")] - StageExpired { stage: u8, expiration: Expiration }, + StageExpired { stage: u8, expiration: Milliseconds }, #[error("Airdrop stage {stage} not expired yet")] - StageNotExpired { stage: u8, expiration: Expiration }, + StageNotExpired { stage: u8, expiration: Milliseconds }, #[error("Wrong Length")] WrongLength {}, @@ -604,8 +692,8 @@ pub enum ContractError { #[error("Not an assigned operator, {msg:?}")] NotAssignedOperator { msg: Option }, - #[error("Invalid Expiration Time")] - InvalidExpirationTime {}, + #[error("Invalid Parameter, {error:?}")] + InvalidParameter { error: Option }, #[error("Invalid Pathname, {error:?}")] InvalidPathname { error: Option }, @@ -627,6 +715,18 @@ pub enum ContractError { #[error("Invalid Transfer Port: {port}")] InvalidTransferPort { port: String }, + + #[error("Invalid Modules: {msg}")] + InvalidModules { msg: String }, + + #[error("Invalid time: {msg}")] + InvalidTimestamp { msg: String }, + + #[error("At least one tier should have no limit")] + InvalidTiers {}, + + #[error("Invalid tier for {operation} operation: {msg} ")] + InvalidTier { operation: String, msg: String }, } impl From for ContractError { diff --git a/andromeda-core/packages/std/src/lib.rs b/andromeda-core/packages/std/src/lib.rs index c8d51c4..d1e342f 100644 --- a/andromeda-core/packages/std/src/lib.rs +++ b/andromeda-core/packages/std/src/lib.rs @@ -5,7 +5,7 @@ pub mod common; pub mod error; pub mod os; -pub use andromeda_macros::{andr_exec, andr_instantiate, andr_instantiate_modules, andr_query}; +pub use andromeda_macros::{andr_exec, andr_instantiate, andr_query}; pub use cw_utils::Expiration; pub use strum_macros::AsRefStr; diff --git a/andromeda-core/packages/std/src/os/adodb.rs b/andromeda-core/packages/std/src/os/adodb.rs index adc233d..cb0671f 100644 --- a/andromeda-core/packages/std/src/os/adodb.rs +++ b/andromeda-core/packages/std/src/os/adodb.rs @@ -1,8 +1,13 @@ +use std::str::FromStr; + use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Addr, Uint128}; +use cosmwasm_std::{ensure, Addr, Api, Uint128}; use schemars::JsonSchema; +use semver::Version; use serde::{Deserialize, Serialize}; +use crate::{ado_base::ownership::OwnershipMessage, error::ContractError}; + #[cw_serde] pub struct InstantiateMsg { pub kernel_address: String, @@ -18,6 +23,10 @@ pub enum ExecuteMsg { version: String, publisher: Option, }, + Unpublish { + ado_type: String, + version: String, + }, UpdateActionFees { ado_type: String, action_fees: Vec, @@ -30,6 +39,8 @@ pub enum ExecuteMsg { ado_type: String, publisher: String, }, + // Base message + Ownership(OwnershipMessage), } #[cw_serde] @@ -58,10 +69,54 @@ impl ActionFee { receiver: Some(receiver), } } -} -#[cw_serde] -pub struct MigrateMsg {} + /// Valiades the provided asset for an action fee + /// An asset is valid if it fits the format "cw20:address" or "native:denom" + /// If the asset type is cw20 the address is also validated + /// TODO: Add denom validation in future cosmwasm version + pub fn validate_asset(&self, api: &dyn Api) -> Result<(), ContractError> { + let asset_split = self.asset.split(':').collect::>(); + // Ensure asset is in the format "cw20:address" or "native:denom" + // This is double validated as the asset type in the ADODB contract for fees is validated as cw20:* or native:* + ensure!( + asset_split.len() == 2 && !asset_split.is_empty(), + ContractError::InvalidAsset { + asset: self.asset.clone() + } + ); + let asset_type = asset_split[0]; + ensure!( + asset_type == "cw20" || asset_type == "native", + ContractError::InvalidAsset { + asset: self.asset.clone() + } + ); + + if asset_type == "cw20" { + api.addr_validate(asset_split[1])?; + } + + Ok(()) + } + + /// Gets the asset string without the asset type + /// + /// i.e. **cw20:address** would return **"address"** or native:denom would return **"denom"** + pub fn get_asset_string(&self) -> Result<&str, ContractError> { + ensure!( + self.asset.contains(':'), + ContractError::InvalidAsset { + asset: self.asset.clone() + } + ); + match self.asset.split(':').last() { + Some(asset) => Ok(asset), + None => Err(ContractError::InvalidAsset { + asset: self.asset.clone(), + }), + } + } +} #[cw_serde] pub struct ADOMetadata { @@ -74,6 +129,10 @@ pub struct ADOMetadata { pub enum QueryMsg { #[returns(u64)] CodeId { key: String }, + // #[returns(Vec)] + // UnpublishedCodeIds {}, + #[returns(IsUnpublishedCodeIdResponse)] + IsUnpublishedCodeId { code_id: u64 }, #[returns(Option)] #[serde(rename = "ado_type")] ADOType { code_id: u64 }, @@ -90,6 +149,9 @@ pub enum QueryMsg { start_after: Option, limit: Option, }, + // #[returns(Vec)] + // #[serde(rename = "unpublished_ado_versions")] + // UnpublishedADOVersions { ado_type: String }, #[returns(Option)] #[serde(rename = "ado_metadata")] ADOMetadata { ado_type: String }, @@ -97,6 +159,20 @@ pub enum QueryMsg { ActionFee { ado_type: String, action: String }, #[returns(Option)] ActionFeeByCodeId { code_id: u64, action: String }, + // Base queries + #[returns(crate::ado_base::version::VersionResponse)] + Version {}, + #[returns(crate::ado_base::ado_type::TypeResponse)] + Type {}, + #[returns(crate::ado_base::ownership::ContractOwnerResponse)] + Owner {}, + #[returns(crate::ado_base::kernel_address::KernelAddressResponse)] + KernelAddress {}, +} + +#[cw_serde] +pub struct IsUnpublishedCodeIdResponse { + pub is_unpublished_code_id: bool, } #[derive( @@ -151,7 +227,10 @@ impl ADOVersion { /// - `ado_type` /// - `ado_type@latest` pub fn validate(&self) -> bool { - !self.clone().into_string().is_empty() && self.clone().into_string().split('@').count() <= 2 + !self.clone().into_string().is_empty() + && self.clone().into_string().split('@').count() <= 2 + && (self.get_version() == "latest" + || Version::from_str(self.get_version().as_str()).is_ok()) } /// Gets the version for the given ADOVersion @@ -183,6 +262,8 @@ impl ADOVersion { #[cfg(test)] mod tests { + use cosmwasm_std::testing::mock_dependencies; + use super::*; #[test] @@ -223,4 +304,30 @@ mod tests { let ado_version = ADOVersion::from_string("ado_type@latest"); assert_eq!(ado_version.get_type(), "ado_type"); } + + #[test] + fn test_action_fee_asset() { + let deps = mock_dependencies(); + let action_fee = ActionFee::new( + "action".to_string(), + "cw20:address".to_string(), + Uint128::zero(), + ); + assert!(action_fee.validate_asset(deps.as_ref().api).is_ok()); + + let action_fee = ActionFee::new( + "action".to_string(), + "native:denom".to_string(), + Uint128::zero(), + ); + assert!(action_fee.validate_asset(deps.as_ref().api).is_ok()); + + let action_fee = + ActionFee::new("action".to_string(), "cw20:aw".to_string(), Uint128::zero()); + assert!(action_fee.validate_asset(deps.as_ref().api).is_err()); + + let action_fee = + ActionFee::new("action".to_string(), "invalid".to_string(), Uint128::zero()); + assert!(action_fee.validate_asset(deps.as_ref().api).is_err()); + } } diff --git a/andromeda-core/packages/std/src/os/aos_querier.rs b/andromeda-core/packages/std/src/os/aos_querier.rs index ee5c634..ab5222f 100644 --- a/andromeda-core/packages/std/src/os/aos_querier.rs +++ b/andromeda-core/packages/std/src/os/aos_querier.rs @@ -1,3 +1,4 @@ +use crate::ado_base::permissioning::LocalPermission; use crate::amp::{ADO_DB_KEY, VFS_KEY}; use crate::error::ContractError; use cosmwasm_schema::cw_serde; @@ -7,7 +8,10 @@ use lazy_static::__Deref; use serde::de::DeserializeOwned; use std::str::from_utf8; -use super::adodb::{ActionFee, QueryMsg as ADODBQueryMsg}; +#[cfg(feature = "rates")] +use crate::ado_base::rates::LocalRate; + +use super::adodb::{ADOVersion, ActionFee, QueryMsg as ADODBQueryMsg}; use super::kernel::ChannelInfo; #[cw_serde] @@ -55,8 +59,8 @@ impl AOSQuerier { code_id: u64, ) -> Result, ContractError> { let key = AOSQuerier::get_map_storage_key("ado_type", &[code_id.to_string().as_bytes()])?; - let ado_type: Option = AOSQuerier::query_storage(querier, adodb_addr, &key)?; - Ok(ado_type) + let ado_type: Option = AOSQuerier::query_storage(querier, adodb_addr, &key)?; + Ok(ado_type.map(|v| v.get_type())) } pub fn ado_type_getter_smart( @@ -65,8 +69,8 @@ impl AOSQuerier { code_id: u64, ) -> Result, ContractError> { let query = ADODBQueryMsg::ADOType { code_id }; - let ado_type: Option = querier.query_wasm_smart(adodb_addr, &query)?; - Ok(ado_type) + let ado_type: Option = querier.query_wasm_smart(adodb_addr, &query)?; + Ok(ado_type.map(|v| v.get_type())) } pub fn ado_publisher_getter( @@ -209,4 +213,33 @@ impl AOSQuerier { None => Err(ContractError::InvalidAddress {}), } } + /// Queries an actor's permission from the address list contract + pub fn get_permission( + querier: &QuerierWrapper, + contract_addr: &Addr, + actor: &str, + ) -> Result { + let key = AOSQuerier::get_map_storage_key("permissioning", &[actor.as_bytes()])?; + let permission: Option = + AOSQuerier::query_storage(querier, contract_addr, key.as_str())?; + match permission { + Some(permission) => Ok(permission), + None => Err(ContractError::InvalidAddress {}), + } + } + + #[cfg(feature = "rates")] + /// Queries the rates contract + pub fn get_rate( + querier: &QuerierWrapper, + addr: &Addr, + action: &str, + ) -> Result { + let key = AOSQuerier::get_map_storage_key("rates", &[action.as_bytes()])?; + let verify: Option = AOSQuerier::query_storage(querier, addr, key.as_str())?; + match verify { + Some(rate) => Ok(rate), + None => Err(ContractError::InvalidAddress {}), + } + } } diff --git a/andromeda-core/packages/std/src/os/economics.rs b/andromeda-core/packages/std/src/os/economics.rs index b961f22..5276f1d 100644 --- a/andromeda-core/packages/std/src/os/economics.rs +++ b/andromeda-core/packages/std/src/os/economics.rs @@ -2,7 +2,7 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use cosmwasm_std::{Addr, Uint128}; use cw20::Cw20ReceiveMsg; -use crate::amp::AndrAddr; +use crate::{ado_base::ownership::OwnershipMessage, amp::AndrAddr}; #[cw_serde] pub struct InstantiateMsg { @@ -45,6 +45,8 @@ pub enum ExecuteMsg { asset: String, }, Receive(Cw20ReceiveMsg), + // Base message + Ownership(OwnershipMessage), } #[cw_serde] @@ -55,9 +57,6 @@ pub enum Cw20HookMsg { Deposit { address: Option }, } -#[cw_serde] -pub struct MigrateMsg {} - #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { @@ -66,12 +65,18 @@ pub enum QueryMsg { /// Returns a `Uint128` representing the current balance #[returns(BalanceResponse)] Balance { asset: String, address: AndrAddr }, + // Base queries + #[returns(crate::ado_base::version::VersionResponse)] + Version {}, + #[returns(crate::ado_base::ado_type::TypeResponse)] + Type {}, + #[returns(crate::ado_base::ownership::ContractOwnerResponse)] + Owner {}, + #[returns(crate::ado_base::kernel_address::KernelAddressResponse)] + KernelAddress {}, } #[cw_serde] pub struct BalanceResponse { pub balance: Uint128, } - -#[cfg(test)] -mod test {} diff --git a/andromeda-core/packages/std/src/os/ibc_registry.rs b/andromeda-core/packages/std/src/os/ibc_registry.rs new file mode 100644 index 0000000..2879a98 --- /dev/null +++ b/andromeda-core/packages/std/src/os/ibc_registry.rs @@ -0,0 +1,115 @@ +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{ensure, Addr}; +use strum_macros::AsRefStr; + +use crate::{ + amp::{messages::AMPPkt, AndrAddr}, + error::ContractError, +}; + +#[cw_serde] +pub struct InstantiateMsg { + pub kernel_address: Addr, + pub owner: Option, + pub service_address: AndrAddr, +} +#[cw_serde] +pub struct DenomInfo { + pub path: String, + pub base_denom: String, +} +#[cw_serde] +pub struct IBCDenomInfo { + pub denom: String, + pub denom_info: DenomInfo, +} + +#[cw_serde] +#[derive(AsRefStr)] +pub enum ExecuteMsg { + /// Receives an AMP Packet for relaying + #[serde(rename = "amp_receive")] + AMPReceive(AMPPkt), + StoreDenomInfo { + ibc_denom_info: Vec, + }, +} + +/// Ensures that the denom starts with 'ibc/' +pub fn verify_denom(denom: &str) -> Result<(), ContractError> { + // Ensure that the denom is formatted correctly. It should start with "ibc/" + ensure!( + denom.starts_with("ibc/"), + ContractError::InvalidDenom { + msg: Some("The denom should start with 'ibc/'".to_string()), + } + ); + let suffix = &denom[4..]; // Get the part after "ibc/" + + // Ensure that there are exactly 64 characters after "ibc/" + if suffix.len() != 64 { + return Err(ContractError::InvalidDenom { + msg: Some("The denom must have exactly 64 characters after 'ibc/'".to_string()), + }); + } + Ok(()) +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(DenomInfoResponse)] + DenomInfo { denom: String }, + #[returns(AllDenomInfoResponse)] + AllDenomInfo { + limit: Option, // Defaults to 100, + start_after: Option, + }, +} + +#[cw_serde] +pub struct DenomInfoResponse { + pub denom_info: DenomInfo, +} + +#[cw_serde] +pub struct AllDenomInfoResponse { + pub denom_info: Vec, +} + +#[cfg(test)] +#[test] +fn test_validate_denom() { + // Empty denom + let empty_denom = "".to_string(); + let err = verify_denom(&empty_denom).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidDenom { + msg: Some("The denom should start with 'ibc/'".to_string()), + } + ); + // Denom that doesn't start with ibc/ + let invalid_denom = "random".to_string(); + let err = verify_denom(&invalid_denom).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidDenom { + msg: Some("The denom should start with 'ibc/'".to_string()), + } + ); + // Denom that's just ibc/ + let empty_ibc_denom = "ibc/".to_string(); + let err = verify_denom(&empty_ibc_denom).unwrap_err(); + assert_eq!( + err, + ContractError::InvalidDenom { + msg: Some("The denom must have exactly 64 characters after 'ibc/'".to_string()), + } + ); + + // Valid denom + let valid_denom = + "ibc/usdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdc".to_string(); + verify_denom(&valid_denom).unwrap() +} diff --git a/andromeda-core/packages/std/src/os/kernel.rs b/andromeda-core/packages/std/src/os/kernel.rs index 8ec5d0a..f4c2dbc 100644 --- a/andromeda-core/packages/std/src/os/kernel.rs +++ b/andromeda-core/packages/std/src/os/kernel.rs @@ -1,3 +1,4 @@ +use crate::ado_base::ownership::OwnershipMessage; use crate::amp::messages::AMPMsg; use crate::amp::messages::AMPPkt; use crate::amp::AndrAddr; @@ -13,6 +14,17 @@ pub struct ChannelInfo { pub supported_modules: Vec, } +impl Default for ChannelInfo { + fn default() -> Self { + ChannelInfo { + kernel_address: "".to_string(), + ics20_channel_id: None, + direct_channel_id: None, + supported_modules: vec![], + } + } +} + #[cw_serde] pub struct InstantiateMsg { pub owner: Option, @@ -49,8 +61,14 @@ pub enum ExecuteMsg { }, /// Recovers funds from failed IBC messages Recover {}, + /// Update Current Chain + UpdateChainName { + chain_name: String, + }, // Only accessible to key contracts Internal(InternalMsg), + // Base message + Ownership(OwnershipMessage), } #[cw_serde] @@ -63,9 +81,6 @@ pub enum InternalMsg { }, } -#[cw_serde] -pub struct MigrateMsg {} - #[cw_serde] pub struct ChannelInfoResponse { pub ics20: Option, @@ -74,6 +89,11 @@ pub struct ChannelInfoResponse { pub supported_modules: Vec, } +#[cw_serde] +pub struct ChainNameResponse { + pub chain_name: String, +} + #[cw_serde] #[derive(QueryResponses)] pub enum QueryMsg { @@ -85,6 +105,15 @@ pub enum QueryMsg { ChannelInfo { chain: String }, #[returns(Vec<::cosmwasm_std::Coin>)] Recoveries { addr: Addr }, + #[returns(ChainNameResponse)] + ChainName {}, + // Base queries + #[returns(crate::ado_base::version::VersionResponse)] + Version {}, + #[returns(crate::ado_base::ado_type::TypeResponse)] + Type {}, + #[returns(crate::ado_base::ownership::ContractOwnerResponse)] + Owner {}, } #[cw_serde] diff --git a/andromeda-core/packages/std/src/os/mod.rs b/andromeda-core/packages/std/src/os/mod.rs index b4d306b..c88826b 100644 --- a/andromeda-core/packages/std/src/os/mod.rs +++ b/andromeda-core/packages/std/src/os/mod.rs @@ -1,5 +1,6 @@ pub mod adodb; pub mod aos_querier; pub mod economics; +pub mod ibc_registry; pub mod kernel; pub mod vfs; diff --git a/andromeda-core/packages/std/src/os/vfs.rs b/andromeda-core/packages/std/src/os/vfs.rs index 850e869..f5adfd3 100644 --- a/andromeda-core/packages/std/src/os/vfs.rs +++ b/andromeda-core/packages/std/src/os/vfs.rs @@ -1,17 +1,30 @@ -use crate::{amp::AndrAddr, error::ContractError}; +use crate::{ado_base::ownership::OwnershipMessage, amp::AndrAddr, error::ContractError}; use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{ensure, Addr, QuerierWrapper}; +use cosmwasm_std::{ensure, Addr, Api, QuerierWrapper}; use regex::Regex; -pub const COMPONENT_NAME_REGEX: &str = r"^[A-Za-z0-9\.\-_]{1,40}$"; -pub const USERNAME_REGEX: &str = r"^[a-z0-9]+$"; -pub const PATH_REGEX: &str = r"^((([A-Za-z0-9]+://)?([A-Za-z0-9\.\-_]{1,40})?(/)?(home|lib)/)|(~(/)?))([A-Za-z0-9\.\-_]{1,40}(/)?)+$"; +pub const COMPONENT_NAME_REGEX: &str = r"^[A-Za-z0-9.\-_]{2,80}$"; +pub const USERNAME_REGEX: &str = r"^[a-z0-9]{2,30}$"; -pub fn convert_component_name(path: String) -> String { - path.replace(' ', "_") +pub const PATH_REGEX: &str = r"^(~[a-z0-9]{2,}|/(lib|home))(/[A-Za-z0-9.\-_]{2,80}?)*(/)?$"; +pub const PROTOCOL_PATH_REGEX: &str = r"^((([A-Za-z0-9]+://)?([A-Za-z0-9.\-_]{2,80}/)))?((~[a-z0-9]{2,}|(lib|home))(/[A-Za-z0-9.\-_]{2,80}?)*(/)?)$"; + +pub fn convert_component_name(path: &str) -> String { + path.trim() + .replace(' ', "_") + .chars() + .filter(|c| c.is_alphanumeric() || *c == '.' || *c == '-' || *c == '_') + .collect::() + .to_lowercase() } pub fn validate_component_name(path: String) -> Result { + ensure!( + path.chars().any(|c| c.is_alphanumeric()), + ContractError::InvalidPathname { + error: Some("Pathname must contain at least one alphanumeric character".to_string()) + } + ); let re = Regex::new(COMPONENT_NAME_REGEX).unwrap(); ensure!( @@ -20,17 +33,35 @@ pub fn validate_component_name(path: String) -> Result { error: Some("Pathname includes an invalid character".to_string()) } ); + Ok(true) } +/// Validates a username against specific criteria. +/// +/// This function checks if a given username meets the following conditions: +/// - It must contain at least three characters +/// - It must only contain alphanumeric characters +/// +/// # Arguments +/// +/// * `username` - A `String` representing the username to be validated. +/// +/// # Returns +/// +/// * `Result` - Returns `Ok(true)` if the username is valid, otherwise returns an `Err` with a `ContractError` detailing the reason for invalidity. pub fn validate_username(username: String) -> Result { + // Ensure the username is not empty. ensure!( !username.is_empty(), ContractError::InvalidUsername { error: Some("Username cannot be empty.".to_string()) } ); + + // Compile the regex for validating alphanumeric characters. let re = Regex::new(USERNAME_REGEX).unwrap(); + // Ensure the username matches the alphanumeric regex pattern. ensure!( re.is_match(&username), ContractError::InvalidPathname { @@ -40,19 +71,59 @@ pub fn validate_username(username: String) -> Result { ) } ); + // Return true if all validations pass. Ok(true) } -pub fn validate_path_name(path: String) -> Result { - let re = Regex::new(PATH_REGEX).unwrap(); +pub fn validate_path_name(api: &dyn Api, path: String) -> Result<(), ContractError> { + let andr_addr = AndrAddr::from_string(path.clone()); + let is_path_reference = path.contains('/'); + let includes_protocol = andr_addr.get_protocol().is_some(); + + // Path is of the form /user/... or /lib/... or prot://... + if is_path_reference { + // Alter regex if path includes a protocol + let regex_str = if includes_protocol { + PROTOCOL_PATH_REGEX + } else { + PATH_REGEX + }; + + let re = Regex::new(regex_str).unwrap(); + ensure!( + re.is_match(&path), + ContractError::InvalidPathname { + error: Some("Pathname includes an invalid character".to_string()) + } + ); + + return Ok(()); + } + + // Path is either a username or address + if !is_path_reference { + let path = path.strip_prefix('~').unwrap_or(&path); + let is_address = api.addr_validate(path).is_ok(); - ensure!( - re.is_match(&path), - ContractError::InvalidPathname { - error: Some("Pathname includes an invalid character".to_string()) + if is_address { + return Ok(()); } - ); - Ok(true) + + let is_username = validate_username(path.to_string()).is_ok(); + + if is_username { + return Ok(()); + } + + return Err(ContractError::InvalidPathname { + error: Some( + "Provided address is neither a valid username nor a valid address".to_string(), + ), + }); + } + + // Does not fit any valid conditions + Err(ContractError::InvalidPathname { error: None }) } #[cw_serde] @@ -80,20 +151,25 @@ impl PathDetails { #[cw_serde] pub enum ExecuteMsg { AddPath { + #[schemars(regex = "COMPONENT_NAME_REGEX")] name: String, address: Addr, parent_address: Option, }, AddSymlink { + #[schemars(regex = "COMPONENT_NAME_REGEX")] name: String, symlink: AndrAddr, parent_address: Option, }, - AddParentPath { + // Registers a child, currently only accessible by an App Contract + AddChild { + #[schemars(regex = "COMPONENT_NAME_REGEX")] name: String, parent_address: AndrAddr, }, RegisterUser { + #[schemars(regex = "USERNAME_REGEX", length(min = 3, max = 30))] username: String, address: Option, }, @@ -106,10 +182,20 @@ pub enum ExecuteMsg { chain: String, address: String, }, + // Base message + Ownership(OwnershipMessage), } #[cw_serde] -pub struct MigrateMsg {} +pub struct SubDirBound { + address: Addr, + name: String, +} +impl From for (Addr, String) { + fn from(val: SubDirBound) -> Self { + (val.address, val.name) + } +} #[cw_serde] #[derive(QueryResponses)] @@ -117,7 +203,12 @@ pub enum QueryMsg { #[returns(Addr)] ResolvePath { path: AndrAddr }, #[returns(Vec)] - SubDir { path: AndrAddr }, + SubDir { + path: AndrAddr, + min: Option, + max: Option, + limit: Option, + }, #[returns(Vec)] Paths { addr: Addr }, #[returns(String)] @@ -126,6 +217,15 @@ pub enum QueryMsg { GetLibrary { address: Addr }, #[returns(AndrAddr)] ResolveSymlink { path: AndrAddr }, + // Base queries + #[returns(crate::ado_base::version::VersionResponse)] + Version {}, + #[returns(crate::ado_base::ado_type::TypeResponse)] + Type {}, + #[returns(crate::ado_base::ownership::ContractOwnerResponse)] + Owner {}, + #[returns(crate::ado_base::kernel_address::KernelAddressResponse)] + KernelAddress {}, } /// Queries the provided VFS contract address to resolve the given path @@ -137,8 +237,11 @@ pub fn vfs_resolve_path( let query = QueryMsg::ResolvePath { path: AndrAddr::from_string(path.into()), }; - let addr = querier.query_wasm_smart::(vfs_contract, &query)?; - Ok(addr) + let addr = querier.query_wasm_smart::(vfs_contract, &query); + match addr { + Ok(addr) => Ok(addr), + Err(_) => Err(ContractError::InvalidAddress {}), + } } /// Queries the provided VFS contract address to resolve the given path @@ -156,98 +259,467 @@ pub fn vfs_resolve_symlink( #[cfg(test)] mod test { + use cosmwasm_std::testing::mock_dependencies; + use super::*; + struct ValidateComponentNameTestCase { + name: &'static str, + input: &'static str, + should_err: bool, + } + #[test] fn test_validate_component_name() { - let valid_name = "component1"; - validate_component_name(valid_name.to_string()).unwrap(); - - let valid_name = "component-1"; - validate_component_name(valid_name.to_string()).unwrap(); - - let valid_name = "component_1"; - validate_component_name(valid_name.to_string()).unwrap(); - - let valid_name = ".component-1"; - validate_component_name(valid_name.to_string()).unwrap(); - - let empty_name = ""; - let res = validate_component_name(empty_name.to_string()); - assert!(res.is_err()); - - let invalid_name = "/ /"; - let res = validate_component_name(invalid_name.to_string()); - assert!(res.is_err()); - - let invalid_name = " "; - let res = validate_component_name(invalid_name.to_string()); - assert!(res.is_err()); + let test_cases: Vec = vec![ + ValidateComponentNameTestCase { + name: "standard component name", + input: "component1", + should_err: false + }, + ValidateComponentNameTestCase { + name: "component with hyphen", + input: "component-2", + should_err: false, + }, + ValidateComponentNameTestCase { + name: "component with underscore", + input: "component_2", + should_err: false, + }, + ValidateComponentNameTestCase { + name: "component with period", + input: ".component2", + should_err: false, + }, + ValidateComponentNameTestCase { + name: "component with invalid character", + input: "component$2", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component with spaces", + input: "component 2", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "empty component name", + input: "", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component name too long", + input: "somereallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongname", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component name with only special characters", + input: "!@#$%^&*()", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component name with leading and trailing spaces", + input: " component2 ", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component name with only numbers", + input: "123456", + should_err: false, + }, + ValidateComponentNameTestCase { + name: "component name one letter", + input: "a", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component name two letters", + input: "ab", + should_err: false, + }, + ValidateComponentNameTestCase { + name: "component with hyphen at the start", + input: "-component-2", + should_err: false, + }, + ValidateComponentNameTestCase { + name: "component with forward slash", + input: "component-2/", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component with backward slash", + input: r"component-2\", + should_err: true, + }, + ValidateComponentNameTestCase { + name: "component name with upper case letters", + input: "ComponentName", + should_err: false, + } + ]; + + for test in test_cases { + let res = validate_component_name(test.input.to_string()); + assert_eq!(res.is_err(), test.should_err, "Test case: {}", test.name); + } + } - let invalid_name = - "somereallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongname"; - let res = validate_component_name(invalid_name.to_string()); - assert!(res.is_err()); + struct ValidatePathNameTestCase { + name: &'static str, + path: &'static str, + should_err: bool, } #[test] fn test_validate_path_name() { - let valid_path = "/home/username"; - validate_path_name(valid_path.to_string()).unwrap(); - - let valid_path = "~username"; - validate_path_name(valid_path.to_string()).unwrap(); - - let valid_path = "~/username"; - validate_path_name(valid_path.to_string()).unwrap(); - - let valid_path = "/home/username/dir1/file"; - validate_path_name(valid_path.to_string()).unwrap(); - - let valid_path = "/home/username/dir1/file/"; - validate_path_name(valid_path.to_string()).unwrap(); - - let valid_path = "vfs://chain/home/username/dir1/file/"; - validate_path_name(valid_path.to_string()).unwrap(); - - let empty_path = ""; - let res = validate_path_name(empty_path.to_string()); - assert!(res.is_err()); - - let invalid_path = "//// ///"; - let res = validate_path_name(invalid_path.to_string()); - assert!(res.is_err()); - - let invalid_path = "vfs:/username/dir1/f!le"; - let res = validate_path_name(invalid_path.to_string()); - assert!(res.is_err()); - - let invalid_path = "vfs://home/username/dir1/f!le"; - let res = validate_path_name(invalid_path.to_string()); - assert!(res.is_err()); - - let invalid_path = "vfs://chain1//username/dir1/f!le"; - let res = validate_path_name(invalid_path.to_string()); - assert!(res.is_err()); - - let invalid_path = "vfs://username/dir1/f!le"; - let res = validate_path_name(invalid_path.to_string()); - assert!(res.is_err()); - - let invalid_path = "vfs://~username/dir1/f!le"; - let res = validate_path_name(invalid_path.to_string()); - assert!(res.is_err()); + let test_cases: Vec = vec![ + ValidatePathNameTestCase { + name: "Simple app path", + path: "./username/app", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Root path", + path: "/", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Relative path with parent directory", + path: "../username/app", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Tilde username reference", + // Username must be short to circumvent it being mistaken as an address + path: "~usr", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Tilde address reference", + path: "~cosmos1abcde", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Tilde username reference with directory", + path: "~usr/app/splitter", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Invalid tilde username reference", + path: "~/username", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Absolute path with tilde", + path: "~/home/username", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Invalid user path", + path: "/user/un", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Valid user path", + path: "/home/usr", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Invalid home path (address)", + path: "/user/cosmos1abcde", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Valid home path (address)", + path: "/home/cosmos1abcde", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Valid lib path", + path: "/lib/library", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Complex invalid path", + path: "/home/username/dir1/../dir2/./file", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with invalid characters", + path: "/home/username/dir1/|file", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with space", + path: "/home/ username/dir1/file", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Empty path", + path: "", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with only special characters", + path: "///", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with only special characters and spaces", + path: "/// / /// //", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Valid ibc protocol path", + path: "ibc://chain/home/username/dir1/file", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Invalid ibc protocol path", + path: "ibc:///home/username/dir1/file", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Standard address", + path: "cosmos1abcde", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Only periods", + path: "/../../../..", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with newline character", + path: "/home/username/dir1\n/file", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with tab character", + path: "/home/username/dir1\t/dir2", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with null character", + path: "/home/username\0/dir1", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with emoji", + path: "/home/username/😊", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with Cyrillic characters", + path: "/home/пользователь/dir1", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with Arabic characters", + path: "/home/مستخدم/dir1", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with Chinese characters", + path: "/home/用户/dir1", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Path with very long name", + path: "/home/username/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + should_err: true, + }, + ValidatePathNameTestCase { + name: "Valid path with multiple subdirectories", + path: "/home/username/dir1/dir2/dir3/dir4", + should_err: false, + }, + ValidatePathNameTestCase { + name: "Path with unprintable ASCII character", + path: "/home/username/\x07file", + should_err: true, + }, + // This case should fail but due to the restriction of mock dependencies we cannot validate it correctly! It is partially validated in test_validate_username + // ValidatePathNameTestCase { + // name: "Really long username", + // path: "~somereallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongname", + // should_err: true, + // }, + // This case should fail but due to the restriction of mock dependencies we cannot validate it correctly! + // ValidatePathNameTestCase { + // name: "Standard address with backslash", + // path: r"\cosmos\1abcde\", + // should_err: true, + // }, + ]; + + for test in test_cases { + let deps = mock_dependencies(); + let res = validate_path_name(&deps.api, test.path.to_string()); + assert_eq!(res.is_err(), test.should_err, "Test case: {}", test.name); + } + } - let invalid_path = "vfs://~/username/dir1/f!le"; - let res = validate_path_name(invalid_path.to_string()); - assert!(res.is_err()); + struct ConvertComponentNameTestCase { + name: &'static str, + input: &'static str, + expected: &'static str, } #[test] fn test_convert_component_name() { - let pre_convert = "Some Component Name"; - let converted = convert_component_name(pre_convert.to_string()); + let test_cases: Vec = vec![ + ConvertComponentNameTestCase { + name: "Standard name with spaces", + input: "Some Component Name", + expected: "some_component_name", + }, + ConvertComponentNameTestCase { + name: "Name with hyphens", + input: "Some-Component-Name", + expected: "some-component-name", + }, + ConvertComponentNameTestCase { + name: "Name with uppercase letters", + input: "SomeCOMPONENTName", + expected: "somecomponentname", + }, + ConvertComponentNameTestCase { + name: "Name with numbers", + input: "Component123", + expected: "component123", + }, + ConvertComponentNameTestCase { + name: "Name with special characters", + input: "Component!@#", + expected: "component", + }, + ConvertComponentNameTestCase { + name: "Empty name", + input: "", + expected: "", + }, + ConvertComponentNameTestCase { + name: "Name with leading and trailing spaces", + input: " Some Component Name ", + expected: "some_component_name", + }, + ConvertComponentNameTestCase { + name: "Name with multiple spaces", + input: "Some Component Name", + expected: "some____component____name", + }, + ]; + + for test in test_cases { + assert_eq!( + convert_component_name(test.input), + test.expected, + "Test case: {}", + test.name + ) + } + } + + struct ValidateUsernameTestCase { + name: &'static str, + username: &'static str, + should_err: bool, + } - assert_eq!("Some_Component_Name", converted) + #[test] + fn test_validate_username() { + let test_cases: Vec = vec![ + ValidateUsernameTestCase { + name: "Valid lowercase username", + username: "validusername", + should_err: false, + }, + ValidateUsernameTestCase { + name: "Valid numeric username", + username: "123456", + should_err: false, + }, + ValidateUsernameTestCase { + name: "Username with uppercase letters", + username: "InvalidUsername", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with special characters", + username: "user!@#", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Empty username", + username: "", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with underscore", + username: "valid_username", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with hyphen", + username: "valid-username", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with period", + username: "valid.username", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with leading numbers", + username: "123validusername", + should_err: false, + }, + ValidateUsernameTestCase { + name: "Username with only three characters", + username: "usr", + should_err: false, + }, + ValidateUsernameTestCase { + name: "Username with only one character", + username: "a", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with whitespace", + username: "valid username", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with leading whitespace", + username: " validusername", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with trailing whitespace", + username: "validusername ", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with mixed case letters", + username: "ValidUserName", + should_err: true, + }, + ValidateUsernameTestCase { + name: "Username with all uppercase letters", + username: "VALIDUSERNAME", + should_err: true, + }, + ]; + + for test in test_cases { + assert_eq!( + validate_username(test.username.to_string()).is_err(), + test.should_err, + "Test case: {}", + test.name + ) + } } } diff --git a/andromeda-core/packages/std/src/testing/mock_querier.rs b/andromeda-core/packages/std/src/testing/mock_querier.rs index 6a62c04..68c1ec8 100644 --- a/andromeda-core/packages/std/src/testing/mock_querier.rs +++ b/andromeda-core/packages/std/src/testing/mock_querier.rs @@ -2,24 +2,30 @@ use crate::{ ado_base::AndromedaQuery, ado_contract::ADOContract, amp::{ADO_DB_KEY, ECONOMICS_KEY, OSMOSIS_ROUTER_KEY, VFS_KEY}, - os::adodb::{ActionFee, QueryMsg as ADODBQueryMsg}, os::kernel::QueryMsg as KernelQueryMsg, os::vfs::QueryMsg as VFSQueryMsg, + os::{ + adodb::{ActionFee, QueryMsg as ADODBQueryMsg}, + kernel::ChannelInfo, + }, }; -#[cfg(feature = "modules")] + use cosmwasm_std::SubMsg; use cosmwasm_std::{ from_json, testing::{MockApi, MockQuerier, MockStorage, MOCK_CONTRACT_ADDR}, - to_json_binary, Addr, Binary, Coin, ContractInfoResponse, ContractResult, OwnedDeps, Querier, - QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, WasmQuery, + to_json_binary, Addr, Binary, CodeInfoResponse, Coin, ContractInfoResponse, ContractResult, + HexBinary, OwnedDeps, Querier, QuerierResult, QueryRequest, SystemError, SystemResult, Uint128, + WasmQuery, }; #[cfg(feature = "primitive")] use cosmwasm_std::{Decimal, Uint128}; -use cw20::{BalanceResponse, Cw20QueryMsg}; +use cw20::{BalanceResponse, Cw20QueryMsg, TokenInfoResponse}; /// Mock CW20 Contract Address pub const MOCK_CW20_CONTRACT: &str = "cw20_contract"; +/// Mock Anchor Contract Address +pub const MOCK_ANCHOR_CONTRACT: &str = "anchor_contract"; /// Mock App Contract Address pub const MOCK_APP_CONTRACT: &str = "app_contract"; /// Mock Primitive Contract Address @@ -55,6 +61,10 @@ pub const MOCK_ACTION: &str = "action"; pub const UNWHITELISTED_ADDRESS: &str = "unwhitelisted_address"; pub const RATES_EXCLUDED_ADDRESS: &str = "rates_excluded_address"; +pub const MOCK_CHECKSUM: &str = "9af782a3a1bcbcd22dbb6a45c751551d9af782a3a1bcbcd22dbb6a45c751551d"; + +pub const MOCK_WALLET: &str = "mock_wallet"; + pub struct WasmMockQuerier { pub base: MockQuerier, } @@ -136,11 +146,14 @@ impl MockAndromedaQuerier { MOCK_KERNEL_CONTRACT => self.handle_kernel_query(msg), MOCK_VFS_CONTRACT => self.handle_vfs_query(msg), MOCK_ADODB_CONTRACT => self.handle_adodb_query(msg), - #[cfg(feature = "modules")] - MOCK_ADDRESS_LIST_CONTRACT => self.handle_address_list_query(msg), + + // MOCK_ADDRESS_LIST_CONTRACT => self.handle_address_list_query(msg), _ => match from_json::(msg) { Ok(msg) => self.handle_ado_query(msg), - _ => panic!("Unsupported query for contract: {contract_addr}"), + _ => SystemResult::Err(SystemError::InvalidRequest { + error: "Unsupported query".to_string(), + request: to_json_binary(&request).unwrap(), + }), }, } } @@ -150,22 +163,51 @@ impl MockAndromedaQuerier { MOCK_KERNEL_CONTRACT => self.handle_kernel_raw_query(key, false), MOCK_FAKE_KERNEL_CONTRACT => self.handle_kernel_raw_query(key, true), MOCK_ADODB_CONTRACT => self.handle_adodb_raw_query(key), - _ => panic!("Unsupported query for contract: {contract_addr}"), + MOCK_CW20_CONTRACT => self.handle_cw20_owner_query(key), + MOCK_ANCHOR_CONTRACT => self.handle_anchor_owner_query(key), + + _ => self.handle_ado_raw_query(key, &Addr::unchecked(contract_addr)), } } // Defaults to code ID 1, returns 2 for `INVALID_CONTRACT` which is considered an invalid ADODB code id QueryRequest::Wasm(WasmQuery::ContractInfo { contract_addr }) => { + if contract_addr == MOCK_WALLET { + return SystemResult::Ok(ContractResult::Err( + "Not a valid contract".to_string(), + )); + } let mut resp = ContractInfoResponse::default(); resp.code_id = match contract_addr.as_str() { + MOCK_APP_CONTRACT => 3, INVALID_CONTRACT => 2, _ => 1, }; SystemResult::Ok(ContractResult::Ok(to_json_binary(&resp).unwrap())) } + QueryRequest::Wasm(WasmQuery::CodeInfo { code_id }) => { + if *code_id == 2u64 { + return SystemResult::Ok(ContractResult::Err("Invalid Code ID".to_string())); + } + let mut resp = CodeInfoResponse::default(); + resp.checksum = HexBinary::from_hex(MOCK_CHECKSUM).unwrap(); + SystemResult::Ok(ContractResult::Ok(to_json_binary(&resp).unwrap())) + } _ => querier.handle_query(request), } } + fn handle_cw20_owner_query(&self, _msg: &Binary) -> QuerierResult { + SystemResult::Ok(ContractResult::Ok( + to_json_binary("cosmos2contract").unwrap(), + )) + } + + fn handle_anchor_owner_query(&self, _msg: &Binary) -> QuerierResult { + SystemResult::Ok(ContractResult::Ok( + to_json_binary("cosmos2contract").unwrap(), + )) + } + /// Handles all kernel queries. /// /// Returns the appropriate `MOCK_CONTRACT_*` address for the given key in the case of a `KeyAddress` query. @@ -205,7 +247,7 @@ impl MockAndromedaQuerier { FAKE_VFS_PATH => SystemResult::Ok(ContractResult::Err("Invalid Path".to_string())), _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&path).unwrap())), }, - VFSQueryMsg::SubDir { path } => match path.as_str() { + VFSQueryMsg::SubDir { path, .. } => match path.as_str() { FAKE_VFS_PATH => SystemResult::Ok(ContractResult::Err("Invalid Path".to_string())), _ => SystemResult::Ok(ContractResult::Ok(to_json_binary(&path).unwrap())), }, @@ -218,6 +260,7 @@ impl MockAndromedaQuerier { VFSQueryMsg::GetLibrary { address } => { SystemResult::Ok(ContractResult::Ok(to_json_binary(&address).unwrap())) } + _ => todo!(), } } @@ -225,6 +268,7 @@ impl MockAndromedaQuerier { /// /// Returns `"actual_address"` for `Get` queries. fn handle_app_query(&self, _msg: &Binary) -> QuerierResult { + // match from_json(msg).unwrap() { // match from_json(msg).unwrap() { // _ => SystemResult::Ok(ContractResult::Err("Error".to_string())), // } @@ -239,6 +283,7 @@ impl MockAndromedaQuerier { fn handle_adodb_query(&self, msg: &Binary) -> QuerierResult { match from_json(msg).unwrap() { ADODBQueryMsg::ADOType { code_id } => match code_id { + 3 => SystemResult::Ok(ContractResult::Ok(to_json_binary(&"app-contract").unwrap())), 1 => SystemResult::Ok(ContractResult::Ok(to_json_binary(&"ADOType").unwrap())), _ => SystemResult::Ok(ContractResult::Err("Invalid Code ID".to_string())), }, @@ -263,6 +308,7 @@ impl MockAndromedaQuerier { value: Primitive::Decimal(Decimal::zero()), }, Some(data) => { + let key: String = from_json(&data).unwrap(); let key: String = from_json(&data).unwrap(); match key.as_str() { "String" => GetValueResponse { @@ -304,64 +350,6 @@ impl MockAndromedaQuerier { } } - #[cfg(feature = "modules")] - /// Handles all address list queries - /// - /// Returns `true` for `OnExecute` queries for any address excluding `UNWHITELISTED_ADDRESS`. - fn handle_address_list_query(&self, msg: &Binary) -> QuerierResult { - use cosmwasm_std::Response; - - use crate::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook) => match hook { - AndromedaHook::OnExecute { sender, .. } => match sender.as_str() { - UNWHITELISTED_ADDRESS => { - SystemResult::Ok(ContractResult::Err("Unwhitelisted Address".to_string())) - } - _ => SystemResult::Ok(ContractResult::Ok( - to_json_binary::(&Response::default()).unwrap(), - )), - }, - AndromedaHook::OnFundsTransfer { .. } => SystemResult::Ok(ContractResult::Ok( - to_json_binary(&OnFundsTransferResponse::default()).unwrap(), - )), - AndromedaHook::OnTokenTransfer { .. } => SystemResult::Ok(ContractResult::Ok( - to_json_binary::(&Response::default()).unwrap(), - )), - }, - } - } - - #[cfg(feature = "modules")] - /// Handles all rates queries - /// - /// The payments required are calculated using the `calculate_mock_rates_response` method within this crate - /// unless the sender is assigned as `RATES_EXCLUDED_ADDRESS`. - fn _handle_rates_query(&self, msg: &Binary) -> QuerierResult { - use cosmwasm_std::Response; - - use crate::ado_base::hooks::{AndromedaHook, HookMsg, OnFundsTransferResponse}; - match from_json(msg).unwrap() { - HookMsg::AndrHook(hook) => match hook { - AndromedaHook::OnExecute { .. } => SystemResult::Ok(ContractResult::Ok( - to_json_binary::(&Response::default()).unwrap(), - )), - AndromedaHook::OnFundsTransfer { sender, .. } => { - if sender.as_str() == RATES_EXCLUDED_ADDRESS { - return SystemResult::Ok(ContractResult::Ok( - to_json_binary(&OnFundsTransferResponse::default()).unwrap(), - )); - } - // let msgs = calculate_mock_rates_response(sender, payload, amount); - todo!("Implement Rates Query") - } - AndromedaHook::OnTokenTransfer { .. } => SystemResult::Ok(ContractResult::Ok( - to_json_binary::(&Response::default()).unwrap(), - )), - }, - } - } - /// Handles all CW20 queries. /// /// Returns a balance of 10 for any `Balance` query. @@ -375,10 +363,34 @@ impl MockAndromedaQuerier { to_json_binary(&balance_response).unwrap(), )) } + Cw20QueryMsg::TokenInfo {} => { + let token_info_response = TokenInfoResponse { + name: "valid-cw20".into(), + symbol: "VCW".to_string(), + decimals: 2, + total_supply: Uint128::new(10_000_000), + }; + SystemResult::Ok(ContractResult::Ok( + to_json_binary(&token_info_response).unwrap(), + )) + } _ => panic!("Unsupported Query"), } } + pub fn handle_ado_raw_query(&self, key: &Binary, contract_addr: &Addr) -> QuerierResult { + let key_vec = key.as_slice(); + let key_str = String::from_utf8(key_vec.to_vec()).unwrap(); + + if key_str.contains("owner") { + return SystemResult::Ok(ContractResult::Ok( + to_json_binary(&Addr::unchecked("owner".to_string())).unwrap(), + )); + } + + panic!("Unsupported query for contract: {contract_addr}") + } + pub fn handle_kernel_raw_query(&self, key: &Binary, fake: bool) -> QuerierResult { let key_vec = key.as_slice(); let key_str = String::from_utf8(key_vec.to_vec()).unwrap(); @@ -412,6 +424,16 @@ impl MockAndromedaQuerier { "andromeda".to_string() }; SystemResult::Ok(ContractResult::Ok(to_json_binary(&res).unwrap())) + } else if key_str.contains("channel") { + SystemResult::Ok(ContractResult::Ok( + to_json_binary(&ChannelInfo { + kernel_address: "kernel".to_string(), + ics20_channel_id: Some("1".to_string()), + direct_channel_id: Some("2".to_string()), + supported_modules: vec![], + }) + .unwrap(), + )) } else { panic!("Invalid Kernel Raw Query") } @@ -443,7 +465,7 @@ impl MockAndromedaQuerier { SystemResult::Ok(ContractResult::Ok( to_json_binary(&ActionFee::new( MOCK_ACTION.to_string(), - "uusd".to_string(), + "native:uusd".to_string(), Uint128::from(10u128), )) .unwrap(), @@ -457,12 +479,18 @@ impl MockAndromedaQuerier { } else if key_str.contains("ado_type") { let split = key_str.split("ado_type"); let key = split.last(); - match key { - Some("1") => { + // let app_contract_key = String::from_utf8(3u64.to_be_bytes().to_vec()).unwrap(); + // let generic_contract_key = String::from_utf8(1u64.to_be_bytes().to_vec()).unwrap(); + if let Some(key) = key { + if key == "3" { + SystemResult::Ok(ContractResult::Ok(to_json_binary("app-contract").unwrap())) + } else if key == "1" { SystemResult::Ok(ContractResult::Ok(to_json_binary("ADOType").unwrap())) + } else { + SystemResult::Ok(ContractResult::Ok(Binary::default())) } - Some(_) => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())), - None => SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())), + } else { + SystemResult::Ok(ContractResult::Err("Invalid Key".to_string())) } } else if key_str.contains("publisher") { let split = key_str.split("ado_type"); @@ -493,7 +521,6 @@ impl MockAndromedaQuerier { } } -#[cfg(feature = "modules")] pub fn calculate_mock_rates_response() -> (Vec, Vec) { todo!("Implement after readding rates contract"); } diff --git a/andromeda-core/tests-integration/Cargo.toml b/andromeda-core/tests-integration/Cargo.toml index e8212ed..2b92990 100644 --- a/andromeda-core/tests-integration/Cargo.toml +++ b/andromeda-core/tests-integration/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "tests-integration" -version = "0.1.0" +version = "1.0.0" edition = "2021" -rust-version = "1.65.0" +rust-version = "1.75.0" publish = false [features] @@ -17,6 +17,7 @@ andromeda-app-contract = { path = "../contracts/app/andromeda-app-contract", fea #Non-Fungible Tokens andromeda-non-fungible-tokens = { workspace = true } +andromeda-fungible-tokens = { workspace = true } andromeda-cw721 = { path = "../contracts/non-fungible-tokens/andromeda-cw721", features = [ "testing", ] } @@ -39,7 +40,15 @@ andromeda-marketplace = { path = "../contracts/non-fungible-tokens/andromeda-mar #Fungible Tokens # andromeda-fungible-tokens = { path = "../packages/andromeda-fungible-tokens" } -# andromeda-cw20 = { path = "../contracts/fungible-tokens/andromeda-cw20", features = ["testing"] } +andromeda-cw20 = { path = "../contracts/fungible-tokens/andromeda-cw20", features = [ + "testing", +] } +andromeda-cw20-staking = { path = "../contracts/fungible-tokens/andromeda-cw20-staking", features = [ + "testing", +] } +andromeda-lockdrop = { path = "../contracts/fungible-tokens/andromeda-lockdrop", features = [ + "testing", +] } # andromeda-cw20-staking = { path = "../contracts/fungible-tokens/andromeda-cw20-staking", features = ["testing"] } # #Modules @@ -62,6 +71,15 @@ andromeda-finance = { workspace = true } andromeda-splitter = { path = "../contracts/finance/andromeda-splitter", features = [ "testing", ] } +andromeda-set-amount-splitter = { path = "../contracts/finance/andromeda-set-amount-splitter", features = [ + "testing", +] } +andromeda-conditional-splitter = { path = "../contracts/finance/andromeda-conditional-splitter", features = [ + "testing", +] } +andromeda-vesting = { path = "../contracts/finance/andromeda-vesting", features = [ + "testing", +] } andromeda-validator-staking = { path = "../contracts/finance/andromeda-validator-staking", features = [ "testing", @@ -83,6 +101,9 @@ andromeda-shunting = { path = "../contracts/modules/andromeda-shunting", feature andromeda-kernel = { path = "../contracts/os/andromeda-kernel", features = [ "testing", ] } +andromeda-ibc-registry = { path = "../contracts/os/andromeda-ibc-registry", features = [ + "testing", +] } andromeda-adodb = { path = "../contracts/os/andromeda-adodb", features = [ "testing", ] } @@ -100,23 +121,25 @@ cosmwasm-std = { workspace = true, features = ["staking"] } cosmwasm-schema = { workspace = true } cw721-base = { workspace = true } cw721 = { workspace = true } -# cw20 = "0.16.0" -# cw20-base = { workspace = true } -# cw-cii = { git = "https://github.com/public-awesome/ics721.git" } -# cw-pause-once = { git = "https://github.com/public-awesome/ics721.git" } -# cw721-rate-limited-proxy = { git = "https://github.com/0xekez/cw721-proxy.git" } +cw20 = { workspace = true } +cw-asset = { workspace = true } +toml = "0.7" andromeda-std = { workspace = true } + [target.'cfg(not(target_arch = "wasm32"))'.dependencies] cw-multi-test = { workspace = true } +[[test]] +name = "app" + # [[test]] # name = "cw721" -# [[test]] -# name = "crowdfund_app" +[[test]] +name = "crowdfund_app" [[test]] name = "auction_app" @@ -133,6 +156,9 @@ name = "validator_staking" [[test]] name = "shunting" +[dependencies] +rstest = "0.19.0" + # [[test]] # name = "cw20_staking_app" diff --git a/andromeda-core/tests-integration/tests/app.rs b/andromeda-core/tests-integration/tests/app.rs new file mode 100644 index 0000000..be5e805 --- /dev/null +++ b/andromeda-core/tests-integration/tests/app.rs @@ -0,0 +1,84 @@ +#![cfg(not(target_arch = "wasm32"))] + +use andromeda_app::app::AppComponent; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; +use andromeda_cw721::mock::{mock_andromeda_cw721, mock_cw721_instantiate_msg}; +use andromeda_std::os::vfs::convert_component_name; +use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder, MockContract}; +use cosmwasm_std::{coin, to_json_binary}; + +#[test] +fn test_app() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(1000, "uandr")]), + ("user1", vec![]), + ]) + .with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("app-contract", mock_andromeda_app()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + + let app_name = "Simple App"; + + // Generate App Components + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + "cw721".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + let cw721_component_ref = AppComponent::new( + "cw721-ref".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![cw721_component, cw721_component_ref]; + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + let app = MockAppContract::instantiate( + app_code_id, + owner, + &mut router, + app_name, + app_components.clone(), + andr.kernel.addr(), + None, + ); + + let components = app.query_components(&router); + assert_eq!(components, app_components); + + let owner_str = owner.to_string(); + let cw721_component_with_symlink = AppComponent::symlink( + "cw721-ref-2", + "cw721", + format!("~{owner_str}/{0}/cw721", convert_component_name(app_name)), + ); + app.execute_add_app_component(&mut router, owner.clone(), cw721_component_with_symlink) + .unwrap(); + + let component_addresses = app.query_components(&router); + assert_eq!(component_addresses.len(), components.len() + 1); + + let cw721_component2 = AppComponent::new( + "cw721-2".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + app.execute_add_app_component(&mut router, owner.clone(), cw721_component2) + .unwrap(); + + let component_addresses = app.query_components(&router); + assert_eq!(component_addresses.len(), components.len() + 2); +} diff --git a/andromeda-core/tests-integration/tests/auction_app.rs b/andromeda-core/tests-integration/tests/auction_app.rs index b2703da..a84037c 100644 --- a/andromeda-core/tests-integration/tests/auction_app.rs +++ b/andromeda-core/tests-integration/tests/auction_app.rs @@ -1,91 +1,310 @@ #![cfg(not(target_arch = "wasm32"))] use andromeda_app::app::AppComponent; -use andromeda_app_contract::mock::{mock_andromeda_app, MockApp}; +use andromeda_app_contract::mock::{mock_andromeda_app, mock_claim_ownership_msg, MockAppContract}; use andromeda_auction::mock::{ - mock_andromeda_auction, mock_auction_instantiate_msg, mock_start_auction, MockAuction, + mock_andromeda_auction, mock_auction_instantiate_msg, mock_place_bid, mock_start_auction, + mock_update_auction, MockAuction, }; +use andromeda_cw20::mock::{mock_andromeda_cw20, mock_cw20_instantiate_msg, mock_minter, MockCW20}; use andromeda_cw721::mock::{mock_andromeda_cw721, mock_cw721_instantiate_msg, MockCW721}; -use andromeda_std::common::expiration::MILLISECONDS_TO_NANOSECONDS_RATIO; -use andromeda_testing::{mock::MockAndromeda, mock_contract::MockContract}; -use cosmwasm_std::{coin, to_json_binary, Addr, BlockInfo, Timestamp, Uint128}; +use andromeda_finance::splitter::AddressPercent; +use andromeda_non_fungible_tokens::auction::{AuctionStateResponse, Cw20HookMsg}; +use andromeda_rates::mock::mock_andromeda_rates; +use andromeda_splitter::mock::{ + mock_andromeda_splitter, mock_splitter_instantiate_msg, mock_splitter_send_msg, +}; +use andromeda_std::{ + ado_base::{ + permissioning::{LocalPermission, Permission}, + rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}, + }, + amp::{AndrAddr, Recipient}, + common::{ + denom::Asset, + expiration::{Expiry, MILLISECONDS_TO_NANOSECONDS_RATIO}, + Milliseconds, + }, + error::ContractError, +}; +use andromeda_testing::{ + mock::mock_app, mock_builder::MockAndromedaBuilder, mock_contract::MockContract, +}; +use cosmwasm_std::{coin, to_json_binary, Addr, BlockInfo, Decimal, Timestamp, Uint128}; +use cw20::Cw20Coin; +use cw_multi_test::Executor; -use cw_multi_test::App; +#[test] +fn test_auction_app_modules() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer_one", vec![coin(1000, "uandr")]), + ("buyer_two", vec![coin(1000, "uandr")]), + ("recipient_one", vec![]), + ("recipient_two", vec![]), + ]) + .with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("auction", mock_andromeda_auction()), + ("app-contract", mock_andromeda_app()), + ("splitter", mock_andromeda_splitter()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let buyer_two = andr.get_wallet("buyer_two"); + let recipient_one = andr.get_wallet("recipient_one"); + let recipient_two = andr.get_wallet("recipient_two"); -fn mock_app() -> App { - App::new(|router, _api, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked("owner"), - [coin(100, "uandr")].to_vec(), - ) - .unwrap(); - router - .bank - .init_balance( - storage, - &Addr::unchecked("buyer_one"), - [coin(100, "uandr")].to_vec(), - ) - .unwrap(); - router - .bank - .init_balance( - storage, - &Addr::unchecked("buyer_two"), - [coin(100, "uandr")].to_vec(), - ) - .unwrap(); - }) -} + // Generate App Components + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + "cw721".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let auction_init_msg = + mock_auction_instantiate_msg(andr.kernel.addr().to_string(), None, None, None); + let auction_component = AppComponent::new( + "auction".to_string(), + "auction".to_string(), + to_json_binary(&auction_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![cw721_component.clone(), auction_component.clone()]; + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Auction App", + app_components, + andr.kernel.addr(), + Some(owner.to_string()), + ); + + router + .execute_contract( + owner.clone(), + Addr::unchecked(app.addr().clone()), + &mock_claim_ownership_msg(None), + &[], + ) + .unwrap(); + + // Mint Tokens + let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); + cw721 + .execute_quick_mint(&mut router, owner.clone(), 1, owner.to_string()) + .unwrap(); + + // Send Token to Auction + let auction: MockAuction = app.query_ado_by_component_name(&router, auction_component.name); + + // Set rates to auction + auction + .execute_add_rate( + &mut router, + owner.clone(), + "Claim".to_string(), + Rate::Local(LocalRate { + rate_type: LocalRateType::Deductive, + recipients: vec![ + Recipient::new(recipient_one, None), + Recipient::new(recipient_two, None), + ], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(25), + }), + description: None, + }), + ) + .unwrap(); + + let start_time = Milliseconds::from_nanos(router.block_info().time.nanos()) + .plus_milliseconds(Milliseconds(100)); + let receive_msg = mock_start_auction( + Some(Expiry::AtTime(start_time)), + Expiry::AtTime(start_time.plus_milliseconds(Milliseconds(1000))), + Asset::NativeToken("uandr".to_string()), + None, + None, + None, + None, + ); + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + auction.addr(), + "0", + &receive_msg, + ) + .unwrap(); + + router.set_block(BlockInfo { + height: router.block_info().height, + time: start_time.into(), + chain_id: router.block_info().chain_id, + }); + + // Query Auction State + let auction_ids: Vec = + auction.query_auction_ids(&mut router, "0".to_string(), cw721.addr().to_string()); + + assert_eq!(auction_ids.len(), 1); + + let auction_id = auction_ids.first().unwrap(); + let auction_state = auction.query_auction_state(&mut router, *auction_id); + + assert_eq!(auction_state.coin_denom, "uandr".to_string()); + assert_eq!(auction_state.owner, owner.to_string()); + + // Place Bid One + auction.execute_place_bid( + &mut router, + buyer_one.clone(), + "0".to_string(), + cw721.addr().to_string(), + &[coin(50, "uandr")], + ); + + // Check Bid Status One + let bids = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids.len(), 1); + + let bid = bids.first().unwrap(); + assert_eq!(bid.bidder, buyer_one.to_string()); + assert_eq!(bid.amount, Uint128::from(50u128)); + + auction.execute_place_bid( + &mut router, + buyer_two.clone(), + "0".to_string(), + cw721.addr().to_string(), + &[coin(100, "uandr")], + ); + + // Check Bid Status One + let bids = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids.len(), 2); + + let bid_two = bids.get(1).unwrap(); + assert_eq!(bid_two.bidder, buyer_two.to_string()); + assert_eq!(bid_two.amount, Uint128::from(100u128)); + + // End Auction + router.set_block(BlockInfo { + height: router.block_info().height, + time: start_time.plus_milliseconds(Milliseconds(1000)).into(), + chain_id: router.block_info().chain_id, + }); + auction + .execute_claim_auction( + &mut router, + buyer_two.clone(), + "0".to_string(), + cw721.addr().to_string(), + ) + .unwrap(); -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) + // Check Final State + let token_owner = cw721.query_owner_of(&router, "0"); + assert_eq!(token_owner, buyer_two); + let owner_balance = router.wrap().query_balance(owner, "uandr").unwrap(); + assert_eq!(owner_balance.amount, Uint128::from(50u128)); + let recipient_one_balance = router.wrap().query_balance(recipient_one, "uandr").unwrap(); + assert_eq!(recipient_one_balance.amount, Uint128::from(25u128)); + let recipient_two_balance = router.wrap().query_balance(recipient_two, "uandr").unwrap(); + assert_eq!(recipient_two_balance.amount, Uint128::from(25u128)); } #[test] -fn test_auction_app() { - let owner = Addr::unchecked("owner"); - let buyer_one = Addr::unchecked("buyer_one"); - let buyer_two = Addr::unchecked("buyer_two"); - - let mut router = mock_app(); - let andr = mock_andromeda(&mut router, owner.clone()); - // Store contract codes - andr.store_ado(&mut router, mock_andromeda_cw721(), "cw721"); - andr.store_ado(&mut router, mock_andromeda_auction(), "auction"); - andr.store_ado(&mut router, mock_andromeda_app(), "app"); +fn test_auction_app_recipient() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer_one", vec![coin(1000, "uandr")]), + ("buyer_two", vec![coin(1000, "uandr")]), + ("recipient_one", vec![]), + ("recipient_two", vec![]), + ]) + .with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("auction", mock_andromeda_auction()), + ("app-contract", mock_andromeda_app()), + ("splitter", mock_andromeda_splitter()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let buyer_two = andr.get_wallet("buyer_two"); + let recipient_one = andr.get_wallet("recipient_one"); + let recipient_two = andr.get_wallet("recipient_two"); // Generate App Components let cw721_init_msg = mock_cw721_instantiate_msg( "Test Tokens".to_string(), "TT".to_string(), owner.to_string(), - None, andr.kernel.addr().to_string(), None, ); let cw721_component = AppComponent::new( - "1".to_string(), + "cw721".to_string(), "cw721".to_string(), to_json_binary(&cw721_init_msg).unwrap(), ); - let auction_init_msg = mock_auction_instantiate_msg(None, andr.kernel.addr().to_string(), None); + let splitter_init_msg = mock_splitter_instantiate_msg( + vec![ + AddressPercent::new( + Recipient::from_string(format!("{recipient_one}")), + Decimal::from_ratio(1u8, 2u8), + ), + AddressPercent::new( + Recipient::from_string(format!("{recipient_two}")), + Decimal::from_ratio(1u8, 2u8), + ), + ], + andr.kernel.addr(), + None, + None, + ); + let splitter_component = AppComponent::new( + "splitter", + "splitter", + to_json_binary(&splitter_init_msg).unwrap(), + ); + + let auction_init_msg = + mock_auction_instantiate_msg(andr.kernel.addr().to_string(), None, None, None); let auction_component = AppComponent::new( - "2".to_string(), + "auction".to_string(), "auction".to_string(), to_json_binary(&auction_init_msg).unwrap(), ); // Create App - let app_components = vec![cw721_component.clone(), auction_component.clone()]; - let app = MockApp::instantiate( - andr.get_code_id(&mut router, "app"), - owner.clone(), + let app_components = vec![ + cw721_component.clone(), + auction_component.clone(), + splitter_component, + ]; + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, &mut router, "Auction App", app_components, @@ -93,6 +312,15 @@ fn test_auction_app() { Some(owner.to_string()), ); + router + .execute_contract( + owner.clone(), + Addr::unchecked(app.addr().clone()), + &mock_claim_ownership_msg(None), + &[], + ) + .unwrap(); + // Mint Tokens let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); cw721 @@ -101,8 +329,17 @@ fn test_auction_app() { // Send Token to Auction let auction: MockAuction = app.query_ado_by_component_name(&router, auction_component.name); - let start_time = router.block_info().time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO + 100; - let receive_msg = mock_start_auction(start_time, 1000, "uandr".to_string(), None, None); + let start_time = Milliseconds::from_nanos(router.block_info().time.nanos()) + .plus_milliseconds(Milliseconds(100)); + let receive_msg = mock_start_auction( + Some(Expiry::AtTime(start_time)), + Expiry::AtTime(start_time.plus_milliseconds(Milliseconds(1000))), + Asset::NativeToken("uandr".to_string()), + None, + None, + None, + Some(Recipient::from_string("./splitter").with_msg(mock_splitter_send_msg())), + ); cw721 .execute_send_nft( &mut router, @@ -115,7 +352,7 @@ fn test_auction_app() { router.set_block(BlockInfo { height: router.block_info().height, - time: Timestamp::from_nanos(start_time * MILLISECONDS_TO_NANOSECONDS_RATIO), + time: start_time.into(), chain_id: router.block_info().chain_id, }); @@ -167,7 +404,7 @@ fn test_auction_app() { // End Auction router.set_block(BlockInfo { height: router.block_info().height, - time: Timestamp::from_nanos((start_time + 1001) * MILLISECONDS_TO_NANOSECONDS_RATIO), + time: start_time.plus_milliseconds(Milliseconds(1000)).into(), chain_id: router.block_info().chain_id, }); auction @@ -183,5 +420,868 @@ fn test_auction_app() { let token_owner = cw721.query_owner_of(&router, "0"); assert_eq!(token_owner, buyer_two); let owner_balance = router.wrap().query_balance(owner, "uandr").unwrap(); - assert_eq!(owner_balance.amount, Uint128::from(200u128)); + assert_eq!(owner_balance.amount, Uint128::zero()); + let recipient_one_balance = router.wrap().query_balance(recipient_one, "uandr").unwrap(); + assert_eq!(recipient_one_balance.amount, Uint128::from(50u128)); + let recipient_two_balance = router.wrap().query_balance(recipient_two, "uandr").unwrap(); + assert_eq!(recipient_two_balance.amount, Uint128::from(50u128)); +} + +#[test] +fn test_auction_app_cw20_restricted() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer_one", vec![coin(1000, "uandr")]), + ("buyer_two", vec![coin(1000, "uandr")]), + ("buyer_three", vec![coin(1000, "uandr")]), + ("recipient_one", vec![]), + ("recipient_two", vec![]), + ]) + .with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("cw20", mock_andromeda_cw20()), + ("auction", mock_andromeda_auction()), + ("app-contract", mock_andromeda_app()), + ("rates", mock_andromeda_rates()), + ("splitter", mock_andromeda_splitter()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let buyer_two = andr.get_wallet("buyer_two"); + let buyer_three = andr.get_wallet("buyer_three"); + // Generate App Components + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + "cw721".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let buyer_one_original_balance = Uint128::new(1_000); + let buyer_two_original_balance = Uint128::new(2_000); + let owner_original_balance = Uint128::new(10_000); + let initial_balances = vec![ + Cw20Coin { + address: buyer_one.to_string(), + amount: buyer_one_original_balance, + }, + Cw20Coin { + address: buyer_two.to_string(), + amount: buyer_two_original_balance, + }, + Cw20Coin { + address: owner.to_string(), + amount: owner_original_balance, + }, + ]; + + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances.clone(), + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + + let second_cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Second Test Tokens".to_string(), + "STTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let second_cw20_component = AppComponent::new( + "second-cw20".to_string(), + "cw20".to_string(), + to_json_binary(&second_cw20_init_msg).unwrap(), + ); + + let auction_init_msg = mock_auction_instantiate_msg( + andr.kernel.addr().to_string(), + None, + Some(vec![AndrAddr::from_string(format!( + "./{}", + cw721_component.name + ))]), + Some(AndrAddr::from_string(format!("./{}", cw20_component.name))), + ); + let auction_component = AppComponent::new( + "auction".to_string(), + "auction".to_string(), + to_json_binary(&auction_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![ + auction_component.clone(), + cw721_component.clone(), + cw20_component.clone(), + second_cw20_component.clone(), + ]; + + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Auction App", + app_components.clone(), + andr.kernel.addr(), + Some(owner.to_string()), + ); + let components = app.query_components(&router); + assert_eq!(components, app_components); + let cw20: MockCW20 = app.query_ado_by_component_name(&router, cw20_component.name); + + // Mint Tokens + let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); + cw721 + .execute_quick_mint(&mut router, owner.clone(), 2, owner.to_string()) + .unwrap(); + + // Authorize NFT contract + let auction: MockAuction = app.query_ado_by_component_name(&router, auction_component.name); + auction + .execute_authorize_token_address(&mut router, owner.clone(), cw721.addr(), None) + .unwrap(); + + // Send Token to Auction + let start_time = router.block_info().time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO + 100; + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + AndrAddr::from_string("./auction".to_string()), + "0", + &mock_start_auction( + Some(Expiry::AtTime(Milliseconds(start_time))), + Expiry::AtTime(Milliseconds(start_time + 2)), + Asset::Cw20Token(AndrAddr::from_string(cw20.addr().to_string())), + None, + None, + None, + None, + ), + ) + .unwrap(); + + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos(start_time * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + + // Query Auction State + let auction_ids = + auction.query_auction_ids(&mut router, "0".to_string(), cw721.addr().to_string()); + assert_eq!(auction_ids.len(), 1); + + let auction_id = auction_ids.first().unwrap(); + let auction_state: AuctionStateResponse = auction.query_auction_state(&mut router, *auction_id); + assert_eq!(auction_state.coin_denom, cw20.addr().to_string()); + + // Try to set permission with an empty vector of actors + let actors = vec![]; + let action = "PlaceBid".to_string(); + let permission = Permission::Local(LocalPermission::blacklisted(None)); + let err: ContractError = auction + .execute_set_permission(&mut router, owner.clone(), actors, action, permission) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::NoActorsProvided {}); + + // Place Bid One + // Blacklist bidder now and blacklist bidder three just to test permissioning multiple actors at the same time + let actors = vec![ + AndrAddr::from_string(buyer_one.clone()), + AndrAddr::from_string(buyer_three.clone()), + ]; + let action = "PlaceBid".to_string(); + let permission = Permission::Local(LocalPermission::blacklisted(None)); + auction + .execute_set_permission(&mut router, owner.clone(), actors, action, permission) + .unwrap(); + + let bid_msg = mock_place_bid("0".to_string(), cw721.addr().to_string()); + + // Bid should be rejected because we blacklisted bidder one + let err: ContractError = router + .execute_contract( + buyer_one.clone(), + Addr::unchecked(auction.addr().clone()), + &bid_msg, + &[coin(50, "uandr")], + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::Unauthorized {}); + + // Bid should be rejected because we blacklisted bidder three + let err: ContractError = router + .execute_contract( + buyer_three.clone(), + Addr::unchecked(auction.addr().clone()), + &bid_msg, + &[coin(50, "uandr")], + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::Unauthorized {}); + + // Now whitelist bidder one + let actors = vec![AndrAddr::from_string(buyer_one.clone())]; + let action = "PlaceBid".to_string(); + let permission = Permission::Local(LocalPermission::whitelisted(None)); + auction + .execute_set_permission(&mut router, owner.clone(), actors, action, permission) + .unwrap(); + + // Try bidding again + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: "0".to_owned(), + token_address: cw721.addr().clone().to_string(), + }; + cw20.execute_send( + &mut router, + buyer_one.clone(), + auction.addr(), + Uint128::new(50), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 1); + + let bid = bids_resp.first().unwrap(); + assert_eq!(bid.bidder, buyer_one.to_string()); + assert_eq!(bid.amount, Uint128::from(50u128)); + + // Second bid by buyer_two + cw20.execute_send( + &mut router, + buyer_two.clone(), + auction.addr(), + Uint128::new(100), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 2); + + let bid_two = bids_resp.get(1).unwrap(); + assert_eq!(bid_two.bidder, buyer_two.to_string()); + assert_eq!(bid_two.amount, Uint128::from(100u128)); + + // Forward time + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos((start_time + 1001) * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + + // End Auction + auction + .execute_claim_auction( + &mut router, + buyer_two.clone(), + "0".to_string(), + cw721.addr().to_string(), + ) + .unwrap(); + + // Check Final State + let owner_resp = cw721.query_owner_of(&router, "0".to_string()); + assert_eq!(owner_resp, buyer_two.to_string()); + + // The auction's owner sold the NFT for 100, so the balance should increase by 100 + let cw20_balance = cw20.query_balance(&router, owner); + assert_eq!( + cw20_balance, + owner_original_balance + .checked_add(Uint128::new(100)) + .unwrap() + ); + + // Buyer two won the auction with a bid of 100, the balance should be 100 less than the original balance + let cw20_balance = cw20.query_balance(&router, buyer_two); + assert_eq!( + cw20_balance, + buyer_two_original_balance + .checked_sub(Uint128::new(100)) + .unwrap() + ); + + // Buyer one was outbid, so the balance should remain unchanged + let cw20_balance = cw20.query_balance(&router, buyer_one); + assert_eq!(cw20_balance, buyer_one_original_balance); + + // Now try holding an auction with a recipient + + // Send Token to Auction + let start_time = router.block_info().time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO + 100; + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + AndrAddr::from_string("./auction".to_string()), + "1", + &mock_start_auction( + Some(Expiry::AtTime(Milliseconds(start_time))), + Expiry::AtTime(Milliseconds(start_time + 2)), + Asset::Cw20Token(AndrAddr::from_string(cw20.addr().to_string())), + None, + None, + Some(vec![buyer_one.clone(), buyer_two.clone()]), + Some(Recipient::from_string(buyer_one)), + ), + ) + .unwrap(); + + // Try updating denom to another unpermissioned cw20, shouldn't work since this a restricted cw20 auction + let second_cw20: MockCW20 = + app.query_ado_by_component_name(&router, second_cw20_component.name); + let update_auction_msg = mock_update_auction( + "0".to_string(), + cw721.addr().to_string(), + Some(Expiry::AtTime(Milliseconds(start_time))), + Expiry::AtTime(Milliseconds(start_time + 2)), + // This cw20 hasn't been permissioned + Asset::Cw20Token(AndrAddr::from_string(second_cw20.addr().to_string())), + None, + None, + Some(vec![buyer_one.clone(), buyer_two.clone()]), + Some(Recipient::from_string(buyer_one)), + ); + + let err: ContractError = router + .execute_contract( + owner.clone(), + auction.addr().clone(), + &update_auction_msg, + &[], + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!( + err, + ContractError::InvalidFunds { + msg: format!( + "Non-permissioned CW20 asset '{}' set as denom.", + second_cw20.addr() + ) + } + ); + + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos(start_time * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + + // Query Auction State + let auction_ids = + auction.query_auction_ids(&mut router, "1".to_string(), cw721.addr().to_string()); + assert_eq!(auction_ids.len(), 1); + + let auction_id = auction_ids.first().unwrap(); + let auction_state: AuctionStateResponse = auction.query_auction_state(&mut router, *auction_id); + assert_eq!(auction_state.coin_denom, cw20.addr().to_string()); + + // Place Bid One + // Whitelisted buyer one at the start of the auction + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: "1".to_owned(), + token_address: cw721.addr().clone().to_string(), + }; + + cw20.execute_send( + &mut router, + buyer_one.clone(), + auction.addr(), + Uint128::new(50), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 1); + + let bid = bids_resp.first().unwrap(); + assert_eq!(bid.bidder, buyer_one.to_string()); + assert_eq!(bid.amount, Uint128::from(50u128)); + + // Second bid by buyer_two + cw20.execute_send( + &mut router, + buyer_two.clone(), + auction.addr(), + Uint128::new(100), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 2); + + let bid_two = bids_resp.get(1).unwrap(); + assert_eq!(bid_two.bidder, buyer_two.to_string()); + assert_eq!(bid_two.amount, Uint128::from(100u128)); + + // Forward time + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos((start_time + 1001) * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + + // End Auction + auction + .execute_claim_auction( + &mut router, + buyer_two.clone(), + "1".to_string(), + cw721.addr().to_string(), + ) + .unwrap(); + + // Check Final State + let owner_resp = cw721.query_owner_of(&router, "1".to_string()); + assert_eq!(owner_resp, buyer_two.to_string()); + + // The auction's owner sold the NFT for 100, but has buyer_one set as recipient. So the balance shouldn't change since the previous auction + let cw20_balance = cw20.query_balance(&router, owner); + assert_eq!( + cw20_balance, + owner_original_balance + .checked_add(Uint128::new(100)) + .unwrap() + ); + + // Buyer two won the auction with a bid of 100, the balance should be 100 less than the original balance + let cw20_balance = cw20.query_balance(&router, buyer_two); + assert_eq!( + cw20_balance, + buyer_two_original_balance + // Purchase from previous and current auction + .checked_sub(Uint128::new(100 + 100)) + .unwrap() + ); + + // Buyer one was outbid, but is set as the auction's recipient, so balance should increase by 100 + let cw20_balance = cw20.query_balance(&router, buyer_one); + assert_eq!( + cw20_balance, + buyer_one_original_balance + .checked_add(Uint128::new(100)) + .unwrap() + ); +} + +#[test] +fn test_auction_app_cw20_unrestricted() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer_one", vec![coin(1000, "uandr")]), + ("buyer_two", vec![coin(1000, "uandr")]), + ]) + .with_contracts(vec![ + ("cw721", mock_andromeda_cw721()), + ("cw20", mock_andromeda_cw20()), + ("auction", mock_andromeda_auction()), + ("app-contract", mock_andromeda_app()), + ("rates", mock_andromeda_rates()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let buyer_two = andr.get_wallet("buyer_two"); + + // Generate App Components + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + "cw721".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let buyer_one_original_balance = Uint128::new(1_000); + let buyer_two_original_balance = Uint128::new(2_000); + let owner_original_balance = Uint128::new(10_000); + let initial_balances = vec![ + Cw20Coin { + address: buyer_one.to_string(), + amount: buyer_one_original_balance, + }, + Cw20Coin { + address: buyer_two.to_string(), + amount: buyer_two_original_balance, + }, + Cw20Coin { + address: owner.to_string(), + amount: owner_original_balance, + }, + ]; + + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances.clone(), + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + + let second_cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Second Test Tokens".to_string(), + "STTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let second_cw20_component = AppComponent::new( + "second-cw20".to_string(), + "cw20".to_string(), + to_json_binary(&second_cw20_init_msg).unwrap(), + ); + + let auction_init_msg = mock_auction_instantiate_msg( + andr.kernel.addr().to_string(), + None, + Some(vec![AndrAddr::from_string(format!( + "./{}", + cw721_component.name + ))]), + None, + ); + let auction_component = AppComponent::new( + "auction".to_string(), + "auction".to_string(), + to_json_binary(&auction_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![ + auction_component.clone(), + cw721_component.clone(), + cw20_component.clone(), + second_cw20_component.clone(), + ]; + + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Auction App", + app_components.clone(), + andr.kernel.addr(), + Some(owner.to_string()), + ); + let components = app.query_components(&router); + assert_eq!(components, app_components); + let cw20: MockCW20 = app.query_ado_by_component_name(&router, cw20_component.name); + + // Mint Tokens + let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); + cw721 + .execute_quick_mint(&mut router, owner.clone(), 2, owner.to_string()) + .unwrap(); + + // Send Token to Auction + let auction: MockAuction = app.query_ado_by_component_name(&router, auction_component.name); + let start_time = router.block_info().time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO + 100; + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + AndrAddr::from_string("./auction".to_string()), + "0", + &mock_start_auction( + Some(Expiry::AtTime(Milliseconds(start_time))), + Expiry::AtTime(Milliseconds(start_time + 2)), + Asset::Cw20Token(AndrAddr::from_string(cw20.addr().to_string())), + None, + None, + Some(vec![buyer_one.clone(), buyer_two.clone()]), + None, + ), + ) + .unwrap(); + + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos(start_time * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + + // Query Auction State + let auction_ids = + auction.query_auction_ids(&mut router, "0".to_string(), cw721.addr().to_string()); + assert_eq!(auction_ids.len(), 1); + + let auction_id = auction_ids.first().unwrap(); + let auction_state: AuctionStateResponse = auction.query_auction_state(&mut router, *auction_id); + assert_eq!(auction_state.coin_denom, cw20.addr().to_string()); + + // Place Bid One + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: "0".to_owned(), + token_address: cw721.addr().clone().to_string(), + }; + cw20.execute_send( + &mut router, + buyer_one.clone(), + auction.addr(), + Uint128::new(50), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 1); + + let bid = bids_resp.first().unwrap(); + assert_eq!(bid.bidder, buyer_one.to_string()); + assert_eq!(bid.amount, Uint128::from(50u128)); + + // Second bid by buyer_two + cw20.execute_send( + &mut router, + buyer_two.clone(), + auction.addr(), + Uint128::new(100), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 2); + + let bid_two = bids_resp.get(1).unwrap(); + assert_eq!(bid_two.bidder, buyer_two.to_string()); + assert_eq!(bid_two.amount, Uint128::from(100u128)); + + // End Auction + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos((start_time + 1001) * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + auction + .execute_claim_auction( + &mut router, + buyer_two.clone(), + "0".to_string(), + cw721.addr().to_string(), + ) + .unwrap(); + + // Check Final State + let owner_resp = cw721.query_owner_of(&router, "0".to_string()); + assert_eq!(owner_resp, buyer_two.to_string()); + + // The auction's owner sold the NFT for 100, so the balance should increase by 100 + let cw20_balance = cw20.query_balance(&router, owner); + assert_eq!( + cw20_balance, + owner_original_balance + .checked_add(Uint128::new(100)) + .unwrap() + ); + + // Buyer two won the auction with a bid of 100, the balance should be 100 less than the original balance + let cw20_balance = cw20.query_balance(&router, buyer_two); + assert_eq!( + cw20_balance, + buyer_two_original_balance + .checked_sub(Uint128::new(100)) + .unwrap() + ); + + // Buyer one was outbid, so the balance should remain unchanged + let cw20_balance = cw20.query_balance(&router, buyer_one); + assert_eq!(cw20_balance, buyer_one_original_balance); + + // + // + // Create a new auction with another cw20 set as the denom + // + // + + let second_cw20: MockCW20 = + app.query_ado_by_component_name(&router, second_cw20_component.name); + + // Send Token to Auction + let start_time = router.block_info().time.nanos() / MILLISECONDS_TO_NANOSECONDS_RATIO + 100; + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + AndrAddr::from_string("./auction".to_string()), + "1", + &mock_start_auction( + Some(Expiry::AtTime(Milliseconds(start_time))), + Expiry::AtTime(Milliseconds(start_time + 2)), + Asset::Cw20Token(AndrAddr::from_string(second_cw20.addr().to_string())), + None, + None, + Some(vec![buyer_one.clone(), buyer_two.clone()]), + None, + ), + ) + .unwrap(); + + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos(start_time * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + + // Query Auction State + let auction_ids = + auction.query_auction_ids(&mut router, "1".to_string(), cw721.addr().to_string()); + assert_eq!(auction_ids.len(), 1); + + let auction_id = auction_ids.first().unwrap(); + let auction_state: AuctionStateResponse = auction.query_auction_state(&mut router, *auction_id); + assert_eq!(auction_state.coin_denom, second_cw20.addr().to_string()); + + // Place Bid One + let hook_msg = Cw20HookMsg::PlaceBid { + token_id: "1".to_owned(), + token_address: cw721.addr().clone().to_string(), + }; + second_cw20 + .execute_send( + &mut router, + buyer_one.clone(), + auction.addr(), + Uint128::new(50), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 1); + + let bid = bids_resp.first().unwrap(); + assert_eq!(bid.bidder, buyer_one.to_string()); + assert_eq!(bid.amount, Uint128::from(50u128)); + + // Second bid by buyer_two + second_cw20 + .execute_send( + &mut router, + buyer_two.clone(), + auction.addr(), + Uint128::new(100), + &hook_msg, + ) + .unwrap(); + + // Check Bid Status One + let bids_resp = auction.query_bids(&mut router, *auction_id); + assert_eq!(bids_resp.len(), 2); + + let bid_two = bids_resp.get(1).unwrap(); + assert_eq!(bid_two.bidder, buyer_two.to_string()); + assert_eq!(bid_two.amount, Uint128::from(100u128)); + + // End Auction + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_nanos((start_time + 1001) * MILLISECONDS_TO_NANOSECONDS_RATIO), + chain_id: router.block_info().chain_id, + }); + auction + .execute_claim_auction( + &mut router, + buyer_two.clone(), + "1".to_string(), + cw721.addr().to_string(), + ) + .unwrap(); + + // Check Final State + let owner_resp = cw721.query_owner_of(&router, "1".to_string()); + assert_eq!(owner_resp, buyer_two.to_string()); + + // The auction's owner sold the NFT for 100, so the balance should increase by 100 + let cw20_balance = second_cw20.query_balance(&router, owner); + assert_eq!( + cw20_balance, + owner_original_balance + .checked_add(Uint128::new(100)) + .unwrap() + ); + + // Buyer two won the auction with a bid of 100, the balance should be 100 less than the original balance + let cw20_balance = second_cw20.query_balance(&router, buyer_two); + assert_eq!( + cw20_balance, + buyer_two_original_balance + .checked_sub(Uint128::new(100)) + .unwrap() + ); + + // Buyer one was outbid, so the balance should remain unchanged + let cw20_balance = second_cw20.query_balance(&router, buyer_one); + assert_eq!(cw20_balance, buyer_one_original_balance); } diff --git a/andromeda-core/tests-integration/tests/conditional_splitter.rs b/andromeda-core/tests-integration/tests/conditional_splitter.rs new file mode 100644 index 0000000..a4e0557 --- /dev/null +++ b/andromeda-core/tests-integration/tests/conditional_splitter.rs @@ -0,0 +1,176 @@ +use andromeda_app::app::{AppComponent, ComponentType}; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; + +use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder, MockContract}; + +use andromeda_std::amp::Recipient; +use cosmwasm_std::{coin, Decimal, Uint128}; + +use andromeda_conditional_splitter::mock::{ + mock_andromeda_conditional_splitter, mock_conditional_splitter_instantiate_msg, + MockConditionalSplitter, +}; +use andromeda_finance::{conditional_splitter::Threshold, splitter::AddressPercent}; + +use std::str::FromStr; + +#[test] +fn test_conditional_splitter() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(100_000, "uandr"), coin(100_000, "uusd")]), + ("recipient1", vec![]), + ("recipient2", vec![]), + ("recipient3", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ( + "conditional-splitter", + mock_andromeda_conditional_splitter(), + ), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let recipient_1 = andr.get_wallet("recipient1"); + let recipient_2 = andr.get_wallet("recipient2"); + let recipient_3 = andr.get_wallet("recipient3"); + + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + + let splitter_recipients = vec![ + AddressPercent { + recipient: Recipient::from_string(recipient_1.to_string()), + percent: Decimal::from_str("0.2").unwrap(), + }, + AddressPercent { + recipient: Recipient::from_string(recipient_2.to_string()), + percent: Decimal::from_str("0.8").unwrap(), + }, + ]; + + // Percentages that don't add up to 100 + let splitter_recipients3 = vec![ + AddressPercent { + recipient: Recipient::from_string(recipient_1.to_string()), + percent: Decimal::from_str("0.2").unwrap(), + }, + AddressPercent { + recipient: Recipient::from_string(recipient_2.to_string()), + percent: Decimal::from_str("0.5").unwrap(), + }, + AddressPercent { + recipient: Recipient::from_string(recipient_3.to_string()), + percent: Decimal::from_str("0.2").unwrap(), + }, + ]; + + let thresholds = vec![ + Threshold::new(Uint128::zero(), splitter_recipients.clone()), + Threshold::new(Uint128::new(10_000), splitter_recipients), + Threshold::new(Uint128::new(20_000), splitter_recipients3), + ]; + + let splitter_init_msg = mock_conditional_splitter_instantiate_msg( + thresholds, + andr.kernel.addr().clone(), + None, + None, + ); + let splitter_app_component = AppComponent { + name: "conditional-splitter".to_string(), + component_type: ComponentType::new(splitter_init_msg), + ado_type: "conditional-splitter".to_string(), + }; + + let app_components = vec![splitter_app_component.clone()]; + let app = MockAppContract::instantiate( + app_code_id, + owner, + &mut router, + "Conditional Splitter App", + app_components, + andr.kernel.addr(), + None, + ); + + let splitter: MockConditionalSplitter = + app.query_ado_by_component_name(&router, splitter_app_component.name); + + let token = coin(1000, "uandr"); + splitter + .execute_send(&mut router, owner.clone(), &[token]) + .unwrap(); + + let balance_1 = router.wrap().query_balance(recipient_1, "uandr").unwrap(); + let balance_2 = router.wrap().query_balance(recipient_2, "uandr").unwrap(); + + assert_eq!(balance_1.amount, Uint128::from(200u128)); + assert_eq!(balance_2.amount, Uint128::from(800u128)); + + // Second batch + let token2 = coin(10_000, "uandr"); + splitter + .execute_send(&mut router, owner.clone(), &[token2]) + .unwrap(); + + let balance_1 = router.wrap().query_balance(recipient_1, "uandr").unwrap(); + let balance_2 = router.wrap().query_balance(recipient_2, "uandr").unwrap(); + + assert_eq!(balance_1.amount, Uint128::from(200u128 + 2000u128)); + assert_eq!(balance_2.amount, Uint128::from(800u128 + 8000u128)); + + // Third batch + let token2 = coin(50_000, "uandr"); + splitter + .execute_send(&mut router, owner.clone(), &[token2]) + .unwrap(); + + let balance_1 = router.wrap().query_balance(recipient_1, "uandr").unwrap(); + let balance_2 = router.wrap().query_balance(recipient_2, "uandr").unwrap(); + let balance_3 = router.wrap().query_balance(recipient_3, "uandr").unwrap(); + + assert_eq!( + balance_1.amount, + Uint128::from(200u128 + 2000u128 + 10_000u128) + ); + assert_eq!( + balance_2.amount, + Uint128::from(800u128 + 8000u128 + 25_000u128) + ); + assert_eq!(balance_3.amount, Uint128::from(10_000u128)); + + let balance_owner = router.wrap().query_balance(owner, "uandr").unwrap(); + // First batch was 1000, second batch was 10,000 and both percentages added up to 100, the third batch was 50,000 but the percentages added up to 90, so 45,000 should have been deducted from his balance + assert_eq!( + balance_owner.amount, + Uint128::from(100_000u128 - 1000u128 - 10_000u128 - 45_000u128) + ); + + // Try sending 2 distinct coins + let uandr_token = coin(10_000, "uandr"); + let uusd_token = coin(100, "uusd"); + + splitter + .execute_send(&mut router, owner.clone(), &[uandr_token, uusd_token]) + .unwrap(); + + let uandr_balance_1 = router.wrap().query_balance(recipient_1, "uandr").unwrap(); + let uandr_balance_2 = router.wrap().query_balance(recipient_2, "uandr").unwrap(); + + let uusd_balance_1 = router.wrap().query_balance(recipient_1, "uusd").unwrap(); + let uusd_balance_2 = router.wrap().query_balance(recipient_2, "uusd").unwrap(); + + assert_eq!( + uandr_balance_1.amount, + Uint128::from(200u128 + 2000u128 + 10_000u128 + 2000u128) + ); + assert_eq!( + uandr_balance_2.amount, + Uint128::from(800u128 + 8000u128 + 25_000u128 + 8000u128) + ); + + assert_eq!(uusd_balance_1.amount, Uint128::from(20u128)); + assert_eq!(uusd_balance_2.amount, Uint128::from(80u128)); +} diff --git a/andromeda-core/tests-integration/tests/crowdfund_app.rs b/andromeda-core/tests-integration/tests/crowdfund_app.rs index acd03b5..2c28534 100644 --- a/andromeda-core/tests-integration/tests/crowdfund_app.rs +++ b/andromeda-core/tests-integration/tests/crowdfund_app.rs @@ -1,313 +1,819 @@ -use andromeda_app::app::{AppComponent, ComponentType}; -use andromeda_app_contract::mock::{mock_andromeda_app, MockApp}; +use std::str::FromStr; + +use andromeda_app::app::AppComponent; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; use andromeda_crowdfund::mock::{ - mock_andromeda_crowdfund, mock_crowdfund_instantiate_msg, MockCrowdfund, + mock_andromeda_crowdfund, mock_crowdfund_instantiate_msg, mock_purchase_cw20_msg, MockCrowdfund, }; +use andromeda_cw20::mock::{mock_andromeda_cw20, mock_cw20_instantiate_msg, mock_minter, MockCW20}; use andromeda_cw721::mock::{mock_andromeda_cw721, mock_cw721_instantiate_msg, MockCW721}; use andromeda_finance::splitter::AddressPercent; -use andromeda_std::amp::{AndrAddr, Recipient}; - -use andromeda_modules::rates::{Rate, RateInfo}; -use andromeda_rates::mock::{mock_andromeda_rates, mock_rates_instantiate_msg}; +use andromeda_non_fungible_tokens::{ + crowdfund::{CampaignConfig, CampaignStage, PresaleTierOrder, SimpleTierOrder, TierMetaData}, + cw721::TokenExtension, +}; use andromeda_splitter::mock::{ mock_andromeda_splitter, mock_splitter_instantiate_msg, mock_splitter_send_msg, }; -use andromeda_std::ado_base::modules::Module; -use std::str::FromStr; - -use andromeda_testing::{mock::MockAndromeda, mock_contract::MockContract}; -use andromeda_vault::mock::{ - mock_andromeda_vault, mock_vault_deposit_msg, mock_vault_instantiate_msg, +use andromeda_std::{ + amp::{AndrAddr, Recipient}, + common::{denom::Asset, encode_binary, Milliseconds}, +}; +use andromeda_testing::{ + mock::{mock_app, MockApp}, + mock_builder::MockAndromedaBuilder, + MockAndromeda, MockContract, }; -use cosmwasm_std::{coin, to_json_binary, Addr, BlockInfo, Decimal, Uint128}; -use cw721::Expiration; -use cw_multi_test::{App, Executor}; - -fn mock_app() -> App { - App::new(|router, _api, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked("owner"), - [coin(999999, "uandr")].to_vec(), - ) - .unwrap(); - router - .bank - .init_balance( - storage, - &Addr::unchecked("buyer_one"), - [coin(100, "uandr")].to_vec(), - ) - .unwrap(); - router - .bank - .init_balance( - storage, - &Addr::unchecked("buyer_two"), - [coin(100, "uandr")].to_vec(), - ) - .unwrap(); - router - .bank - .init_balance( - storage, - &Addr::unchecked("buyer_three"), - [coin(100, "uandr")].to_vec(), - ) - .unwrap(); - }) +use cosmwasm_std::{coin, to_json_binary, BlockInfo, Coin, Decimal, Empty, Uint128, Uint64}; +use cw20::Cw20Coin; +use cw_multi_test::Contract; +use rstest::{fixture, rstest}; + +struct TestCase { + router: MockApp, + andr: MockAndromeda, + crowdfund: MockCrowdfund, + cw20: Option, + cw721: MockCW721, + presale: Vec, } -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) +#[fixture] +fn wallets() -> Vec<(&'static str, Vec)> { + vec![ + ("owner", vec![]), + ("buyer_one", vec![coin(1000000, "uandr")]), + ("recipient", vec![]), + ("recipient1", vec![]), + ("recipient2", vec![]), + ] } -#[test] -fn test_crowdfund_app() { - let owner = Addr::unchecked("owner"); - let vault_one_recipient_addr = Addr::unchecked("vault_one_recipient"); - let vault_two_recipient_addr = Addr::unchecked("vault_two_recipient"); - let buyer_one = Addr::unchecked("buyer_one"); - let buyer_two = Addr::unchecked("buyer_two"); - let buyer_three = Addr::unchecked("buyer_three"); - - let mut router = mock_app(); - let andr = mock_andromeda(&mut router, owner.clone()); - - // Store contract codes - andr.store_ado(&mut router, mock_andromeda_cw721(), "cw721"); - andr.store_ado(&mut router, mock_andromeda_crowdfund(), "crowdfund"); - andr.store_ado(&mut router, mock_andromeda_vault(), "vault"); - andr.store_ado(&mut router, mock_andromeda_splitter(), "splitter"); - let app_code_id = andr.store_ado(&mut router, mock_andromeda_app(), "app"); - let rates_code_id = andr.store_ado(&mut router, mock_andromeda_rates(), "rates"); - - // Generate App Components - // App component names must be less than 3 characters or longer than 54 characters to force them to be 'invalid' as the MockApi struct used within the CosmWasm App struct only contains those two validation checks - let rates_recipient = "rates_recipient"; - // Generate rates contract - let rates: Vec = [RateInfo { - rate: Rate::Flat(coin(1, "uandr")), - is_additive: false, - recipients: [Recipient::from_string(rates_recipient.to_string())].to_vec(), - description: Some("Some test rate".to_string()), - }] - .to_vec(); - let rates_init_msg = mock_rates_instantiate_msg(rates, andr.kernel.addr().to_string(), None); - let rates_addr = router - .instantiate_contract( - rates_code_id, - owner.clone(), - &rates_init_msg, - &[], - "rates", - None, - ) - .unwrap(); +#[fixture] +fn contracts() -> Vec<(&'static str, Box>)> { + vec![ + ("cw20", mock_andromeda_cw20()), + ("cw721", mock_andromeda_cw721()), + ("crowdfund", mock_andromeda_crowdfund()), + ("splitter", mock_andromeda_splitter()), + ("app-contract", mock_andromeda_app()), + ] +} - let modules: Vec = vec![Module::new("rates", rates_addr.to_string(), false)]; +#[fixture] +fn setup( + #[default(true)] use_native_token: bool, + #[default(None)] withdrawal_recipient: Option, + wallets: Vec<(&'static str, Vec)>, + contracts: Vec<(&'static str, Box>)>, +) -> TestCase { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(wallets) + .with_contracts(contracts) + .build(&mut router); - let crowdfund_app_component = AppComponent { - name: "1".to_string(), - ado_type: "crowdfund".to_string(), - component_type: ComponentType::New( - to_json_binary(&mock_crowdfund_instantiate_msg( - AndrAddr::from_string("./2".to_string()), - false, - Some(modules), - andr.kernel.addr().to_string(), - None, - )) - .unwrap(), - ), - }; - let cw721_component = AppComponent { - name: "2".to_string(), - ado_type: "cw721".to_string(), - component_type: ComponentType::new(mock_cw721_instantiate_msg( - "Test Tokens".to_string(), - "TT".to_string(), - "./1", // Crowdfund must be minter - None, - andr.kernel.addr().to_string(), - None, - )), - }; - let vault_one_app_component = AppComponent { - name: "3".to_string(), - ado_type: "vault".to_string(), - component_type: ComponentType::new(mock_vault_instantiate_msg( - andr.kernel.addr().to_string(), - None, - )), - }; - let vault_two_app_component = AppComponent { - name: "4".to_string(), - ado_type: "vault".to_string(), - component_type: ComponentType::new(mock_vault_instantiate_msg( - andr.kernel.addr().to_string(), - None, - )), - }; + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let recipient = + withdrawal_recipient.unwrap_or(Recipient::new(andr.get_wallet("recipient"), None)); - // Create splitter recipient structures - let vault_one_recipient = - Recipient::from_string(format!("~/am/app/{}", vault_one_app_component.name)).with_msg( - mock_vault_deposit_msg( - Some(AndrAddr::from_string(vault_one_recipient_addr.to_string())), - None, - ), - ); - let vault_two_recipient = - Recipient::from_string(format!("~/am/app/{}", vault_two_app_component.name)).with_msg( - mock_vault_deposit_msg( - Some(AndrAddr::from_string(vault_two_recipient_addr.to_string())), - None, - ), - ); + // Prepare Splitter component which can be used as a withdrawal address for some test cases + let recipient_1 = andr.get_wallet("recipient1"); + let recipient_2 = andr.get_wallet("recipient2"); let splitter_recipients = vec![ AddressPercent { - recipient: vault_one_recipient, - percent: Decimal::from_str("0.5").unwrap(), + recipient: Recipient::from_string(recipient_1.to_string()), + percent: Decimal::from_str("0.2").unwrap(), }, AddressPercent { - recipient: vault_two_recipient, - percent: Decimal::from_str("0.5").unwrap(), + recipient: Recipient::from_string(recipient_2.to_string()), + percent: Decimal::from_str("0.8").unwrap(), }, ]; - let splitter_init_msg = mock_splitter_instantiate_msg(splitter_recipients, andr.kernel.addr().clone(), None, None); - let splitter_app_component = AppComponent { - name: "5".to_string(), - component_type: ComponentType::new(&splitter_init_msg), - ado_type: "splitter".to_string(), + let splitter_component = AppComponent::new( + "splitter".to_string(), + "splitter".to_string(), + to_json_binary(&splitter_init_msg).unwrap(), + ); + // Add cw721 component + let cw721_init_msg = mock_cw721_instantiate_msg( + "Campaign Tier".to_string(), + "CT".to_string(), + "./crowdfund".to_string(), + andr.kernel.addr().to_string(), + None, + ); + + let cw721_component = AppComponent::new( + "cw721".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let mut app_components = vec![splitter_component, cw721_component.clone()]; + + // Add cw20 components for test cases using cw20 + let cw20_component: Option = match use_native_token { + true => None, + false => { + let initial_balances = vec![Cw20Coin { + address: buyer_one.to_string(), + amount: Uint128::from(1000000u128), + }]; + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + app_components.push(cw20_component.clone()); + Some(cw20_component) + } + }; + let denom = match use_native_token { + true => Asset::NativeToken("uandr".to_string()), + false => Asset::Cw20Token(AndrAddr::from_string(format!( + "./{}", + cw20_component.clone().unwrap().name + ))), }; + // Add campaign component + // *** IMPORTANT *** + // campaign component should be added in the last order + // as it is using vfs to other components(potentially components in the same app) - let app_components = vec![ - cw721_component.clone(), - crowdfund_app_component.clone(), - vault_one_app_component.clone(), - vault_two_app_component.clone(), - splitter_app_component.clone(), - ]; + let campaign_config = mock_campaign_config( + denom, + AndrAddr::from_string(format!("./{}", cw721_component.name)), + recipient.clone(), + Some(Uint128::new(1000)), + ); + let crowdfund_init_msg = mock_crowdfund_instantiate_msg( + campaign_config, + vec![], + andr.kernel.addr(), + Some(owner.to_string()), + ); + let crowdfund_component = AppComponent::new( + "crowdfund".to_string(), + "crowdfund".to_string(), + to_json_binary(&crowdfund_init_msg).unwrap(), + ); - let app = MockApp::instantiate( - app_code_id, - owner.clone(), + app_components.push(crowdfund_component.clone()); + + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, &mut router, - "app", + "Crowdfund App", app_components.clone(), - andr.kernel.addr().clone(), + andr.kernel.addr(), Some(owner.to_string()), ); - let components = app.query_components(&router); - assert_eq!(components, app_components); + let crowdfund: MockCrowdfund = + app.query_ado_by_component_name(&router, crowdfund_component.name); - let _vault_one_addr = app.query_component_addr(&router, vault_one_app_component.name); - let _vault_two_addr = app.query_component_addr(&router, vault_two_app_component.name); - app.execute_claim_ownership(&mut router, owner.clone(), None) - .unwrap(); + let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); - let cw721_contract = - app.query_ado_by_component_name::(&router, cw721_component.name); - let crowdfund_contract = - app.query_ado_by_component_name::(&router, crowdfund_app_component.name); - - let minter = cw721_contract.query_minter(&router); - assert_eq!(minter, crowdfund_contract.addr()); + let cw20: Option = match use_native_token { + true => None, + false => Some(app.query_ado_by_component_name(&router, cw20_component.unwrap().name)), + }; - // Mint Tokens - crowdfund_contract - .execute_quick_mint(owner.clone(), &mut router, 5, owner.to_string()) + let meta_data = TierMetaData { + token_uri: None, + extension: TokenExtension { + ..Default::default() + }, + }; + crowdfund + .execute_add_tier( + owner.clone(), + &mut router, + Uint64::one(), + "Tier 1".to_string(), + Uint128::new(100), + None, + meta_data.clone(), + ) .unwrap(); - - // Start Sale - let token_price = coin(100, "uandr"); - - let sale_recipient = - Recipient::from_string(format!("~/am/app/{}", splitter_app_component.name)) - .with_msg(mock_splitter_send_msg()); - let expiration = Expiration::AtHeight(router.block_info().height + 5); - crowdfund_contract - .execute_start_sale( + crowdfund + .execute_add_tier( owner.clone(), &mut router, - expiration, - token_price.clone(), - Uint128::from(3u128), - Some(1), - sale_recipient, + Uint64::new(2u64), + "Tier 2".to_string(), + Uint128::new(200), + Some(Uint128::new(100)), + meta_data, ) .unwrap(); - // Buy Tokens - let buyers = vec![buyer_one, buyer_two, buyer_three]; - for buyer in buyers.clone() { - crowdfund_contract - .execute_purchase(buyer, &mut router, Some(1), &[token_price.clone()]) - .unwrap(); + let presale = vec![PresaleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10u128), + orderer: buyer_one.clone(), + }]; + + TestCase { + router, + andr, + crowdfund, + cw20, + cw721, + presale, } - let crowdfund_balance = router +} + +#[rstest] +fn test_successful_crowdfund_app_native(setup: TestCase) { + let TestCase { + mut router, + andr, + crowdfund, + cw721, + presale, + .. + } = setup; + + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let recipient = Recipient::new(andr.get_wallet("recipient"), None); + + // Start campaign + let start_time = None; + let end_time = Milliseconds::from_nanos(router.block_info().time.plus_days(1).nanos()); + + let _ = crowdfund.execute_start_campaign( + owner.clone(), + &mut router, + start_time, + end_time, + Some(presale), + ); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 0); + assert_eq!(summary.current_stage, CampaignStage::ONGOING.to_string()); + + // Purchase tiers + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_seconds(1), + chain_id: router.block_info().chain_id, + }); + + let orders = vec![ + SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }, + SimpleTierOrder { + level: Uint64::new(2), + amount: Uint128::new(10), + }, + ]; + let buyer_one_original_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + let _ = crowdfund.execute_purchase( + buyer_one.clone(), + &mut router, + orders, + vec![coin(5000, "uandr")], + ); + let buyer_one_balance = router .wrap() - .query_balance(crowdfund_contract.addr().clone(), token_price.denom) + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + + assert_eq!( + buyer_one_balance, + buyer_one_original_balance - Uint128::new(10 * 100 + 200 * 10) + ); + + // End campaign + let _ = crowdfund.execute_end_campaign(owner.clone(), &mut router); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 10 * 100 + 200 * 10); + assert_eq!(summary.current_stage, CampaignStage::SUCCESS.to_string()); + let recipient_balance = router + .wrap() + .query_balance(recipient.clone().address, "uandr") + .unwrap() + .amount; + assert_eq!(summary.current_capital, recipient_balance.into()); + + // Claim tier + let _ = crowdfund + .execute_claim(buyer_one.clone(), &mut router) .unwrap(); - assert_eq!(crowdfund_balance.amount, Uint128::from(300u128)); + // buyer_one should own 30 tiers now (10 pre order + 20 purchased) + let owner_resp = cw721.query_owner_of(&router, "0".to_string()); + assert_eq!(owner_resp, buyer_one.to_string()); + let owner_resp = cw721.query_owner_of(&router, "29".to_string()); + assert_eq!(owner_resp, buyer_one.to_string()); +} - // End Sale - let block_info = router.block_info(); +#[rstest] +fn test_crowdfund_app_native_discard( + #[with(true, Some(mock_recipient_with_invalid_msg("./splitter")))] setup: TestCase, +) { + let TestCase { + mut router, + andr, + crowdfund, + presale, + .. + } = setup; + + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + + // Start campaign + let start_time = None; + let end_time = Milliseconds::from_nanos(router.block_info().time.plus_days(1).nanos()); + + let _ = crowdfund.execute_start_campaign( + owner.clone(), + &mut router, + start_time, + end_time, + Some(presale), + ); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 0); + assert_eq!(summary.current_stage, CampaignStage::ONGOING.to_string()); + + // Purchase tiers router.set_block(BlockInfo { - height: block_info.height + 5, - time: block_info.time, - chain_id: block_info.chain_id, + height: router.block_info().height, + time: router.block_info().time.plus_seconds(1), + chain_id: router.block_info().chain_id, }); - crowdfund_contract - .execute_end_sale(owner.clone(), &mut router, None) + let orders = vec![ + SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }, + SimpleTierOrder { + level: Uint64::new(2), + amount: Uint128::new(10), + }, + ]; + let buyer_one_original_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + let _ = crowdfund.execute_purchase( + buyer_one.clone(), + &mut router, + orders, + vec![coin(5000, "uandr")], + ); + let buyer_one_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + + assert_eq!( + buyer_one_balance, + buyer_one_original_balance - Uint128::new(10 * 100 + 200 * 10) + ); + + let _ = crowdfund.execute_end_campaign(owner.clone(), &mut router); + + let summary = crowdfund.query_campaign_summary(&mut router); + + // Campaign could not be ended due to invalid withdrawal recipient msg + assert_eq!(summary.current_stage, CampaignStage::ONGOING.to_string()); + + // Discard campaign + let _ = crowdfund.execute_discard_campaign(owner.clone(), &mut router); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_stage, CampaignStage::FAILED.to_string()); + + // Refund + let buyer_one_original_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + let _ = crowdfund + .execute_claim(buyer_one.clone(), &mut router) .unwrap(); - crowdfund_contract - .execute_end_sale(owner, &mut router, None) + let buyer_one_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + assert_eq!( + buyer_one_balance, + buyer_one_original_balance + Uint128::new(10 * 100 + 200 * 10) + ); +} + +#[rstest] +fn test_crowdfund_app_native_with_ado_recipient( + #[with(true, Some(mock_recipient_with_valid_msg("./splitter")))] setup: TestCase, +) { + let TestCase { + mut router, + andr, + crowdfund, + presale, + .. + } = setup; + + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let recipient_1 = andr.get_wallet("recipient1"); + let recipient_2 = andr.get_wallet("recipient2"); + + // Start campaign + let start_time = None; + let end_time = Milliseconds::from_nanos(router.block_info().time.plus_days(1).nanos()); + + let _ = crowdfund.execute_start_campaign( + owner.clone(), + &mut router, + start_time, + end_time, + Some(presale), + ); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 0); + assert_eq!(summary.current_stage, CampaignStage::ONGOING.to_string()); + + // Purchase tiers + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_seconds(1), + chain_id: router.block_info().chain_id, + }); + + let orders = vec![ + SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }, + SimpleTierOrder { + level: Uint64::new(2), + amount: Uint128::new(10), + }, + ]; + let buyer_one_original_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + let _ = crowdfund.execute_purchase( + buyer_one.clone(), + &mut router, + orders, + vec![coin(5000, "uandr")], + ); + let buyer_one_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + + assert_eq!( + buyer_one_balance, + buyer_one_original_balance - Uint128::new(10 * 100 + 200 * 10) + ); + + let _ = crowdfund.execute_end_campaign(owner.clone(), &mut router); + + let summary = crowdfund.query_campaign_summary(&mut router); + + // Campaign could not be ended due to invalid withdrawal recipient msg + assert_eq!(summary.current_stage, CampaignStage::SUCCESS.to_string()); + + let recipient_1_balance = router + .wrap() + .query_balance(recipient_1, "uandr") + .unwrap() + .amount; + let recipient_2_balance = router + .wrap() + .query_balance(recipient_2, "uandr") + .unwrap() + .amount; + assert_eq!(recipient_1_balance.u128(), summary.current_capital / 5); + assert_eq!(recipient_2_balance.u128(), summary.current_capital * 4 / 5); +} + +#[rstest] +fn test_failed_crowdfund_app_native(setup: TestCase) { + let TestCase { + mut router, + andr, + crowdfund, + presale, + .. + } = setup; + + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + + // Start campaign + let start_time = None; + let end_time = Milliseconds::from_nanos(router.block_info().time.plus_days(1).nanos()); + + let _ = crowdfund.execute_start_campaign( + owner.clone(), + &mut router, + start_time, + end_time, + Some(presale), + ); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 0); + assert_eq!(summary.current_stage, CampaignStage::ONGOING.to_string()); + + // Purchase tiers + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_seconds(1), + chain_id: router.block_info().chain_id, + }); + + let orders = vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(5), + }]; + let buyer_one_original_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + let _ = crowdfund.execute_purchase( + buyer_one.clone(), + &mut router, + orders, + vec![coin(5000, "uandr")], + ); + let buyer_one_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + + assert_eq!( + buyer_one_balance, + buyer_one_original_balance - Uint128::new(5 * 100) + ); + + // End campaign + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_days(2), + chain_id: router.block_info().chain_id, + }); + + let _ = crowdfund.execute_end_campaign(owner.clone(), &mut router); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 5 * 100); + assert_eq!(summary.current_stage, CampaignStage::FAILED.to_string()); + + // Refund + let buyer_one_original_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + let _ = crowdfund + .execute_claim(buyer_one.clone(), &mut router) + .unwrap(); + let buyer_one_balance = router + .wrap() + .query_balance(buyer_one.clone(), "uandr") + .unwrap() + .amount; + assert_eq!( + buyer_one_balance, + buyer_one_original_balance + Uint128::new(5 * 100) + ); +} + +#[rstest] +fn test_successful_crowdfund_app_cw20(#[with(false)] setup: TestCase) { + let TestCase { + mut router, + andr, + cw721, + crowdfund, + cw20, + presale, + } = setup; + let cw20 = cw20.unwrap(); + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let recipient = Recipient::new(andr.get_wallet("recipient"), None); + + let start_time = None; + let end_time = Milliseconds::from_nanos(router.block_info().time.plus_days(1).nanos()); + + let _ = crowdfund.execute_start_campaign( + owner.clone(), + &mut router, + start_time, + end_time, + Some(presale), + ); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 0); + assert_eq!(summary.current_stage, CampaignStage::ONGOING.to_string()); + + // Purchase tiers + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_seconds(1), + chain_id: router.block_info().chain_id, + }); + + let orders = vec![ + SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(10), + }, + SimpleTierOrder { + level: Uint64::new(2), + amount: Uint128::new(10), + }, + ]; + let buyer_one_original_balance = cw20.query_balance(&router, buyer_one.clone()); + let hook_msg = mock_purchase_cw20_msg(orders); + + cw20.execute_send( + &mut router, + buyer_one.clone(), + crowdfund.addr(), + Uint128::new(5000), + &hook_msg, + ) + .unwrap(); + + let buyer_one_balance = cw20.query_balance(&router, buyer_one.clone()); + assert_eq!( + buyer_one_balance, + buyer_one_original_balance - Uint128::new(10 * 100 + 200 * 10) + ); + + // End campaign + let _ = crowdfund.execute_end_campaign(owner.clone(), &mut router); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 10 * 100 + 200 * 10); + assert_eq!(summary.current_stage, CampaignStage::SUCCESS.to_string()); + let recipient_balance = cw20.query_balance(&router, recipient.clone().address); + assert_eq!(summary.current_capital, recipient_balance.into()); + + // Claim tier + let _ = crowdfund + .execute_claim(buyer_one.clone(), &mut router) .unwrap(); + // buyer_one should own 30 tiers now (10 pre order + 20 purchased) + let owner_resp = cw721.query_owner_of(&router, "0".to_string()); + assert_eq!(owner_resp, buyer_one.to_string()); + let owner_resp = cw721.query_owner_of(&router, "29".to_string()); + assert_eq!(owner_resp, buyer_one.to_string()); +} + +#[rstest] +fn test_failed_crowdfund_app_cw20(#[with(false)] setup: TestCase) { + let TestCase { + mut router, + andr, + crowdfund, + presale, + cw20, + .. + } = setup; + let cw20 = cw20.unwrap(); + + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + + // Start campaign + let start_time = None; + let end_time = Milliseconds::from_nanos(router.block_info().time.plus_days(1).nanos()); - // Check final state - //Check token transfers - for (i, buyer) in buyers.iter().enumerate() { - let owner = cw721_contract.query_owner_of(&router, i.to_string()); - assert_eq!(owner, buyer.to_string()); + let _ = crowdfund.execute_start_campaign( + owner.clone(), + &mut router, + start_time, + end_time, + Some(presale), + ); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 0); + assert_eq!(summary.current_stage, CampaignStage::ONGOING.to_string()); + + // Purchase tiers + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_seconds(1), + chain_id: router.block_info().chain_id, + }); + + let orders = vec![SimpleTierOrder { + level: Uint64::one(), + amount: Uint128::new(5), + }]; + + let buyer_one_original_balance = cw20.query_balance(&router, buyer_one.clone()); + let hook_msg = mock_purchase_cw20_msg(orders); + + cw20.execute_send( + &mut router, + buyer_one.clone(), + crowdfund.addr(), + Uint128::new(5000), + &hook_msg, + ) + .unwrap(); + + let buyer_one_balance = cw20.query_balance(&router, buyer_one.clone()); + + assert_eq!( + buyer_one_balance, + buyer_one_original_balance - Uint128::new(5 * 100) + ); + + // End campaign + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_days(2), + chain_id: router.block_info().chain_id, + }); + + let _ = crowdfund.execute_end_campaign(owner.clone(), &mut router); + let summary = crowdfund.query_campaign_summary(&mut router); + assert_eq!(summary.current_capital, 5 * 100); + assert_eq!(summary.current_stage, CampaignStage::FAILED.to_string()); + + // Refund + let buyer_one_original_balance = cw20.query_balance(&router, buyer_one.clone()); + let _ = crowdfund + .execute_claim(buyer_one.clone(), &mut router) + .unwrap(); + let buyer_one_balance = cw20.query_balance(&router, buyer_one.clone()); + assert_eq!( + buyer_one_balance, + buyer_one_original_balance + Uint128::new(5 * 100) + ); +} + +fn mock_campaign_config( + denom: Asset, + token_address: AndrAddr, + withdrawal_recipient: Recipient, + soft_cap: Option, +) -> CampaignConfig { + CampaignConfig { + title: Some("First Crowdfund".to_string()), + description: Some("Demo campaign for testing".to_string()), + banner: Some("http://".to_string()), + url: Some("http://".to_string()), + denom, + token_address, + withdrawal_recipient, + soft_cap, + hard_cap: None, } +} + +fn mock_recipient_with_invalid_msg(addr: &str) -> Recipient { + Recipient::new(addr, Some(encode_binary(b"invalid msg").unwrap())) +} - // TODO: FIX VAULT BALANCES - // //Check vault balances - - // let balance_one: Vec = router - // .wrap() - // .query_wasm_smart( - // vault_one_addr, - // &mock_vault_get_balance( - // AndrAddr::from_string(vault_one_recipient_addr.to_string()), - // None, - // None, - // ), - // ) - // .unwrap(); - // assert!(!balance_one.is_empty()); - // assert_eq!(balance_one[0], coin(148, "uandr")); - - // let balance_two: Vec = router - // .wrap() - // .query_wasm_smart( - // vault_two_addr, - // &mock_vault_get_balance( - // AndrAddr::from_string(vault_two_recipient_addr.to_string()), - // None, - // None, - // ), - // ) - // .unwrap(); - // assert!(!balance_two.is_empty()); - // assert_eq!(balance_two[0], coin(148, "uandr")); +fn mock_recipient_with_valid_msg(addr: &str) -> Recipient { + Recipient::new( + addr, + Some(to_json_binary(&mock_splitter_send_msg()).unwrap()), + ) } diff --git a/andromeda-core/tests-integration/tests/cw20_app.rs b/andromeda-core/tests-integration/tests/cw20_app.rs new file mode 100644 index 0000000..bfea341 --- /dev/null +++ b/andromeda-core/tests-integration/tests/cw20_app.rs @@ -0,0 +1,148 @@ +#![cfg(not(target_arch = "wasm32"))] +use andromeda_app::app::AppComponent; +use andromeda_app_contract::mock::{mock_andromeda_app, mock_claim_ownership_msg, MockAppContract}; +use andromeda_cw20::mock::{mock_andromeda_cw20, mock_cw20_instantiate_msg, mock_minter, MockCW20}; +use andromeda_std::{ + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}, + amp::Recipient, +}; + +use andromeda_testing::{ + mock::mock_app, mock_builder::MockAndromedaBuilder, mock_contract::MockContract, +}; +use cosmwasm_std::{coin, to_json_binary, Addr, Decimal, Uint128}; +use cw20::Cw20Coin; +use cw_multi_test::Executor; + +#[test] +fn test_cw20_with_rates() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer_one", vec![coin(1000, "uandr")]), + ("buyer_two", vec![coin(1000, "uandr")]), + ("recipient_one", vec![]), + ("recipient_two", vec![]), + ]) + .with_contracts(vec![ + ("cw20", mock_andromeda_cw20()), + ("app-contract", mock_andromeda_app()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer_one = andr.get_wallet("buyer_one"); + let buyer_two = andr.get_wallet("buyer_two"); + let recipient_one = andr.get_wallet("recipient_one"); + let recipient_two = andr.get_wallet("recipient_two"); + + // Generate App Components + let initial_balances = vec![ + Cw20Coin { + address: buyer_one.to_string(), + amount: Uint128::from(1000u128), + }, + Cw20Coin { + address: buyer_two.to_string(), + amount: Uint128::from(2000u128), + }, + Cw20Coin { + address: owner.to_string(), + amount: Uint128::from(10000u128), + }, + ]; + let buyer_two_original_balance = Uint128::from(2000u128); + + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![cw20_component.clone()]; + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Auction App", + app_components, + andr.kernel.addr(), + Some(owner.to_string()), + ); + + router + .execute_contract( + owner.clone(), + Addr::unchecked(app.addr().clone()), + &mock_claim_ownership_msg(None), + &[], + ) + .unwrap(); + + let cw20: MockCW20 = app.query_ado_by_component_name(&router, cw20_component.name); + + // Set rates to SendFrom + cw20.execute_add_rate( + &mut router, + owner.clone(), + "TransferFrom".to_string(), + Rate::Local(LocalRate { + rate_type: LocalRateType::Deductive, + recipients: vec![ + Recipient::new(recipient_one, None), + Recipient::new(recipient_two, None), + ], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(10), + }), + description: None, + }), + ) + .unwrap(); + + // Increase allowance for owner + cw20.execute_increase_allowance( + &mut router, + owner.clone(), + buyer_one.clone().into_string(), + Uint128::new(100000), + ) + .unwrap(); + + // Execute SendFrom + cw20.execute_transfer_from( + &mut router, + buyer_one.clone(), + buyer_two, + Uint128::new(10), + owner.clone().into_string(), + ) + .unwrap(); + // Rates are 10% , so we expect a balance of one for recipients one and two and the leftover 8 will be sent to buyer two + let recip_one_balance = cw20.query_balance(&router, recipient_one); + assert_eq!(Uint128::one(), recip_one_balance); + + let recip_two_balance = cw20.query_balance(&router, recipient_two); + assert_eq!(Uint128::one(), recip_two_balance); + + let buyer_two_balance = cw20.query_balance(&router, buyer_two); + assert_eq!( + buyer_two_original_balance + .checked_add(Uint128::new(8)) + .unwrap(), + buyer_two_balance + ); +} diff --git a/andromeda-core/tests-integration/tests/cw20_staking.rs b/andromeda-core/tests-integration/tests/cw20_staking.rs new file mode 100644 index 0000000..220388b --- /dev/null +++ b/andromeda-core/tests-integration/tests/cw20_staking.rs @@ -0,0 +1,434 @@ +use std::fs; + +use andromeda_app::app::AppComponent; +use andromeda_app_contract::mock::{mock_andromeda_app, mock_app_instantiate_msg, MockAppContract}; +use andromeda_cw20::mock::{ + mock_andromeda_cw20, mock_cw20_instantiate_msg, mock_cw20_send, mock_cw20_transfer, + mock_get_cw20_balance, mock_get_version, mock_minter, +}; +use andromeda_cw20_staking::mock::{ + mock_andromeda_cw20_staking, mock_cw20_get_staker, mock_cw20_stake, + mock_cw20_staking_add_reward_tokens, mock_cw20_staking_instantiate_msg, + mock_cw20_staking_update_global_indexes, +}; +use andromeda_fungible_tokens::cw20_staking::{AllocationConfig, StakerResponse}; + +use andromeda_std::common::expiration::Expiry; +use andromeda_std::{amp::AndrAddr, common::Milliseconds}; + +use andromeda_std::ado_base::version::VersionResponse; +use andromeda_testing::{ + mock::{mock_app, MockAndromeda, MockApp}, + mock_builder::MockAndromedaBuilder, + MockContract, +}; +use cosmwasm_std::{coin, to_json_binary, BlockInfo, Timestamp, Uint128}; +use cw20::{BalanceResponse, Cw20Coin}; +use cw_asset::AssetInfoUnchecked; +use cw_multi_test::Executor; +use toml::Value; + +fn setup_andr(router: &mut MockApp) -> MockAndromeda { + MockAndromedaBuilder::new(router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(1000, "uandr"), coin(1000, "uusd")]), + ("staker_one", vec![]), + ("staker_two", vec![]), + ]) + .with_contracts(vec![ + ("cw20", mock_andromeda_cw20()), + ("cw20-staking", mock_andromeda_cw20_staking()), + ("app-contract", mock_andromeda_app()), + ]) + .build(router) +} + +fn setup_app(andr: &MockAndromeda, router: &mut MockApp) -> MockAppContract { + let owner = andr.get_wallet("owner"); + let staker_one = andr.get_wallet("staker_one"); + let staker_two = andr.get_wallet("staker_two"); + + // Create App Components + let initial_balances = vec![ + Cw20Coin { + address: staker_one.to_string(), + amount: Uint128::from(1000u128), + }, + Cw20Coin { + address: staker_two.to_string(), + amount: Uint128::from(2000u128), + }, + Cw20Coin { + address: owner.to_string(), + amount: Uint128::from(10000u128), + }, + ]; + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + + let cw20_staking_init_msg = mock_cw20_staking_instantiate_msg( + format!("./{}", cw20_component.name), + andr.kernel.addr().to_string(), + None, + ); + let cw20_staking_component = AppComponent::new( + "cw20staking".to_string(), + "cw20-staking".to_string(), + to_json_binary(&cw20_staking_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![cw20_component, cw20_staking_component]; + let app_init_msg = mock_app_instantiate_msg( + "Staking App".to_string(), + app_components, + andr.kernel.addr().clone(), + None, + ); + + let app_code_id = andr.get_code_id(router, "app-contract"); + let app = MockAppContract::instantiate( + app_code_id, + owner, + router, + app_init_msg.name, + app_init_msg.app_components, + andr.kernel.addr(), + None, + ); + + app +} + +fn get_cw20_contract_version() -> Result> { + // Read the Cargo.toml file + let content = fs::read_to_string("../contracts/fungible-tokens/andromeda-cw20/Cargo.toml")?; + + // Parse the Cargo.toml content + let parsed_toml = content.parse::()?; + + // Extract the version string + if let Some(version) = parsed_toml + .get("package") + .and_then(|pkg| pkg.get("version")) + .and_then(|v| v.as_str()) + { + Ok(version.to_string()) + } else { + Err("Version not found in Cargo.toml".into()) + } +} + +#[test] +fn test_cw20_staking_app() { + let mut router = mock_app(None); + + let andr = setup_andr(&mut router); + let app = setup_app(&andr, &mut router); + let owner = andr.get_wallet("owner"); + let staker_one = andr.get_wallet("staker_one"); + let staker_two = andr.get_wallet("staker_two"); + + // Component Addresses + let cw20_addr = andr + .vfs + .query_resolve_path(&mut router, format!("/home/{}/cw20", app.addr())); + let cw20_staking_addr = andr + .vfs + .query_resolve_path(&mut router, format!("/home/{}/cw20staking", app.addr())); + + // Check Balances + let balance_one: BalanceResponse = router + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &mock_get_cw20_balance(staker_one.to_string()), + ) + .unwrap(); + + let version: VersionResponse = router + .wrap() + .query_wasm_smart(cw20_addr.clone(), &mock_get_version()) + .unwrap(); + assert_eq!(version.version, get_cw20_contract_version().unwrap()); + + assert_eq!(balance_one.balance, Uint128::from(1000u128)); + let balance_two: BalanceResponse = router + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &mock_get_cw20_balance(staker_two.to_string()), + ) + .unwrap(); + assert_eq!(balance_two.balance, Uint128::from(2000u128)); + + // Stake Tokens + let staking_msg_one = mock_cw20_send( + cw20_staking_addr.to_string(), + Uint128::from(1000u128), + to_json_binary(&mock_cw20_stake()).unwrap(), + ); + router + .execute_contract(staker_one.clone(), cw20_addr.clone(), &staking_msg_one, &[]) + .unwrap(); + + let staking_msg_two = mock_cw20_send( + cw20_staking_addr.to_string(), + Uint128::from(2000u128), + to_json_binary(&mock_cw20_stake()).unwrap(), + ); + router + .execute_contract(staker_two.clone(), cw20_addr.clone(), &staking_msg_two, &[]) + .unwrap(); + + // Transfer Tokens for Reward + let transfer_msg = mock_cw20_transfer( + AndrAddr::from_string(format!("~{cw20_staking_addr}")), + Uint128::from(3000u128), + ); + router + .execute_contract(owner.clone(), cw20_addr, &transfer_msg, &[]) + .unwrap(); + + // Check staking status + let staker_one_info: StakerResponse = router + .wrap() + .query_wasm_smart( + cw20_staking_addr.clone(), + &mock_cw20_get_staker(staker_one.to_string()), + ) + .unwrap(); + assert_eq!(staker_one_info.share, Uint128::from(1000u128)); + assert_eq!(staker_one_info.balance, Uint128::from(2000u128)); + + let staker_two_info: StakerResponse = router + .wrap() + .query_wasm_smart( + cw20_staking_addr, + &mock_cw20_get_staker(staker_two.to_string()), + ) + .unwrap(); + assert_eq!(staker_two_info.share, Uint128::from(2000u128)); + assert_eq!(staker_two_info.balance, Uint128::from(4000u128)); +} + +#[test] +fn test_cw20_staking_app_delayed() { + let mut router = mock_app(None); + let andr = setup_andr(&mut router); + let app = setup_app(&andr, &mut router); + let owner = andr.get_wallet("owner"); + let staker_one = andr.get_wallet("staker_one"); + let staker_two = andr.get_wallet("staker_two"); + + // Component Addresses + let cw20_addr = andr + .vfs + .query_resolve_path(&mut router, format!("/home/{}/cw20", app.addr())); + let cw20_staking_addr = andr + .vfs + .query_resolve_path(&mut router, format!("/home/{}/cw20staking", app.addr())); + + let reward_token = AssetInfoUnchecked::native("uandr"); + let add_reward_msg = mock_cw20_staking_add_reward_tokens( + reward_token, + Expiry::AtTime(Milliseconds::from_seconds( + router.block_info().time.seconds() + 1, + )), + None, + ); + router + .execute_contract( + owner.clone(), + cw20_staking_addr.clone(), + &add_reward_msg, + &[], + ) + .unwrap(); + + let reward_token_two = AssetInfoUnchecked::native("uusd"); + let add_reward_msg = mock_cw20_staking_add_reward_tokens( + reward_token_two, + Expiry::AtTime(Milliseconds::from_seconds( + router.block_info().time.seconds() + 1, + )), + Some(AllocationConfig { + till_timestamp: Expiry::AtTime(Milliseconds::from_seconds( + router.block_info().time.seconds() + 101, + )), + cycle_rewards: Uint128::from(3u128), + cycle_duration: Milliseconds::from_seconds(1), + reward_increase: None, + }), + ); + router + .execute_contract( + owner.clone(), + cw20_staking_addr.clone(), + &add_reward_msg, + &[], + ) + .unwrap(); + + router + .send_tokens( + owner.clone(), + cw20_staking_addr.clone(), + &[coin(60u128, "uandr")], + ) + .unwrap(); + router + .send_tokens( + owner.clone(), + cw20_staking_addr.clone(), + &[coin(300u128, "uusd")], + ) + .unwrap(); + // Check Balances + let balance_one: BalanceResponse = router + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &mock_get_cw20_balance(staker_one.to_string()), + ) + .unwrap(); + assert_eq!(balance_one.balance, Uint128::from(1000u128)); + let balance_two: BalanceResponse = router + .wrap() + .query_wasm_smart( + cw20_addr.clone(), + &mock_get_cw20_balance(staker_two.to_string()), + ) + .unwrap(); + assert_eq!(balance_two.balance, Uint128::from(2000u128)); + + // Stake Tokens + let staking_msg_one = mock_cw20_send( + AndrAddr::from_string("./cw20staking"), + Uint128::from(1000u128), + to_json_binary(&mock_cw20_stake()).unwrap(), + ); + router + .execute_contract(staker_one.clone(), cw20_addr.clone(), &staking_msg_one, &[]) + .unwrap(); + + let staking_msg_two = mock_cw20_send( + cw20_staking_addr.to_string(), + Uint128::from(2000u128), + to_json_binary(&mock_cw20_stake()).unwrap(), + ); + router + .execute_contract(staker_two.clone(), cw20_addr.clone(), &staking_msg_two, &[]) + .unwrap(); + + // Transfer Tokens for Reward + let transfer_msg = mock_cw20_transfer( + AndrAddr::from_string(cw20_staking_addr.to_string()), + Uint128::from(3000u128), + ); + router + .execute_contract(owner.clone(), cw20_addr, &transfer_msg, &[]) + .unwrap(); + + // Check staking status + let staker_one_info: StakerResponse = router + .wrap() + .query_wasm_smart( + cw20_staking_addr.clone(), + &mock_cw20_get_staker(staker_one.to_string()), + ) + .unwrap(); + assert_eq!(staker_one_info.share, Uint128::from(1000u128)); + assert_eq!(staker_one_info.balance, Uint128::from(2000u128)); + assert_eq!(staker_one_info.pending_rewards.len(), 2); + for (_, reward) in staker_one_info.pending_rewards { + assert_eq!(reward, Uint128::zero()); + } + + let staker_two_info: StakerResponse = router + .wrap() + .query_wasm_smart( + cw20_staking_addr.clone(), + &mock_cw20_get_staker(staker_two.to_string()), + ) + .unwrap(); + assert_eq!(staker_two_info.share, Uint128::from(2000u128)); + assert_eq!(staker_two_info.balance, Uint128::from(4000u128)); + assert_eq!(staker_two_info.pending_rewards.len(), 2); + for (_, reward) in staker_two_info.pending_rewards { + assert_eq!(reward, Uint128::zero()); + } + + // Advance Time + router.set_block(BlockInfo { + height: router.block_info().height, + time: Timestamp::from_seconds(router.block_info().time.seconds() + 51), + chain_id: router.block_info().chain_id, + }); + + let update_global_indexes = + mock_cw20_staking_update_global_indexes(Some(vec![AssetInfoUnchecked::native("uandr")])); + router + .execute_contract( + owner.clone(), + cw20_staking_addr.clone(), + &update_global_indexes, + &[], + ) + .unwrap(); + + let staker_one_info: StakerResponse = router + .wrap() + .query_wasm_smart( + cw20_staking_addr.clone(), + &mock_cw20_get_staker(staker_one.to_string()), + ) + .unwrap(); + assert_eq!(staker_one_info.share, Uint128::from(1000u128)); + assert_eq!(staker_one_info.balance, Uint128::from(2000u128)); + assert_eq!(staker_one_info.pending_rewards.len(), 2); + for (asset, reward) in staker_one_info.pending_rewards { + if asset == "uusd" { + assert_eq!(reward, Uint128::from(50u128)) + } + + if asset == "uandr" { + assert_eq!(reward, Uint128::from(20u128)) + } + } + + let staker_two_info: StakerResponse = router + .wrap() + .query_wasm_smart( + cw20_staking_addr, + &mock_cw20_get_staker(staker_two.to_string()), + ) + .unwrap(); + assert_eq!(staker_two_info.share, Uint128::from(2000u128)); + assert_eq!(staker_two_info.balance, Uint128::from(4000u128)); + assert_eq!(staker_two_info.pending_rewards.len(), 2); + for (asset, reward) in staker_two_info.pending_rewards { + if asset == "uusd" { + assert_eq!(reward, Uint128::from(100u128)) + } + + if asset == "uandr" { + assert_eq!(reward, Uint128::from(40u128)) + } + } +} diff --git a/andromeda-core/tests-integration/tests/ibc_registry.rs b/andromeda-core/tests-integration/tests/ibc_registry.rs new file mode 100644 index 0000000..d6c36a7 --- /dev/null +++ b/andromeda-core/tests-integration/tests/ibc_registry.rs @@ -0,0 +1,112 @@ +use andromeda_app_contract::mock::mock_andromeda_app; +use andromeda_ibc_registry::mock::mock_andromeda_ibc_registry; +use andromeda_std::{ + error::ContractError, + os::ibc_registry::{AllDenomInfoResponse, DenomInfo, DenomInfoResponse, IBCDenomInfo}, +}; +use andromeda_testing::{ + ibc_registry::MockIbcRegistry, mock::mock_app, mock_builder::MockAndromedaBuilder, +}; +use cosmwasm_std::coin; + +#[test] +fn test_ibc_registry() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(100_000, "uandr"), coin(100_000, "uusd")]), + ("service_address", vec![]), + ("user1", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("ibc_registry", mock_andromeda_ibc_registry()), + ]) + .build(&mut router); + let service_address = andr.get_wallet("service_address").clone(); + let user1 = andr.get_wallet("user1").clone(); + + let ibc_registry: MockIbcRegistry = andr.ibc_registry; + + // Test Store Denom Info + + let ibc_denom_info = IBCDenomInfo { + denom: "ibc/andrandrandrandrandrandrandrandrandrandrandrandrandrandrandrandr".to_string(), + denom_info: DenomInfo { + path: "path".to_string(), + base_denom: "base_denom".to_string(), + }, + }; + ibc_registry + .execute_execute_store_denom_info( + &mut router, + service_address.clone(), + None, + vec![ibc_denom_info], + ) + .unwrap(); + + let query_res = ibc_registry.query_denom_info( + &mut router, + "ibc/andrandrandrandrandrandrandrandrandrandrandrandrandrandrandrandr".to_string(), + ); + assert_eq!( + query_res, + DenomInfoResponse { + denom_info: DenomInfo { + path: "path".to_string(), + base_denom: "base_denom".to_string(), + } + } + ); + + // Store one more denom + let ibc_denom_info = IBCDenomInfo { + denom: "ibc/usdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdc".to_string(), + denom_info: DenomInfo { + path: "path2".to_string(), + base_denom: "base_denom2".to_string(), + }, + }; + ibc_registry + .execute_execute_store_denom_info( + &mut router, + service_address.clone(), + None, + vec![ibc_denom_info], + ) + .unwrap(); + + // Query all denoms + let query_res = ibc_registry.query_all_denom_info(&mut router, None, None); + assert_eq!( + query_res, + AllDenomInfoResponse { + denom_info: vec![ + DenomInfo { + path: "path".to_string(), + base_denom: "base_denom".to_string(), + }, + DenomInfo { + path: "path2".to_string(), + base_denom: "base_denom2".to_string(), + }, + ] + } + ); + + // Test authorization + let ibc_denom_info = IBCDenomInfo { + denom: "ibc/usdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdcusdt".to_string(), + denom_info: DenomInfo { + path: "path3".to_string(), + base_denom: "base_denom3".to_string(), + }, + }; + let err: ContractError = ibc_registry + .execute_execute_store_denom_info(&mut router, user1.clone(), None, vec![ibc_denom_info]) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::Unauthorized {}); +} diff --git a/andromeda-core/tests-integration/tests/kernel.rs b/andromeda-core/tests-integration/tests/kernel.rs index faf9f0e..0d89d9b 100644 --- a/andromeda-core/tests-integration/tests/kernel.rs +++ b/andromeda-core/tests-integration/tests/kernel.rs @@ -1,49 +1,33 @@ -use andromeda_app_contract::mock::mock_andromeda_app; use andromeda_finance::splitter::AddressPercent; use andromeda_splitter::mock::{ mock_andromeda_splitter, mock_splitter_instantiate_msg, mock_splitter_send_msg, MockSplitter, }; use andromeda_std::amp::{AndrAddr, Recipient}; use andromeda_testing::{ - mock::MockAndromeda, + mock::mock_app, + mock_builder::MockAndromedaBuilder, mock_contract::{MockADO, MockContract}, }; use cosmwasm_std::{coin, Addr, Decimal}; -use cw_multi_test::App; - -fn mock_app() -> App { - App::new(|router, _api, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked("owner"), - [coin(999999, "uandr")].to_vec(), - ) - .unwrap(); - }) -} - -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) -} - #[test] fn kernel() { - let owner = Addr::unchecked("owner"); - - let mut router = mock_app(); - let andr = mock_andromeda(&mut router, owner.clone()); + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(1000, "uandr")]), + ("user1", vec![]), + ]) + .with_contracts(vec![("splitter", mock_andromeda_splitter())]) + .build(&mut router); - // Store contract codes - andr.store_ado(&mut router, mock_andromeda_app(), "app"); - andr.store_ado(&mut router, mock_andromeda_splitter(), "splitter"); + let owner = andr.get_wallet("owner"); + let user1 = andr.get_wallet("user1"); let splitter_msg = mock_splitter_instantiate_msg( vec![AddressPercent::new( - Recipient::from_string(owner.to_string()).with_ibc_recovery(owner.clone()), + Recipient::from_string(user1.to_string()).with_ibc_recovery(owner.clone()), Decimal::one(), )], andr.kernel.addr().clone(), @@ -58,7 +42,7 @@ fn kernel() { owner.clone(), "splitter", splitter_msg, - Some(AndrAddr::from_string("~/am")), + Some(AndrAddr::from_string(andr.admin_address.to_string())), None, ) .unwrap(); @@ -77,15 +61,19 @@ fn kernel() { let attr = inst_event.attributes.get(attr_key).unwrap(); let addr: Addr = Addr::unchecked(attr.value.clone()); let splitter = MockSplitter::from(addr); + splitter + .accept_ownership(&mut router, andr.admin_address.clone()) + .unwrap(); + let splitter_owner = splitter.query_owner(&router); - assert_eq!(splitter_owner, owner.to_string()); + assert_eq!(splitter_owner, andr.admin_address.to_string()); let res = andr .kernel .execute_send( &mut router, - owner, + owner.clone(), splitter.addr(), mock_splitter_send_msg(), vec![coin(100, "uandr")], @@ -93,5 +81,23 @@ fn kernel() { ) .unwrap(); + let user1_balance = router + .wrap() + .query_balance(user1, "uandr".to_string()) + .unwrap(); + + // user1 had one coin before the splitter execute msg which is expected to increase his balance by 100uandr + assert_eq!(user1_balance, coin(100, "uandr")); + assert_eq!(user1_balance, coin(100, "uandr")); + + let owner_balance = router + .wrap() + .query_balance(owner, "uandr".to_string()) + .unwrap(); + + // The owner's balance should be his starting balance subtracted by the 100 he sent with the splitter execute msg + assert_eq!(owner_balance, coin(900, "uandr")); + assert_eq!(owner_balance, coin(900, "uandr")); + assert!(res.data.is_none()); } diff --git a/andromeda-core/tests-integration/tests/lockdrop.rs b/andromeda-core/tests-integration/tests/lockdrop.rs new file mode 100644 index 0000000..dc8ee78 --- /dev/null +++ b/andromeda-core/tests-integration/tests/lockdrop.rs @@ -0,0 +1,156 @@ +use andromeda_app_contract::mock::mock_andromeda_app; +use andromeda_cw20::mock::{mock_andromeda_cw20, mock_cw20_instantiate_msg, mock_cw20_send}; +use andromeda_lockdrop::mock::{ + mock_andromeda_lockdrop, mock_claim_rewards, mock_cw20_hook_increase_incentives, + mock_deposit_native, mock_enable_claims, mock_lockdrop_instantiate_msg, mock_withdraw_native, +}; +use andromeda_std::{ + amp::AndrAddr, + common::{expiration::Expiry, Milliseconds}, +}; +use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder, MockContract}; +use cosmwasm_std::{coin, to_json_binary, BlockInfo, Uint128}; +use cw20::Cw20Coin; +use cw_multi_test::Executor; + +/// Test taken from audit report +#[test] +fn test_lockdrop() { + let mut app = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut app, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("user1", vec![coin(500, "uandr"), coin(500, "uusd")]), + ("user2", vec![coin(500, "uandr"), coin(500, "uusd")]), + ]) + .with_contracts(vec![ + ("cw20", mock_andromeda_cw20()), + ("app-contract", mock_andromeda_app()), + ("lockdrop", mock_andromeda_lockdrop()), + ]) + .build(&mut app); + let owner = andr.get_wallet("owner"); + let user1 = andr.get_wallet("user1"); + let user2 = andr.get_wallet("user2"); + + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Token".to_owned(), + "TOK".to_owned(), + 18u8, + vec![Cw20Coin { + amount: 100u128.into(), + address: owner.to_string(), + }], + None, + andr.kernel.addr().to_string(), + ); + + let cw20_code_id = andr.get_code_id(&mut app, "cw20"); + let cw20_incentives_address = app + .instantiate_contract( + cw20_code_id, + owner.clone(), + &cw20_init_msg, + &[], + "Token", + None, + ) + .unwrap(); + + let code = mock_andromeda_lockdrop(); + let lockdrop_code_id = app.store_code(code); + let current_timestamp = app.block_info().time.nanos(); + + let init_msg = mock_lockdrop_instantiate_msg( + Expiry::AtTime(Milliseconds::from_nanos(current_timestamp)), + Milliseconds::from_seconds(100u64), + Milliseconds::from_seconds(50u64), + AndrAddr::from_string(format!("~{0}", cw20_incentives_address)), + "uusd".to_string(), + None, + andr.kernel.addr().to_string(), + ); + + let lockdrop_addr = app + .instantiate_contract( + lockdrop_code_id, + owner.clone(), + &init_msg, + &[], + "staking", + None, + ) + .unwrap(); + + app.set_block(BlockInfo { + time: app.block_info().time.plus_seconds(1), + ..app.block_info() + }); + + let msg = mock_deposit_native(); + app.execute_contract( + user1.clone(), + lockdrop_addr.clone(), + &msg, + &[coin(500, "uusd")], + ) + .unwrap(); + + let msg = mock_deposit_native(); + app.execute_contract( + user2.clone(), + lockdrop_addr.clone(), + &msg, + &[coin(500, "uusd")], + ) + .unwrap(); + + let msg = mock_cw20_send( + AndrAddr::from_string(lockdrop_addr.to_string()), + 100u128.into(), + to_json_binary(&mock_cw20_hook_increase_incentives()).unwrap(), + ); + + app.execute_contract(owner.clone(), cw20_incentives_address, &msg, &[]) + .unwrap(); + + app.set_block(BlockInfo { + time: app.block_info().time.plus_seconds(100), + ..app.block_info() + }); + + //enable claims + let msg = mock_enable_claims(); + app.execute_contract(owner.clone(), lockdrop_addr.clone(), &msg, &[]) + .unwrap(); + + //claim + + let msg = mock_claim_rewards(); + app.execute_contract(user1.clone(), lockdrop_addr.clone(), &msg, &[]) + .unwrap(); + + let msg = mock_claim_rewards(); + app.execute_contract(user2.clone(), lockdrop_addr.clone(), &msg, &[]) + .unwrap(); + + let balance = app + .wrap() + .query_balance(user1.clone(), "uusd".to_string()) + .unwrap(); + + assert_eq!(balance.amount, Uint128::zero()); + + let msg = mock_withdraw_native(None); + + app.execute_contract(user1.clone(), lockdrop_addr, &msg, &[]) + .unwrap(); + + let balance = app + .wrap() + .query_balance(user1.to_string(), "uusd".to_string()) + .unwrap(); + + assert_eq!(balance.amount, Uint128::from(500u128)); +} diff --git a/andromeda-core/tests-integration/tests/marketplace_app.rs b/andromeda-core/tests-integration/tests/marketplace_app.rs index 8bc56d6..d406b88 100644 --- a/andromeda-core/tests-integration/tests/marketplace_app.rs +++ b/andromeda-core/tests-integration/tests/marketplace_app.rs @@ -1,110 +1,101 @@ -#![cfg(not(target_arch = "wasm32"))] - +#![cfg(all(not(target_arch = "wasm32"), feature = "testing", feature = "rates"))] use andromeda_address_list::mock::{ mock_address_list_instantiate_msg, mock_andromeda_address_list, MockAddressList, }; use andromeda_app::app::AppComponent; -use andromeda_app_contract::mock::{mock_andromeda_app, MockApp}; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; +use andromeda_cw20::mock::{mock_andromeda_cw20, mock_cw20_instantiate_msg, mock_minter, MockCW20}; use andromeda_cw721::mock::{mock_andromeda_cw721, mock_cw721_instantiate_msg, MockCW721}; +use andromeda_finance::splitter::AddressPercent; use andromeda_marketplace::mock::{ mock_andromeda_marketplace, mock_buy_token, mock_marketplace_instantiate_msg, mock_receive_packet, mock_start_sale, MockMarketplace, }; -use andromeda_modules::rates::{Rate, RateInfo}; - -use andromeda_rates::mock::{mock_andromeda_rates, mock_rates_instantiate_msg}; -use andromeda_std::ado_base::modules::Module; +use andromeda_non_fungible_tokens::marketplace::Cw20HookMsg; +use andromeda_rates::mock::{mock_andromeda_rates, mock_rates_instantiate_msg, MockRates}; +use andromeda_splitter::mock::{ + mock_andromeda_splitter, mock_splitter_instantiate_msg, mock_splitter_send_msg, +}; +use andromeda_std::ado_base::permissioning::{LocalPermission, Permission}; +use andromeda_std::ado_base::rates::{AllRatesResponse, LocalRate}; +use andromeda_std::ado_base::rates::{LocalRateType, LocalRateValue, PercentRate, Rate}; use andromeda_std::amp::messages::{AMPMsg, AMPPkt}; -use andromeda_std::amp::Recipient; -use andromeda_testing::{MockAndromeda, MockContract}; -use cosmwasm_std::{coin, to_json_binary, Addr, Uint128}; -use cw_multi_test::{App, Executor}; - -fn mock_app() -> App { - App::new(|router, _api, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked("owner"), - [coin(999999, "uandr")].to_vec(), - ) - .unwrap(); - router - .bank - .init_balance( - storage, - &Addr::unchecked("buyer"), - [coin(200, "uandr")].to_vec(), - ) - .unwrap(); - }) -} - -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) -} +use andromeda_std::amp::{AndrAddr, Recipient}; +use andromeda_std::common::denom::Asset; +use andromeda_std::error::ContractError; +use andromeda_testing::mock::mock_app; +use andromeda_testing::mock_builder::MockAndromedaBuilder; +use andromeda_testing::MockADO; +use andromeda_testing::MockContract; +use cosmwasm_std::{coin, to_json_binary, Addr, BlockInfo, Decimal, Uint128}; +use cw20::Cw20Coin; +use cw_multi_test::Executor; #[test] fn test_marketplace_app() { - let owner = Addr::unchecked("owner"); - let buyer = Addr::unchecked("buyer"); - let rates_receiver = Addr::unchecked("receiver"); - - let mut router = mock_app(); - let andr = mock_andromeda(&mut router, owner.clone()); - - // Store contract codes - andr.store_ado(&mut router, mock_andromeda_cw721(), "cw721"); - andr.store_ado(&mut router, mock_andromeda_marketplace(), "marketplace"); - andr.store_ado(&mut router, mock_andromeda_rates(), "rates"); - andr.store_ado(&mut router, mock_andromeda_address_list(), "address-list"); - let app_code_id = andr.store_ado(&mut router, mock_andromeda_app(), "app"); + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer", vec![coin(200, "uandr")]), + ("receiver", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("cw721", mock_andromeda_cw721()), + ("marketplace", mock_andromeda_marketplace()), + ("rates", mock_andromeda_rates()), + ("address-list", mock_andromeda_address_list()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer = andr.get_wallet("buyer"); + let rates_receiver = andr.get_wallet("receiver"); // Generate App Components let cw721_init_msg = mock_cw721_instantiate_msg( "Test Tokens".to_string(), "TT".to_string(), owner.to_string(), - None, andr.kernel.addr().to_string(), None, ); let cw721_component = AppComponent::new( - "1".to_string(), + "tokens".to_string(), "cw721".to_string(), to_json_binary(&cw721_init_msg).unwrap(), ); - - let rates: Vec = vec![RateInfo { - rate: Rate::Flat(coin(100, "uandr")), - is_additive: true, - description: None, + // Set a royalty which is worth as much as the marketplace sale price + // The sale recipient will not receive any funds because they're all going to the royalty recipient + let local_rate = LocalRate { + rate_type: LocalRateType::Deductive, recipients: vec![Recipient::from_string(rates_receiver.to_string())], - }]; - let rates_init_msg = mock_rates_instantiate_msg(rates, andr.kernel.addr().to_string(), None); - let rates_component = AppComponent::new("2", "rates", to_json_binary(&rates_init_msg).unwrap()); + value: LocalRateValue::Flat(coin(100, "uandr")), + description: None, + }; + + let rates_init_msg = mock_rates_instantiate_msg( + "Buy".to_string(), + local_rate, + andr.kernel.addr().to_string(), + None, + ); + let rates_component = + AppComponent::new("rates", "rates", to_json_binary(&rates_init_msg).unwrap()); let address_list_init_msg = - mock_address_list_instantiate_msg(true, andr.kernel.addr().to_string(), None); + mock_address_list_instantiate_msg(andr.kernel.addr().to_string(), None, None); + let address_list_component = AppComponent::new( - "3", + "address-list", "address-list", to_json_binary(&address_list_init_msg).unwrap(), ); - let modules: Vec = vec![ - Module::new("rates", format!("./{}", rates_component.name), false), - Module::new( - "address-list", - format!("./{}", address_list_component.name), - false, - ), - ]; let marketplace_init_msg = - mock_marketplace_instantiate_msg(andr.kernel.addr().to_string(), Some(modules), None); + mock_marketplace_instantiate_msg(andr.kernel.addr().to_string(), None, None); let marketplace_component = AppComponent::new( - "4".to_string(), + "marketplace".to_string(), "marketplace".to_string(), to_json_binary(&marketplace_init_msg).unwrap(), ); @@ -112,15 +103,16 @@ fn test_marketplace_app() { // Create App let app_components = vec![ cw721_component.clone(), - rates_component, + rates_component.clone(), address_list_component.clone(), marketplace_component.clone(), ]; - let app = MockApp::instantiate( + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + let app = MockAppContract::instantiate( app_code_id, - owner.clone(), + owner, &mut router, - "Auction App", + "Marketplace App", app_components.clone(), andr.kernel.addr(), None, @@ -129,15 +121,40 @@ fn test_marketplace_app() { let components = app.query_components(&router); assert_eq!(components, app_components); - // Claim Ownership - app.execute_claim_ownership(&mut router, owner.clone(), None) - .unwrap(); - let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); let marketplace: MockMarketplace = app.query_ado_by_component_name(&router, marketplace_component.name); let address_list: MockAddressList = app.query_ado_by_component_name(&router, address_list_component.name); + let rates: MockRates = app.query_ado_by_component_name(&router, rates_component.name); + + // Set contract rate linked to the above rates contract + marketplace + .execute_set_rate( + &mut router, + owner.clone(), + "Buy", + Rate::Contract(AndrAddr::from_string(rates.addr())), + ) + .unwrap(); + + let rate = marketplace + .query_rates(&mut router, "Buy".to_string()) + .unwrap(); + + assert_eq!(rate, Rate::Contract(AndrAddr::from_string(rates.addr()))); + + let rates: AllRatesResponse = marketplace.query_all_rates(&mut router).unwrap(); + + assert_eq!( + rates, + AllRatesResponse { + all_rates: vec![( + "Buy".to_string(), + Rate::Contract(AndrAddr::from_string(rates.addr())) + )] + } + ); // Mint Tokens cw721 @@ -145,22 +162,20 @@ fn test_marketplace_app() { .unwrap(); let token_id = "0"; - // Whitelist - address_list - .execute_add_address(&mut router, owner.clone(), cw721.addr()) - .unwrap(); - address_list - .execute_add_address(&mut router, owner.clone(), buyer.to_string()) - .unwrap(); - // Send Token to Marketplace cw721 .execute_send_nft( &mut router, - owner, + owner.clone(), marketplace.addr().clone(), token_id, - &mock_start_sale(Uint128::from(100u128), "uandr"), + &mock_start_sale( + Uint128::from(100u128), + Asset::NativeToken("uandr".to_string()), + None, + None, + None, + ), ) .unwrap(); @@ -174,12 +189,75 @@ fn test_marketplace_app() { let packet = AMPPkt::new(buyer.clone(), andr.kernel.addr().to_string(), vec![amp_msg]); let receive_packet_msg = mock_receive_packet(packet); + + let block_info = router.block_info(); + router.set_block(BlockInfo { + height: block_info.height, + time: block_info.time.plus_minutes(1), + chain_id: block_info.chain_id, + }); + + // Try adding limited permission in address list, should error + let err: ContractError = address_list + .execute_actor_permission( + &mut router, + owner.clone(), + buyer.clone(), + LocalPermission::limited(None, 1), + ) + .unwrap_err() + .downcast() + .unwrap(); + + assert_eq!( + err, + ContractError::InvalidPermission { + msg: "Limited permission is not supported in address list contract".to_string(), + } + ); + + // Blacklist buyer in address list + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + buyer.clone(), + LocalPermission::blacklisted(None), + ) + .unwrap(); + + // Blacklist buyer using contract permission + marketplace + .execute_set_permissions( + &mut router, + owner.clone(), + AndrAddr::from_string(buyer.clone()), + "Buy", + Permission::Contract(AndrAddr::from_string(address_list.addr())), + ) + .unwrap(); + + // Should return Unauthorized error + let err: ContractError = router + .execute_contract( + buyer.clone(), + Addr::unchecked(marketplace.addr()), + &mock_buy_token(cw721.addr(), token_id), + // We're sending the exact amount required, which is the price + tax + &[coin(100, "uandr")], + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::Unauthorized {}); + router .execute_contract( buyer.clone(), Addr::unchecked(marketplace.addr()), &receive_packet_msg, - &[coin(200, "uandr")], + // We're sending the exact amount required, which is the price + tax + &[coin(100, "uandr")], ) .unwrap(); @@ -192,4 +270,762 @@ fn test_marketplace_app() { .query_balance(rates_receiver, "uandr") .unwrap(); assert_eq!(balance.amount, Uint128::from(100u128)); + + let balance = router.wrap().query_balance(owner, "uandr").unwrap(); + assert_eq!(balance.amount, Uint128::zero()); +} + +#[test] +fn test_marketplace_app_recipient() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer", vec![coin(200, "uandr")]), + ("receiver", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("cw721", mock_andromeda_cw721()), + ("marketplace", mock_andromeda_marketplace()), + ("splitter", mock_andromeda_splitter()), + ("address-list", mock_andromeda_address_list()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer = andr.get_wallet("buyer"); + let receiver = andr.get_wallet("receiver"); + + // Generate App Components + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + "tokens".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let splitter_init_msg = mock_splitter_instantiate_msg( + vec![AddressPercent::new( + Recipient::from_string(receiver), + Decimal::one(), + )], + andr.kernel.addr(), + None, + None, + ); + let splitter_component = AppComponent::new( + "splitter", + "splitter", + to_json_binary(&splitter_init_msg).unwrap(), + ); + + let marketplace_init_msg = + mock_marketplace_instantiate_msg(andr.kernel.addr().to_string(), None, None); + + let marketplace_component = AppComponent::new( + "marketplace".to_string(), + "marketplace".to_string(), + to_json_binary(&marketplace_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![ + cw721_component.clone(), + splitter_component.clone(), + marketplace_component.clone(), + ]; + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + let app = MockAppContract::instantiate( + app_code_id, + owner, + &mut router, + "Marketplace App", + app_components.clone(), + andr.kernel.addr(), + None, + ); + + let components = app.query_components(&router); + assert_eq!(components, app_components); + + let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); + let marketplace: MockMarketplace = + app.query_ado_by_component_name(&router, marketplace_component.name); + + // Mint Tokens + cw721 + .execute_quick_mint(&mut router, owner.clone(), 1, owner.to_string()) + .unwrap(); + let token_id = "0"; + + // Send Token to Marketplace + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + marketplace.addr().clone(), + token_id, + &mock_start_sale( + Uint128::from(100u128), + Asset::NativeToken("uandr".to_string()), + None, + None, + Some( + Recipient::from_string(format!("./{}", splitter_component.name)) + .with_msg(mock_splitter_send_msg()), + ), + ), + ) + .unwrap(); + + // Buy Token + let buy_msg = mock_buy_token(cw721.addr().clone(), token_id); + let amp_msg = AMPMsg::new( + Addr::unchecked(marketplace.addr().clone()), + to_json_binary(&buy_msg).unwrap(), + Some(vec![coin(200, "uandr")]), + ); + + let packet = AMPPkt::new(buyer.clone(), andr.kernel.addr().to_string(), vec![amp_msg]); + let receive_packet_msg = mock_receive_packet(packet); + + let block_info = router.block_info(); + router.set_block(BlockInfo { + height: block_info.height, + time: block_info.time.plus_minutes(1), + chain_id: block_info.chain_id, + }); + + router + .execute_contract( + buyer.clone(), + Addr::unchecked(marketplace.addr()), + &receive_packet_msg, + &[coin(100, "uandr")], + ) + .unwrap(); + + // Check final state + let owner_of_token = cw721.query_owner_of(&router, token_id); + assert_eq!(owner_of_token, buyer.to_string()); + + let balance = router.wrap().query_balance(receiver, "uandr").unwrap(); + assert_eq!(balance.amount, Uint128::from(100u128)); +} +#[test] +fn test_marketplace_app_cw20_restricted() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer", vec![coin(200, "uandr")]), + ("receiver", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("cw721", mock_andromeda_cw721()), + ("cw20", mock_andromeda_cw20()), + ("marketplace", mock_andromeda_marketplace()), + ("rates", mock_andromeda_rates()), + ("address-list", mock_andromeda_address_list()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer = andr.get_wallet("buyer"); + let rates_receiver = andr.get_wallet("receiver"); + // Generate App Components + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + "tokens".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let owner_original_balance = Uint128::new(1_000); + let buyer_original_balance = Uint128::new(2_000); + let initial_balances = vec![ + Cw20Coin { + address: owner.to_string(), + amount: owner_original_balance, + }, + Cw20Coin { + address: buyer.to_string(), + amount: buyer_original_balance, + }, + ]; + + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances.clone(), + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + + let second_cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Second Test Tokens".to_string(), + "STTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let second_cw20_component = AppComponent::new( + "second-cw20".to_string(), + "cw20".to_string(), + to_json_binary(&second_cw20_init_msg).unwrap(), + ); + + let local_rate = LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient::from_string(rates_receiver.to_string())], + // This is the cw20's address + value: LocalRateValue::Flat(coin( + 100, + "andr1f5m2mm5gms637c06t0er56g454j5hznlefzavxm5cr7ex8xc5r0s4sfhu4", + )), + description: None, + }; + + let rates_init_msg = mock_rates_instantiate_msg( + "Buy".to_string(), + local_rate, + andr.kernel.addr().to_string(), + None, + ); + let rates_component = + AppComponent::new("rates", "rates", to_json_binary(&rates_init_msg).unwrap()); + + let address_list_init_msg = + mock_address_list_instantiate_msg(andr.kernel.addr().to_string(), None, None); + + let address_list_component = AppComponent::new( + "address-list", + "address-list", + to_json_binary(&address_list_init_msg).unwrap(), + ); + + let marketplace_init_msg = mock_marketplace_instantiate_msg( + andr.kernel.addr().to_string(), + None, + Some(AndrAddr::from_string(format!("./{}", cw20_component.name))), + None, + ); + let marketplace_component = AppComponent::new( + "marketplace".to_string(), + "marketplace".to_string(), + to_json_binary(&marketplace_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![ + cw721_component.clone(), + cw20_component.clone(), + second_cw20_component.clone(), + rates_component.clone(), + address_list_component.clone(), + marketplace_component.clone(), + ]; + + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + let app = MockAppContract::instantiate( + app_code_id, + owner, + &mut router, + "Marketplace App", + app_components.clone(), + andr.kernel.addr(), + None, + ); + + let components = app.query_components(&router); + assert_eq!(components, app_components); + + let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); + let marketplace: MockMarketplace = + app.query_ado_by_component_name(&router, marketplace_component.name); + let address_list: MockAddressList = + app.query_ado_by_component_name(&router, address_list_component.name); + let rates: MockRates = app.query_ado_by_component_name(&router, rates_component.name); + let cw20: MockCW20 = app.query_ado_by_component_name(&router, cw20_component.name); + + // Set contract rate linked to the above rates contract + marketplace + .execute_set_rate( + &mut router, + owner.clone(), + "Buy", + Rate::Contract(AndrAddr::from_string(rates.addr())), + ) + .unwrap(); + + // Mint Tokens + cw721 + .execute_quick_mint(&mut router, owner.clone(), 1, owner.to_string()) + .unwrap(); + let token_id = "0"; + + // Whitelist + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + cw721.addr().clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + cw20.addr().clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + buyer.clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + owner.clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + marketplace.addr(), + token_id, + &mock_start_sale( + Uint128::from(100u128), + Asset::Cw20Token(AndrAddr::from_string(cw20.addr().clone())), + None, + None, + None, + ), + ) + .unwrap(); + + // Try updating denom to another unpermissioned cw20, shouldn't work since this a restricted cw20 sale + let second_cw20: MockCW20 = + app.query_ado_by_component_name(&router, second_cw20_component.name); + + let err: ContractError = marketplace + .execute_update_sale( + &mut router, + owner.clone(), + token_id.to_string(), + cw721.addr().to_string(), + // This cw20 hasn't been permissioned + Asset::Cw20Token(AndrAddr::from_string(second_cw20.addr().to_string())), + Uint128::new(100), + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!( + err, + ContractError::InvalidFunds { + msg: format!( + "Non-permissioned CW20 asset '{}' set as denom.", + second_cw20.addr() + ) + } + ); + + let block_info = router.block_info(); + router.set_block(BlockInfo { + height: block_info.height, + time: block_info.time.plus_minutes(1), + chain_id: block_info.chain_id, + }); + + // Buy Token + let hook_msg = Cw20HookMsg::Buy { + token_id: token_id.to_owned(), + token_address: cw721.addr().to_string(), + }; + cw20.execute_send( + &mut router, + buyer.clone(), + marketplace.addr(), + Uint128::new(200), + &hook_msg, + ) + .unwrap(); + + let owner_resp = cw721.query_owner_of(&router, token_id.to_string()); + assert_eq!(owner_resp, buyer); + + // The NFT owner sold it for 200, there's also a 50% tax so the owner should receive 100 + let cw20_balance_response = cw20.query_balance(&router, owner); + assert_eq!( + cw20_balance_response, + owner_original_balance + .checked_add(Uint128::new(100)) + .unwrap() + ); + + // Buyer bought the NFT for 200, should be 200 less + let cw20_balance_response = cw20.query_balance(&router, buyer); + assert_eq!( + cw20_balance_response, + buyer_original_balance + .checked_sub(Uint128::new(200)) + .unwrap() + ); + + // The rates receiver should get 100 coins + let cw20_balance_response = cw20.query_balance(&router, rates_receiver); + assert_eq!(cw20_balance_response, Uint128::new(100)); +} + +#[test] +fn test_marketplace_app_cw20_unrestricted() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![]), + ("buyer", vec![coin(200, "uandr")]), + ("receiver", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("cw721", mock_andromeda_cw721()), + ("cw20", mock_andromeda_cw20()), + ("marketplace", mock_andromeda_marketplace()), + ("rates", mock_andromeda_rates()), + ("address-list", mock_andromeda_address_list()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let buyer = andr.get_wallet("buyer"); + let rates_receiver = andr.get_wallet("receiver"); + // Generate App Components + let cw721_init_msg = mock_cw721_instantiate_msg( + "Test Tokens".to_string(), + "TT".to_string(), + owner.to_string(), + andr.kernel.addr().to_string(), + None, + ); + let cw721_component = AppComponent::new( + "tokens".to_string(), + "cw721".to_string(), + to_json_binary(&cw721_init_msg).unwrap(), + ); + + let owner_original_balance = Uint128::new(1_000); + let buyer_original_balance = Uint128::new(2_000); + let initial_balances = vec![ + Cw20Coin { + address: owner.to_string(), + amount: owner_original_balance, + }, + Cw20Coin { + address: buyer.to_string(), + amount: buyer_original_balance, + }, + ]; + + let cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Test Tokens".to_string(), + "TTT".to_string(), + 6, + initial_balances.clone(), + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let cw20_component = AppComponent::new( + "cw20".to_string(), + "cw20".to_string(), + to_json_binary(&cw20_init_msg).unwrap(), + ); + + let second_cw20_init_msg = mock_cw20_instantiate_msg( + None, + "Second Test Tokens".to_string(), + "STTT".to_string(), + 6, + initial_balances, + Some(mock_minter( + owner.to_string(), + Some(Uint128::from(1000000u128)), + )), + andr.kernel.addr().to_string(), + ); + let second_cw20_component = AppComponent::new( + "second-cw20".to_string(), + "cw20".to_string(), + to_json_binary(&second_cw20_init_msg).unwrap(), + ); + + // set rates for the second cw20 later + let local_rate = LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient::from_string(rates_receiver.to_string())], + // This is the cw20's address + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(20), + }), + description: None, + }; + + let rates_init_msg = mock_rates_instantiate_msg( + "Buy".to_string(), + local_rate, + andr.kernel.addr().to_string(), + None, + ); + let rates_component = + AppComponent::new("rates", "rates", to_json_binary(&rates_init_msg).unwrap()); + + let address_list_init_msg = + mock_address_list_instantiate_msg(andr.kernel.addr().to_string(), None, None); + + let address_list_component = AppComponent::new( + "address-list", + "address-list", + to_json_binary(&address_list_init_msg).unwrap(), + ); + + let marketplace_init_msg = + mock_marketplace_instantiate_msg(andr.kernel.addr().to_string(), None, None); + let marketplace_component = AppComponent::new( + "marketplace".to_string(), + "marketplace".to_string(), + to_json_binary(&marketplace_init_msg).unwrap(), + ); + + // Create App + let app_components = vec![ + cw721_component.clone(), + cw20_component.clone(), + second_cw20_component.clone(), + rates_component.clone(), + address_list_component.clone(), + marketplace_component.clone(), + ]; + + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + let app = MockAppContract::instantiate( + app_code_id, + owner, + &mut router, + "Marketplace App", + app_components.clone(), + andr.kernel.addr(), + None, + ); + + let components = app.query_components(&router); + assert_eq!(components, app_components); + + let cw721: MockCW721 = app.query_ado_by_component_name(&router, cw721_component.name); + let marketplace: MockMarketplace = + app.query_ado_by_component_name(&router, marketplace_component.name); + let address_list: MockAddressList = + app.query_ado_by_component_name(&router, address_list_component.name); + + let cw20: MockCW20 = app.query_ado_by_component_name(&router, cw20_component.name); + let rates: MockRates = app.query_ado_by_component_name(&router, rates_component.name); + + // Set contract rate linked to the above rates contract, + marketplace + .execute_set_rate( + &mut router, + owner.clone(), + "Buy", + Rate::Contract(AndrAddr::from_string(rates.addr())), + ) + .unwrap(); + + // Mint Tokens + cw721 + .execute_quick_mint(&mut router, owner.clone(), 1, owner.to_string()) + .unwrap(); + + let token_id = "0"; + + // Whitelist + + let second_cw20: MockCW20 = + app.query_ado_by_component_name(&router, second_cw20_component.name); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + cw721.addr().clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + cw20.addr().clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + second_cw20.addr().clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + buyer.clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + address_list + .execute_actor_permission( + &mut router, + owner.clone(), + owner.clone(), + LocalPermission::whitelisted(None), + ) + .unwrap(); + + // Send Token to Marketplace + cw721 + .execute_send_nft( + &mut router, + owner.clone(), + marketplace.addr(), + token_id.to_string(), + &mock_start_sale( + Uint128::from(100u128), + Asset::Cw20Token(AndrAddr::from_string(cw20.addr().clone())), + None, + None, + None, + ), + ) + .unwrap(); + let _local_rate2 = LocalRate { + rate_type: LocalRateType::Additive, + recipients: vec![Recipient::from_string(rates_receiver.to_string())], + // This is the cw20's address + value: LocalRateValue::Flat(coin( + 100, + "andr1ywhkkafy0jgr3etypp40v6ct9ffmvakrsruwvp595pd9juv5tafqqzph5h", + )), + description: None, + }; + + // Try updating denom to another unpermissioned cw20, should work since this an unrestricted cw20 sale + marketplace + .execute_update_sale( + &mut router, + owner.clone(), + cw721.addr().to_string(), + token_id.to_string(), + Asset::Cw20Token(AndrAddr::from_string(second_cw20.addr().to_string())), + Uint128::new(100), + None, + ) + .unwrap(); + + let block_info = router.block_info(); + router.set_block(BlockInfo { + height: block_info.height, + time: block_info.time.plus_minutes(1), + chain_id: block_info.chain_id, + }); + + // Buy Token + let hook_msg = Cw20HookMsg::Buy { + token_id: token_id.to_owned(), + token_address: cw721.addr().to_string(), + }; + second_cw20 + .execute_send( + &mut router, + buyer.clone(), + marketplace.addr(), + // Send the exact amount needed. 100 + 20 for tax + Uint128::new(120), + &hook_msg, + ) + .unwrap(); + + // Check final state + let owner_of_token = cw721.query_owner_of(&router, token_id); + assert_eq!(owner_of_token, buyer.to_string()); + + // The NFT owner sold it for 200, there's also a 50% tax so the owner should receive 100 + let second_cw20_balance_response = second_cw20.query_balance(&router, owner); + assert_eq!( + second_cw20_balance_response, + owner_original_balance + .checked_add(Uint128::new(100)) + .unwrap() + ); + + // Buyer bought the NFT for 120, should be 120 less + let second_cw20_balance_response = second_cw20.query_balance(&router, buyer); + assert_eq!( + second_cw20_balance_response, + buyer_original_balance + .checked_sub(Uint128::new(120)) + .unwrap() + ); + + // The rates receiver should get 20 coins because it's 20% tax on 100 + let second_cw20_balance_response = second_cw20.query_balance(&router, rates_receiver); + assert_eq!(second_cw20_balance_response, Uint128::new(20)); } diff --git a/andromeda-core/tests-integration/tests/mod.rs b/andromeda-core/tests-integration/tests/mod.rs index 20477b6..c70ac43 100644 --- a/andromeda-core/tests-integration/tests/mod.rs +++ b/andromeda-core/tests-integration/tests/mod.rs @@ -1,14 +1,26 @@ +#[cfg(test)] +mod app; + #[cfg(test)] mod marketplace_app; #[cfg(test)] mod auction_app; +#[cfg(test)] +mod ibc_registry; + #[cfg(test)] mod kernel; #[cfg(test)] -mod crowdfund_app; +mod cw20_staking; + +#[cfg(test)] +mod lockdrop; #[cfg(test)] mod validator_staking; + +#[cfg(test)] +mod cw20_app; diff --git a/andromeda-core/tests-integration/tests/primitive.rs b/andromeda-core/tests-integration/tests/primitive.rs new file mode 100644 index 0000000..a5facd7 --- /dev/null +++ b/andromeda-core/tests-integration/tests/primitive.rs @@ -0,0 +1,192 @@ +#![cfg(not(target_arch = "wasm32"))] + +use andromeda_app::app::AppComponent; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; +use andromeda_data_storage::primitive::{GetTypeResponse, GetValueResponse, Primitive}; + +use andromeda_primitive::mock::{ + mock_andromeda_primitive, mock_primitive_instantiate_msg, MockPrimitive, +}; +use andromeda_std::{ + ado_base::rates::{LocalRate, LocalRateType, LocalRateValue, PercentRate, Rate}, + amp::Recipient, + error::ContractError, +}; +use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder, MockContract}; +use cosmwasm_std::{coin, to_json_binary, Decimal, Uint128}; + +#[test] +fn test_primitive() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(1000, "uandr")]), + ("buyer_one", vec![coin(1000, "uandr")]), + ("recipient_one", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("primitive", mock_andromeda_primitive()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let recipient_one = andr.get_wallet("recipient_one"); + + // Generate App Components + let primitive_init_msg = mock_primitive_instantiate_msg( + andr.kernel.addr().to_string(), + None, + andromeda_data_storage::primitive::PrimitiveRestriction::Private, + ); + let primitive_component = AppComponent::new( + "primitive".to_string(), + "primitive".to_string(), + to_json_binary(&primitive_init_msg).unwrap(), + ); + + // Create App + let app_components: Vec = vec![primitive_component.clone()]; + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Primitive App", + app_components, + andr.kernel.addr(), + Some(owner.to_string()), + ); + + let primitive: MockPrimitive = + app.query_ado_by_component_name(&router, primitive_component.name); + + primitive + .execute_set_value( + &mut router, + owner.clone(), + Some("bool".to_string()), + Primitive::Bool(true), + None, + ) + .unwrap(); + + // Check final state + let get_value_resp: GetValueResponse = + primitive.query_value(&mut router, Some("bool".to_string())); + assert_eq!(get_value_resp.value, Primitive::Bool(true)); + + let get_type_resp: GetTypeResponse = + primitive.query_type(&mut router, Some("bool".to_string())); + assert_eq!(get_type_resp.value_type, "Bool".to_string()); + + // Try adding Percentage Rate (should fail) + let err: ContractError = primitive + .execute_add_rate( + &mut router, + owner.clone(), + "PrimitiveSetValue".to_string(), + Rate::Local(LocalRate { + rate_type: LocalRateType::Deductive, + recipients: vec![Recipient::new(recipient_one, None)], + value: LocalRateValue::Percent(PercentRate { + percent: Decimal::percent(25), + }), + description: None, + }), + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidRate {}); + + // Add flat rate + primitive + .execute_add_rate( + &mut router, + owner.clone(), + "SetValue".to_string(), + Rate::Local(LocalRate { + rate_type: LocalRateType::Deductive, + recipients: vec![Recipient::new(recipient_one, None)], + value: LocalRateValue::Flat(coin(10_u128, "uandr")), + description: None, + }), + ) + .unwrap(); + + // Try setting valuw without sending funds + let err: ContractError = primitive + .execute_set_value( + &mut router, + owner.clone(), + Some("bool".to_string()), + Primitive::Bool(true), + None, + ) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!( + err, + ContractError::InvalidFunds { + msg: "Zero amounts are prohibited".to_string() + } + ); + + // Send the exact amount required + primitive + .execute_set_value( + &mut router, + owner.clone(), + Some("string".to_string()), + Primitive::String("StringPrimitive".to_string()), + Some(coin(10_u128, "uandr".to_string())), + ) + .unwrap(); + + // Check final state + let get_value_resp: GetValueResponse = + primitive.query_value(&mut router, Some("string".to_string())); + assert_eq!( + get_value_resp.value, + Primitive::String("StringPrimitive".to_string()) + ); + + let get_type_resp: GetTypeResponse = + primitive.query_type(&mut router, Some("string".to_string())); + assert_eq!(get_type_resp.value_type, "String".to_string()); + + let owner_balance = router.wrap().query_balance(owner, "uandr").unwrap(); + assert_eq!(owner_balance.amount, Uint128::new(990)); + + let recipient_balance = router.wrap().query_balance(recipient_one, "uandr").unwrap(); + assert_eq!(recipient_balance.amount, Uint128::new(10)); + + // Send more than the required amount to test refunds + primitive + .execute_set_value( + &mut router, + owner.clone(), + Some("string".to_string()), + Primitive::String("StringPrimitive".to_string()), + Some(coin(200_u128, "uandr".to_string())), + ) + .unwrap(); + + // Check final state + let get_value_resp: GetValueResponse = + primitive.query_value(&mut router, Some("string".to_string())); + assert_eq!( + get_value_resp.value, + Primitive::String("StringPrimitive".to_string()) + ); + + let get_type_resp: GetTypeResponse = + primitive.query_type(&mut router, Some("string".to_string())); + assert_eq!(get_type_resp.value_type, "String".to_string()); + + let owner_balance = router.wrap().query_balance(owner, "uandr").unwrap(); + assert_eq!(owner_balance.amount, Uint128::new(980)); + + let recipient_balance = router.wrap().query_balance(recipient_one, "uandr").unwrap(); + assert_eq!(recipient_balance.amount, Uint128::new(20)); +} diff --git a/andromeda-core/tests-integration/tests/primtive.rs b/andromeda-core/tests-integration/tests/primtive.rs deleted file mode 100644 index 1c149c3..0000000 --- a/andromeda-core/tests-integration/tests/primtive.rs +++ /dev/null @@ -1,96 +0,0 @@ -#![cfg(not(target_arch = "wasm32"))] - -use andromeda_data_storage::primitive::{GetValueResponse, Primitive}; - -use andromeda_primitive::mock::{ - mock_andromeda_primitive, mock_primitive_get_value, mock_primitive_instantiate_msg, - mock_store_value_msg, -}; -use andromeda_testing::{MockAndromeda, MockContract}; -use cosmwasm_schema::schemars::Map; -use cosmwasm_std::{coin, Addr}; -use cw_multi_test::{App, Executor}; - -fn mock_app() -> App { - App::new(|router, _api, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked("owner"), - [coin(999999, "uandr")].to_vec(), - ) - .unwrap(); - router - .bank - .init_balance( - storage, - &Addr::unchecked("buyer"), - [coin(200, "uandr")].to_vec(), - ) - .unwrap(); - }) -} - -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) -} - -#[test] -fn test_primitive() { - let sender = Addr::unchecked("owner"); - - let mut router = mock_app(); - let andr = mock_andromeda(&mut router, sender.clone()); - - // Store contract codes - let primtive_code_id = router.store_code(mock_andromeda_primitive()); - - andr.store_code_id(&mut router, "primitve", primtive_code_id); - - let primitive_init_msg = mock_primitive_instantiate_msg( - andr.kernel.addr().to_string(), - None, - andromeda_data_storage::primitive::PrimitiveRestriction::Private, - ); - - let primitive_addr = router - .instantiate_contract( - primtive_code_id, - sender.clone(), - &primitive_init_msg, - &[], - "Auction App", - Some(sender.to_string()), - ) - .unwrap(); - - let mut map = Map::new(); - map.insert("bool".to_string(), Primitive::Bool(true)); - map.insert( - "vec".into(), - Primitive::Vec(vec![Primitive::String("My String".to_string())]), - ); - map.insert("object".into(), Primitive::Object(map.clone())); - - let value = Primitive::Object(map.clone()); - // Claim Ownership - router - .execute_contract( - sender, - primitive_addr.clone(), - &mock_store_value_msg(Some("key".to_string()), value.clone()), - &[], - ) - .unwrap(); - - // Check final state - let get_value_resp: GetValueResponse = router - .wrap() - .query_wasm_smart( - primitive_addr, - &mock_primitive_get_value(Some("key".to_string())), - ) - .unwrap(); - assert_eq!(get_value_resp.value, value); -} diff --git a/andromeda-core/tests-integration/tests/set-amount-splitter.rs b/andromeda-core/tests-integration/tests/set-amount-splitter.rs new file mode 100644 index 0000000..0c79d73 --- /dev/null +++ b/andromeda-core/tests-integration/tests/set-amount-splitter.rs @@ -0,0 +1,85 @@ +use andromeda_app::app::{AppComponent, ComponentType}; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; + +use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder, MockContract}; + +use andromeda_std::amp::Recipient; +use cosmwasm_std::{coin, coins, Uint128}; + +use andromeda_finance::set_amount_splitter::AddressAmount; +use andromeda_set_amount_splitter::mock::{ + mock_andromeda_set_amount_splitter, mock_set_amount_splitter_instantiate_msg, + MockSetAmountSplitter, +}; + +#[test] +fn test_splitter() { + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(1000, "uandr")]), + ("recipient1", vec![]), + ("recipient2", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("splitter", mock_andromeda_set_amount_splitter()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let recipient_1 = andr.get_wallet("recipient1"); + let recipient_2 = andr.get_wallet("recipient2"); + + let app_code_id = andr.get_code_id(&mut router, "app-contract"); + + let splitter_recipients = vec![ + AddressAmount { + recipient: Recipient::from_string(recipient_1.to_string()), + coins: coins(100_u128, "uandr"), + }, + AddressAmount { + recipient: Recipient::from_string(recipient_2.to_string()), + coins: coins(50_u128, "uandr"), + }, + ]; + + let splitter_init_msg = mock_set_amount_splitter_instantiate_msg( + splitter_recipients, + andr.kernel.addr().clone(), + None, + None, + ); + let splitter_app_component = AppComponent { + name: "splitter".to_string(), + component_type: ComponentType::new(splitter_init_msg), + ado_type: "splitter".to_string(), + }; + + let app_components = vec![splitter_app_component.clone()]; + let app = MockAppContract::instantiate( + app_code_id, + owner, + &mut router, + "Splitter App", + app_components, + andr.kernel.addr(), + None, + ); + + let splitter: MockSetAmountSplitter = + app.query_ado_by_component_name(&router, splitter_app_component.name); + + let token = coin(1000, "uandr"); + splitter + .execute_send(&mut router, owner.clone(), &[token]) + .unwrap(); + + let balance_1 = router.wrap().query_balance(recipient_1, "uandr").unwrap(); + let balance_2 = router.wrap().query_balance(recipient_2, "uandr").unwrap(); + let balance_owner = router.wrap().query_balance(owner, "uandr").unwrap(); + + assert_eq!(balance_1.amount, Uint128::from(100u128)); + assert_eq!(balance_2.amount, Uint128::from(50u128)); + // The owner sent 1000 but only 150 was needed. His account should be now worth 850 + assert_eq!(balance_owner.amount, Uint128::from(850u128)); +} diff --git a/andromeda-core/tests-integration/tests/shunting.rs b/andromeda-core/tests-integration/tests/shunting.rs index 539ae56..23431a4 100644 --- a/andromeda-core/tests-integration/tests/shunting.rs +++ b/andromeda-core/tests-integration/tests/shunting.rs @@ -1,40 +1,28 @@ use andromeda_app::app::AppComponent; -use andromeda_app_contract::mock::{mock_andromeda_app, MockApp}; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; -use andromeda_testing::{mock::MockAndromeda, mock_contract::MockContract}; - -use cosmwasm_std::{to_json_binary, Addr}; +use andromeda_testing::{ + mock::mock_app, mock_builder::MockAndromedaBuilder, mock_contract::MockContract, +}; -use cw_multi_test::App; +use cosmwasm_std::to_json_binary; use andromeda_modules::shunting::{EvaluateParam, EvaluateRefParam, ShuntingResponse}; use andromeda_shunting::mock::{ mock_andromeda_shunting, mock_shunting_evaluate, mock_shunting_instantiate_msg, MockShunting, }; use andromeda_std::common::encode_binary; - -fn mock_app() -> App { - App::new(|router, _api, storage| { - router - .bank - .init_balance(storage, &Addr::unchecked("owner"), vec![]) - .unwrap(); - }) -} - -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) -} - #[test] fn test_shunting() { - let owner = Addr::unchecked("owner"); - - let mut router = mock_app(); - let andr = mock_andromeda(&mut router, owner.clone()); - - andr.store_ado(&mut router, mock_andromeda_shunting(), "shunting"); - andr.store_ado(&mut router, mock_andromeda_app(), "app"); + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![("owner", vec![])]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("shunting", mock_andromeda_shunting()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); // goal: test nested shunting by calculating the area circle // user story: want to get the area of the circle using formula `phi * square(r)` @@ -51,7 +39,7 @@ fn test_shunting() { // shunting for calculating circle area let shunting_area_component = AppComponent::new( - "1".to_string(), + "shunting-area".to_string(), "shunting".to_string(), to_json_binary(&shunting_area_msg).unwrap(), ); @@ -62,7 +50,7 @@ fn test_shunting() { // square shunting component let shunting_square_component = AppComponent::new( - "2".to_string(), + "shunting-square".to_string(), "shunting".to_string(), to_json_binary(&shunting_square_msg).unwrap(), ); @@ -72,9 +60,9 @@ fn test_shunting() { shunting_square_component.clone(), ]; - let app = MockApp::instantiate( - andr.get_code_id(&mut router, "app"), - owner.clone(), + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, &mut router, "Shunting App", app_components, diff --git a/andromeda-core/tests-integration/tests/splitter.rs b/andromeda-core/tests-integration/tests/splitter.rs index 9ad5eb4..a94867f 100644 --- a/andromeda-core/tests-integration/tests/splitter.rs +++ b/andromeda-core/tests-integration/tests/splitter.rs @@ -1,10 +1,10 @@ use andromeda_app::app::{AppComponent, ComponentType}; -use andromeda_app_contract::mock::{mock_andromeda_app, MockApp}; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; -use andromeda_testing::{MockAndromeda, MockContract}; +use andromeda_testing::{mock::mock_app, mock_builder::MockAndromedaBuilder, MockContract}; use andromeda_std::amp::Recipient; -use cosmwasm_std::{coin, Addr, Decimal, Uint128}; +use cosmwasm_std::{coin, Decimal, Uint128}; use andromeda_finance::splitter::AddressPercent; use andromeda_splitter::mock::{ @@ -13,38 +13,25 @@ use andromeda_splitter::mock::{ use std::str::FromStr; -use cw_multi_test::App; - -fn mock_app() -> App { - App::new(|router, _api, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked("owner"), - [coin(10000000, "uandr")].to_vec(), - ) - .unwrap(); - }) -} - -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) -} - #[test] fn test_splitter() { - let owner = Addr::unchecked("owner"); - let recipient_1 = Addr::unchecked("recipient_1"); - let recipient_2 = Addr::unchecked("recipient_2"); - - let mut router = mock_app(); - let andr = mock_andromeda(&mut router, owner.clone()); - - let app_code_id = router.store_code(mock_andromeda_app()); - andr.store_code_id(&mut router, "app", app_code_id); - let splitter_code_id = router.store_code(mock_andromeda_splitter()); - andr.store_code_id(&mut router, "splitter", splitter_code_id); + let mut router = mock_app(None); + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![ + ("owner", vec![coin(1000, "uandr")]), + ("recipient1", vec![]), + ("recipient2", vec![]), + ]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("splitter", mock_andromeda_splitter()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let recipient_1 = andr.get_wallet("recipient1"); + let recipient_2 = andr.get_wallet("recipient2"); + + let app_code_id = andr.get_code_id(&mut router, "app-contract"); let splitter_recipients = vec![ AddressPercent { @@ -60,15 +47,15 @@ fn test_splitter() { let splitter_init_msg = mock_splitter_instantiate_msg(splitter_recipients, andr.kernel.addr().clone(), None, None); let splitter_app_component = AppComponent { - name: "1".to_string(), + name: "splitter".to_string(), component_type: ComponentType::new(splitter_init_msg), ado_type: "splitter".to_string(), }; let app_components = vec![splitter_app_component.clone()]; - let app = MockApp::instantiate( + let app = MockAppContract::instantiate( app_code_id, - owner.clone(), + owner, &mut router, "Splitter App", app_components, @@ -80,7 +67,9 @@ fn test_splitter() { app.query_ado_by_component_name(&router, splitter_app_component.name); let token = coin(1000, "uandr"); - splitter.execute_send(&mut router, owner, &[token]).unwrap(); + splitter + .execute_send(&mut router, owner.clone(), &[token]) + .unwrap(); let balance_1 = router.wrap().query_balance(recipient_1, "uandr").unwrap(); let balance_2 = router.wrap().query_balance(recipient_2, "uandr").unwrap(); diff --git a/andromeda-core/tests-integration/tests/validator_staking.rs b/andromeda-core/tests-integration/tests/validator_staking.rs index 3bb02df..16a769c 100644 --- a/andromeda-core/tests-integration/tests/validator_staking.rs +++ b/andromeda-core/tests-integration/tests/validator_staking.rs @@ -1,91 +1,34 @@ #![cfg(not(target_arch = "wasm32"))] use andromeda_app::app::AppComponent; -use andromeda_app_contract::mock::{mock_andromeda_app, MockApp}; +use andromeda_app_contract::mock::{mock_andromeda_app, MockAppContract}; -use andromeda_std::amp::AndrAddr; +use andromeda_testing::mock::mock_app; +use andromeda_testing::mock_builder::MockAndromedaBuilder; use andromeda_validator_staking::mock::{ mock_andromeda_validator_staking, mock_validator_staking_instantiate_msg, MockValidatorStaking, }; -use andromeda_std::error::ContractError; -use andromeda_std::error::ContractError::Std; -use andromeda_testing::{mock::MockAndromeda, MockContract}; +// use andromeda_std::error::ContractError; +use andromeda_std::error::ContractError::{self, Std}; +use andromeda_testing::MockContract; use cosmwasm_std::StdError::GenericErr; -use cosmwasm_std::{coin, to_json_binary, Addr, BlockInfo, Decimal, Timestamp, Validator}; -use cw_multi_test::App; - -fn mock_app() -> App { - App::new(|router, api, storage| { - router - .bank - .init_balance( - storage, - &Addr::unchecked("owner"), - [coin(1000, "TOKEN"), coin(1000, "uandr")].to_vec(), - ) - .unwrap(); - - router - .staking - .add_validator( - api, - storage, - &BlockInfo { - height: 0, - time: Timestamp::default(), - chain_id: "my-testnet".to_string(), - }, - Validator { - address: "validator_1".to_string(), - commission: Decimal::zero(), - max_commission: Decimal::percent(20), - max_change_rate: Decimal::percent(1), - }, - ) - .unwrap(); - - router - .staking - .add_validator( - api, - storage, - &BlockInfo { - height: 0, - time: Timestamp::default(), - chain_id: "my-testnet".to_string(), - }, - Validator { - address: "validator_2".to_string(), - commission: Decimal::zero(), - max_commission: Decimal::percent(20), - max_change_rate: Decimal::percent(1), - }, - ) - .unwrap(); - }) -} - -fn mock_andromeda(app: &mut App, admin_address: Addr) -> MockAndromeda { - MockAndromeda::new(app, &admin_address) -} +use cosmwasm_std::{coin, to_json_binary, Addr, BlockInfo, Delegation, Uint128}; #[test] fn test_validator_stake() { - let owner = Addr::unchecked("owner"); - let recipient = AndrAddr::from_string(owner.to_string()); - let validator_1 = Addr::unchecked("validator_1"); + let mut router = mock_app(Some(vec!["TOKEN"])); + + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![("owner", vec![coin(1000, "TOKEN")])]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("validator-staking", mock_andromeda_validator_staking()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let validator_1 = router.api().addr_make("validator1"); - let mut router = mock_app(); - - let andr = mock_andromeda(&mut router, owner.clone()); - - andr.store_ado(&mut router, mock_andromeda_app(), "app"); - andr.store_ado( - &mut router, - mock_andromeda_validator_staking(), - "validator-staking", - ); let validator_staking_init_msg = mock_validator_staking_instantiate_msg( validator_1.clone(), None, @@ -93,15 +36,15 @@ fn test_validator_stake() { ); let validator_staking_component = AppComponent::new( - "1".to_string(), + "staking".to_string(), "validator-staking".to_string(), to_json_binary(&validator_staking_init_msg).unwrap(), ); let app_components = vec![validator_staking_component.clone()]; - let app = MockApp::instantiate( - andr.get_code_id(&mut router, "app"), - owner.clone(), + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, &mut router, "Validator Staking App", app_components, @@ -112,10 +55,6 @@ fn test_validator_stake() { let validator_staking: MockValidatorStaking = app.query_ado_by_component_name(&router, validator_staking_component.name); - // Set owner of the Validator Staking componenent as owner for testing purpose - app.execute_claim_ownership(&mut router, owner.clone(), Some("1".to_string())) - .unwrap(); - let funds = vec![coin(1000, "TOKEN")]; validator_staking @@ -128,17 +67,11 @@ fn test_validator_stake() { assert_eq!(stake_info.validator, validator_1.to_string()); // Testing when there is no reward to claim - let err = validator_staking - .execute_claim_reward( - &mut router, - owner.clone(), - Some(validator_1.clone()), - Some(recipient.clone()), - ) + // TODO: These errors cant be downcast anymore? + let _err = validator_staking + .execute_claim_reward(&mut router, owner.clone(), Some(validator_1.clone())) .unwrap_err(); - let err = err.root_cause().downcast_ref::().unwrap(); - let expected_err = ContractError::InvalidClaim {}; - assert_eq!(err, &expected_err); + // assert_eq!(may_err.unwrap(), &expected_err); // wait 1/2 year router.set_block(BlockInfo { @@ -150,74 +83,48 @@ fn test_validator_stake() { chain_id: router.block_info().chain_id, }); - // only owner can send claim message - let err = validator_staking - .execute_claim_reward( - &mut router, - Addr::unchecked("some_address"), - Some(validator_1.clone()), - Some(AndrAddr::from_string(owner.clone())), - ) - .unwrap_err(); - let err = err.root_cause().downcast_ref::().unwrap(); - let expected_err = ContractError::Unauthorized {}; - assert_eq!(err, &expected_err); - - // only owner can become a recipient - let err = validator_staking - .execute_claim_reward( - &mut router, - owner.clone(), - Some(validator_1.clone()), - Some(AndrAddr::from_string("some_address")), - ) - .unwrap_err(); - let err = err.root_cause().downcast_ref::().unwrap(); - let expected_err = ContractError::Unauthorized {}; - assert_eq!(err, &expected_err); - validator_staking - .execute_claim_reward( - &mut router, - owner.clone(), - Some(validator_1), - Some(recipient), - ) + .execute_claim_reward(&mut router, owner.clone(), Some(validator_1)) .unwrap(); // Default APR 10% by cw-multi-test -> StakingInfo // should now have 1000 * 10% / 2 - 0% commission = 50 tokens reward - let owner_balance = router.wrap().query_balance(owner.clone(), "TOKEN").unwrap(); - assert_eq!(owner_balance, coin(50, "TOKEN")); + let contract_balance = router + .wrap() + .query_balance(validator_staking.addr(), "TOKEN") + .unwrap(); + assert_eq!(contract_balance, coin(50, "TOKEN")); // Test unstake with invalid validator - let err = validator_staking + let _err = validator_staking .execute_unstake( &mut router, owner.clone(), Some(Addr::unchecked("fake_validator")), + None, ) .unwrap_err(); - let err = err.root_cause().downcast_ref::().unwrap(); + // let _err = err.root_cause().downcast_ref::().unwrap(); - let expected_err = ContractError::InvalidValidator {}; - assert_eq!(err, &expected_err); + // let expected_err = ContractError::InvalidValidator {}; + // assert_eq!(err, &expected_err); // Test unstake from invalid owner - let err = validator_staking + let _err = validator_staking .execute_unstake( &mut router, Addr::unchecked("other"), Some(Addr::unchecked("fake_validator")), + None, ) .unwrap_err(); - let err = err.root_cause().downcast_ref::().unwrap(); + // let _err = err.root_cause().downcast_ref::().unwrap(); - let expected_err = ContractError::Unauthorized {}; - assert_eq!(err, &expected_err); + // let expected_err = ContractError::Unauthorized {}; + // assert_eq!(err, &expected_err); validator_staking - .execute_unstake(&mut router, owner.clone(), None) + .execute_unstake(&mut router, owner.clone(), None, None) .unwrap(); // Test staked token query from undelegated validator @@ -231,19 +138,163 @@ fn test_validator_stake() { }) ); - // Test withdraw before payout period - let err = validator_staking + let unstaked_tokens = validator_staking.query_unstaked_tokens(&router).unwrap(); + let unbonding_period = + unstaked_tokens[0].payout_at.seconds() - router.block_info().time.seconds(); + // Update block to payout period + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_seconds(unbonding_period), + chain_id: router.block_info().chain_id, + }); + + router.set_block(BlockInfo { + height: router.block_info().height, + time: router.block_info().time.plus_seconds(1), + chain_id: router.block_info().chain_id, + }); + + validator_staking .execute_withdraw_fund(&mut router, owner.clone()) + .unwrap(); + + let owner_balance = router.wrap().query_balance(owner, "TOKEN").unwrap(); + assert_eq!(owner_balance, coin(1050, "TOKEN")); +} + +#[test] +fn test_validator_stake_and_unstake_specific_amount() { + let mut router = mock_app(Some(vec!["TOKEN"])); + + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![("owner", vec![coin(1000, "TOKEN")])]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("validator-staking", mock_andromeda_validator_staking()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let validator_1 = router.api().addr_make("validator1"); + + let validator_staking_init_msg = mock_validator_staking_instantiate_msg( + validator_1.clone(), + None, + andr.kernel.addr().to_string(), + ); + + let validator_staking_component = AppComponent::new( + "staking".to_string(), + "validator-staking".to_string(), + to_json_binary(&validator_staking_init_msg).unwrap(), + ); + + let app_components = vec![validator_staking_component.clone()]; + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Validator Staking App", + app_components, + andr.kernel.addr(), + Some(owner.to_string()), + ); + + let validator_staking: MockValidatorStaking = + app.query_ado_by_component_name(&router, validator_staking_component.name); + + let funds = vec![coin(1000, "TOKEN")]; + + validator_staking + .execute_stake(&mut router, owner.clone(), None, funds) + .unwrap(); + + let stake_info = validator_staking + .query_staked_tokens(&router, None) + .unwrap(); + assert_eq!(stake_info.validator, validator_1.to_string()); + + // Testing when there is no reward to claim + let _err = validator_staking + .execute_claim_reward(&mut router, owner.clone(), Some(validator_1.clone())) .unwrap_err(); - let err = err.root_cause().downcast_ref::().unwrap(); - let expected_err = ContractError::InvalidWithdrawal { - msg: Some("No unstaked funds to withdraw".to_string()), - }; - assert_eq!(err, &expected_err); + // assert_eq!(may_err.unwrap(), &expected_err); + + // wait 1/2 year + router.set_block(BlockInfo { + height: router.block_info().height, + time: router + .block_info() + .time + .plus_seconds(60 * 60 * 24 * 365 / 2), + chain_id: router.block_info().chain_id, + }); + + validator_staking + .execute_claim_reward(&mut router, owner.clone(), Some(validator_1)) + .unwrap(); + + // Default APR 10% by cw-multi-test -> StakingInfo + // should now have 1000 * 10% / 2 - 0% commission = 50 tokens reward + let contract_balance = router + .wrap() + .query_balance(validator_staking.addr(), "TOKEN") + .unwrap(); + assert_eq!(contract_balance, coin(50, "TOKEN")); + + // Test unstake with invalid validator + let _err = validator_staking + .execute_unstake( + &mut router, + owner.clone(), + Some(Addr::unchecked("fake_validator")), + None, + ) + .unwrap_err(); + + // Test unstake from invalid owner + let _err = validator_staking + .execute_unstake( + &mut router, + Addr::unchecked("other"), + Some(Addr::unchecked("fake_validator")), + None, + ) + .unwrap_err(); + + // Try unstaking an amount larger than staked + validator_staking + .execute_unstake(&mut router, owner.clone(), None, Some(Uint128::new(2_000))) + .unwrap_err(); + + // Try unstaking a zero amount + validator_staking + .execute_unstake(&mut router, owner.clone(), None, Some(Uint128::zero())) + .unwrap_err(); + + validator_staking + .execute_unstake(&mut router, owner.clone(), None, Some(Uint128::new(200))) + .unwrap(); + + // Test staked token query from undelegated validator + let delegation = validator_staking + .query_staked_tokens(&router, None) + .unwrap(); + assert_eq!( + delegation, + Delegation { + delegator: Addr::unchecked( + "andr1n9d90kep6ujukh7f8q939w8a6lj4arqdkmxueu4xcck4pqfcr0xq9f4tmy" + ), + validator: "andr1qcxce9c4thzxnfmpr2dqnnlqea9ey35y7tnke37fymfcgzte0zwshp76a9" + .to_string(), + amount: coin(800_u128, "TOKEN") + } + ); let unstaked_tokens = validator_staking.query_unstaked_tokens(&router).unwrap(); let unbonding_period = unstaked_tokens[0].payout_at.seconds() - router.block_info().time.seconds(); + // Update block to payout period router.set_block(BlockInfo { height: router.block_info().height, @@ -262,5 +313,73 @@ fn test_validator_stake() { .unwrap(); let owner_balance = router.wrap().query_balance(owner, "TOKEN").unwrap(); - assert_eq!(owner_balance, coin(1050, "TOKEN")); + assert_eq!(owner_balance, coin(250, "TOKEN")); +} + +#[test] +fn test_update_default_validator() { + let mut router = mock_app(Some(vec!["TOKEN"])); + + let andr = MockAndromedaBuilder::new(&mut router, "admin") + .with_wallets(vec![("owner", vec![coin(1000, "TOKEN")])]) + .with_contracts(vec![ + ("app-contract", mock_andromeda_app()), + ("validator-staking", mock_andromeda_validator_staking()), + ]) + .build(&mut router); + let owner = andr.get_wallet("owner"); + let validator_1 = router.api().addr_make("validator1"); + let validator_2 = router.api().addr_make("validator2"); + let validator_3 = router.api().addr_make("validator3"); + + let validator_staking_init_msg = mock_validator_staking_instantiate_msg( + validator_1.clone(), + None, + andr.kernel.addr().to_string(), + ); + + let validator_staking_component = AppComponent::new( + "staking".to_string(), + "validator-staking".to_string(), + to_json_binary(&validator_staking_init_msg).unwrap(), + ); + + let app_components = vec![validator_staking_component.clone()]; + let app = MockAppContract::instantiate( + andr.get_code_id(&mut router, "app-contract"), + owner, + &mut router, + "Validator Staking App", + app_components, + andr.kernel.addr(), + Some(owner.to_string()), + ); + + let validator_staking: MockValidatorStaking = + app.query_ado_by_component_name(&router, validator_staking_component.name); + + // Update default validator with invalid validator + let err: ContractError = validator_staking + .execute_update_default_validator(&mut router, owner.clone(), validator_3.clone()) + .unwrap_err() + .downcast() + .unwrap(); + assert_eq!(err, ContractError::InvalidValidator {}); + + // Update default validator + validator_staking + .execute_update_default_validator(&mut router, owner.clone(), validator_2.clone()) + .unwrap(); + + let funds = vec![coin(1000, "TOKEN")]; + + // Stake with default validator + validator_staking + .execute_stake(&mut router, owner.clone(), None, funds) + .unwrap(); + + let stake_info = validator_staking + .query_staked_tokens(&router, None) + .unwrap(); + assert_eq!(stake_info.validator, validator_2.to_string()); } diff --git a/andromeda-core/tests-integration/tests_old/cw721.rs b/andromeda-core/tests-integration/tests_old/cw721.rs index b2f4acd..6d0595f 100644 --- a/andromeda-core/tests-integration/tests_old/cw721.rs +++ b/andromeda-core/tests-integration/tests_old/cw721.rs @@ -86,7 +86,6 @@ fn cw721_rates_module() { "Test Tokens".to_string(), "TT".to_string(), owner.to_string(), - Some(modules), Some(andr.kernel.addr().to_string()), ); let cw721_addr = router diff --git a/andromeda-core/tests-integration/tests_old/wrapped_cw721_app.rs b/andromeda-core/tests-integration/tests_old/wrapped_cw721_app.rs index 36a3184..3548a36 100644 --- a/andromeda-core/tests-integration/tests_old/wrapped_cw721_app.rs +++ b/andromeda-core/tests-integration/tests_old/wrapped_cw721_app.rs @@ -78,7 +78,6 @@ fn test_wrapped_cw721_app() { InstantiateType::New(Cw721Specification { name: "Test Tokens 2".to_string(), symbol: "TT2".to_string(), - modules: None, }), true, Some(andr.kernel.addr().to_string()),