> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrate Stellar Assets Contracts

> Test and use Stellar assets in a Stellar smart contract

When interacting with assets in a smart contract, the [Stellar Asset Contract](https://developers.stellar.org/docs/tokens/stellar-asset-contract.md) 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 theme={"theme":{"light":"github-light","dark":"github-dark"}}
use soroban_sdk::{contract, contractimpl}
use soroban_sdk::token;

#[contract]
pub struct MyContract;

#[contractimpl]
impl MyContract {
    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(&e, &id);
        // Call token functions part of the Stellar SEP-41 token interface
        client.transfer(...);
    }
}
```

The `asset` parameter is not the address of the issuer of an asset, it corresponds to the deployed contract address for this asset.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract id asset \
    --source-account 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]: https://developers.stellar.org/docs/tools/cli/cookbook/deploy-stellar-asset-contract.md

> [!NOTE]
>
> **Clients**
>
> 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 theme={"theme":{"light":"github-light","dark":"github-dark"}}
> let client = token::StellarAssetClient::new(&env, &id);
> // 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(...);
> ```

## Testing

Soroban Rust SDK provides an easy way to instantiate a Stellar Asset Contract tokens using `register_stellar_asset_contract_v2`. This function can be seen as the deployment of a generic token. It also allows you to manipulate flags on the issuer account like `AUTH_REVOCABLE` and `AUTH_REQUIRED`. In the following example, we are following the best practices outlined in the [Issuing and Distribution Accounts section](https://developers.stellar.org/docs/tokens/control-asset-access.md#issuing-and-distribution-accounts):

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
#![cfg(test)]

use soroban_sdk::testutils::Address as _;
use soroban_sdk::{token, Address, Env};
use token::{StellarAssetClient, TokenClient};

#[test]
fn test() {
    let e = Env::default();
    e.mock_all_auths();

    let issuer = Address::generate(&e);
    let distributor = Address::generate(&e);

    let sac = e.register_stellar_asset_contract_v2(issuer.clone());
    let token_address = sac.address();

    // client for SEP-41 functions
    let token = TokenClient::new(&e, &token_address);
    // client for Stellar Asset Contract functions
    let token_sac = StellarAssetClient::new(&e, &token_address);

    // 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(&distributor, &genesis_amount);

    assert_eq!(token.balance(&distributor), genesis_amount);

    // Make issuer AuthRequired and AuthRevocable
    sac.issuer().set_flag(IssuerFlags::RevocableFlag);
    sac.issuer().set_flag(IssuerFlags::RequiredFlag);
}
```

## Examples

See the full examples that utilize the token contract in various ways for more details:

* [Timelock](https://developers.stellar.org/docs/build/smart-contracts/example-contracts/timelock.md) and [single offer](https://developers.stellar.org/docs/build/smart-contracts/example-contracts/single-offer-sale.md) move token via `transfer` to and from the contract
* [Atomic swap](https://developers.stellar.org/docs/build/smart-contracts/example-contracts/atomic-swap.md) uses `transfer` to transfer token on behalf of the user

[sep-41 token interface]: https://developers.stellar.org/docs/tokens/token-interface.md

[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
