✓ Verified 💻 Development ✓ Enhanced Data

Multichain Protocol

Turn any AI agent into a 19-chain crypto wallet via MeneseSDK on ICP.

Rating
4.3 (268 reviews)
Downloads
48,577 downloads
Version
1.0.0

Overview

Turn any AI agent into a 19-chain crypto wallet via MeneseSDK on ICP.

Key Features

1

Install dfx (ICP SDK)

2

Install the skill

3

Create an ICP identity (if you don't have one)

4

Try it — your first 5 sends are free

5

(optional): Deploy your own canister for production

Complete Documentation

View Source →

Multichain Protocol — MeneseSDK Wallet Skill

Operate across 19 blockchains from a single ICP canister or CLI: Solana, Ethereum, Bitcoin, Arbitrum, Base, Polygon, BSC, Optimism, ICP, XRP, SUI, TON, Cardano, Aptos, NEAR, Tron, Litecoin, CloakCoin, THORChain.

Powered by Menese Protocol | Canister ID (mainnet): urs2a-ziaaa-aaaad-aembq-cai


Pricing

First 5 transactions are FREE — no signup, no credit card, just install and go.

After the free tier, transaction signing is charged per action via your DeveloperKey (msk_*). Read-only operations (balances, addresses, pool queries) are always free.


Quickstart (2 minutes)

Step 1: Install dfx (ICP SDK)

If you don't have dfx installed, run this single command:

bash
sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)"

Verify it works:

bash
dfx --version

That's it. No accounts needed, no wallets to set up — dfx handles everything.

Step 2: Install the skill

bash
clawhub install multichain-protocol

Or manually: copy SKILL.md + wallet_commands.py to your workspace.

Step 3: Create an ICP identity (if you don't have one)

bash
dfx identity new my-wallet
dfx identity use my-wallet

Step 4: Try it — your first 5 sends are free

Ask your bot:

text
"show my wallet addresses"
"what's my SOL balance?"
"send 0.1 ETH to 0xABC..."
"swap 100 USDC to SOL on Raydium"
"set up a DCA: buy $50 of BTC every day"

Step 5 (optional): Deploy your own canister for production

For multi-user, automation, and timers — deploy WalletBot.mo as your own ICP canister.


Two Integration Approaches

Canister (Recommended)CLI (Quick)
FlowUser → ClawdBot → Your Canister → MeneseSDKUser → ClawdBot → dfx canister call → MeneseSDK
SetupDeploy WalletBot.mo, register with SDKCopy scripts/wallet_commands.py, done
Best forMulti-user, automation, timers, productionSingle-user, prototyping, testing
AutomationICP timers for DCA/rebalance/botsNone (manual only)

Best Practice: Cache Addresses

Addresses are deterministic — the same principal always gets the same addresses on every chain. Fetch once, cache forever.

motoko
// Canister pattern — cache in stable var
stable var cachedAddresses : ?AddressBook = null;

public shared func getAddresses() : async AddressBook {
  switch (cachedAddresses) {
    case (?addrs) { addrs };  // Return cached — no inter-canister call
    case null {
      let sol = await menese.getMySolanaAddress();
      let evm = await menese.getMyEvmAddress();
      // ... fetch all chains once ...
      let addrs = { solana = sol.address; evm = evm.evmAddress; /* ... */ };
      cachedAddresses := ?addrs;
      addrs;
    };
  };
};

python
# CLI pattern — fetch once, store in file
import json, os
CACHE_FILE = "addresses_cache.json"

def get_addresses():
    if os.path.exists(CACHE_FILE):
        return json.load(open(CACHE_FILE))
    addrs = fetch_all_addresses()  # dfx calls
    json.dump(addrs, open(CACHE_FILE, "w"))
    return addrs

Why: Saves inter-canister call latency + cycles. Addresses never change for a given principal.


EVM Chains — Bring Your Own RPC

All EVM operations (ETH, Arbitrum, Base, Polygon, BSC, Optimism) require your own RPC endpoint. MeneseSDK does not manage EVM RPCs.

ChainChain IDFree Public RPC
Ethereum1https://eth.llamarpc.com
Arbitrum42161https://arb1.arbitrum.io/rpc
Base8453https://mainnet.base.org
Polygon137https://polygon-rpc.com
BSC56https://bsc-dataseed1.binance.org
Optimism10https://mainnet.optimism.io
Use Alchemy/Infura for production reliability.


Complete Tool Reference

Every operation available, organized by category. Each tool shows the function, parameters, return type, cost, and a usage example.

Tool 1: Get Addresses (FREE)

Deterministic per-principal. Cache after first call.

ChainFunctionField to Extract
SolanagetMySolanaAddress.address
EVM (all 6)getMyEvmAddress.evmAddress (NOT .address)
BitcoingetMyBitcoinAddress.bech32Address
LitecoingetMyLitecoinAddress.bech32Address
SUIgetMySuiAddress.suiAddress (NOT .address)
XRPgetMyXrpAddress.classicAddress
TONgetMyTonAddress.nonBounceable (NOT .address)
CardanogetMyCardanoAddress.bech32Address
AptosgetMyAptosAddress.address
NEARgetMyNearAddress.implicitAccountId (NOT .accountId)
TrongetTronAddress.base58Address (NOT .base58)
CloakCoingetMyCloakAddress.base58Address
THORChaingetMyThorAddress.bech32Address
Batch: getAllAddresses() — all chains in one call. Solana ATA: getMySolanaAta(mintBase58) — get associated token account for an SPL token.

motoko
// Example: get SOL address
let info = await menese.getMySolanaAddress();
let myAddress = info.address;  // "5xK2abc..."

bash
# CLI
dfx canister call urs2a-ziaaa-aaaad-aembq-cai getMySolanaAddress --network ic --query

Tool 2: Check Balances (FREE)

ChainFunctionReturnsUnit
SolanagetMySolanaBalanceResultlamports (÷10^9)
ICPgetICPBalanceResulte8s (÷10^8)
ICP (for addr)getICPBalanceFor(principal)Resulte8s (÷10^8)
BitcoingetBitcoinBalanceNat64satoshis (÷10^8)
LitecoingetLitecoinBalanceNat64litoshis (÷10^8)
EVMgetMyEvmBalance(rpcUrl)Resultwei (÷10^18)
XRPgetMyXrpBalanceResultdrops as text
SUIgetMySuiBalanceNat64mist (÷10^9)
TONgetMyTonBalanceResultnanotons (÷10^9)
CardanogetCardanoBalanceResultlovelace (÷10^6)
AptosgetAptosBalanceResultoctas (÷10^8)
NEARgetMyNearBalanceNatyoctoNEAR (÷10^24)
THORChaingetThorBalance[{amount, denom}]units (÷10^8)
CloakCoingetCloakBalanceResult<{address, balance, utxoCount}, Text>units (÷10^6)
TrongetTrxBalance(address)Resultsun (÷10^6)
ICRC-1 tokensgetICRC1Balance(ledgerId)Resultsmallest unit
ICRC-1 (for addr)getICRC1BalanceFor(principal, ledgerId)Resultsmallest unit
ICRC-1 infogetICRC1TokenInfo(ledgerId)Resultname, symbol, decimals
ICP tokens listgetSupportedICPTokens()[{name,symbol,canisterId,type_,category}]query
TRC-20 tokensgetMyTrc20Balance(contract)Resultsmallest unit
Batch: getAllBalances() — parallel fetch across all chains.

Performance tip: For high-frequency reads, query chain RPCs directly using cached addresses. MeneseSDK is best for signing; your own RPC is faster for reads.

motoko
// Example: check SOL balance, convert to human-readable
switch (await menese.getMySolanaBalance()) {
  case (#ok(lamports)) { /* lamports / 1_000_000_000 = SOL */ };
  case (#err(e)) { /* handle error */ };
};

Tool 3: Send Tokens ($0.05 client / $0.10 agent)

Return types differ by chain — getting this wrong causes runtime errors.

ChainFunctionParamsReturn
SolanasendSolTransaction(to, lamports:Nat64)Result
ICPsendICP(to:Principal, e8s:Nat64)Result
ICRC-1sendICRC1(to:Principal, amount:Nat, ledger:Text)Result
BitcoinsendBitcoin(to, sats:Nat64)Result
LitecoinsendLitecoin(to, litoshis:Nat64)Result (NOT BtcLtc!)
EVMsendEvmNativeTokenAutonomous(to, wei:Nat, rpc, chainId:Nat, ?quoteId)Result
XRPsendXrpAutonomous(to, amountXrp:Text, ?destTag:Nat32)FLAT SendResultXrp
SUIsendSui(to, mist:Nat64)Result
TONsendTonSimple(to, nanotons:Nat64)FLAT SendResultTon
AptossendAptos(to, octas:Nat64)Result
NEARsendNearTransfer(to, yocto:Nat)Result
TronsendTrx(to, sun:Nat64)Result
CardanosendCardanoTransaction(to, lovelace:Nat64)Result
CloakCoinsendCloak(to, amount:Nat64)Result
THORChainsendThor(to, amount:Nat64, memo:Text)Result
SPL TokentransferSplToken(amount:Nat64, srcAta, dstAta)TransferAndSendResult
XRP IOUsendXrpIOU(dest, currency, issuer, amount, ?tag)SendResultXrp
TRC-20sendTrc20(contract, to, amount:Nat, feeLimit:Nat64)Result
Variant extras: sendBitcoinDynamicFee, sendBitcoinWithFee, sendLitecoinWithFee, sendSuiMax, sendTon (with bounce/comment), sendTonWithComment.

motoko
// Example: send 0.5 SOL
switch (await menese.sendSolTransaction("5xK2abc...", 500_000_000)) {
  case (#ok(txHash)) { /* success — txHash is the Solana TX signature */ };
  case (#err(e)) { /* handle error */ };
};

// Example: send XRP (FLAT return — check .success, not #ok)
let r = await menese.sendXrpAutonomous("rDestAddr...", "10.5", null);
if (r.success) { /* r.txHash, r.explorerUrl */ }
else { /* r.message has error */ };

Tool 3b: ICRC-2 Approve & TransferFrom ($0.05 client / $0.10 agent)

ICRC-2 adds ERC-20-style approve + transferFrom to ICP tokens. Use when building escrow, payment splitters, or any pattern where a canister needs to spend tokens on behalf of users.

OperationFunctionParamsReturn
Approve spenderapproveICRC2(spender:Principal, amount:Nat, expiresAt:?Nat64, ledgerId:Text)Result
Check allowancegetICRC2Allowance(owner:Principal, spender:Principal, ledgerId:Text)Result — FREE
TransferFromtransferFromICRC2(from:Principal, to:Principal, amount:Nat, ledgerId:Text)Result
motoko
// Approve MeneseSDK canister to spend 100 ckUSDC on your behalf
let ckUSDC = "xevnm-gaaaa-aaaar-qafnq-cai";
let sdk = Principal.fromText("urs2a-ziaaa-aaaad-aembq-cai");
let r = await menese.approveICRC2(sdk, 100_000_000, null, ckUSDC);  // 100 ckUSDC (6 dec)

// Check remaining allowance (FREE)
let allowance = await menese.getICRC2Allowance(myPrincipal, sdk, ckUSDC);

// Transfer from (requires prior approval)
let t = await menese.transferFromICRC2(userPrincipal, treasuryPrincipal, 50_000_000, ckUSDC);

Tool 4: Swap on DEXes ($0.075 client / $0.15 agent)

DEXChainFunctionKey Details
RaydiumSolanaswapRaydiumApiUser8 params, FLAT return
Uniswap V3EVMswapTokens, swapTokensMultiHopPass quoteId or rpc+chainId
Uniswap shortcutsEVMswapETHForUSDC, swapUSDCForETHQuick ETH↔USDC
ICPSwap/KongSwapICPexecuteICPDexSwap(SwapRequest)Auto-routes best price
CetusSUIexecuteSuiSwap(network, from, to, amountIn, minOut)Network: #mainnet
MinswapCardanoexecuteMinswapSwap(tokenIn, tokenOut, amount, slippage)Float slippage %
XRP DEXXRPxrpSwap(destAmount, sendMax, paths, slipBps)Use xrpFindPaths first
Always get a quote first (FREE):
  • Raydium: getRaydiumQuote(inputMint, outputMint, amount, slipBps)
  • Uniswap: getTokenQuote(from, to, amountIn, rpc)
  • ICP: getICPDexQuote(tokenIn, tokenOut, amountIn, slipPct)AggregatedQuote (compares ICPSwap vs KongSwap)
  • SUI: getSuiSwapQuote(network, from, to, amountIn, slipBps)
  • Cardano: getMinswapQuote(tokenIn, tokenOut, amountIn, slipPct)
  • XRP: xrpFindPaths(destAmount, sourceCurrencies)
motoko
// Example: swap 1 SOL → USDC on Raydium
let SOL = "So11111111111111111111111111111111111111112";
let USDC = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";

let result = await menese.swapRaydiumApiUser(
  SOL, USDC,
  1_000_000_000,  // 1 SOL in lamports
  150,            // 1.5% slippage
  true,           // wrapSol: input is native SOL
  false,          // unwrapSol: output is USDC not SOL
  null, null      // auto-detect ATAs
);
// FLAT record — access directly:
// result.txSignature, result.outputAmount, result.priceImpactPct

motoko
// Example: swap on ICP DEX (auto-routes to ICPSwap or KongSwap)
let swapReq : Menese.SwapRequest = {
  tokenIn = "ryjl3-tyaaa-aaaaa-aaaba-cai";  // ICP ledger
  tokenOut = "mxzaz-hqaaa-aaaar-qaada-cai";  // ckUSDC
  amountIn = 100_000_000;  // 1 ICP
  minAmountOut = 0;
  slippagePct = 1.0;
  preferredDex = null;  // auto-pick best price
};
let result = await menese.executeICPDexSwap(swapReq);

Tool 5: Bridge ETH↔SOL ($0.10 client / $0.20 agent)

DirectionFunctionParams
ETH→SOLquickUltrafastEthToSol(ethWei:Nat)
USDC→SOLquickUltrafastUsdcToSol(usdc:Nat)
ETH→TokenquickUltrafastEthToToken(ethWei:Nat, outputMint, slipBps:Nat)
SOL→ETHquickSolToEth(solLamports:Nat64, slipBps:Nat)
USDC SOL→ETHquickUsdcBridgeSolToEth(usdc:Nat64)
CCTP (any)quickCctpBridge(srcChainId, usdc, outputToken, fast, slipBps, ethRpc)
motoko
// Example: bridge 0.1 ETH to Solana
let result = await menese.quickUltrafastEthToSol(100_000_000_000_000_000);  // 0.1 ETH in wei
// Result<Text, Text> — ok = status text

Tool 6: DeFi — Aave V3 ($0.10 agent)

OperationFunctionParams
Supply ETHaaveSupplyEth(wei:Nat, rpc, ?quoteId) → Result
Withdraw ETHaaveWithdrawEth(wei:Nat, rpc, ?quoteId) → Result
Supply ERC-20aaveSupplyToken(tokenAddr, amount:Nat, rpc, ?quoteId)
Withdraw ERC-20aaveWithdrawToken(tokenAddr, amount:Nat, rpc, ?quoteId)
Read aWETH balgetAWethBalance(user, rpc) → FREE
Read aToken balgetATokenBalance(aTokenAddr, user, rpc) → FREE
motoko
// Supply 0.5 ETH to Aave → receive aWETH (~2-3% APY)
let r = await menese.aaveSupplyEth(500_000_000_000_000_000, ethRpc, null);
switch (r) {
  case (#ok(res)) { /* res.txHash, res.aTokenAddress */ };
  case (#err(e)) { /* error */ };
};

Tool 7: DeFi — Lido Staking ($0.10 agent)

OperationFunctionReturn
Stake ETH→stETHstakeEthForStEth(wei, rpc, ?quoteId)Result
Wrap stETH→wstETHwrapStEth(amount, rpc, ?quoteId)Result
Unwrap wstETH→stETHunwrapWstEth(amount, rpc, ?quoteId)Result
Read stETH balgetStEthBalance(user, rpc)FREE
Read wstETH balgetWstEthBalance(user, rpc)FREE
motoko
// Stake 1 ETH with Lido (~3-4% APY), then wrap for DeFi composability
ignore await menese.stakeEthForStEth(1_000_000_000_000_000_000, ethRpc, null);
ignore await menese.wrapStEth(1_000_000_000_000_000_000, ethRpc, null);

Tool 8: DeFi — Uniswap V3 Liquidity ($0.10 agent)

OperationFunction
Add ETH+Token LPaddLiquidityETH(tokenSymbol, tokenAmt, ethAmt, slipBps, rpc, ?quoteId)
Add Token+Token LPaddLiquidity(tokenA, tokenB, amtA, amtB, slipBps, rpc, ?quoteId)
Remove ETH LPremoveLiquidityETH(tokenSymbol, lpAmt, slipBps, feeOnTransfer, rpc, ?quoteId)
Remove Token LPremoveLiquidity(tokenA, tokenB, lpAmt, slipBps, rpc, ?quoteId)
Read reservesgetPoolReserves(tokenA, tokenB, rpc) — FREE
Get pair addrgetPairAddress(tokenA, tokenB, rpc) — FREE

Tool 9: Custom EVM Contract Calls

OperationFunctionCost
Read (view)callEvmContractRead(contract, selector4byte, argsHexes, rpc)FREE
Write (tx)callEvmContractWrite(contract, selector, args, rpc, chainId, value, ?quoteId)$0.10
Selector = first 4 bytes of keccak256("functionName(type1,type2)"), hex-encoded, no 0x prefix.

motoko
// Read Chainlink ETH/USD price (FREE)
let result = await menese.callEvmContractRead(
  "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419",  // ETH/USD feed
  "feaf968c",  // latestRoundData()
  [], ethRpc
);

Tool 10: Strategy Engine (rule creation FREE, execution per-action pricing)

OperationFunctionCost
Create ruleaddStrategyRule(Rule)FREE
List rulesgetMyStrategyRules()FREE
Update statusupdateStrategyRuleStatus(ruleId, status)FREE
Delete ruledeleteStrategyRule(ruleId)FREE
View logsgetStrategyLogs()FREE
Init automationinitAutomation()FREE
Rule types: #DCA, #StopLoss, #TakeProfit, #Rebalance, #Scheduled, #APYMigration, #LiquidityProvision, #VolatilityTrigger.

Rule statuses: #Active, #Paused, #Cancelled, #Executed, #Executing, #Failed, #Draft, #Confirmed, #Ready.

Tool 11: Solana ATA / XRP Trustlines (setup)

OperationFunctionCost
Create Solana ATAcreateMySolanaAtaForMint(mint, ata)Send pricing
Create ATA (custom program)createMySolanaAtaForMintWithProgram(mint, ata, programId)Send pricing
Set XRP trustlinexrpSetTrustline(currency, issuer, limit)Send pricing
Read XRP trustlinesxrpGetAccountLines()FREE
Get Solana ATAgetMySolanaAta(mint)FREE

Tool 12: Developer/Billing

OperationFunctionCost
Register canisterregisterDeveloperCanister(Principal, appName)FREE
Get dev keygetMyDeveloperKey()FREE
Regenerate keyregenerateDeveloperKey()FREE
Validate keyvalidateDeveloperKey(key)FREE
Check accountgetMyGatewayAccount() → UserAccountFREE
Check dev accountgetMyDeveloperAccount() → ?DeveloperAccountV3FREE
Deposit creditsdepositGatewayCredits(currency, amount)ICP cost

Tool 13: Utility

OperationFunctionCost
BTC max sendgetBitcoinMaxSendAmount(?feeRate) → {maxAmount, fee, utxoCount}FREE
LTC max sendgetLitecoinMaxSendAmount(?feeRate) → {maxAmount, fee, utxoCount}FREE
Health checkhealth()FREE
Versionversion()FREE

Tool 14: ICP DEX LP Management ($0.10 agent)

Manage liquidity positions on ICPSwap and KongSwap. The SDK aggregates both DEXes.

OperationFunctionCost
List poolsgetICPDexPools() → [PoolInfo]FREE
List tokensgetICPDexTokens() → [DexToken]FREE
View positionsgetICPLPPositions() → [LPPosition]FREE
Add liquidityaddICPLiquidity(AddLiquidityRequest) → Result$0.10
Remove liquidityremoveICPLiquidity(RemoveLiquidityRequest) → Result$0.10
Types:

text
AddLiquidityRequest = { poolId:Text, dex:{#ICPSwap|#KongSwap}, token0:Text, token1:Text, token0Amount:Nat, token1Amount:Nat, slippagePct:Float }
RemoveLiquidityRequest = { poolId:Text, dex:{#ICPSwap|#KongSwap}, lpTokens:Nat, slippagePct:Float }
LPPosition = { poolId, dex, token0, token1, token0Symbol, token1Symbol, liquidity:Nat, token0Amount, token1Amount, unclaimedFees:?(Nat,Nat), valueUsd:?Nat }
PoolInfo = { poolId, dex, token0, token1, token0Symbol, token1Symbol, reserve0, reserve1, fee, tvl:?Nat, apr:?Float, volume24h:?Nat }
DexToken = { canisterId, symbol, name, decimals:Nat8, fee:Nat, standard:{#ICRC1|#ICRC2|#DIP20}, logo:?Text, category:?Text, availableOn:[DexId] }

Well-known pools: ICP/ckUSDC, ckBTC/ICP, ICP/ckETH, ckUSDT/ckUSDC, CHAT/ICP (on both ICPSwap and KongSwap).

motoko
// Discover pools, then add liquidity
let pools = await menese.getICPDexPools();
// Find ICP/ckUSDC pool
let pool = Array.find<DexTypes.PoolInfo>(pools, func(p) { p.token0Symbol == "ICP" and p.token1Symbol == "ckUSDC" });

switch (pool) {
  case (?p) {
    let req : DexTypes.AddLiquidityRequest = {
      poolId = p.poolId;
      dex = p.dex;
      token0 = "ryjl3-tyaaa-aaaaa-aaaba-cai";  // ICP ledger
      token1 = "xevnm-gaaaa-aaaar-qafnq-cai";  // ckUSDC
      token0Amount = 100_000_000;  // 1 ICP
      token1Amount = 10_000_000;   // 10 ckUSDC
      slippagePct = 1.0;
    };
    let result = await menese.addICPLiquidity(req);
  };
  case null { /* pool not found */ };
};

// View positions
let positions = await menese.getICPLPPositions();
// Remove liquidity
let removeReq : DexTypes.RemoveLiquidityRequest = {
  poolId = positions[0].poolId;
  dex = positions[0].dex;
  lpTokens = positions[0].liquidity;  // Remove all
  slippagePct = 1.0;
};
let removed = await menese.removeICPLiquidity(removeReq);

Tool 15: ICP AI Rebalancer (FREE)

AI-powered portfolio rebalancing recommendations using Herfindahl-Hirschman Index diversification scoring, impermanent loss estimation, and risk-adjusted APY analysis.

OperationFunctionCost
Get recommendationsgetICPRebalanceRecommendations(preferences, tokenBalances, pools?) → [RebalanceRecommendation]FREE
Types:

text
RebalancePreferences = { targetCategories:[Text], riskTolerance:Text, minApy:?Float, maxImpermanentLoss:?Float, autoCompound:Bool }
  targetCategories: ["stablecoin", "defi", "lst", "yield", "wrapped", "meme", "ecosystem"]
  riskTolerance: "conservative" | "moderate" | "aggressive"

RebalanceRecommendation = { id, action:{#Swap|#AddLiquidity|#RemoveLiquidity|#Compound}, fromToken, toToken, fromSymbol, toSymbol, amount:Nat, reason:Text, estimatedApy:?Float, currentApy:?Float, impermanentLossRisk:{#Low|#Medium|#High}, confidence:Float, estimatedGasUsd:?Float }

motoko
// Get rebalancing recommendations for your ICP portfolio
let prefs : DexTypes.RebalancePreferences = {
  targetCategories = ["stablecoin", "defi", "lst"];
  riskTolerance = "moderate";
  minApy = ?5.0;        // Only suggest >5% APY
  maxImpermanentLoss = ?10.0;  // Max 10% IL risk
  autoCompound = true;
};

// Pass current balances: [(canisterId, amount)]
let balances = [
  ("ryjl3-tyaaa-aaaaa-aaaba-cai", 500_000_000),  // 5 ICP
  ("xevnm-gaaaa-aaaar-qafnq-cai", 100_000_000),  // 100 ckUSDC
  ("mxzaz-hqaaa-aaaar-qaada-cai", 50_000),        // 0.0005 ckBTC
];

let recommendations = await menese.getICPRebalanceRecommendations(prefs, balances, null);
for (rec in recommendations.vals()) {
  Debug.print(rec.reason # " | Confidence: " # Float.toText(rec.confidence));
  // e.g., "Swap 2 ICP → ckUSDC and add to ICP/ckUSDC pool for 12.5% APY | Confidence: 0.85"
};


Combining Tools — Practical Automation Examples

The real power is combining these tools. Below are complete patterns showing how tools work together.

Example 1: DCA Bot (Timer + Balance + Swap)

Buy USDC with SOL every hour if balance exceeds threshold.

motoko
// Tools used: getMySolanaBalance (FREE) + swapRaydiumApiUser ($0.075)
func dcaCycle() : async () {
  let balance = switch (await menese.getMySolanaBalance()) {
    case (#ok(v)) v; case (#err(_)) return;
  };
  if (balance < 500_000_000) return;  // < 0.5 SOL, skip

  let swapAmt = balance - 50_000_000;  // Keep 0.05 SOL for rent
  let _ = await menese.swapRaydiumApiUser(
    "So11111111111111111111111111111111111111112",  // SOL
    "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",  // USDC
    swapAmt, 150, true, false, null, null
  );
};

// Run every hour
let timerId = Timer.recurringTimer<system>(#seconds(3600), dcaCycle);

Example 2: Stop-Loss via Strategy Engine

Set a stop-loss rule that auto-sells when price drops. No timer needed — MeneseSDK evaluates.

motoko
// Tool used: addStrategyRule (FREE to create, execution costs per action)
let rule : Menese.Rule = {
  id = 0;
  ruleType = #StopLoss;
  status = #Active;
  chainType = #Solana;
  triggerPrice = 120_000_000;  // Trigger at this price level
  sizePct = 100;  // Sell 100% of position
  positionId = 0;
  createdAt = Time.now();
  dcaConfig = null; lpConfig = null; scheduledConfig = null;
  apyMigrationConfig = null; volatilityConfig = null;
  swapAmountLamports = ?1_000_000_000;  // 1 SOL
  swapAmountWei = null;
};
let ruleId = await menese.addStrategyRule(rule);

Example 3: Take-Profit + Stop-Loss Combo

Set both on the same position — whichever triggers first wins.

motoko
// Tools: addStrategyRule × 2
// Take-profit at 200
let tp : Menese.Rule = { /* ... */ ruleType = #TakeProfit; triggerPrice = 200_000_000; sizePct = 50; /* sell half */ /* ... */ };
let tpId = await menese.addStrategyRule(tp);

// Stop-loss at 100
let sl : Menese.Rule = { /* ... */ ruleType = #StopLoss; triggerPrice = 100_000_000; sizePct = 100; /* sell all */ /* ... */ };
let slId = await menese.addStrategyRule(sl);

// When one triggers, cancel the other
// Check via getMyStrategyRules() or getStrategyLogs() in your timer

Example 4: DCA via Strategy Engine (no custom timer)

Let MeneseSDK handle the scheduling internally.

motoko
// Tool: addStrategyRule with DCA config
let dca : Menese.Rule = {
  id = 0;
  ruleType = #DCA;
  status = #Active;
  chainType = #Solana;
  triggerPrice = 0; sizePct = 100; positionId = 0;
  createdAt = Time.now();
  dcaConfig = ?{
    amountPerInterval = 100_000_000;  // 0.1 SOL per buy
    currentInterval = 0;
    intervalSeconds = 3600;  // Every hour
    lastExecutedAt = 0;
    maxIntervals = 168;  // Run for 1 week (168 hours)
    targetToken = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";  // Buy USDC
    totalSpent = 0;
  };
  lpConfig = null; scheduledConfig = null;
  apyMigrationConfig = null; volatilityConfig = null;
  swapAmountLamports = ?100_000_000;
  swapAmountWei = null;
};
ignore await menese.addStrategyRule(dca);

Example 5: Multi-Chain Sweep (Balance + Send across chains)

Check all balances, sweep any above threshold to treasury.

motoko
// Tools: getAllBalances (FREE) + sendSolTransaction + sendICP + sendEvmNativeTokenAutonomous
func sweepCycle() : async () {
  let bals = await menese.getAllBalances();

  // Sweep SOL if > 1 SOL
  switch (bals.solana) {
    case (#ok(lamports)) {
      if (lamports > 1_000_000_000) {
        ignore await menese.sendSolTransaction(solTreasury, lamports - 50_000_000);
      };
    };
    case (#err(_)) {};
  };

  // Sweep ICP if > 1 ICP
  switch (bals.icp) {
    case (#ok(e8s)) {
      if (e8s > 100_000_000) {
        ignore await menese.sendICP(Principal.fromText(icpTreasury), e8s - 100_000);
      };
    };
    case (#err(_)) {};
  };

  // Sweep ETH if > 0.1 ETH
  switch (await menese.getMyEvmBalance(ethRpc)) {
    case (#ok(wei)) {
      if (wei > 100_000_000_000_000_000) {
        ignore await menese.sendEvmNativeTokenAutonomous(
          ethTreasury, wei - 50_000_000_000_000_000, ethRpc, 1, null
        );
      };
    };
    case (#err(_)) {};
  };
};

Example 6: DeFi Yield Rebalancer (Aave + Lido + LP)

Allocate idle ETH across DeFi protocols on a timer.

motoko
// Tools: getMyEvmBalance + getAWethBalance + getStEthBalance (all FREE)
//        + aaveSupplyEth + stakeEthForStEth + wrapStEth ($0.10 each)

func rebalanceCycle() : async () {
  let evmAddr = (await menese.getMyEvmAddress()).evmAddress;  // Cached ideally
  let ethBal = switch (await menese.getMyEvmBalance(ethRpc)) { case (#ok(v)) v; case _ 0 };
  let aaveBal = switch (await menese.getAWethBalance(evmAddr, ethRpc)) { case (#ok(v)) v; case _ 0 };
  let lidoBal = switch (await menese.getStEthBalance(evmAddr, ethRpc)) { case (#ok(v)) v; case _ 0 };

  let reserve = 50_000_000_000_000_000;  // 0.05 ETH for gas
  if (ethBal <= reserve) return;
  let deployable = ethBal - reserve;

  // 50% Aave, 50% Lido
  let aaveTarget = deployable / 2;
  let lidoTarget = deployable / 2;

  if (aaveTarget > aaveBal and aaveTarget - aaveBal > 10_000_000_000_000_000) {
    ignore await menese.aaveSupplyEth(aaveTarget - aaveBal, ethRpc, null);
  };
  if (lidoTarget > lidoBal and lidoTarget - lidoBal > 10_000_000_000_000_000) {
    ignore await menese.stakeEthForStEth(lidoTarget - lidoBal, ethRpc, null);
    ignore await menese.wrapStEth(lidoTarget - lidoBal, ethRpc, null);
  };
};

// Run every 6 hours
let timerId = Timer.recurringTimer<system>(#seconds(21600), rebalanceCycle);

Example 7: Cross-Chain Arbitrage (Bridge + Swap)

Move funds between Ethereum and Solana to capture price differences.

motoko
// Tools: getTokenQuote (FREE) + getRaydiumQuote (FREE)
//        + quickUltrafastEthToSol ($0.10) + swapRaydiumApiUser ($0.075)

// 1. Check ETH USDC price on Uniswap
let ethQuote = await menese.getTokenQuote("USDC", "WETH", 1000_000_000, ethRpc);

// 2. Check SOL USDC price on Raydium
let solQuote = await menese.getRaydiumQuote(USDC_MINT, SOL_MINT, 1000_000_000, 100);

// 3. If profitable, bridge and swap
// Bridge ETH → SOL: quickUltrafastEthToSol
// Swap on Raydium: swapRaydiumApiUser
// Bridge back: quickSolToEth

Example 8: Merchant Payment Flow (Address + Balance + Sweep)

Accept payments and auto-sweep to treasury.

motoko
// Tools: getMySolanaAddress (FREE, cached) + getMySolanaBalance (FREE)
//        + sendSolTransaction ($0.05)

// 1. Show payment address to customer (from cache)
let payAddr = cachedAddresses.solana;

// 2. Periodically check if payment arrived (FREE)
let bal = switch (await menese.getMySolanaBalance()) { case (#ok(v)) v; case _ 0 };
if (bal >= invoiceAmount) {
  // 3. Mark paid, sweep to treasury
  ignore await menese.sendSolTransaction(treasury, bal - 50_000_000);
};

Example 9: Scheduled Weekly Swap (Strategy Engine)

Use #Scheduled rule type for time-based operations without custom timers.

motoko
let weekly : Menese.Rule = {
  id = 0;
  ruleType = #Scheduled;
  status = #Active;
  chainType = #Solana;
  triggerPrice = 0; sizePct = 100; positionId = 0;
  createdAt = Time.now();
  dcaConfig = null;
  scheduledConfig = ?{};  // SDK handles scheduling details
  lpConfig = null; apyMigrationConfig = null; volatilityConfig = null;
  swapAmountLamports = ?500_000_000;  // 0.5 SOL
  swapAmountWei = null;
};
ignore await menese.addStrategyRule(weekly);

Example 10: Monitor + React to Volatility

Use #VolatilityTrigger or custom timer with price feeds.

motoko
// Strategy engine approach:
let volRule : Menese.Rule = {
  id = 0;
  ruleType = #VolatilityTrigger;
  status = #Active;
  chainType = #EVM;
  triggerPrice = 0; sizePct = 50; positionId = 0;
  createdAt = Time.now();
  dcaConfig = null; lpConfig = null; scheduledConfig = null;
  apyMigrationConfig = null;
  volatilityConfig = ?{};  // SDK evaluates volatility conditions
  swapAmountLamports = null;
  swapAmountWei = ?500_000_000_000_000_000;  // 0.5 ETH
};

// Custom approach: read Chainlink price feed + react
func checkVolatility() : async () {
  let price = await menese.callEvmContractRead(
    "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419",  // ETH/USD Chainlink
    "feaf968c", [], ethRpc
  );
  // Parse price, compare to threshold, execute swap if needed
};


Unit Conversion Quick Reference

ChainUnitDecimals1 Token =
Solanalamports91,000,000,000
ICPe8s8100,000,000
Bitcoinsatoshis8100,000,000
Litecoinlitoshis8100,000,000
EVMwei1810^18
XRPdrops (Text)6"1.0"
SUImist91,000,000,000
TONnanotons91,000,000,000
Cardanolovelace61,000,000
Aptosoctas8100,000,000
NEARyoctoNEAR2410^24
Tronsun61,000,000
CloakCoinunits61,000,000
THORChainunits8100,000,000

Common Pitfalls

  • Wrong field namesevmAddress not address, suiAddress not address, nonBounceable not address, implicitAccountId not accountId, base58Address not base58
  • Flat vs variant returns — XRP and TON send return FLAT records (check .success). Raydium swap also returns FLAT. Everything else uses Result with #ok/#err.
  • Litecoin ≠ Bitcoin return type — Litecoin = SendResult (.txHash), Bitcoin = SendResultBtcLtc (.txid + .fee)
  • CloakCoin = 6 decimals, never 8
  • EVM needs your RPC — configure endpoints before any EVM operation
  • XRP amount is Text — pass "1.5" not 1500000
  • Cache addresses — deterministic per principal, fetch once and store
  • Always keep a reserve — leave min balance for rent/fees (0.05 SOL, 0.001 ICP, 0.05 ETH)
  • Get quotes before swaps — all quote functions are FREE
  • Strategy rules are FREE to create — you only pay when execution happens

Pricing Summary

OperationClient ModeAgent Mode
Addresses/Balances/QuotesFREEFREE
Strategy rule CRUDFREEFREE
Send/Transfer$0.05$0.10
DEX Swap$0.075$0.15
Bridge$0.10$0.20
DeFi (Aave/Lido/LP/Custom)$0.10
TierPriceActions/Month
Free$05 (lifetime)
Developer$35/mo1,000
Pro$99/mo5,000
Enterprise$249/moUnlimited

Files in This Skill

FilePurpose
SKILL.mdThis guide — all tools, examples, best practices
WalletBot.moICP canister wrapping MeneseSDK (production use)
scripts/wallet_commands.pyPython CLI for dfx calls (prototyping/testing)
references/api-surface.mdFull API — every type definition and function signature
references/automation.mdDeep dive — timer bots, DeFi yield, strategy patterns, custom contracts

Installation

Terminal bash

openclaw install multichain-protocol
    
Copied!

💻Code Examples

dfx --version

dfx---version.txt
That's it. No accounts needed, no wallets to set up — dfx handles everything.

### Step 2: Install the skill

clawhub install multichain-protocol

clawhub-install-multichain-protocol.txt
Or manually: copy `SKILL.md` + `wallet_commands.py` to your workspace.

### Step 3: Create an ICP identity (if you don't have one)

dfx identity use my-wallet

dfx-identity-use-my-wallet.txt
### Step 4: Try it — your first 5 sends are free

Ask your bot:

"set up a DCA: buy $50 of BTC every day"

set-up-a-dca-buy-50-of-btc-every-day.txt
### Step 5 (optional): Deploy your own canister for production

For multi-user, automation, and timers — deploy `WalletBot.mo` as your own ICP canister.

---

## Two Integration Approaches

| | Canister (Recommended) | CLI (Quick) |
|---|---|---|
| **Flow** | User → ClawdBot → Your Canister → MeneseSDK | User → ClawdBot → `dfx canister call` → MeneseSDK |
| **Setup** | Deploy `WalletBot.mo`, register with SDK | Copy `scripts/wallet_commands.py`, done |
| **Best for** | Multi-user, automation, timers, production | Single-user, prototyping, testing |
| **Automation** | ICP timers for DCA/rebalance/bots | None (manual only) |

---

## Best Practice: Cache Addresses

Addresses are **deterministic** — the same principal always gets the same addresses on every chain. Fetch once, cache forever.

return addrs

-return-addrs.txt
**Why**: Saves inter-canister call latency + cycles. Addresses never change for a given principal.

---

## EVM Chains — Bring Your Own RPC

All EVM operations (ETH, Arbitrum, Base, Polygon, BSC, Optimism) require **your own RPC endpoint**. MeneseSDK does not manage EVM RPCs.

| Chain | Chain ID | Free Public RPC |
|-------|----------|----------------|
| Ethereum | 1 | `https://eth.llamarpc.com` |
| Arbitrum | 42161 | `https://arb1.arbitrum.io/rpc` |
| Base | 8453 | `https://mainnet.base.org` |
| Polygon | 137 | `https://polygon-rpc.com` |
| BSC | 56 | `https://bsc-dataseed1.binance.org` |
| Optimism | 10 | `https://mainnet.optimism.io` |

Use Alchemy/Infura for production reliability.

---

## Complete Tool Reference

Every operation available, organized by category. Each tool shows the function, parameters, return type, cost, and a usage example.

### Tool 1: Get Addresses (FREE)

Deterministic per-principal. **Cache after first call.**

| Chain | Function | Field to Extract |
|-------|----------|-----------------|
| Solana | `getMySolanaAddress` | `.address` |
| EVM (all 6) | `getMyEvmAddress` | `.evmAddress` (NOT `.address`) |
| Bitcoin | `getMyBitcoinAddress` | `.bech32Address` |
| Litecoin | `getMyLitecoinAddress` | `.bech32Address` |
| SUI | `getMySuiAddress` | `.suiAddress` (NOT `.address`) |
| XRP | `getMyXrpAddress` | `.classicAddress` |
| TON | `getMyTonAddress` | `.nonBounceable` (NOT `.address`) |
| Cardano | `getMyCardanoAddress` | `.bech32Address` |
| Aptos | `getMyAptosAddress` | `.address` |
| NEAR | `getMyNearAddress` | `.implicitAccountId` (NOT `.accountId`) |
| Tron | `getTronAddress` | `.base58Address` (NOT `.base58`) |
| CloakCoin | `getMyCloakAddress` | `.base58Address` |
| THORChain | `getMyThorAddress` | `.bech32Address` |

**Batch**: `getAllAddresses()` — all chains in one call.
**Solana ATA**: `getMySolanaAta(mintBase58)` — get associated token account for an SPL token.

dfx canister call urs2a-ziaaa-aaaad-aembq-cai getMySolanaAddress --network ic --query

dfx-canister-call-urs2a-ziaaa-aaaad-aembq-cai-getmysolanaaddress---network-ic---query.txt
### Tool 2: Check Balances (FREE)

| Chain | Function | Returns | Unit |
|-------|----------|---------|------|
| Solana | `getMySolanaBalance` | `Result<Nat64, Text>` | lamports (÷10^9) |
| ICP | `getICPBalance` | `Result<Nat64, Text>` | e8s (÷10^8) |
| ICP (for addr) | `getICPBalanceFor(principal)` | `Result<Nat64, Text>` | e8s (÷10^8) |
| Bitcoin | `getBitcoinBalance` | `Nat64` | satoshis (÷10^8) |
| Litecoin | `getLitecoinBalance` | `Nat64` | litoshis (÷10^8) |
| EVM | `getMyEvmBalance(rpcUrl)` | `Result<Nat, Text>` | wei (÷10^18) |
| XRP | `getMyXrpBalance` | `Result<Text, Text>` | drops as text |
| SUI | `getMySuiBalance` | `Nat64` | mist (÷10^9) |
| TON | `getMyTonBalance` | `Result<Nat64, Text>` | nanotons (÷10^9) |
| Cardano | `getCardanoBalance` | `Result<Nat64, Text>` | lovelace (÷10^6) |
| Aptos | `getAptosBalance` | `Result<Nat64, Text>` | octas (÷10^8) |
| NEAR | `getMyNearBalance` | `Nat` | yoctoNEAR (÷10^24) |
| THORChain | `getThorBalance` | `[{amount, denom}]` | units (÷10^8) |
| CloakCoin | `getCloakBalance` | `Result<{address, balance, utxoCount}, Text>` | units (÷10^6) |
| Tron | `getTrxBalance(address)` | `Result<Nat64, Text>` | sun (÷10^6) |
| ICRC-1 tokens | `getICRC1Balance(ledgerId)` | `Result<Nat, Text>` | smallest unit |
| ICRC-1 (for addr) | `getICRC1BalanceFor(principal, ledgerId)` | `Result<Nat, Text>` | smallest unit |
| ICRC-1 info | `getICRC1TokenInfo(ledgerId)` | `Result<TokenInfo, Text>` | name, symbol, decimals |
| ICP tokens list | `getSupportedICPTokens()` | `[{name,symbol,canisterId,type_,category}]` | query |
| TRC-20 tokens | `getMyTrc20Balance(contract)` | `Result<Nat, Text>` | smallest unit |

**Batch**: `getAllBalances()` — parallel fetch across all chains.

**Performance tip**: For high-frequency reads, query chain RPCs directly using cached addresses. MeneseSDK is best for signing; your own RPC is faster for reads.

};

.txt
### Tool 3: Send Tokens ($0.05 client / $0.10 agent)

**Return types differ by chain** — getting this wrong causes runtime errors.

| Chain | Function | Params | Return |
|-------|----------|--------|--------|
| Solana | `sendSolTransaction` | `(to, lamports:Nat64)` | `Result<Text, Text>` |
| ICP | `sendICP` | `(to:Principal, e8s:Nat64)` | `Result<SendICPResult, Text>` |
| ICRC-1 | `sendICRC1` | `(to:Principal, amount:Nat, ledger:Text)` | `Result<SendICRC1Result, Text>` |
| Bitcoin | `sendBitcoin` | `(to, sats:Nat64)` | `Result<SendResultBtcLtc, Text>` |
| Litecoin | `sendLitecoin` | `(to, litoshis:Nat64)` | `Result<SendResult, Text>` (NOT BtcLtc!) |
| EVM | `sendEvmNativeTokenAutonomous` | `(to, wei:Nat, rpc, chainId:Nat, ?quoteId)` | `Result<SendResultEvm, Text>` |
| XRP | `sendXrpAutonomous` | `(to, amountXrp:Text, ?destTag:Nat32)` | **FLAT** `SendResultXrp` |
| SUI | `sendSui` | `(to, mist:Nat64)` | `Result<SendResult, Text>` |
| TON | `sendTonSimple` | `(to, nanotons:Nat64)` | **FLAT** `SendResultTon` |
| Aptos | `sendAptos` | `(to, octas:Nat64)` | `Result<SendResult, Text>` |
| NEAR | `sendNearTransfer` | `(to, yocto:Nat)` | `Result<Text, Text>` |
| Tron | `sendTrx` | `(to, sun:Nat64)` | `Result<Text, Text>` |
| Cardano | `sendCardanoTransaction` | `(to, lovelace:Nat64)` | `Result<Text, Text>` |
| CloakCoin | `sendCloak` | `(to, amount:Nat64)` | `Result<SendResultCloak, Text>` |
| THORChain | `sendThor` | `(to, amount:Nat64, memo:Text)` | `Result<Text, Text>` |
| SPL Token | `transferSplToken` | `(amount:Nat64, srcAta, dstAta)` | `TransferAndSendResult` |
| XRP IOU | `sendXrpIOU` | `(dest, currency, issuer, amount, ?tag)` | `SendResultXrp` |
| TRC-20 | `sendTrc20` | `(contract, to, amount:Nat, feeLimit:Nat64)` | `Result<Text, Text>` |

**Variant extras**: `sendBitcoinDynamicFee`, `sendBitcoinWithFee`, `sendLitecoinWithFee`, `sendSuiMax`, `sendTon` (with bounce/comment), `sendTonWithComment`.

else { /* r.message has error */ };

else---rmessage-has-error--.txt
### Tool 3b: ICRC-2 Approve & TransferFrom ($0.05 client / $0.10 agent)

ICRC-2 adds ERC-20-style `approve` + `transferFrom` to ICP tokens. Use when building escrow, payment splitters, or any pattern where a canister needs to spend tokens on behalf of users.

| Operation | Function | Params | Return |
|-----------|----------|--------|--------|
| Approve spender | `approveICRC2` | `(spender:Principal, amount:Nat, expiresAt:?Nat64, ledgerId:Text)` | `Result<ApproveResult, Text>` |
| Check allowance | `getICRC2Allowance` | `(owner:Principal, spender:Principal, ledgerId:Text)` | `Result<Allowance, Text>` — FREE |
| TransferFrom | `transferFromICRC2` | `(from:Principal, to:Principal, amount:Nat, ledgerId:Text)` | `Result<TransferFromResult, Text>` |

let t = await menese.transferFromICRC2(userPrincipal, treasuryPrincipal, 50_000_000, ckUSDC);

let-t--await-menesetransferfromicrc2userprincipal-treasuryprincipal-50000000-ckusdc.txt
### Tool 4: Swap on DEXes ($0.075 client / $0.15 agent)

| DEX | Chain | Function | Key Details |
|-----|-------|----------|-------------|
| Raydium | Solana | `swapRaydiumApiUser` | 8 params, FLAT return |
| Uniswap V3 | EVM | `swapTokens`, `swapTokensMultiHop` | Pass quoteId or rpc+chainId |
| Uniswap shortcuts | EVM | `swapETHForUSDC`, `swapUSDCForETH` | Quick ETH↔USDC |
| ICPSwap/KongSwap | ICP | `executeICPDexSwap(SwapRequest)` | Auto-routes best price |
| Cetus | SUI | `executeSuiSwap(network, from, to, amountIn, minOut)` | Network: `#mainnet` |
| Minswap | Cardano | `executeMinswapSwap(tokenIn, tokenOut, amount, slippage)` | Float slippage % |
| XRP DEX | XRP | `xrpSwap(destAmount, sendMax, paths, slipBps)` | Use xrpFindPaths first |

**Always get a quote first (FREE)**:
- Raydium: `getRaydiumQuote(inputMint, outputMint, amount, slipBps)`
- Uniswap: `getTokenQuote(from, to, amountIn, rpc)`
- ICP: `getICPDexQuote(tokenIn, tokenOut, amountIn, slipPct)` → `AggregatedQuote` (compares ICPSwap vs KongSwap)
- SUI: `getSuiSwapQuote(network, from, to, amountIn, slipBps)`
- Cardano: `getMinswapQuote(tokenIn, tokenOut, amountIn, slipPct)`
- XRP: `xrpFindPaths(destAmount, sourceCurrencies)`

let result = await menese.executeICPDexSwap(swapReq);

let-result--await-meneseexecuteicpdexswapswapreq.txt
### Tool 5: Bridge ETH↔SOL ($0.10 client / $0.20 agent)

| Direction | Function | Params |
|-----------|----------|--------|
| ETH→SOL | `quickUltrafastEthToSol` | `(ethWei:Nat)` |
| USDC→SOL | `quickUltrafastUsdcToSol` | `(usdc:Nat)` |
| ETH→Token | `quickUltrafastEthToToken` | `(ethWei:Nat, outputMint, slipBps:Nat)` |
| SOL→ETH | `quickSolToEth` | `(solLamports:Nat64, slipBps:Nat)` |
| USDC SOL→ETH | `quickUsdcBridgeSolToEth` | `(usdc:Nat64)` |
| CCTP (any) | `quickCctpBridge` | `(srcChainId, usdc, outputToken, fast, slipBps, ethRpc)` |

Tags

#productivity_and-tasks

Quick Info

Category Development
Model Claude 3.5
Complexity Multi-Agent
Author kyounesmercatura
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install multichain-protocol