From c9d7381f8fa694810bb418ce78a4fb200f25f7a0 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 5 Jul 2024 00:19:21 +0200 Subject: [PATCH 01/11] Move SAC example section from tokens to guide --- .../conventions/stellar-asset-contract.mdx | 60 +++++++++++++++++++ docs/tokens/stellar-asset-contract.mdx | 56 ----------------- 2 files changed, 60 insertions(+), 56 deletions(-) create mode 100644 docs/build/guides/conventions/stellar-asset-contract.mdx diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx new file mode 100644 index 000000000..e8240f505 --- /dev/null +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -0,0 +1,60 @@ +--- +title: Integrate Stellar Assets Contracts +description: Test and use Stellar assets in a Soroban smart contract +--- + +From the contract perspective Stellar Asset Contract is not different from any other token that implements the Soroban token interface. The Rust SDK contains a pregenerated client for any contract that implements the token interface: + +```rust +use soroban_sdk::token; + +struct MyContract; + +#[contractimpl] +impl MyContract { + fn token_fn(e: Env, id: Address) { + // Create a client instance for the provided token identifier. If the id + // value corresponds to an SAC contract, then SAC implementation is used. + let client = token::Client::new(&env, &id); + // Call token operations part of the SEP-41 token interface + client.transfer(...); + } +} +``` + +:::info Clients + +A client created by [`token::Client`] implements the functions defined by any contract that implements the [SEP-41 Token Interface]. But the Stellar Asset Contract exposes additional functions such as `mint`. To access the additional functions, another client needs to be used: [`token::StellarAssetClient`]. This client only implements the functions which are not part of the SEP-41. + +```rust +let client = token::StellarAssetClient::new(&env, &id); +// Call token operations which are not part of the SEP-41 token interface +// but part of the CAP-46-6 Smart Contract Standardized Asset +client.mint(...); +``` + +::: + +### Examples + +See the full examples that utilize the token contract in various ways for more details: + +- [Timelock](../../smart-contracts/example-contracts/timelock.mdx) and [single offer](../../smart-contracts/example-contracts/single-offer-sale.mdx) move token via `xfer` to and from the contract +- [Atomic swap](../../smart-contracts/example-contracts/atomic-swap.mdx) uses `incr_allow` to transfer token on behalf of the user + +Notice, that these examples don't do anything to support SAC specifically. + +### Testing + +Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract`. For example: + +```rust +let admin = Address::random(); +let user = Address::random(); +let token = StellarAssetClient::new(e, &e.register_stellar_asset_contract(admin.clone())); +token.mint(&admin, &user, &1000); +``` + +See the tests in the [examples](#examples) above for the full test implementation. + +[sep-41 token interface]: ../../../tokens/token-interface.mdx diff --git a/docs/tokens/stellar-asset-contract.mdx b/docs/tokens/stellar-asset-contract.mdx index 2429cf2f6..37097b39f 100644 --- a/docs/tokens/stellar-asset-contract.mdx +++ b/docs/tokens/stellar-asset-contract.mdx @@ -103,62 +103,6 @@ Unprivileged mutators require authorization from the `Address` that spends or al Priviliged mutators require authorization from a specific privileged identity, known as the "administrator". For example, only the administrator can `mint` more of the token. Similarly, only the administrator can appoint a new administrator. -## Using Stellar Asset Contract with other contracts - -From the contract perspective Stellar Asset Contract is not different from any other token that implements the Soroban token interface. The Rust SDK contains a pregenerated client for any contract that implements the token interface: - -```rust -use soroban_sdk::token; - -struct MyContract; - -#[contractimpl] -impl MyContract { - fn token_fn(e: Env, id: Address) { - // Create a client instance for the provided token identifier. If the id - // value corresponds to an SAC contract, then SAC implementation is used. - let client = token::Client::new(&env, &id); - // Call token operations part of the SEP-41 token interface - client.transfer(...); - } -} -``` - -:::info Clients - -A client created by [`token::Client`] implements the functions defined by any contract that implements the [SEP-41 Token Interface]. But the Stellar Asset Contract exposes additional functions such as `mint`. To access the additional functions, another client needs to be used: [`token::StellarAssetClient`]. This client only implements the functions which are not part of the SEP-41. - -```rust -let client = token::StellarAssetClient::new(&env, &id); -// Call token operations which are not part of the SEP-41 token interface -// but part of the CAP-46-6 Smart Contract Standardized Asset -client.mint(...); -``` - -::: - -### Examples - -See the full examples that utilize the token contract in various ways for more details: - -- [Timelock](../build/smart-contracts/example-contracts/timelock.mdx) and [single offer](../build/smart-contracts/example-contracts/single-offer-sale.mdx) move token via `xfer` to and from the contract -- [Atomic swap](../build/smart-contracts/example-contracts/atomic-swap.mdx) uses `incr_allow` to transfer token on behalf of the user - -Notice, that these examples don't do anything to support SAC specifically. - -### Testing - -Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract`. For example: - -```rust -let admin = Address::random(); -let user = Address::random(); -let token = StellarAssetClient::new(e, &e.register_stellar_asset_contract(admin.clone())); -token.mint(&admin, &user, &1000); -``` - -See the tests in the [examples](#examples) above for the full test implementation. - ## Contract Interface This interface can be found in the [SDK]. It extends the common [SEP-41 Token Interface]. From 17447fa1328da5537c84ebb84cf7520c759a5199 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 5 Jul 2024 01:40:59 +0200 Subject: [PATCH 02/11] Expand example with balance check --- .../conventions/stellar-asset-contract.mdx | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx index e8240f505..e3dfdfa0e 100644 --- a/docs/build/guides/conventions/stellar-asset-contract.mdx +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -3,7 +3,7 @@ title: Integrate Stellar Assets Contracts description: Test and use Stellar assets in a Soroban smart contract --- -From the contract perspective Stellar Asset Contract is not different from any other token that implements the Soroban token interface. The Rust SDK contains a pregenerated client for any contract that implements the token interface: +From the contract perspective Stellar Asset Contract is not different from any other token that implements the Soroban [SEP-41 Token Interface]. The Rust SDK contains a pregenerated client for any contract that implements the token interface: ```rust use soroban_sdk::token; @@ -15,7 +15,7 @@ impl MyContract { fn token_fn(e: Env, id: Address) { // Create a client instance for the provided token identifier. If the id // value corresponds to an SAC contract, then SAC implementation is used. - let client = token::Client::new(&env, &id); + let client = token::TokenClient::new(&env, &id); // Call token operations part of the SEP-41 token interface client.transfer(...); } @@ -35,26 +35,46 @@ client.mint(...); ::: -### Examples +### Testing -See the full examples that utilize the token contract in various ways for more details: +Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract`. This function can be seen as the deployment of a generic token. In the following example, we are following the best practices outlined in the [Issuing and Distribution Accounts section](../../../tokens/control-asset-access.mdx#issuing-and-distribution-accounts): -- [Timelock](../../smart-contracts/example-contracts/timelock.mdx) and [single offer](../../smart-contracts/example-contracts/single-offer-sale.mdx) move token via `xfer` to and from the contract -- [Atomic swap](../../smart-contracts/example-contracts/atomic-swap.mdx) uses `incr_allow` to transfer token on behalf of the user +```rust +#![cfg(test)] -Notice, that these examples don't do anything to support SAC specifically. +use soroban_sdk::testutils::Address as _; +use soroban_sdk::{token, Address, Env}; +use token::TokenClient; +use token::StellarAssetClient; -### Testing +#[test] +fn test() { + let e = Env::default(); + e.mock_all_auths(); -Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract`. For example: + let issuer = Address::random(); + let distributer = Address::random(); -```rust -let admin = Address::random(); -let user = Address::random(); -let token = StellarAssetClient::new(e, &e.register_stellar_asset_contract(admin.clone())); -token.mint(&admin, &user, &1000); + let token_address = e.register_stellar_asset_contract(issuer.clone()); + + // client for SEP-41 operations + let token = TokenClient::new(&e, &token_address); + // client for Stellar Asset Contract operations + let token_sac = StellarAssetClient::new(&e, &token_address); + + // 1e7 diff between minimal unit and unit itself + let genesis_amount: i128 = 1_000_000_000 * 10_000_000; + + token_sac.mint(&issuer, &distributer, &genesis_amount); + + assert_eq!(token.balance(&distributor), genesis_amount); ``` -See the tests in the [examples](#examples) above for the full test implementation. +### Examples + +See the full examples that utilize the token contract in various ways for more details: + +- [Timelock](../../smart-contracts/example-contracts/timelock.mdx) and [single offer](../../smart-contracts/example-contracts/single-offer-sale.mdx) move token via `xfer` to and from the contract +- [Atomic swap](../../smart-contracts/example-contracts/atomic-swap.mdx) uses `incr_allow` to transfer token on behalf of the user [sep-41 token interface]: ../../../tokens/token-interface.mdx From 8c507cac771893765c59d2512dfd0cb652d7c06b Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 5 Jul 2024 01:41:13 +0200 Subject: [PATCH 03/11] Remove native token page --- docs/build/guides/testing/mint-native-token.mdx | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 docs/build/guides/testing/mint-native-token.mdx diff --git a/docs/build/guides/testing/mint-native-token.mdx b/docs/build/guides/testing/mint-native-token.mdx deleted file mode 100644 index fd404a0bb..000000000 --- a/docs/build/guides/testing/mint-native-token.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Mint native XLM in a contract test -hide_table_of_contents: true -draft: true ---- - -It can often be necessary to test whether your contract's interactions surrounding tokens work as intended. Often, the token you test again can be created from arbitrary details. However, there are occassions where testing against a specific token can be advantageous. Here is a test function that makes use of the Stellar Asset Contract for the native XLM token. - -```rust -env.token.native_asset_contract(); // or some such... -``` From c28f6fe5b541e5522e800bfc6c23a12feb29ca2f Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 5 Jul 2024 01:56:01 +0200 Subject: [PATCH 04/11] Link to CAP --- docs/build/guides/conventions/stellar-asset-contract.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx index e3dfdfa0e..90734bba2 100644 --- a/docs/build/guides/conventions/stellar-asset-contract.mdx +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -24,7 +24,7 @@ impl MyContract { :::info Clients -A client created by [`token::Client`] implements the functions defined by any contract that implements the [SEP-41 Token Interface]. But the Stellar Asset Contract exposes additional functions such as `mint`. To access the additional functions, another client needs to be used: [`token::StellarAssetClient`]. This client only implements the functions which are not part of the SEP-41. +A client created by [`token::Client`] implements the functions defined by any contract that implements the [SEP-41 Token Interface]. But with [CAP-46-6 smart contract standardized asset], the Stellar Asset Contract exposes additional functions such as `mint`. To access the additional functions, another client needs to be used: [`token::StellarAssetClient`]. This client only implements the functions from CAP-46-6, which are not part of the SEP-41. ```rust let client = token::StellarAssetClient::new(&env, &id); @@ -78,3 +78,4 @@ See the full examples that utilize the token contract in various ways for more d - [Atomic swap](../../smart-contracts/example-contracts/atomic-swap.mdx) uses `incr_allow` to transfer token on behalf of the user [sep-41 token interface]: ../../../tokens/token-interface.mdx +[cap-46-6 smart contract standardized asset]: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-06.md From 1c6997f43b63103ea586f4c74b85f71e0148b192 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 12 Jul 2024 19:24:51 +0200 Subject: [PATCH 05/11] Fix links --- .../guides/conventions/stellar-asset-contract.mdx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx index 90734bba2..3f0803e6c 100644 --- a/docs/build/guides/conventions/stellar-asset-contract.mdx +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -22,6 +22,19 @@ impl MyContract { } ``` +The address parameter is not the address of the issuer of an asset, it corresponds to the deployed contract address for this asset. + +```bash +stellar contract id asset \ + --source G... \ + --network testnet \ + --asset [asset:issuer] +``` + +E.g. for USDC, it would be `--asset USDC:G...` For the native asset, XLM, `--asset native`. See the [deploy SAC] guide for more details. + +[deploy SAC]: ../cli/deploy-stellar-asset-contract.mdx + :::info Clients A client created by [`token::Client`] implements the functions defined by any contract that implements the [SEP-41 Token Interface]. But with [CAP-46-6 smart contract standardized asset], the Stellar Asset Contract exposes additional functions such as `mint`. To access the additional functions, another client needs to be used: [`token::StellarAssetClient`]. This client only implements the functions from CAP-46-6, which are not part of the SEP-41. From 6b7ca7c9794b489d904c82b28efc53f258587894 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Fri, 12 Jul 2024 19:25:10 +0200 Subject: [PATCH 06/11] Add info about address --- docs/tokens/stellar-asset-contract.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tokens/stellar-asset-contract.mdx b/docs/tokens/stellar-asset-contract.mdx index 37097b39f..e80b4f033 100644 --- a/docs/tokens/stellar-asset-contract.mdx +++ b/docs/tokens/stellar-asset-contract.mdx @@ -52,12 +52,12 @@ Every Stellar asset on Stellar has reserved a contract address that the Stellar It can be deployed using the [Stellar CLI] as shown [here](../build/guides/cli/deploy-stellar-asset-contract.mdx). -Or the [Stellar SDK] can be used as shown [here](../learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx#xdr-usage) by calling `InvokeHostFunctionOp` with `HOST_FUNCTION_TYPE_CREATE_CONTRACT` and `CONTRACT_ID_FROM_ASSET`. The resulting token will have a deterministic identifier, which will be the sha256 hash of `HashIDPreimage::ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET` xdr specified [here][contract_id]. +Or the [Stellar CLI] can be used as shown [here](../learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx#xdr-usage) by calling `InvokeHostFunctionOp` with `HOST_FUNCTION_TYPE_CREATE_CONTRACT` and `CONTRACT_ID_FROM_ASSET`. The resulting token will have a deterministic identifier, which will be the sha256 hash of `HashIDPreimage::ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET` xdr specified [here][contract_id]. Anyone can deploy the instances of Stellar Asset Contract. Note, that the initialization of the Stellar Asset Contracts happens automatically during the deployment. Asset Issuer will have the administrative permissions after the contract has been deployed. [contract_id]: https://github.com/stellar/stellar-xdr/blob/dc23adf60e095a6ce626b2b09128e58a5eae0cd0/Stellar-transaction.x#L661 -[stellar-cli]: ../tools/developer-tools.mdx#cli +[stellar cli]: ../tools/developer-tools.mdx#cli ## Interacting with classic Stellar assets From 1a28cc1c814b046200cb91a7afd3922a48ae6b2e Mon Sep 17 00:00:00 2001 From: Pamphile Roy <23188539+tupui@users.noreply.github.com> Date: Mon, 22 Jul 2024 22:46:09 +0200 Subject: [PATCH 07/11] Apply suggestions from code review Co-authored-by: Elliot Voris --- .../guides/conventions/stellar-asset-contract.mdx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx index 3f0803e6c..13119cf06 100644 --- a/docs/build/guides/conventions/stellar-asset-contract.mdx +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -3,11 +3,12 @@ title: Integrate Stellar Assets Contracts description: Test and use Stellar assets in a Soroban smart contract --- -From the contract perspective Stellar Asset Contract is not different from any other token that implements the Soroban [SEP-41 Token Interface]. The Rust SDK contains a pregenerated client for any contract that implements the token interface: +When interacting with assets in a smart contract, the Stellar Asset Contract is not different from any other token that implements the Stellar [SEP-41 Token Interface]. The Rust SDK contains a pre-generated client for any contract that implements the token interface: ```rust use soroban_sdk::token; +#[contract] struct MyContract; #[contractimpl] @@ -22,7 +23,7 @@ impl MyContract { } ``` -The address parameter is not the address of the issuer of an asset, it corresponds to the deployed contract address for this asset. +The `asset` parameter is not the address of the issuer of an asset, it corresponds to the deployed contract address for this asset. ```bash stellar contract id asset \ @@ -35,9 +36,9 @@ E.g. for USDC, it would be `--asset USDC:G...` For the native asset, XLM, `--ass [deploy SAC]: ../cli/deploy-stellar-asset-contract.mdx -:::info Clients +:::info[Clients] -A client created by [`token::Client`] implements the functions defined by any contract that implements the [SEP-41 Token Interface]. But with [CAP-46-6 smart contract standardized asset], the Stellar Asset Contract exposes additional functions such as `mint`. To access the additional functions, another client needs to be used: [`token::StellarAssetClient`]. This client only implements the functions from CAP-46-6, which are not part of the SEP-41. +A client created by [`token::TokenClient`] implements the functions defined by any contract that implements the [SEP-41 Token Interface]. But with [CAP-46-6 smart contract standardized asset], the Stellar Asset Contract exposes additional functions such as `mint`. To access the additional functions, another client needs to be used: [`token::StellarAssetClient`]. This client only implements the functions from CAP-46-6, which are not part of the SEP-41 interface. ```rust let client = token::StellarAssetClient::new(&env, &id); @@ -87,7 +88,7 @@ fn test() { See the full examples that utilize the token contract in various ways for more details: -- [Timelock](../../smart-contracts/example-contracts/timelock.mdx) and [single offer](../../smart-contracts/example-contracts/single-offer-sale.mdx) move token via `xfer` to and from the contract +- [Timelock](../../smart-contracts/example-contracts/timelock.mdx) and [single offer](../../smart-contracts/example-contracts/single-offer-sale.mdx) move token via `transfer` to and from the contract - [Atomic swap](../../smart-contracts/example-contracts/atomic-swap.mdx) uses `incr_allow` to transfer token on behalf of the user [sep-41 token interface]: ../../../tokens/token-interface.mdx From b360ab149832c870bd3c822569d802d1b0c29635 Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Mon, 22 Jul 2024 23:13:00 +0200 Subject: [PATCH 08/11] Address comments from review --- .../path-payment.mdx | 48 +++++++++---------- .../conventions/stellar-asset-contract.mdx | 29 ++++++----- .../example-contracts/atomic-swap.mdx | 2 +- docs/tokens/stellar-asset-contract.mdx | 3 +- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/docs/build/apps/example-application-tutorial/path-payment.mdx b/docs/build/apps/example-application-tutorial/path-payment.mdx index 1a3f166fd..a65f4bb57 100644 --- a/docs/build/apps/example-application-tutorial/path-payment.mdx +++ b/docs/build/apps/example-application-tutorial/path-payment.mdx @@ -119,30 +119,30 @@ Most of this page has been discussed in the [Payment section](./payment.mdx#the- /* ... */ }) : // highlight-start - pathPayment && strictReceive - ? await createPathPaymentStrictReceiveTransaction({ - source: data.publicKey, - sourceAsset: sendAsset, - sourceAmount: sendAmount, - destination: otherDestination ? otherPublicKey : destination, - destinationAsset: receiveAsset, - destinationAmount: receiveAmount, - memo: memo, - }) - : pathPayment && !strictReceive - ? await createPathPaymentStrictSendTransaction({ - source: data.publicKey, - sourceAsset: sendAsset, - sourceAmount: sendAmount, - destination: otherDestination ? otherPublicKey : destination, - destinationAsset: receiveAsset, - destinationAmount: receiveAmount, - memo: memo, - }) - : // highlight-end - await createPaymentTransaction({ - /* ... */ - }); + pathPayment && strictReceive + ? await createPathPaymentStrictReceiveTransaction({ + source: data.publicKey, + sourceAsset: sendAsset, + sourceAmount: sendAmount, + destination: otherDestination ? otherPublicKey : destination, + destinationAsset: receiveAsset, + destinationAmount: receiveAmount, + memo: memo, + }) + : pathPayment && !strictReceive + ? await createPathPaymentStrictSendTransaction({ + source: data.publicKey, + sourceAsset: sendAsset, + sourceAmount: sendAmount, + destination: otherDestination ? otherPublicKey : destination, + destinationAsset: receiveAsset, + destinationAmount: receiveAmount, + memo: memo, + }) + : // highlight-end + await createPaymentTransaction({ + /* ... */ + }); /* ... */ }; diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx index 13119cf06..938761275 100644 --- a/docs/build/guides/conventions/stellar-asset-contract.mdx +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -6,20 +6,21 @@ description: Test and use Stellar assets in a Soroban smart contract When interacting with assets in a smart contract, the Stellar Asset Contract is not different from any other token that implements the Stellar [SEP-41 Token Interface]. The Rust SDK contains a pre-generated client for any contract that implements the token interface: ```rust +use soroban_sdk::{contract, contractimpl} use soroban_sdk::token; #[contract] -struct MyContract; +pub struct MyContract; #[contractimpl] impl MyContract { - fn token_fn(e: Env, id: Address) { - // Create a client instance for the provided token identifier. If the id - // value corresponds to an SAC contract, then SAC implementation is used. - let client = token::TokenClient::new(&env, &id); - // Call token operations part of the SEP-41 token interface - client.transfer(...); - } + pub fn token_fn(e: Env, id: Address) { + // Create a client instance for the provided token identifier. If the id + // value corresponds to an SAC contract, then SAC implementation is used. + let client = token::TokenClient::new(&env, &id); + // Call token functions part of the Stellar SEP-41 token interface + client.transfer(...); + } } ``` @@ -42,7 +43,7 @@ A client created by [`token::TokenClient`] implements the functions defined by a ```rust let client = token::StellarAssetClient::new(&env, &id); -// Call token operations which are not part of the SEP-41 token interface +// Call token functions which are not part of the SEP-41 token interface // but part of the CAP-46-6 Smart Contract Standardized Asset client.mint(...); ``` @@ -71,12 +72,14 @@ fn test() { let token_address = e.register_stellar_asset_contract(issuer.clone()); - // client for SEP-41 operations + // client for SEP-41 functions let token = TokenClient::new(&e, &token_address); - // client for Stellar Asset Contract operations + // client for Stellar Asset Contract functions let token_sac = StellarAssetClient::new(&e, &token_address); - // 1e7 diff between minimal unit and unit itself + // note that you need to account for the difference between the minimal + // unit and the unit itself when working with amounts. + // E.g. to mint 1 TOKEN, we need to use 1*1e7 in the mint function. let genesis_amount: i128 = 1_000_000_000 * 10_000_000; token_sac.mint(&issuer, &distributer, &genesis_amount); @@ -89,7 +92,7 @@ fn test() { See the full examples that utilize the token contract in various ways for more details: - [Timelock](../../smart-contracts/example-contracts/timelock.mdx) and [single offer](../../smart-contracts/example-contracts/single-offer-sale.mdx) move token via `transfer` to and from the contract -- [Atomic swap](../../smart-contracts/example-contracts/atomic-swap.mdx) uses `incr_allow` to transfer token on behalf of the user +- [Atomic swap](../../smart-contracts/example-contracts/atomic-swap.mdx) uses `transfer` to transfer token on behalf of the user [sep-41 token interface]: ../../../tokens/token-interface.mdx [cap-46-6 smart contract standardized asset]: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-06.md diff --git a/docs/build/smart-contracts/example-contracts/atomic-swap.mdx b/docs/build/smart-contracts/example-contracts/atomic-swap.mdx index e50bf474a..db5b87f21 100644 --- a/docs/build/smart-contracts/example-contracts/atomic-swap.mdx +++ b/docs/build/smart-contracts/example-contracts/atomic-swap.mdx @@ -180,7 +180,7 @@ fn move_token( } ``` -The swap itself is implemented via two token moves: from `a` to `b` and from `b` to `a`. The token move is implemented via allowance: the users don't need to know each other in order to perform the swap, and instead they authorize the swap contract to spend the necessary amount of token on their behalf via `incr_allow`. Soroban auth framework makes sure that the `incr_allow` signatures would have the proper context, and they won't be usable outside the `swap` contract invocation. +The swap itself is implemented via two token moves: from `a` to `b` and from `b` to `a`. The token move is implemented via allowance: the users don't need to know each other in order to perform the swap, and instead they authorize the swap contract to spend the necessary amount of token on their behalf via `transfer`. Soroban auth framework makes sure that the `transfer` signatures would have the proper context, and they won't be usable outside the `swap` contract invocation. ### Tests diff --git a/docs/tokens/stellar-asset-contract.mdx b/docs/tokens/stellar-asset-contract.mdx index 14b5aa2c8..cc33ef1fc 100644 --- a/docs/tokens/stellar-asset-contract.mdx +++ b/docs/tokens/stellar-asset-contract.mdx @@ -52,12 +52,13 @@ Every Stellar asset on Stellar has reserved a contract address that the Stellar It can be deployed using the [Stellar CLI] as shown [here](../build/guides/cli/deploy-stellar-asset-contract.mdx). -Or the [Stellar CLI] can be used as shown [here](../learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx#xdr-usage) by calling `InvokeHostFunctionOp` with `HOST_FUNCTION_TYPE_CREATE_CONTRACT` and `CONTRACT_ID_FROM_ASSET`. The resulting token will have a deterministic identifier, which will be the sha256 hash of `HashIDPreimage::ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET` xdr specified [here][contract_id]. +Or the [Stellar SDK] can be used as shown [here](../learn/encyclopedia/contract-development/contract-interactions/stellar-transaction.mdx#xdr-usage) by calling `InvokeHostFunctionOp` with `HOST_FUNCTION_TYPE_CREATE_CONTRACT` and `CONTRACT_ID_FROM_ASSET`. The resulting token will have a deterministic identifier, which will be the sha256 hash of `HashIDPreimage::ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET` xdr specified [here][contract_id]. Anyone can deploy the instances of Stellar Asset Contract. Note, that the initialization of the Stellar Asset Contracts happens automatically during the deployment. Asset Issuer will have the administrative permissions after the contract has been deployed. [contract_id]: https://github.com/stellar/stellar-xdr/blob/dc23adf60e095a6ce626b2b09128e58a5eae0cd0/Stellar-transaction.x#L661 [stellar cli]: ../tools/developer-tools/README.mdx#cli +[stellar sdk]: ../tools/sdks/library.mdx ## Interacting with classic Stellar assets From 88b6c18cab0cdcaa3bdbd7d987dd08a7c640475b Mon Sep 17 00:00:00 2001 From: Tupui <23188539+tupui@users.noreply.github.com> Date: Mon, 22 Jul 2024 23:17:48 +0200 Subject: [PATCH 09/11] Revert path-payment change --- .../path-payment.mdx | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/build/apps/example-application-tutorial/path-payment.mdx b/docs/build/apps/example-application-tutorial/path-payment.mdx index a65f4bb57..1a3f166fd 100644 --- a/docs/build/apps/example-application-tutorial/path-payment.mdx +++ b/docs/build/apps/example-application-tutorial/path-payment.mdx @@ -119,30 +119,30 @@ Most of this page has been discussed in the [Payment section](./payment.mdx#the- /* ... */ }) : // highlight-start - pathPayment && strictReceive - ? await createPathPaymentStrictReceiveTransaction({ - source: data.publicKey, - sourceAsset: sendAsset, - sourceAmount: sendAmount, - destination: otherDestination ? otherPublicKey : destination, - destinationAsset: receiveAsset, - destinationAmount: receiveAmount, - memo: memo, - }) - : pathPayment && !strictReceive - ? await createPathPaymentStrictSendTransaction({ - source: data.publicKey, - sourceAsset: sendAsset, - sourceAmount: sendAmount, - destination: otherDestination ? otherPublicKey : destination, - destinationAsset: receiveAsset, - destinationAmount: receiveAmount, - memo: memo, - }) - : // highlight-end - await createPaymentTransaction({ - /* ... */ - }); + pathPayment && strictReceive + ? await createPathPaymentStrictReceiveTransaction({ + source: data.publicKey, + sourceAsset: sendAsset, + sourceAmount: sendAmount, + destination: otherDestination ? otherPublicKey : destination, + destinationAsset: receiveAsset, + destinationAmount: receiveAmount, + memo: memo, + }) + : pathPayment && !strictReceive + ? await createPathPaymentStrictSendTransaction({ + source: data.publicKey, + sourceAsset: sendAsset, + sourceAmount: sendAmount, + destination: otherDestination ? otherPublicKey : destination, + destinationAsset: receiveAsset, + destinationAmount: receiveAmount, + memo: memo, + }) + : // highlight-end + await createPaymentTransaction({ + /* ... */ + }); /* ... */ }; From 7c2afad118555e6ea9ec2e3b039962a26abe6c67 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 24 Jul 2024 09:34:33 -0500 Subject: [PATCH 10/11] move link definitions from tokens page to this guide --- docs/build/guides/conventions/stellar-asset-contract.mdx | 2 ++ docs/tokens/stellar-asset-contract.mdx | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx index 938761275..bc48fc620 100644 --- a/docs/build/guides/conventions/stellar-asset-contract.mdx +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -96,3 +96,5 @@ See the full examples that utilize the token contract in various ways for more d [sep-41 token interface]: ../../../tokens/token-interface.mdx [cap-46-6 smart contract standardized asset]: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-06.md +[`token::tokenclient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.TokenClient.html +[`token::stellarassetclient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.StellarAssetClient.html diff --git a/docs/tokens/stellar-asset-contract.mdx b/docs/tokens/stellar-asset-contract.mdx index cc33ef1fc..068f47379 100644 --- a/docs/tokens/stellar-asset-contract.mdx +++ b/docs/tokens/stellar-asset-contract.mdx @@ -112,6 +112,3 @@ This interface can be found in the [SDK]. It extends the common [SEP-41 Token In [sdk]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/index.html [cap-46-6 smart contract standardized asset]: https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-06.md [sep-41 token interface]: ./token-interface.mdx -[`soroban_sdk::token`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/ -[`token::tokenclient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.TokenClient.html -[`token::stellarassetclient`]: https://docs.rs/soroban-sdk/latest/soroban_sdk/token/struct.StellarAssetClient.html From 9e017f4cfe8d38a21c04b4237babaaa0c73d8891 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Wed, 24 Jul 2024 09:35:51 -0500 Subject: [PATCH 11/11] nitpick some headings, add a closing curly bracket in an code block --- .../guides/conventions/stellar-asset-contract.mdx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/build/guides/conventions/stellar-asset-contract.mdx b/docs/build/guides/conventions/stellar-asset-contract.mdx index bc48fc620..821a9ca89 100644 --- a/docs/build/guides/conventions/stellar-asset-contract.mdx +++ b/docs/build/guides/conventions/stellar-asset-contract.mdx @@ -3,7 +3,11 @@ title: Integrate Stellar Assets Contracts description: Test and use Stellar assets in a Soroban smart contract --- -When interacting with assets in a smart contract, the Stellar Asset Contract is not different from any other token that implements the Stellar [SEP-41 Token Interface]. The Rust SDK contains a pre-generated client for any contract that implements the token interface: +When interacting with assets in a smart contract, the Stellar Asset Contract is not different from any other token that implements the Stellar [SEP-41 Token Interface]. + +## Contract Code + +The Rust SDK contains a pre-generated client for any contract that implements the token interface: ```rust use soroban_sdk::{contract, contractimpl} @@ -50,7 +54,7 @@ client.mint(...); ::: -### Testing +## Testing Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract`. This function can be seen as the deployment of a generic token. In the following example, we are following the best practices outlined in the [Issuing and Distribution Accounts section](../../../tokens/control-asset-access.mdx#issuing-and-distribution-accounts): @@ -85,9 +89,10 @@ fn test() { token_sac.mint(&issuer, &distributer, &genesis_amount); assert_eq!(token.balance(&distributor), genesis_amount); +} ``` -### Examples +## Examples See the full examples that utilize the token contract in various ways for more details: