Solana DEX Aggregation & Yield Discovery
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 heightsolana_get_tps— transactions per secondsolana_get_balance— native SOL balancesolana_get_token_accounts— all SPL token accountssolana_get_price— Jupiter price oraclesolana_swap— Jupiter swap quote with routingsolana_get_yield— cross-protocol yield discoverysolana_stake— native SOL stakingsolana_resolve_domain— Bonfida SNS resolutionsolana_get_nft/solana_get_nfts_by_owner— Metaplex DASsolana_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,847Step 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.00001847Step 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_swapWhat You Learned
- Jupiter aggregation — finding optimal swap routes across Solana DEXs
- Yield discovery — scanning Marinade, Jito, Raydium, Kamino for the best APY
- Native staking — delegating SOL to validators for staking rewards
- SNS domains — resolving
.solnames to wallet addresses via Bonfida - Metaplex DAS — inspecting NFT metadata and ownership
- SPL tokens — querying balances, accounts, and token metadata
- Settlement — finalizing profits on the Tenzro Ledger
- Cross-VM tokens — how SPL tokens map to native TNZO via the SPL Token Adapter (Sei V2 pointer model)
Next Steps
- See the Base L2 Yield Strategy tutorial for Chainlink price feeds and ERC-4626 vaults
- See the Canton DvP Settlement tutorial for institutional RWA tokenization
- Read the Cross-Chain Arbitrage tutorial for multi-chain trade routing