← 返回
未分类

Multichain Protocol

Turn any AI agent into a 19-chain crypto wallet via MeneseSDK on ICP. Send tokens, swap on DEXes (Raydium, Uniswap, ICPSwap, KongSwap, Cetus, Minswap), bridg...
kyounesmercatura
未分类 clawhub v1.0.0 100000 Key: 无需
★ 0
Stars
📥 291
下载
💾 0
安装

概述

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:

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

Verify it works:

dfx --version

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

Step 2: Install the skill

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)

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

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

Ask your bot:

"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.

// 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;
    };
  };
};
# 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.

// Example: get SOL address
let info = await menese.getMySolanaAddress();
let myAddress = info.address;  // "5xK2abc..."
# 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.

// 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.

// 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
// 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)
// 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
// 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)
// 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
// 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
// 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.

// 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:

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).

// 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:

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 }
// 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.

// 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.

// 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.

// 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.

// 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.

// 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.

// 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.

// 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.

// 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.

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.

// 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

  1. Wrong field namesevmAddress not address, suiAddress not address, nonBounceable not address, implicitAccountId not accountId, base58Address not base58
  2. 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.
  3. Litecoin ≠ Bitcoin return type — Litecoin = SendResult (.txHash), Bitcoin = SendResultBtcLtc (.txid + .fee)
  4. CloakCoin = 6 decimals, never 8
  5. EVM needs your RPC — configure endpoints before any EVM operation
  6. XRP amount is Text — pass "1.5" not 1500000
  7. Cache addresses — deterministic per principal, fetch once and store
  8. Always keep a reserve — leave min balance for rent/fees (0.05 SOL, 0.001 ICP, 0.05 ETH)
  9. Get quotes before swaps — all quote functions are FREE
  10. 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

版本历史

共 1 个版本

  • v1.0.0 当前
    2026-05-12 05:51 安全 安全

安全检测

暂无安全检测报告