From ee9e03fbc565bec36f56ac811e65a851d4bf453b Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:07:39 -0700 Subject: [PATCH] Add auth sdk page (#108) * noop * noop * Update sdk and cli versions and output (#87) * Update code samples in quickstart (#88) * empty * Update the tutorial for creating a project (#89) * Update the tutorial for writing a contract (#90) * Update the tutorial for testing (#91) * Update the hello_world contract (#92) * Small fix to hello contract * Update the increment contract (#93) * Small fix to increment example * Update the custom_types contract (#94) * Add auth example and update auth learn page (#95) * Put auth example earlier in list of examples (#98) (cherry picked from commit fc2fc75d34aad6eecae9d5f8de10f16268edd7c2) * Add events example (#100) * Update the cross_contract contract (#99) * Small tweak to contract call doc * Fix to contract call code sample * Fix to contract call code sample * noop to try and make it deploy properly * Reorder examples so that contract events appears higher in list * Fix headings of cross contract example (#102) * Add soroban-cli read example * Tweak language about developer discord * Some changes to the events example page (#101) * Rename standard-contracts and update token-contract (#103) * Rename Standard Contracts to Built-In Contracts * Update built-in-contracts/token-contract and examples/authorization * Fix title capitalization of built-in contracts page (#104) * Add stub for token example (#105) * Update authorization docs to line up with contract examples (#106) * Small fixes for token contract doc * Make authorization docs line up with the example * Instruct users to checkout v0.0.4 tag for examples (#107) * fix pages and sdk instructions * Add auth sdk page Co-authored-by: Tyler van der Hoeven Co-authored-by: Siddharth Suresh Co-authored-by: Jay Geng Co-authored-by: jonjove <31668823+jonjove@users.noreply.github.com> --- docs/getting-started/quick-start.mdx | 49 ++++++++++++++-------------- docs/getting-started/setup.mdx | 18 ++++++---- docs/tutorials/create-a-project.mdx | 48 ++++++++++++--------------- docs/tutorials/testing.mdx | 47 +++++++++++++++++--------- docs/tutorials/write-a-contract.mdx | 18 ++++------ 5 files changed, 97 insertions(+), 83 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 5bf6d1535..3e6e1acd7 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -39,15 +39,13 @@ The `soroban-sdk` is in early development. Report issues crate-type = ["cdylib", "rlib"] [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -first-project = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -60,17 +58,17 @@ codegen-units = 1 lto = true ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -81,33 +79,33 @@ Open the `src/lib.rs` file, and copy-paste the following code. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } #[cfg(test)] mod test { - use super::{Contract, hello}; - use soroban_sdk::{vec, Env, FixedBinary, Symbol}; + use super::{Contract, ContractClient}; + use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } } @@ -166,3 +164,6 @@ You should see the following output: ``` [`soroban-cli`]: setup#install-the-soroban-cli + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index d5b0eaf48..4070513b0 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -44,7 +44,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.0.2 soroban-cli +cargo install --locked --version 0.0.4 soroban-cli ``` :::caution @@ -61,7 +61,9 @@ soroban-cli ``` ``` -soroban-cli 0.0.2 +❯ soroban-cli +soroban-cli 0.0.4 +https://soroban.stellar.org USAGE: soroban-cli @@ -70,10 +72,14 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - deploy Deploy a WASM file as a contract - version Print version information + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + read Print the current value of a contract-data ledger entry + serve Run a local webserver for web app development and testing + deploy Deploy a WASM file as a contract + gen Generate code client bindings for a contract + version Print version information + completion Print shell completion code for the specified shell ``` diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index a1bc76b16..27e2eb889 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,28 +44,26 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: ## Configure the `release` Profile @@ -92,24 +90,17 @@ lto = true The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" -[package] -name = "project-name" -version = "0.1.0" -edition = "2021" - [lib] crate-type = ["cdylib", "rlib"] +[features] +testutils = ["soroban-sdk/testutils"] + [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } - -[features] -default = ["export"] -export = [] -testutils = ["soroban-sdk/testutils"] +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -121,3 +112,6 @@ panic = "abort" codegen-units = 1 lto = true ``` + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index cafdc2622..5653bc0d2 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -17,15 +17,14 @@ Contract](write-a-contract.mdx), a simple test will look like this. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ``` @@ -36,26 +35,38 @@ impl Contract { ```rust #![cfg(test)] -use super::{Contract, hello}; -use soroban_sdk::{vec, Env, FixedBinary}; +use super::{Contract, ContractClient}; +use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } ``` + +:::info +The above example is a [Rust unit test] that lives inside the `src/` directory. +Note that if you place the test in the `tests/` directory it becomes a [Rust +integration test] with the test being compiled separately. Integration tests +require `#![cfg(feature = "testutils")]` at the top of the file and to be run +with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to +enable the generated Soroban test utilities. +::: + + In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. @@ -69,23 +80,26 @@ if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. ```rust -let contract_id = FixedBinary::from_array(&env, [0; 32]); -env.register_contract(&contract_id, HelloContract); +let contract_id = BytesN::from_array(&env, &[0; 32]); +env.register_contract(&contract_id, Contract); ``` All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have an `invoke` function generated, that can be -used to invoke the contract function within the environment. +`#[contractimpl]` attribute have a corresponding function generated in a +generated client type. The client type will be named the same as the contract +type with `Client` appended. For example, in our contract the contract type is +`Contract`, and the client is named `ContractClient`. ```rust -let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); +let client = ContractClient::new(&env, &contract_id); +let words = client.hello(&symbol!("Dev")); ``` The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); ``` @@ -103,3 +117,6 @@ test test::test ... ok ``` Try changing the values in the test to see how it works. + +[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 3165ebbd8..b617e3a62 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -16,7 +16,7 @@ well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the @@ -26,13 +26,13 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Binary`, `FixedBinary`, that all utilize the Soroban environment's -memory and native capabilities. +`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban +environment's memory and native capabilities. ```rust pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { todo!() @@ -46,22 +46,18 @@ externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. -Implementations annotated can be configured to export the contract functions -only if a feature is enabled, with `export_if = "[feature-name]"`. - Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ```