Tenzro Testnet is live —request testnet TNZO
← Back to Tutorials

Solana DEX Aggregation & Yield Discovery

DeFiAdvanced35 min

Build an autonomous Solana DeFi agent using the Tenzro Rust SDK and the Solana MCP tools. The agent queries Jupiter for real-time prices and optimal swap routes, discovers yield opportunities across Solana protocols (Marinade, Jito, Raydium, Kamino), stakes SOL with validators, resolves .sol domains via Bonfida SNS, and inspects NFT metadata via Metaplex DAS — then settles all profits back on the Tenzro Ledger.

What You'll Build

  • A TDIP identity and MPC wallet via the Rust SDK
  • An autonomous agent with Solana DEX capabilities
  • Real-time price queries via Jupiter aggregator
  • DEX swap quotes (SOL → USDC) with slippage protection
  • Cross-protocol yield discovery (Marinade, Jito, Raydium, Kamino)
  • Native SOL staking with validators
  • Bonfida SNS domain resolution
  • Metaplex DAS NFT metadata inspection
  • SPL token info and balance queries
  • Settlement of profits on the Tenzro Ledger

Solana MCP Tools Used

This tutorial uses 12 of the 14 tools available on the Solana MCP server (port 3003):

  • solana_get_slot — current slot height
  • solana_get_tps — transactions per second
  • solana_get_balance — native SOL balance
  • solana_get_token_accounts — all SPL token accounts
  • solana_get_price — Jupiter price oracle
  • solana_swap — Jupiter swap quote with routing
  • solana_get_yield — cross-protocol yield discovery
  • solana_stake — native SOL staking
  • solana_resolve_domain — Bonfida SNS resolution
  • solana_get_nft / solana_get_nfts_by_owner — Metaplex DAS
  • solana_get_token_info — SPL token metadata

Cross-VM Token Architecture (Sei V2 Pointer Model)

SPL tokens in the Tenzro network use the SPL Token Adapter, which maps standard SPL Token Program instructions to the native TnzoToken layer. Token amounts are converted from 18 decimals (native) to 9 decimals (SPL) automatically. Because Tenzro implements the Sei V2 pointer model, balances are shared across all three VMs — the same underlying balance backs wTNZO on EVM, the SPL adapter on SVM, and the CIP-56 holding on Canton. There is no bridge risk or liquidity fragmentation. See the Cross-VM Token Architecture docs for details.

Prerequisites

[dependencies]
tenzro-sdk = "0.1"
tokio = { version = "1", features = ["full"] }
tracing-subscriber = "0.3"
uuid = { version = "1", features = ["v4"] }

Step 1: Connect & Provision Identity

use tenzro_sdk::{TenzroClient, SettlementRequest, config::SdkConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = SdkConfig::testnet();
    let client = TenzroClient::connect(config).await?;
// Register a human identity via TDIP
let identity = client.identity().register_human("Solana DeFi Trader").await?;
println!("DID: {}", identity.did);

// Create an MPC wallet
let wallet = client.wallet().create_wallet().await?;
println!("Wallet: {}", wallet.address);

Step 2: Register the Agent

// Register the agent with Solana DeFi capabilities
let agent = client.agent().register(
    "solana-defi-agent",
    "Solana DEX Aggregator",
    &["defi", "swap", "solana", "jupiter"],
).await?;
println!("Agent ID: {}", agent.agent_id);

Step 3: Check Network Health

Before trading, verify the Solana network is healthy. High TPS indicates normal congestion levels:

// Check Solana network health
let slot = client.agent().send_message(
    &agent.agent_id,
    "Use solana_get_slot tool",
).await?;
println!("Current slot: {}", slot.payload);

let tps = client.agent().send_message(
    &agent.agent_id,
    "Use solana_get_tps tool",
).await?;
println!("Current TPS: {}", tps.payload);
Current slot: 312847562
Current TPS: 3,847

Step 4: Query Token Balances

Check the native SOL balance and enumerate all SPL token accounts:

// Check SOL balance
let sol_balance = client.agent().send_message(
    &agent.agent_id,
    &format!("Use solana_get_balance tool: address={}", wallet.address),
).await?;
println!("SOL balance: {}", sol_balance.payload);

// List all SPL token accounts
let token_accounts = client.agent().send_message(
    &agent.agent_id,
    &format!("Use solana_get_token_accounts tool: owner={}", wallet.address),
).await?;
println!("SPL tokens: {}", token_accounts.payload);

Step 5: Fetch Real-Time Prices

Jupiter aggregates prices across all Solana DEXs. Query by token mint address:

// SOL price via Jupiter
let sol_price = client.agent().send_message(
    &agent.agent_id,
    "Use solana_get_price tool: token_mint=So11111111111111111111111111111111111111112",
).await?;
println!("SOL/USD: {}", sol_price.payload);

// BONK price
let bonk_price = client.agent().send_message(
    &agent.agent_id,
    "Use solana_get_price tool: token_mint=DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
).await?;
println!("BONK/USD: {}", bonk_price.payload);
SOL/USD: $147.82
BONK/USD: $0.00001847

Step 6: Get Jupiter Swap Quote

Jupiter finds the best route across Raydium, Orca, Phoenix, and other Solana DEXs. The slippage_bps=50 sets 0.5% maximum slippage tolerance:

// Get Jupiter swap quote: 1 SOL → USDC
// Jupiter aggregates across Raydium, Orca, Phoenix, and other Solana DEXs
let swap_quote = client.agent().send_message(
    &agent.agent_id,
    "Use solana_swap tool: \
     input_mint=So11111111111111111111111111111111111111112, \
     output_mint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, \
     amount=1000000000, \
     slippage_bps=50",
).await?;
println!("Swap quote: {}", swap_quote.payload);
Swap quote: {
  "input": "1.000 SOL",
  "output": "147.41 USDC",
  "price_impact": "0.02%",
  "route": "SOL → USDC via Raydium CLMM",
  "slippage_bps": 50,
  "min_output": "146.67 USDC"
}

Jupiter Routing

Jupiter evaluates all possible swap routes across Solana's DEX ecosystem and returns the one with the best output amount. Routes can split across multiple pools and DEXs for optimal execution. The price_impact field helps the agent decide whether the trade size is appropriate for the available liquidity.

Step 7: Discover Yield Opportunities

Scan across Solana DeFi protocols for the best yield opportunities:

// Discover yield opportunities across Solana DeFi
let yields = client.agent().send_message(
    &agent.agent_id,
    "Use solana_get_yield tool",
).await?;
println!("Yields: {}", yields.payload);
Yields: [
  { "protocol": "Marinade",  "asset": "mSOL",   "apy": "7.2%",  "tvl": "$842M" },
  { "protocol": "Jito",      "asset": "JitoSOL", "apy": "7.8%",  "tvl": "$2.1B" },
  { "protocol": "Raydium",   "asset": "RAY-SOL", "apy": "24.5%", "tvl": "$156M" },
  { "protocol": "Kamino",    "asset": "USDC",    "apy": "11.3%", "tvl": "$320M" }
]

Step 8: Stake SOL for Native Yield

Stake SOL directly with a validator for native staking rewards:

// Stake SOL with a validator for native yield
let stake_result = client.agent().send_message(
    &agent.agent_id,
    "Use solana_stake tool: \
     amount=500000000, \
     validator=Vote111111111111111111111111111111111111111",
).await?;
println!("Stake result: {}", stake_result.payload);
Stake result: {
  "stake_account": "StakE...abc123",
  "amount": "0.5 SOL",
  "validator": "Vote111...111",
  "activation_epoch": 612,
  "estimated_apy": "7.1%"
}

Step 9: Resolve SNS Domain & Inspect NFTs

Bonfida SNS (Solana Name Service) resolves .sol domains to wallet addresses. Metaplex DAS provides rich NFT metadata:

// Resolve a .sol domain via Bonfida SNS
let domain = client.agent().send_message(
    &agent.agent_id,
    "Use solana_resolve_domain tool: domain=tenzro.sol",
).await?;
println!("tenzro.sol → {}", domain.payload);
tenzro.sol  7f3a...9c1e
// Inspect NFT metadata via Metaplex DAS
let nft = client.agent().send_message(
    &agent.agent_id,
    "Use solana_get_nft tool: mint=Bq5H...xyz789",
).await?;
println!("NFT: {}", nft.payload);

// List all NFTs owned by a wallet
let nfts = client.agent().send_message(
    &agent.agent_id,
    &format!("Use solana_get_nfts_by_owner tool: owner={}", wallet.address),
).await?;
println!("Owned NFTs: {}", nfts.payload);

Step 10: Token Info & Settlement

Query detailed SPL token metadata and settle profits:

// Get detailed SPL token info
let token_info = client.agent().send_message(
    &agent.agent_id,
    "Use solana_get_token_info tool: \
     mint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
).await?;
println!("USDC info: {}", token_info.payload);
USDC info: {
  "name": "USD Coin",
  "symbol": "USDC",
  "decimals": 6,
  "supply": "3,247,891,234.567890",
  "mint_authority": "FMnt...abc",
  "freeze_authority": "FMnt...abc"
}
// Settle swap profits on Tenzro Ledger
let settlement = client.settlement().settle(SettlementRequest {
    request_id: format!("sol-swap-{}", uuid::Uuid::new_v4()),
    provider: wallet.address.clone(),
    customer: "0x0000000000000000000000000000000000000000".to_string(),
    amount: 500,
    asset: "TNZO".to_string(),
}).await?;
println!("Settlement: {}", settlement.receipt_id);
println!("Status:     {}", settlement.status);

The "TNZO" asset refers to the native ledger token. In cross-VM settlement contexts (for example, settling on EVM), the wTNZO ERC-20 pointer contract is used automatically — no manual wrapping is needed thanks to the Sei V2 pointer model.

Run the Full Example

The complete example is available at sdk/tenzro-sdk/examples/defi_solana_swap.rs:

cargo run --example defi_solana_swap

What You Learned

Next Steps