Skip to content

Latest commit

 

History

History
110 lines (80 loc) · 4.59 KB

File metadata and controls

110 lines (80 loc) · 4.59 KB
title Integrate Stellar Assets Contracts
hide_table_of_contents true
description Test and use Stellar assets in a Stellar 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.

Contract Code

The Rust SDK contains a pre-generated client for any contract that implements the token interface:

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(&env, &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.

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.

:::info[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.

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:

#![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: