diff --git a/packages/crypto/Readme.md b/packages/crypto/Readme.md index 0f33276..d2fe283 100644 --- a/packages/crypto/Readme.md +++ b/packages/crypto/Readme.md @@ -2,4 +2,46 @@ ⚠️ This package is a sub-package of the `secret-toolkit` package. Please see its crate page for more context. -This package contains all the tools related to crypto +This crate contains common cryptography tools used in the development of Secret Contracts +running on the Secret Network. + +Note: It has a deep dependency tree and increases compilation times significantly. + +Add the following to your `cargo.toml` file: + +```toml +[dependencies] +secret-toolkit = { version = "0.3.0", features = ["crypto"] } +secret-toolkit-crypto = { version = "0.3.0", features = ["hash", "rand", "ecc-secp256k1"] } +``` + +## Example usage: + +```ignore +# extern crate secret_toolkit_crypto; + +# use secret_toolkit_crypto::{sha_256, Prng, secp256k1::{PrivateKey, PublicKey, Signature}}; +# use base64; +# use cosmwasm_std::{StdError, testing::mock_dependencies}; + +# fn main() -> Result<(), StdError> { +# let deps = mock_dependencies(20, &[]); +let entropy: String = "secret".to_owned(); +let prng_seed: Vec = sha_256(base64::encode(&entropy.clone()).as_bytes()).to_vec(); + +let mut rng = Prng::new(&prng_seed, entropy.as_bytes()); + +let private_key: PrivateKey = PrivateKey::parse(&rng.rand_bytes())?; +let public_key: PublicKey = private_key.pubkey(); + +let message: &[u8] = b"message"; +let signature: Signature = private_key.sign(message, deps.api); +# Ok(()) +# } +``` + +### Cargo Features +- `["hash"]` - Provides an easy-to-use `sha256` function. Uses [sha2](https://crates.io/crates/sha2). +- `["rand"]` - Used to generate pseudo-random numbers. Uses [rand_chacha] and [rand_core]. +- `["ecc-secp256k1"]` - Contains types and methods for working with secp256k1 keys and signatures, + as well as standard constants for key sizes. Uses [secp256k1](https://crates.io/crates/secp256k1). diff --git a/packages/crypto/src/lib.rs b/packages/crypto/src/lib.rs index 83ee3a0..91035ae 100644 --- a/packages/crypto/src/lib.rs +++ b/packages/crypto/src/lib.rs @@ -1,47 +1,4 @@ -//! # Crypto -//! This crate contains common cryptography tools used in the development of Secret Contracts -//! running on the Secret Network. -//! -//! Note: It has a deep dependency tree and increases compilation times significantly. -//! -//! Add the following to your `cargo.toml` file: -//! -//! ```toml -//! [dependencies] -//! secret-toolkit = { version = "0.3.0", features = ["crypto"] } -//! secret-toolkit-crypto = { version = "0.3.0", features = ["hash", "rand", "ecc-secp256k1"] } -//! ``` -//! -//! ## Example usage: -//! -//! ```ignore -//! # extern crate secret_toolkit_crypto; -//! -//! # use secret_toolkit_crypto::{sha_256, Prng, secp256k1::{PrivateKey, PublicKey, Signature}}; -//! # use base64; -//! # use cosmwasm_std::{StdError, testing::mock_dependencies}; -//! -//! # fn main() -> Result<(), StdError> { -//! # let deps = mock_dependencies(20, &[]); -//! let entropy: String = "secret".to_owned(); -//! let prng_seed: Vec = sha_256(base64::encode(&entropy.clone()).as_bytes()).to_vec(); -//! -//! let mut rng = Prng::new(&prng_seed, entropy.as_bytes()); -//! -//! let private_key: PrivateKey = PrivateKey::parse(&rng.rand_bytes())?; -//! let public_key: PublicKey = private_key.pubkey(); -//! -//! let message: &[u8] = b"message"; -//! let signature: Signature = private_key.sign(message, deps.api); -//! # Ok(()) -//! # } -//! ``` -//! -//! ### Cargo Features -//! - `["hash"]` - Provides an easy-to-use `sha256` function. Uses [sha2](https://crates.io/crates/sha2). -//! - `["rand"]` - Used to generate pseudo-random numbers. Uses [rand_chacha] and [rand_core]. -//! - `["ecc-secp256k1"]` - Contains types and methods for working with secp256k1 keys and signatures, -//! as well as standard constants for key sizes. Uses [secp256k1](https://crates.io/crates/secp256k1). +#![doc = include_str!("../Readme.md")] #[cfg(feature = "hash")] mod hash; diff --git a/packages/incubator/Readme.md b/packages/incubator/Readme.md index 54d8eaa..306a068 100644 --- a/packages/incubator/Readme.md +++ b/packages/incubator/Readme.md @@ -7,8 +7,8 @@ This package contains tools that are not yet final and may change or contain unk ## Max heap storage A "max heap store" is a storage wrapper that implements a binary tree maxheap data structure. -https://en.wikipedia.org/wiki/Min-max_heap -Implementation based on https://algorithmtutor.com/Data-Structures/Tree/Binary-Heaps/ + +Implementation based on * Insertion O(log n) * Remove max O(log n) @@ -17,7 +17,7 @@ Implementation based on https://algorithmtutor.com/Data-Structures/Tree/Binary-H The usage of `MaxHeapStoreMut` and `MaxHeapStore` are modeled on `AppendStoreMut` and `AppendStore`, respectively. To add an item to the heap use `insert` and to take the top value off use `remove`, which also returns the item that was removed. To peek at the max value without removing, use the `get_max` function. Duplicate items can be added to the heap. -```rust +```ignore let mut storage = MockStorage::new(); let mut heap_store = MaxHeapStoreMut::attach_or_create(&mut storage)?; heap_store.insert(&1234)?; @@ -35,7 +35,7 @@ assert_eq!(heap_store.remove(), Ok(1234)); In order to use a custom struct with `MaxHeapStore` you will need to implement the appropriate Ordering traits. The following is an example with a custom struct `Tx` that uses the `amount` field to determine order in the heap: -```rust +```ignore #[derive(Serialize, Deserialize, Clone, Debug, Eq)] pub struct Tx { address: HumanAddr, @@ -110,7 +110,7 @@ In effect, this example is a graph structure where the nodes are elements and th See tests in `generational_store.rs` for more examples, including iteration. -```rust +```ignore let mut storage = MockStorage::new(); let mut gen_store = GenerationalStoreMut::attach_or_create(&mut storage)?; let alpha = gen_store.insert(String::from("Alpha")); diff --git a/packages/incubator/src/lib.rs b/packages/incubator/src/lib.rs index a5ad360..f695992 100644 --- a/packages/incubator/src/lib.rs +++ b/packages/incubator/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + #[cfg(feature = "generational-store")] pub mod generational_store; #[cfg(feature = "generational-store")] diff --git a/packages/permit/src/lib.rs b/packages/permit/src/lib.rs index 79a4519..f9eb4e1 100644 --- a/packages/permit/src/lib.rs +++ b/packages/permit/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + pub mod funcs; pub mod state; pub mod structs; diff --git a/packages/serialization/src/lib.rs b/packages/serialization/src/lib.rs index 6147864..9b8c0f5 100644 --- a/packages/serialization/src/lib.rs +++ b/packages/serialization/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + use serde::{de::DeserializeOwned, Serialize}; use cosmwasm_std::StdResult; diff --git a/packages/snip20/Readme.md b/packages/snip20/Readme.md index 0db0b2a..01b6899 100644 --- a/packages/snip20/Readme.md +++ b/packages/snip20/Readme.md @@ -11,7 +11,7 @@ You can create a HandleMsg variant and call the `to_cosmos_msg` function to gene Or you can call the individual function for each Handle message to generate the appropriate callback CosmosMsg. Example: -```rust +```ignore let recipient = HumanAddr("ADDRESS_TO_TRANSFER_TO".to_string()); let amount = Uint128(10000); let padding = None; @@ -41,7 +41,7 @@ You probably have also noticed that CreateViewingKey is not supported. This is ## Queries These are the types that SNIP20 tokens can return from queries -```rust +```ignore pub struct TokenInfo { pub name: String, pub symbol: String, @@ -127,7 +127,7 @@ You can create a QueryMsg variant and call the `query` function to query a SNIP2 Or you can call the individual function for each query. Example: -```rust +```ignore let address = HumanAddr("ADDRESS_WHOSE_BALANCE_IS_BEING_REQUESTED".to_string()); let key = "THE_VIEWING_KEY_PREVIOUSLY_SET_BY_THE_ADDRESS".to_string(); let block_size = 256; @@ -137,4 +137,4 @@ Example: let balance = balance_query(&deps.querier, address, key, block_size, callback_code_hash, contract_addr)?; ``` -In this example, we are doing a Balance query for the specified address/key pair and storing the response in the balance variable, which is of the Balance type defined above. The query message is padded to blocks of 256 bytes. \ No newline at end of file +In this example, we are doing a Balance query for the specified address/key pair and storing the response in the balance variable, which is of the Balance type defined above. The query message is padded to blocks of 256 bytes. diff --git a/packages/snip20/src/lib.rs b/packages/snip20/src/lib.rs index 14aef56..dc6af67 100644 --- a/packages/snip20/src/lib.rs +++ b/packages/snip20/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + pub mod batch; pub mod handle; pub mod query; diff --git a/packages/snip721/Readme.md b/packages/snip721/Readme.md index bb59d87..1316187 100755 --- a/packages/snip721/Readme.md +++ b/packages/snip721/Readme.md @@ -11,7 +11,7 @@ You can create a HandleMsg variant and call the `to_cosmos_msg` function to gene Or you can call the individual function for each Handle message to generate the appropriate callback CosmosMsg. Example: -```rust +```ignore let recipient = HumanAddr("ADDRESS_TO_TRANSFER_TO".to_string()); let token_id = "TOKEN_ID".to_string(); let memo = Some("TRANSFER_MEMO".to_string()); @@ -43,7 +43,7 @@ You probably have also noticed that CreateViewingKey is not supported. This is ## Queries These are the types that the SNIP-721 toolkit queries can return -```rust +```ignore pub struct ContractInfo { pub name: String, pub symbol: String, @@ -166,7 +166,7 @@ You can create a QueryMsg variant and call the `query` function to query a SNIP- Or you can call the individual function for each query. Example: -```rust +```ignore let token_id = "TOKEN_ID".to_string(); let viewer = Some(ViewerInfo { address: HumanAddr("VIEWER'S_ADDRESS".to_string()), @@ -180,4 +180,4 @@ Example: let nft_dossier = nft_dossier_query(&deps.querier, token_id, viewer, include_expired, block_size, callback_code_hash, contract_addr)?; ``` -In this example, we are doing an NftDossier query on the token named "TOKEN_ID", supplying the address and viewing key of the querier, and storing the response in the nft_dossier variable, which is of the NftDossier type defined above. Because no `include_expired` was specified, the response defaults to only displaying approvals that have not expired, but approvals will only be displayed if the viewer is the owner of the token. The query message is padded to blocks of 256 bytes. \ No newline at end of file +In this example, we are doing an NftDossier query on the token named "TOKEN_ID", supplying the address and viewing key of the querier, and storing the response in the nft_dossier variable, which is of the NftDossier type defined above. Because no `include_expired` was specified, the response defaults to only displaying approvals that have not expired, but approvals will only be displayed if the viewer is the owner of the token. The query message is padded to blocks of 256 bytes. diff --git a/packages/snip721/src/lib.rs b/packages/snip721/src/lib.rs index 88c3a12..05531e2 100644 --- a/packages/snip721/src/lib.rs +++ b/packages/snip721/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + //#![allow(clippy::field_reassign_with_default)] pub mod expiration; pub mod handle; diff --git a/packages/snip721/src/metadata.rs b/packages/snip721/src/metadata.rs index 3dc2ce9..6a7d491 100644 --- a/packages/snip721/src/metadata.rs +++ b/packages/snip721/src/metadata.rs @@ -16,7 +16,7 @@ pub struct Metadata { /// metadata extension /// You can add any metadata fields you need here. These fields are based on -/// https://docs.opensea.io/docs/metadata-standards and are the metadata fields that +/// and are the metadata fields that /// Stashh uses for robust NFT display. Urls should be prefixed with `http://`, `https://`, `ipfs://`, or /// `ar://` #[derive(Serialize, Deserialize, JsonSchema, Clone, PartialEq, Debug, Default)] diff --git a/packages/storage/src/lib.rs b/packages/storage/src/lib.rs index 65eed61..ed39852 100644 --- a/packages/storage/src/lib.rs +++ b/packages/storage/src/lib.rs @@ -1,4 +1,5 @@ -#[doc = include_str!("../Readme.md")] +#![doc = include_str!("../Readme.md")] + pub mod append_store; pub mod deque_store; pub mod item; diff --git a/packages/toolkit/src/lib.rs b/packages/toolkit/src/lib.rs index 2612edb..66bf181 100644 --- a/packages/toolkit/src/lib.rs +++ b/packages/toolkit/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + #[cfg(feature = "crypto")] pub use secret_toolkit_crypto as crypto; #[cfg(feature = "incubator")] diff --git a/packages/utils/Readme.md b/packages/utils/Readme.md index 70a069c..92ce050 100644 --- a/packages/utils/Readme.md +++ b/packages/utils/Readme.md @@ -12,14 +12,14 @@ elsewhere. There isn't an overarching theme for the items in this package. ## Calls module This module contains traits used to call another contract. Do not forget to add the `use` statement for the traits you want. -```rust +```ignore use secret_toolkit::utils::{InitCallback, HandleCallback, Query}; ``` Also, don't forget to add the toolkit dependency to your Cargo.toml ### Instantiating another contract -If you want to instantiate another contract, you should first copy/paste the InitMsg of that contract. For example, if you wanted to create an instance of the counter contract at https://github.com/enigmampc/secret-template -```rust +If you want to instantiate another contract, you should first copy/paste the InitMsg of that contract. For example, if you wanted to create an instance of the counter contract at +```ignore #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct CounterInitMsg { pub count: i32, @@ -30,7 +30,7 @@ impl InitCallback for CounterInitMsg { } ``` You would copy/paste its InitMsg, and rename it so that it does not conflict with the InitMsg you have defined for your own contract. Then you would implement the `InitCallback` trait as above, setting the BLOCK_SIZE constant to the size of the blocks you want your instantiation message padded to. -```rust +```ignore let counter_init_msg = CounterInitMsg { count: 100 }; @@ -52,7 +52,7 @@ Next, in the init or handle function that will instantiate the other contract, y ### Calling a handle function of another contract You should first copy/paste the specific HandleMsg(s) you want to call. For example, if you wanted to reset the counter you instantiated above -```rust +```ignore #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub enum CounterHandleMsg { Reset { count: i32 }, @@ -63,7 +63,7 @@ impl HandleCallback for CounterHandleMsg { } ``` You would copy/paste the Reset variant of its HandleMsg enum, and rename the enum so that it does not conflict with the HandleMsg enum you have defined for your own contract. Then you would implement the `HandleCallback` trait as above, setting the BLOCK_SIZE constant to the size of the blocks you want your Reset message padded to. If you need to call multiple different Handle messages, even if they are to different contracts, you can include all the Handle messages as variants in the same enum (you can not have two variants with the same name within the same enum, though). -```rust +```ignore let reset_msg = CounterHandleMsg::Reset { count: 200, }; @@ -84,7 +84,7 @@ Next, in the init or handle function that will call the other contract, you will ### Querying another contract You should first copy/paste the specific QueryMsg(s) you want to call. For example, if you wanted to get the count of the counter you instantiated above -```rust +```ignore #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum CounterQueryMsg { @@ -96,7 +96,7 @@ impl Query for CounterQueryMsg { } ``` You would copy/paste the GetCount variant of its QueryMsg enum, and rename the enum so that it does not conflict with the QueryMsg enum you have defined for your own contract. Then you would implement the `Query` trait as above, setting the BLOCK_SIZE constant to the size of the blocks you want your query message padded to. If you need to perform multiple different queries, even if they are to different contracts, you can include all the Query messages as variants in the same enum (you can not have two variants with the same name within the same enum, though). -```rust +```ignore #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] pub struct CountResponse { pub count: i32, @@ -105,7 +105,7 @@ pub struct CountResponse { Next, you will copy/paste the response of the query. If the other contract defines its response to the query with a struct, you are good to go. If, however, the other contract returns an enum variant, one approach is to copy the fields of the variant and place them in a struct. Because an enum variant gets serialized with the name of the variant, you will then also want to create a wrapper struct whose only field has the name of the variant, and whose type is the struct you defined with the variant's fields. For example, if you wanted to do a token_info query of the [SNIP20 reference implementation](https://github.com/enigmampc/snip20-reference-impl), I would recommend using the SNIP20 toolkit function, but just for the sake of example, let's say you forgot that toolkit existed. -```rust +```ignore #[derive(Serialize, Deserialize, JsonSchema, Debug)] pub struct TokenInfo { pub name: String, @@ -122,7 +122,7 @@ pub struct TokenInfoResponse { You would copy the QueryAnswer::TokenInfo enum variant and create a TokenInfo struct with those fields. You should make all those fields public if you need to access them. Then you would create the TokenInfoResponse wrapper struct, which has only one field whose name is the name of the QueryAnswer variant in snake case (token_info). As a reminder, you only need to do this to properly deserialize the response if it was defined as an enum in the other contract. Now to perform the query -```rust +```ignore let get_count = CounterQueryMsg::GetCount {}; let count_response: CountResponse = get_count.query( &deps.querier, @@ -141,7 +141,7 @@ The feature toggles are designed to be flexible, so you can choose whether to pu ### Initializing Features Normally you'd want to initialize the features in the `init()` function: -```rust +```ignore pub fn init( deps: &mut Extern, env: Env, @@ -166,7 +166,7 @@ pub fn init( The feature field in `FeatureStatus` can be anything, as long as it's implementing `serde::Serialize`. In this example it's: -```rust +```ignore #[derive(Serialize)] pub enum Features { Feature1, @@ -175,7 +175,7 @@ pub enum Features { ``` For the `status` field, you should use the built-in `FeatureToggle::Status` enum: -```rust +```ignore #[derive(Serialize, Debug, Deserialize, Clone, JsonSchema, PartialEq)] pub enum Status { NotPaused, @@ -187,7 +187,7 @@ The defult value of `Status` is `Status::NotPaused`. ### Put a toggle on a message Putting a toggle on a message (or any code section of your choosing) is as easy as calling `FeatureToggle::require_not_paused()`. For example if we have a `Redeem` message in our contract, and we initialized the feature as `Features::Redeem`: -```rust +```ignore fn redeem( deps: &mut Extern, env: Env, @@ -203,7 +203,7 @@ If the status of the `Features::Redeem` feature is `Paused`, the contract will e ### Pause/unpause a feature Firstly, we will need to add `Pause` and `Unpause` messages in our `HandleMsg` enum. We can simply use `FeatureToggle::FeatureToggleHandleMsg` - it's an enum that contains default messages that `FeatureToggle` also has default implementation for: -```rust +```ignore pub enum HandleMsg { // Contract messages Redeem { @@ -217,7 +217,7 @@ pub enum HandleMsg { ``` The `FeatureToggle` struct contains a default implementation for triggering (pausing/unpausing) a feature, so you can just call it from your `handle()` function: -```rust +```ignore pub fn handle( deps: &mut Extern, env: Env, @@ -243,7 +243,7 @@ Similarly to the section above, add `FeatureToggleHandleMsg` to your `HandleMsg` Note: you should only add `Features(FeatureToggleHandleMsg)` to the `HandleMsg` enum once, and it'll add all the supported messages. `FeatureToggle` provides with default implementation for these too, but you can wrap it with your own logic like requiring the caller to be admin, etc.: -```rust +```ignore pub fn handle( deps: &mut Extern, env: Env, @@ -292,7 +292,7 @@ Note: `set_pauser` and `remove_pauser` are permissionless by default. ### Overriding the default implementation If you don't like the default implementation or want to override it for any other reason (for example, using a different storage namespace), you can do that by defining your own struct and implement `FeatureToggleTrait` for it: -```rust +```ignore struct TrollFeatureToggle {} impl FeatureToggleTrait for TrollFeatureToggle { @@ -322,7 +322,7 @@ impl FeatureToggleTrait for TrollFeatureToggle { ### Queries Similarly to `FeatureToggleHandleMsg`, query messages (and default implementations) are also provided: -```rust +```ignore #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum FeatureToggleQueryMsg { diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index ca35f58..ec584aa 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + pub mod calls; pub mod feature_toggle; pub mod padding; diff --git a/packages/viewing_key/src/lib.rs b/packages/viewing_key/src/lib.rs index f5119b0..5c05009 100644 --- a/packages/viewing_key/src/lib.rs +++ b/packages/viewing_key/src/lib.rs @@ -1,3 +1,5 @@ +#![doc = include_str!("../Readme.md")] + extern crate core; use subtle::ConstantTimeEq;