Toolkit for issuing and managing Stellar assets and bridging them to Soroban.
Install
mkdir -p .claude/skills/assets && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/18577" && unzip -o skill.zip -d .claude/skills/assets && rm skill.zipInstalls to .claude/skills/assets
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Stellar Assets (classic) + trustlines + Stellar Asset Contract (SAC) bridge to Soroban. Covers asset issuance, distribution, authorization flags, clawback, regulated assets, trustline management, and the SAC interop layer that exposes classic assets as Soroban tokens. Use when tokenizing real-world assets, issuing stablecoins, managing trustlines, or bridging classic assets to Soroban contracts.Key capabilities
- →Issue new classic Stellar assets
- →Set up trustlines for asset holders
- →Manage issuer flags like `AUTH_REQUIRED` and `AUTH_CLAWBACK_ENABLED`
- →Bridge classic assets into Soroban contracts via the Stellar Asset Contract (SAC)
- →Lock issuing accounts for fixed-supply tokens
- →Publish asset metadata using SEP-0001 (stellar.toml)
How it works
The skill facilitates the issuance and management of classic Stellar assets, including trustline setup and issuer flag configuration. It also enables bridging these assets to Soroban contracts through the Stellar Asset Contract (SAC).
Inputs & outputs
When to use assets
- →Issue new stablecoin
- →Configure trustlines
- →Bridge assets to Soroban
- →Set asset authorization flags
About this skill
Stellar Assets, Trustlines, and SAC
Stellar's native token mechanism: classic asset issuance, trustlines, and the Stellar Asset Contract (SAC) bridge that makes classic assets usable from Soroban. Default to classic assets over custom Soroban tokens unless you need custom logic.
When to use this skill
- Issuing a new asset (stablecoin, security token, utility token)
- Setting up trustlines from a client or contract
- Managing issuer flags (auth required, auth revocable, clawback)
- Bridging a classic asset into a Soroban contract via SAC
- Building regulated-asset flows (compliance, KYC, freeze)
Related skills
- Custom token contracts (when classic isn't enough) →
../soroban/SKILL.md - UI flows for trustline creation and asset display →
../dapp/SKILL.md - Looking up balances and trustline state →
../data/SKILL.md - Token-related SEPs (SEP-41, SEP-7, etc.) →
../standards/SKILL.md
Overview
Stellar has two token mechanisms:
- Stellar Assets (Classic): Built-in, highly efficient, full ecosystem support
- Soroban Tokens: Custom contracts with flexible logic
Recommendation: Prefer Stellar Assets unless you need custom token logic.
Stellar Assets (Classic)
Asset Types
| Type | Description |
|---|---|
| Native (XLM) | Stellar's native currency, no trustline needed |
| Credit | Issued by an account, requires trustline |
| Liquidity Pool Shares | Represent LP positions |
Asset Identifiers
import * as StellarSdk from "@stellar/stellar-sdk";
// Native XLM
const xlm = StellarSdk.Asset.native();
// Credit asset (code + issuer)
const usdc = new StellarSdk.Asset(
"USDC",
"GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN"
);
// Asset code rules:
// - 1-4 chars: alphanumeric (credit_alphanum4)
// - 5-12 chars: alphanumeric (credit_alphanum12)
Issuing Assets
Create Issuing Account
import * as StellarSdk from "@stellar/stellar-sdk";
const server = new StellarSdk.Horizon.Server("https://horizon-testnet.stellar.org");
// 1. Create issuing account (should be separate from distribution)
const issuerKeypair = StellarSdk.Keypair.random();
const distributorKeypair = StellarSdk.Keypair.random();
// 2. Fund accounts (testnet)
await fetch(`https://friendbot.stellar.org?addr=${issuerKeypair.publicKey()}`);
await fetch(`https://friendbot.stellar.org?addr=${distributorKeypair.publicKey()}`);
Issue Asset
const asset = new StellarSdk.Asset("MYTOKEN", issuerKeypair.publicKey());
// 1. Distributor creates trustline to issuer
const distributorAccount = await server.loadAccount(distributorKeypair.publicKey());
const trustlineTx = new StellarSdk.TransactionBuilder(distributorAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.changeTrust({
asset: asset,
limit: "1000000", // Max amount to hold
})
)
.setTimeout(180)
.build();
trustlineTx.sign(distributorKeypair);
await server.submitTransaction(trustlineTx);
// 2. Issuer sends tokens to distributor
const issuerAccount = await server.loadAccount(issuerKeypair.publicKey());
const issueTx = new StellarSdk.TransactionBuilder(issuerAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.payment({
destination: distributorKeypair.publicKey(),
asset: asset,
amount: "1000000",
})
)
.setTimeout(180)
.build();
issueTx.sign(issuerKeypair);
await server.submitTransaction(issueTx);
Lock Issuing Account
For fixed-supply tokens, lock the issuer:
const lockTx = new StellarSdk.TransactionBuilder(issuerAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.setOptions({
masterWeight: 0, // Disable master key
})
)
.setTimeout(180)
.build();
lockTx.sign(issuerKeypair);
await server.submitTransaction(lockTx);
// Issuer can never issue more tokens
Asset Flags
Configure issuer account flags for compliance:
const setFlagsTx = new StellarSdk.TransactionBuilder(issuerAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.setOptions({
setFlags:
StellarSdk.AuthRequiredFlag | // Trustlines require approval
StellarSdk.AuthRevocableFlag | // Can freeze trustlines
StellarSdk.AuthClawbackEnabledFlag, // Can clawback tokens
})
)
.setTimeout(180)
.build();
Flag Descriptions
| Flag | Effect |
|---|---|
AUTH_REQUIRED | Users must get approval before receiving tokens |
AUTH_REVOCABLE | Issuer can freeze user balances |
AUTH_IMMUTABLE | Flags cannot be changed (permanent) |
AUTH_CLAWBACK_ENABLED | Issuer can clawback tokens from accounts |
Authorize Trustline
// When AUTH_REQUIRED is set, approve trustlines:
const authorizeTx = new StellarSdk.TransactionBuilder(issuerAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.setTrustLineFlags({
trustor: userPublicKey,
asset: asset,
flags: {
authorized: true,
// authorizedToMaintainLiabilities: true, // Partial auth
},
})
)
.setTimeout(180)
.build();
Clawback Tokens
// Requires AUTH_CLAWBACK_ENABLED flag
const clawbackTx = new StellarSdk.TransactionBuilder(issuerAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.clawback({
asset: asset,
from: targetAccountId,
amount: "100",
})
)
.setTimeout(180)
.build();
Trustlines
Create Trustline
const changeTrustTx = new StellarSdk.TransactionBuilder(userAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: StellarSdk.Networks.TESTNET,
})
.addOperation(
StellarSdk.Operation.changeTrust({
asset: asset,
limit: "10000", // 0 to remove trustline
})
)
.setTimeout(180)
.build();
Check Trustline Status
const account = await server.loadAccount(userPublicKey);
const trustline = account.balances.find(
(b) =>
b.asset_type !== "native" &&
b.asset_code === "USDC" &&
b.asset_issuer === usdcIssuer
);
if (trustline) {
console.log("Balance:", trustline.balance);
console.log("Limit:", trustline.limit);
console.log("Authorized:", trustline.is_authorized);
}
Stellar Asset Contract (SAC)
SAC provides Soroban interface for Stellar Assets, enabling smart contract interactions.
Deploy SAC for Existing Asset
# Get the SAC address for an asset
stellar contract asset deploy \
--asset USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN \
--source alice \
--network testnet
SAC Address Derivation
import * as StellarSdk from "@stellar/stellar-sdk";
const asset = new StellarSdk.Asset("USDC", issuerPublicKey);
const contractId = asset.contractId(StellarSdk.Networks.TESTNET);
// Returns the deterministic SAC contract address
Using SAC in Soroban Contracts
use soroban_sdk::{token::Client as TokenClient, Address, Env};
pub fn transfer_asset(
env: Env,
from: Address,
to: Address,
asset_contract: Address,
amount: i128,
) {
from.require_auth();
// Use standard token interface
let token = TokenClient::new(&env, &asset_contract);
token.transfer(&from, &to, &amount);
}
SAC vs Custom Token Interface
SAC implements the standard Soroban token interface:
balance(id: Address) -> i128transfer(from: Address, to: Address, amount: i128)approve(from: Address, spender: Address, amount: i128, expiration_ledger: u32)allowance(from: Address, spender: Address) -> i128decimals() -> u32name() -> Stringsymbol() -> Symbol
When to Use What
Use Stellar Assets When:
- Standard fungible token (currency, stablecoin)
- Need full ecosystem support (wallets, exchanges)
- Regulatory compliance features (freeze, clawback)
- Performance critical (classic operations are cheaper)
- DEX integration via order book
Use Soroban Custom Tokens When:
- Complex transfer logic (royalties, fees, restrictions)
- Custom authorization schemes
- Non-standard token behaviors
- Integration with custom DeFi contracts
- NFTs or semi-fungible tokens
Use SAC When:
- Need Stellar Asset in Soroban contract
- Building DeFi protocols with existing assets
- Bridge between classic and smart contract operations
Querying Assets
Get Account Balances
const account = await server.loadAccount(publicKey);
for (const balance of account.balances) {
if (balance.asset_type === "native") {
console.log("XLM:", balance.balance);
} else {
console.log(`${balance.asset_code}:`, balance.balance);
}
}
Find Assets
// Search for assets by code
const assets = await server
.assets()
.forCode("USDC")
.call();
// Get specific asset details
const assetDetails = await server
.assets()
.forCode("USDC")
.forIssuer(issuerPublicKey)
.call();
Get Asset Statistics
const stats = await server
.assets()
.forCode("USDC")
.forIssuer(issuerPublicKey)
.call();
// stats includes:
// - amount: total issued
// - num_accounts: trustline count
// - flags: issuer flags
SEP Standards for Assets
SEP-0001 (stellar.toml)
Publish asset metadata in your domain's /.well-known/stellar.toml:
[[CURRENCIES]]
code = "MYTOKEN"
issuer = "GABC..."
display_decimals = 2
name = "My Token"
desc = "A description of my token"
image = "https://example.com/token-logo.png"
SEP-0010 (Web Authentication)
Authenticate users with their Stellar accounts:
---
*Content truncated.*
When not to use it
- →When custom token logic is required beyond classic Stellar assets
- →When building custom token contracts on Soroban
Limitations
- →Prefers Stellar Assets over custom Soroban tokens unless custom logic is needed
- →Requires separate issuing and distribution accounts for best practice
- →Requires publishing stellar.toml for asset metadata
How it compares
This skill focuses on Stellar's native asset mechanism and its integration with Soroban via SAC, offering a built-in, efficient token solution distinct from custom Soroban token contracts.
Compared to similar skills
assets side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| assets (this skill) | 0 | 1mo | Review | Intermediate |
| stripe-integration | 48 | 2mo | No flags | Advanced |
| pagination | 1 | 5mo | No flags | Intermediate |
| convex | 0 | 5mo | No flags | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by salazarsebas
View all by salazarsebas →You might also like
stripe-integration
wshobson
Implement Stripe payment processing for robust, PCI-compliant payment flows including checkout, subscriptions, and webhooks. Use when integrating Stripe payments, building subscription systems, or implementing secure checkout flows.
pagination
dadbodgeoff
Implement cursor-based and offset pagination for APIs. Covers efficient database queries, stable sorting, and pagination metadata.
convex
waynesutton
Umbrella skill for all Convex development patterns. Routes to specific skills like convex-functions, convex-realtime, convex-agents, etc.
moai-domain-backend
modu-ai
Backend development specialist covering API design, database integration, microservices architecture, and modern backend patterns.
senior-backend
Cor-Incorporated
Guides backend system development with Node.js, Express, Go, Python, PostgreSQL, GraphQL, and REST APIs. Use when the user says: 'design an API', 'optimize database queries', 'implement authentication', 'set up backend', 'create API endpoint', 'database migration', 'fix N+1 query', 'add rate limitin
alwib-backend
Tsuev
Develop and maintain the Alwib NestJS backend in `backend/`. Use when implementing or refactoring modules, controllers, services, DTO validation, Swagger docs, authentication/authorization flows, Prisma schema and migrations, and backend lint/test flows.