{"skill":{"slug":"multichain-protocol","displayName":"Multichain Protocol","summary":"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...","description":"---\nname: multichain-protocol\ndescription: 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), bridge cross-chain, manage DeFi positions (Aave, Lido, LP), automate trading (DCA, stop-loss, rebalancing), and process payments — all from a single ICP canister.\nversion: 1.0.0\nmetadata:\n  openclaw:\n    emoji: \"🌐\"\n    requires:\n      bins:\n        - name: dfx\n          install: \"sh -ci \\\"$(curl -fsSL https://internetcomputer.org/install.sh)\\\"\"\n          check: \"dfx --version\"\n        - name: python3\n          install: \"apt install -y python3 || brew install python3\"\n          check: \"python3 --version\"\n    author: Menese Protocol Team\n    license: MIT\n    tags:\n      - crypto\n      - wallet\n      - defi\n      - multi-chain\n      - icp\n      - payments\n---\n\n# Multichain Protocol — MeneseSDK Wallet Skill\n\nOperate 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.\n\n**Powered by Menese Protocol** | **Canister ID (mainnet):** `urs2a-ziaaa-aaaad-aembq-cai`\n\n---\n\n## Pricing\n\n**First 5 transactions are FREE** — no signup, no credit card, just install and go.\n\nAfter the free tier, transaction signing is charged per action via your DeveloperKey (`msk_*`). Read-only operations (balances, addresses, pool queries) are always free.\n\n---\n\n## Quickstart (2 minutes)\n\n### Step 1: Install dfx (ICP SDK)\n\nIf you don't have `dfx` installed, run this single command:\n\n```bash\nsh -ci \"$(curl -fsSL https://internetcomputer.org/install.sh)\"\n```\n\nVerify it works:\n```bash\ndfx --version\n```\n\nThat's it. No accounts needed, no wallets to set up — dfx handles everything.\n\n### Step 2: Install the skill\n\n```bash\nclawhub install multichain-protocol\n```\n\nOr manually: copy `SKILL.md` + `wallet_commands.py` to your workspace.\n\n### Step 3: Create an ICP identity (if you don't have one)\n\n```bash\ndfx identity new my-wallet\ndfx identity use my-wallet\n```\n\n### Step 4: Try it — your first 5 sends are free\n\nAsk your bot:\n```\n\"show my wallet addresses\"\n\"what's my SOL balance?\"\n\"send 0.1 ETH to 0xABC...\"\n\"swap 100 USDC to SOL on Raydium\"\n\"set up a DCA: buy $50 of BTC every day\"\n```\n\n### Step 5 (optional): Deploy your own canister for production\n\nFor multi-user, automation, and timers — deploy `WalletBot.mo` as your own ICP canister.\n\n---\n\n## Two Integration Approaches\n\n| | Canister (Recommended) | CLI (Quick) |\n|---|---|---|\n| **Flow** | User → ClawdBot → Your Canister → MeneseSDK | User → ClawdBot → `dfx canister call` → MeneseSDK |\n| **Setup** | Deploy `WalletBot.mo`, register with SDK | Copy `scripts/wallet_commands.py`, done |\n| **Best for** | Multi-user, automation, timers, production | Single-user, prototyping, testing |\n| **Automation** | ICP timers for DCA/rebalance/bots | None (manual only) |\n\n---\n\n## Best Practice: Cache Addresses\n\nAddresses are **deterministic** — the same principal always gets the same addresses on every chain. Fetch once, cache forever.\n\n```motoko\n// Canister pattern — cache in stable var\nstable var cachedAddresses : ?AddressBook = null;\n\npublic shared func getAddresses() : async AddressBook {\n  switch (cachedAddresses) {\n    case (?addrs) { addrs };  // Return cached — no inter-canister call\n    case null {\n      let sol = await menese.getMySolanaAddress();\n      let evm = await menese.getMyEvmAddress();\n      // ... fetch all chains once ...\n      let addrs = { solana = sol.address; evm = evm.evmAddress; /* ... */ };\n      cachedAddresses := ?addrs;\n      addrs;\n    };\n  };\n};\n```\n\n```python\n# CLI pattern — fetch once, store in file\nimport json, os\nCACHE_FILE = \"addresses_cache.json\"\n\ndef get_addresses():\n    if os.path.exists(CACHE_FILE):\n        return json.load(open(CACHE_FILE))\n    addrs = fetch_all_addresses()  # dfx calls\n    json.dump(addrs, open(CACHE_FILE, \"w\"))\n    return addrs\n```\n\n**Why**: Saves inter-canister call latency + cycles. Addresses never change for a given principal.\n\n---\n\n## EVM Chains — Bring Your Own RPC\n\nAll EVM operations (ETH, Arbitrum, Base, Polygon, BSC, Optimism) require **your own RPC endpoint**. MeneseSDK does not manage EVM RPCs.\n\n| Chain | Chain ID | Free Public RPC |\n|-------|----------|----------------|\n| Ethereum | 1 | `https://eth.llamarpc.com` |\n| Arbitrum | 42161 | `https://arb1.arbitrum.io/rpc` |\n| Base | 8453 | `https://mainnet.base.org` |\n| Polygon | 137 | `https://polygon-rpc.com` |\n| BSC | 56 | `https://bsc-dataseed1.binance.org` |\n| Optimism | 10 | `https://mainnet.optimism.io` |\n\nUse Alchemy/Infura for production reliability.\n\n---\n\n## Complete Tool Reference\n\nEvery operation available, organized by category. Each tool shows the function, parameters, return type, cost, and a usage example.\n\n### Tool 1: Get Addresses (FREE)\n\nDeterministic per-principal. **Cache after first call.**\n\n| Chain | Function | Field to Extract |\n|-------|----------|-----------------|\n| Solana | `getMySolanaAddress` | `.address` |\n| EVM (all 6) | `getMyEvmAddress` | `.evmAddress` (NOT `.address`) |\n| Bitcoin | `getMyBitcoinAddress` | `.bech32Address` |\n| Litecoin | `getMyLitecoinAddress` | `.bech32Address` |\n| SUI | `getMySuiAddress` | `.suiAddress` (NOT `.address`) |\n| XRP | `getMyXrpAddress` | `.classicAddress` |\n| TON | `getMyTonAddress` | `.nonBounceable` (NOT `.address`) |\n| Cardano | `getMyCardanoAddress` | `.bech32Address` |\n| Aptos | `getMyAptosAddress` | `.address` |\n| NEAR | `getMyNearAddress` | `.implicitAccountId` (NOT `.accountId`) |\n| Tron | `getTronAddress` | `.base58Address` (NOT `.base58`) |\n| CloakCoin | `getMyCloakAddress` | `.base58Address` |\n| THORChain | `getMyThorAddress` | `.bech32Address` |\n\n**Batch**: `getAllAddresses()` — all chains in one call.\n**Solana ATA**: `getMySolanaAta(mintBase58)` — get associated token account for an SPL token.\n\n```motoko\n// Example: get SOL address\nlet info = await menese.getMySolanaAddress();\nlet myAddress = info.address;  // \"5xK2abc...\"\n```\n\n```bash\n# CLI\ndfx canister call urs2a-ziaaa-aaaad-aembq-cai getMySolanaAddress --network ic --query\n```\n\n### Tool 2: Check Balances (FREE)\n\n| Chain | Function | Returns | Unit |\n|-------|----------|---------|------|\n| Solana | `getMySolanaBalance` | `Result<Nat64, Text>` | lamports (÷10^9) |\n| ICP | `getICPBalance` | `Result<Nat64, Text>` | e8s (÷10^8) |\n| ICP (for addr) | `getICPBalanceFor(principal)` | `Result<Nat64, Text>` | e8s (÷10^8) |\n| Bitcoin | `getBitcoinBalance` | `Nat64` | satoshis (÷10^8) |\n| Litecoin | `getLitecoinBalance` | `Nat64` | litoshis (÷10^8) |\n| EVM | `getMyEvmBalance(rpcUrl)` | `Result<Nat, Text>` | wei (÷10^18) |\n| XRP | `getMyXrpBalance` | `Result<Text, Text>` | drops as text |\n| SUI | `getMySuiBalance` | `Nat64` | mist (÷10^9) |\n| TON | `getMyTonBalance` | `Result<Nat64, Text>` | nanotons (÷10^9) |\n| Cardano | `getCardanoBalance` | `Result<Nat64, Text>` | lovelace (÷10^6) |\n| Aptos | `getAptosBalance` | `Result<Nat64, Text>` | octas (÷10^8) |\n| NEAR | `getMyNearBalance` | `Nat` | yoctoNEAR (÷10^24) |\n| THORChain | `getThorBalance` | `[{amount, denom}]` | units (÷10^8) |\n| CloakCoin | `getCloakBalance` | `Result<{address, balance, utxoCount}, Text>` | units (÷10^6) |\n| Tron | `getTrxBalance(address)` | `Result<Nat64, Text>` | sun (÷10^6) |\n| ICRC-1 tokens | `getICRC1Balance(ledgerId)` | `Result<Nat, Text>` | smallest unit |\n| ICRC-1 (for addr) | `getICRC1BalanceFor(principal, ledgerId)` | `Result<Nat, Text>` | smallest unit |\n| ICRC-1 info | `getICRC1TokenInfo(ledgerId)` | `Result<TokenInfo, Text>` | name, symbol, decimals |\n| ICP tokens list | `getSupportedICPTokens()` | `[{name,symbol,canisterId,type_,category}]` | query |\n| TRC-20 tokens | `getMyTrc20Balance(contract)` | `Result<Nat, Text>` | smallest unit |\n\n**Batch**: `getAllBalances()` — parallel fetch across all chains.\n\n**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.\n\n```motoko\n// Example: check SOL balance, convert to human-readable\nswitch (await menese.getMySolanaBalance()) {\n  case (#ok(lamports)) { /* lamports / 1_000_000_000 = SOL */ };\n  case (#err(e)) { /* handle error */ };\n};\n```\n\n### Tool 3: Send Tokens ($0.05 client / $0.10 agent)\n\n**Return types differ by chain** — getting this wrong causes runtime errors.\n\n| Chain | Function | Params | Return |\n|-------|----------|--------|--------|\n| Solana | `sendSolTransaction` | `(to, lamports:Nat64)` | `Result<Text, Text>` |\n| ICP | `sendICP` | `(to:Principal, e8s:Nat64)` | `Result<SendICPResult, Text>` |\n| ICRC-1 | `sendICRC1` | `(to:Principal, amount:Nat, ledger:Text)` | `Result<SendICRC1Result, Text>` |\n| Bitcoin | `sendBitcoin` | `(to, sats:Nat64)` | `Result<SendResultBtcLtc, Text>` |\n| Litecoin | `sendLitecoin` | `(to, litoshis:Nat64)` | `Result<SendResult, Text>` (NOT BtcLtc!) |\n| EVM | `sendEvmNativeTokenAutonomous` | `(to, wei:Nat, rpc, chainId:Nat, ?quoteId)` | `Result<SendResultEvm, Text>` |\n| XRP | `sendXrpAutonomous` | `(to, amountXrp:Text, ?destTag:Nat32)` | **FLAT** `SendResultXrp` |\n| SUI | `sendSui` | `(to, mist:Nat64)` | `Result<SendResult, Text>` |\n| TON | `sendTonSimple` | `(to, nanotons:Nat64)` | **FLAT** `SendResultTon` |\n| Aptos | `sendAptos` | `(to, octas:Nat64)` | `Result<SendResult, Text>` |\n| NEAR | `sendNearTransfer` | `(to, yocto:Nat)` | `Result<Text, Text>` |\n| Tron | `sendTrx` | `(to, sun:Nat64)` | `Result<Text, Text>` |\n| Cardano | `sendCardanoTransaction` | `(to, lovelace:Nat64)` | `Result<Text, Text>` |\n| CloakCoin | `sendCloak` | `(to, amount:Nat64)` | `Result<SendResultCloak, Text>` |\n| THORChain | `sendThor` | `(to, amount:Nat64, memo:Text)` | `Result<Text, Text>` |\n| SPL Token | `transferSplToken` | `(amount:Nat64, srcAta, dstAta)` | `TransferAndSendResult` |\n| XRP IOU | `sendXrpIOU` | `(dest, currency, issuer, amount, ?tag)` | `SendResultXrp` |\n| TRC-20 | `sendTrc20` | `(contract, to, amount:Nat, feeLimit:Nat64)` | `Result<Text, Text>` |\n\n**Variant extras**: `sendBitcoinDynamicFee`, `sendBitcoinWithFee`, `sendLitecoinWithFee`, `sendSuiMax`, `sendTon` (with bounce/comment), `sendTonWithComment`.\n\n```motoko\n// Example: send 0.5 SOL\nswitch (await menese.sendSolTransaction(\"5xK2abc...\", 500_000_000)) {\n  case (#ok(txHash)) { /* success — txHash is the Solana TX signature */ };\n  case (#err(e)) { /* handle error */ };\n};\n\n// Example: send XRP (FLAT return — check .success, not #ok)\nlet r = await menese.sendXrpAutonomous(\"rDestAddr...\", \"10.5\", null);\nif (r.success) { /* r.txHash, r.explorerUrl */ }\nelse { /* r.message has error */ };\n```\n\n### Tool 3b: ICRC-2 Approve & TransferFrom ($0.05 client / $0.10 agent)\n\nICRC-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.\n\n| Operation | Function | Params | Return |\n|-----------|----------|--------|--------|\n| Approve spender | `approveICRC2` | `(spender:Principal, amount:Nat, expiresAt:?Nat64, ledgerId:Text)` | `Result<ApproveResult, Text>` |\n| Check allowance | `getICRC2Allowance` | `(owner:Principal, spender:Principal, ledgerId:Text)` | `Result<Allowance, Text>` — FREE |\n| TransferFrom | `transferFromICRC2` | `(from:Principal, to:Principal, amount:Nat, ledgerId:Text)` | `Result<TransferFromResult, Text>` |\n\n```motoko\n// Approve MeneseSDK canister to spend 100 ckUSDC on your behalf\nlet ckUSDC = \"xevnm-gaaaa-aaaar-qafnq-cai\";\nlet sdk = Principal.fromText(\"urs2a-ziaaa-aaaad-aembq-cai\");\nlet r = await menese.approveICRC2(sdk, 100_000_000, null, ckUSDC);  // 100 ckUSDC (6 dec)\n\n// Check remaining allowance (FREE)\nlet allowance = await menese.getICRC2Allowance(myPrincipal, sdk, ckUSDC);\n\n// Transfer from (requires prior approval)\nlet t = await menese.transferFromICRC2(userPrincipal, treasuryPrincipal, 50_000_000, ckUSDC);\n```\n\n### Tool 4: Swap on DEXes ($0.075 client / $0.15 agent)\n\n| DEX | Chain | Function | Key Details |\n|-----|-------|----------|-------------|\n| Raydium | Solana | `swapRaydiumApiUser` | 8 params, FLAT return |\n| Uniswap V3 | EVM | `swapTokens`, `swapTokensMultiHop` | Pass quoteId or rpc+chainId |\n| Uniswap shortcuts | EVM | `swapETHForUSDC`, `swapUSDCForETH` | Quick ETH↔USDC |\n| ICPSwap/KongSwap | ICP | `executeICPDexSwap(SwapRequest)` | Auto-routes best price |\n| Cetus | SUI | `executeSuiSwap(network, from, to, amountIn, minOut)` | Network: `#mainnet` |\n| Minswap | Cardano | `executeMinswapSwap(tokenIn, tokenOut, amount, slippage)` | Float slippage % |\n| XRP DEX | XRP | `xrpSwap(destAmount, sendMax, paths, slipBps)` | Use xrpFindPaths first |\n\n**Always get a quote first (FREE)**:\n- Raydium: `getRaydiumQuote(inputMint, outputMint, amount, slipBps)`\n- Uniswap: `getTokenQuote(from, to, amountIn, rpc)`\n- ICP: `getICPDexQuote(tokenIn, tokenOut, amountIn, slipPct)` → `AggregatedQuote` (compares ICPSwap vs KongSwap)\n- SUI: `getSuiSwapQuote(network, from, to, amountIn, slipBps)`\n- Cardano: `getMinswapQuote(tokenIn, tokenOut, amountIn, slipPct)`\n- XRP: `xrpFindPaths(destAmount, sourceCurrencies)`\n\n```motoko\n// Example: swap 1 SOL → USDC on Raydium\nlet SOL = \"So11111111111111111111111111111111111111112\";\nlet USDC = \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\";\n\nlet result = await menese.swapRaydiumApiUser(\n  SOL, USDC,\n  1_000_000_000,  // 1 SOL in lamports\n  150,            // 1.5% slippage\n  true,           // wrapSol: input is native SOL\n  false,          // unwrapSol: output is USDC not SOL\n  null, null      // auto-detect ATAs\n);\n// FLAT record — access directly:\n// result.txSignature, result.outputAmount, result.priceImpactPct\n```\n\n```motoko\n// Example: swap on ICP DEX (auto-routes to ICPSwap or KongSwap)\nlet swapReq : Menese.SwapRequest = {\n  tokenIn = \"ryjl3-tyaaa-aaaaa-aaaba-cai\";  // ICP ledger\n  tokenOut = \"mxzaz-hqaaa-aaaar-qaada-cai\";  // ckUSDC\n  amountIn = 100_000_000;  // 1 ICP\n  minAmountOut = 0;\n  slippagePct = 1.0;\n  preferredDex = null;  // auto-pick best price\n};\nlet result = await menese.executeICPDexSwap(swapReq);\n```\n\n### Tool 5: Bridge ETH↔SOL ($0.10 client / $0.20 agent)\n\n| Direction | Function | Params |\n|-----------|----------|--------|\n| ETH→SOL | `quickUltrafastEthToSol` | `(ethWei:Nat)` |\n| USDC→SOL | `quickUltrafastUsdcToSol` | `(usdc:Nat)` |\n| ETH→Token | `quickUltrafastEthToToken` | `(ethWei:Nat, outputMint, slipBps:Nat)` |\n| SOL→ETH | `quickSolToEth` | `(solLamports:Nat64, slipBps:Nat)` |\n| USDC SOL→ETH | `quickUsdcBridgeSolToEth` | `(usdc:Nat64)` |\n| CCTP (any) | `quickCctpBridge` | `(srcChainId, usdc, outputToken, fast, slipBps, ethRpc)` |\n\n```motoko\n// Example: bridge 0.1 ETH to Solana\nlet result = await menese.quickUltrafastEthToSol(100_000_000_000_000_000);  // 0.1 ETH in wei\n// Result<Text, Text> — ok = status text\n```\n\n### Tool 6: DeFi — Aave V3 ($0.10 agent)\n\n| Operation | Function | Params |\n|-----------|----------|--------|\n| Supply ETH | `aaveSupplyEth` | `(wei:Nat, rpc, ?quoteId)` → `Result<SupplyEthResult, Text>` |\n| Withdraw ETH | `aaveWithdrawEth` | `(wei:Nat, rpc, ?quoteId)` → `Result<WithdrawEthResult, Text>` |\n| Supply ERC-20 | `aaveSupplyToken` | `(tokenAddr, amount:Nat, rpc, ?quoteId)` |\n| Withdraw ERC-20 | `aaveWithdrawToken` | `(tokenAddr, amount:Nat, rpc, ?quoteId)` |\n| Read aWETH bal | `getAWethBalance` | `(user, rpc)` → FREE |\n| Read aToken bal | `getATokenBalance` | `(aTokenAddr, user, rpc)` → FREE |\n\n```motoko\n// Supply 0.5 ETH to Aave → receive aWETH (~2-3% APY)\nlet r = await menese.aaveSupplyEth(500_000_000_000_000_000, ethRpc, null);\nswitch (r) {\n  case (#ok(res)) { /* res.txHash, res.aTokenAddress */ };\n  case (#err(e)) { /* error */ };\n};\n```\n\n### Tool 7: DeFi — Lido Staking ($0.10 agent)\n\n| Operation | Function | Return |\n|-----------|----------|--------|\n| Stake ETH→stETH | `stakeEthForStEth(wei, rpc, ?quoteId)` | `Result<StakeResult, Text>` |\n| Wrap stETH→wstETH | `wrapStEth(amount, rpc, ?quoteId)` | `Result<WrapResult, Text>` |\n| Unwrap wstETH→stETH | `unwrapWstEth(amount, rpc, ?quoteId)` | `Result<UnwrapResult, Text>` |\n| Read stETH bal | `getStEthBalance(user, rpc)` | FREE |\n| Read wstETH bal | `getWstEthBalance(user, rpc)` | FREE |\n\n```motoko\n// Stake 1 ETH with Lido (~3-4% APY), then wrap for DeFi composability\nignore await menese.stakeEthForStEth(1_000_000_000_000_000_000, ethRpc, null);\nignore await menese.wrapStEth(1_000_000_000_000_000_000, ethRpc, null);\n```\n\n### Tool 8: DeFi — Uniswap V3 Liquidity ($0.10 agent)\n\n| Operation | Function |\n|-----------|----------|\n| Add ETH+Token LP | `addLiquidityETH(tokenSymbol, tokenAmt, ethAmt, slipBps, rpc, ?quoteId)` |\n| Add Token+Token LP | `addLiquidity(tokenA, tokenB, amtA, amtB, slipBps, rpc, ?quoteId)` |\n| Remove ETH LP | `removeLiquidityETH(tokenSymbol, lpAmt, slipBps, feeOnTransfer, rpc, ?quoteId)` |\n| Remove Token LP | `removeLiquidity(tokenA, tokenB, lpAmt, slipBps, rpc, ?quoteId)` |\n| Read reserves | `getPoolReserves(tokenA, tokenB, rpc)` — FREE |\n| Get pair addr | `getPairAddress(tokenA, tokenB, rpc)` — FREE |\n\n### Tool 9: Custom EVM Contract Calls\n\n| Operation | Function | Cost |\n|-----------|----------|------|\n| Read (view) | `callEvmContractRead(contract, selector4byte, argsHexes, rpc)` | FREE |\n| Write (tx) | `callEvmContractWrite(contract, selector, args, rpc, chainId, value, ?quoteId)` | $0.10 |\n\nSelector = first 4 bytes of `keccak256(\"functionName(type1,type2)\")`, hex-encoded, no `0x` prefix.\n\n```motoko\n// Read Chainlink ETH/USD price (FREE)\nlet result = await menese.callEvmContractRead(\n  \"0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419\",  // ETH/USD feed\n  \"feaf968c\",  // latestRoundData()\n  [], ethRpc\n);\n```\n\n### Tool 10: Strategy Engine (rule creation FREE, execution per-action pricing)\n\n| Operation | Function | Cost |\n|-----------|----------|------|\n| Create rule | `addStrategyRule(Rule)` | FREE |\n| List rules | `getMyStrategyRules()` | FREE |\n| Update status | `updateStrategyRuleStatus(ruleId, status)` | FREE |\n| Delete rule | `deleteStrategyRule(ruleId)` | FREE |\n| View logs | `getStrategyLogs()` | FREE |\n| Init automation | `initAutomation()` | FREE |\n\nRule types: `#DCA`, `#StopLoss`, `#TakeProfit`, `#Rebalance`, `#Scheduled`, `#APYMigration`, `#LiquidityProvision`, `#VolatilityTrigger`.\n\nRule statuses: `#Active`, `#Paused`, `#Cancelled`, `#Executed`, `#Executing`, `#Failed`, `#Draft`, `#Confirmed`, `#Ready`.\n\n### Tool 11: Solana ATA / XRP Trustlines (setup)\n\n| Operation | Function | Cost |\n|-----------|----------|------|\n| Create Solana ATA | `createMySolanaAtaForMint(mint, ata)` | Send pricing |\n| Create ATA (custom program) | `createMySolanaAtaForMintWithProgram(mint, ata, programId)` | Send pricing |\n| Set XRP trustline | `xrpSetTrustline(currency, issuer, limit)` | Send pricing |\n| Read XRP trustlines | `xrpGetAccountLines()` | FREE |\n| Get Solana ATA | `getMySolanaAta(mint)` | FREE |\n\n### Tool 12: Developer/Billing\n\n| Operation | Function | Cost |\n|-----------|----------|------|\n| Register canister | `registerDeveloperCanister(Principal, appName)` | FREE |\n| Get dev key | `getMyDeveloperKey()` | FREE |\n| Regenerate key | `regenerateDeveloperKey()` | FREE |\n| Validate key | `validateDeveloperKey(key)` | FREE |\n| Check account | `getMyGatewayAccount()` → `UserAccount` | FREE |\n| Check dev account | `getMyDeveloperAccount()` → `?DeveloperAccountV3` | FREE |\n| Deposit credits | `depositGatewayCredits(currency, amount)` | ICP cost |\n\n### Tool 13: Utility\n\n| Operation | Function | Cost |\n|-----------|----------|------|\n| BTC max send | `getBitcoinMaxSendAmount(?feeRate)` → `{maxAmount, fee, utxoCount}` | FREE |\n| LTC max send | `getLitecoinMaxSendAmount(?feeRate)` → `{maxAmount, fee, utxoCount}` | FREE |\n| Health check | `health()` | FREE |\n| Version | `version()` | FREE |\n\n### Tool 14: ICP DEX LP Management ($0.10 agent)\n\nManage liquidity positions on ICPSwap and KongSwap. The SDK aggregates both DEXes.\n\n| Operation | Function | Cost |\n|-----------|----------|------|\n| List pools | `getICPDexPools()` → `[PoolInfo]` | FREE |\n| List tokens | `getICPDexTokens()` → `[DexToken]` | FREE |\n| View positions | `getICPLPPositions()` → `[LPPosition]` | FREE |\n| Add liquidity | `addICPLiquidity(AddLiquidityRequest)` → `Result<AddLiquidityResult, Text>` | $0.10 |\n| Remove liquidity | `removeICPLiquidity(RemoveLiquidityRequest)` → `Result<RemoveLiquidityResult, Text>` | $0.10 |\n\n**Types:**\n\n```\nAddLiquidityRequest = { poolId:Text, dex:{#ICPSwap|#KongSwap}, token0:Text, token1:Text, token0Amount:Nat, token1Amount:Nat, slippagePct:Float }\nRemoveLiquidityRequest = { poolId:Text, dex:{#ICPSwap|#KongSwap}, lpTokens:Nat, slippagePct:Float }\nLPPosition = { poolId, dex, token0, token1, token0Symbol, token1Symbol, liquidity:Nat, token0Amount, token1Amount, unclaimedFees:?(Nat,Nat), valueUsd:?Nat }\nPoolInfo = { poolId, dex, token0, token1, token0Symbol, token1Symbol, reserve0, reserve1, fee, tvl:?Nat, apr:?Float, volume24h:?Nat }\nDexToken = { canisterId, symbol, name, decimals:Nat8, fee:Nat, standard:{#ICRC1|#ICRC2|#DIP20}, logo:?Text, category:?Text, availableOn:[DexId] }\n```\n\n**Well-known pools:** ICP/ckUSDC, ckBTC/ICP, ICP/ckETH, ckUSDT/ckUSDC, CHAT/ICP (on both ICPSwap and KongSwap).\n\n```motoko\n// Discover pools, then add liquidity\nlet pools = await menese.getICPDexPools();\n// Find ICP/ckUSDC pool\nlet pool = Array.find<DexTypes.PoolInfo>(pools, func(p) { p.token0Symbol == \"ICP\" and p.token1Symbol == \"ckUSDC\" });\n\nswitch (pool) {\n  case (?p) {\n    let req : DexTypes.AddLiquidityRequest = {\n      poolId = p.poolId;\n      dex = p.dex;\n      token0 = \"ryjl3-tyaaa-aaaaa-aaaba-cai\";  // ICP ledger\n      token1 = \"xevnm-gaaaa-aaaar-qafnq-cai\";  // ckUSDC\n      token0Amount = 100_000_000;  // 1 ICP\n      token1Amount = 10_000_000;   // 10 ckUSDC\n      slippagePct = 1.0;\n    };\n    let result = await menese.addICPLiquidity(req);\n  };\n  case null { /* pool not found */ };\n};\n\n// View positions\nlet positions = await menese.getICPLPPositions();\n// Remove liquidity\nlet removeReq : DexTypes.RemoveLiquidityRequest = {\n  poolId = positions[0].poolId;\n  dex = positions[0].dex;\n  lpTokens = positions[0].liquidity;  // Remove all\n  slippagePct = 1.0;\n};\nlet removed = await menese.removeICPLiquidity(removeReq);\n```\n\n### Tool 15: ICP AI Rebalancer (FREE)\n\nAI-powered portfolio rebalancing recommendations using Herfindahl-Hirschman Index diversification scoring, impermanent loss estimation, and risk-adjusted APY analysis.\n\n| Operation | Function | Cost |\n|-----------|----------|------|\n| Get recommendations | `getICPRebalanceRecommendations(preferences, tokenBalances, pools?)` → `[RebalanceRecommendation]` | FREE |\n\n**Types:**\n\n```\nRebalancePreferences = { targetCategories:[Text], riskTolerance:Text, minApy:?Float, maxImpermanentLoss:?Float, autoCompound:Bool }\n  targetCategories: [\"stablecoin\", \"defi\", \"lst\", \"yield\", \"wrapped\", \"meme\", \"ecosystem\"]\n  riskTolerance: \"conservative\" | \"moderate\" | \"aggressive\"\n\nRebalanceRecommendation = { 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 }\n```\n\n```motoko\n// Get rebalancing recommendations for your ICP portfolio\nlet prefs : DexTypes.RebalancePreferences = {\n  targetCategories = [\"stablecoin\", \"defi\", \"lst\"];\n  riskTolerance = \"moderate\";\n  minApy = ?5.0;        // Only suggest >5% APY\n  maxImpermanentLoss = ?10.0;  // Max 10% IL risk\n  autoCompound = true;\n};\n\n// Pass current balances: [(canisterId, amount)]\nlet balances = [\n  (\"ryjl3-tyaaa-aaaaa-aaaba-cai\", 500_000_000),  // 5 ICP\n  (\"xevnm-gaaaa-aaaar-qafnq-cai\", 100_000_000),  // 100 ckUSDC\n  (\"mxzaz-hqaaa-aaaar-qaada-cai\", 50_000),        // 0.0005 ckBTC\n];\n\nlet recommendations = await menese.getICPRebalanceRecommendations(prefs, balances, null);\nfor (rec in recommendations.vals()) {\n  Debug.print(rec.reason # \" | Confidence: \" # Float.toText(rec.confidence));\n  // e.g., \"Swap 2 ICP → ckUSDC and add to ICP/ckUSDC pool for 12.5% APY | Confidence: 0.85\"\n};\n```\n\n---\n\n## Combining Tools — Practical Automation Examples\n\nThe real power is combining these tools. Below are complete patterns showing how tools work together.\n\n### Example 1: DCA Bot (Timer + Balance + Swap)\n\nBuy USDC with SOL every hour if balance exceeds threshold.\n\n```motoko\n// Tools used: getMySolanaBalance (FREE) + swapRaydiumApiUser ($0.075)\nfunc dcaCycle() : async () {\n  let balance = switch (await menese.getMySolanaBalance()) {\n    case (#ok(v)) v; case (#err(_)) return;\n  };\n  if (balance < 500_000_000) return;  // < 0.5 SOL, skip\n\n  let swapAmt = balance - 50_000_000;  // Keep 0.05 SOL for rent\n  let _ = await menese.swapRaydiumApiUser(\n    \"So11111111111111111111111111111111111111112\",  // SOL\n    \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\",  // USDC\n    swapAmt, 150, true, false, null, null\n  );\n};\n\n// Run every hour\nlet timerId = Timer.recurringTimer<system>(#seconds(3600), dcaCycle);\n```\n\n### Example 2: Stop-Loss via Strategy Engine\n\nSet a stop-loss rule that auto-sells when price drops. No timer needed — MeneseSDK evaluates.\n\n```motoko\n// Tool used: addStrategyRule (FREE to create, execution costs per action)\nlet rule : Menese.Rule = {\n  id = 0;\n  ruleType = #StopLoss;\n  status = #Active;\n  chainType = #Solana;\n  triggerPrice = 120_000_000;  // Trigger at this price level\n  sizePct = 100;  // Sell 100% of position\n  positionId = 0;\n  createdAt = Time.now();\n  dcaConfig = null; lpConfig = null; scheduledConfig = null;\n  apyMigrationConfig = null; volatilityConfig = null;\n  swapAmountLamports = ?1_000_000_000;  // 1 SOL\n  swapAmountWei = null;\n};\nlet ruleId = await menese.addStrategyRule(rule);\n```\n\n### Example 3: Take-Profit + Stop-Loss Combo\n\nSet both on the same position — whichever triggers first wins.\n\n```motoko\n// Tools: addStrategyRule × 2\n// Take-profit at 200\nlet tp : Menese.Rule = { /* ... */ ruleType = #TakeProfit; triggerPrice = 200_000_000; sizePct = 50; /* sell half */ /* ... */ };\nlet tpId = await menese.addStrategyRule(tp);\n\n// Stop-loss at 100\nlet sl : Menese.Rule = { /* ... */ ruleType = #StopLoss; triggerPrice = 100_000_000; sizePct = 100; /* sell all */ /* ... */ };\nlet slId = await menese.addStrategyRule(sl);\n\n// When one triggers, cancel the other\n// Check via getMyStrategyRules() or getStrategyLogs() in your timer\n```\n\n### Example 4: DCA via Strategy Engine (no custom timer)\n\nLet MeneseSDK handle the scheduling internally.\n\n```motoko\n// Tool: addStrategyRule with DCA config\nlet dca : Menese.Rule = {\n  id = 0;\n  ruleType = #DCA;\n  status = #Active;\n  chainType = #Solana;\n  triggerPrice = 0; sizePct = 100; positionId = 0;\n  createdAt = Time.now();\n  dcaConfig = ?{\n    amountPerInterval = 100_000_000;  // 0.1 SOL per buy\n    currentInterval = 0;\n    intervalSeconds = 3600;  // Every hour\n    lastExecutedAt = 0;\n    maxIntervals = 168;  // Run for 1 week (168 hours)\n    targetToken = \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\";  // Buy USDC\n    totalSpent = 0;\n  };\n  lpConfig = null; scheduledConfig = null;\n  apyMigrationConfig = null; volatilityConfig = null;\n  swapAmountLamports = ?100_000_000;\n  swapAmountWei = null;\n};\nignore await menese.addStrategyRule(dca);\n```\n\n### Example 5: Multi-Chain Sweep (Balance + Send across chains)\n\nCheck all balances, sweep any above threshold to treasury.\n\n```motoko\n// Tools: getAllBalances (FREE) + sendSolTransaction + sendICP + sendEvmNativeTokenAutonomous\nfunc sweepCycle() : async () {\n  let bals = await menese.getAllBalances();\n\n  // Sweep SOL if > 1 SOL\n  switch (bals.solana) {\n    case (#ok(lamports)) {\n      if (lamports > 1_000_000_000) {\n        ignore await menese.sendSolTransaction(solTreasury, lamports - 50_000_000);\n      };\n    };\n    case (#err(_)) {};\n  };\n\n  // Sweep ICP if > 1 ICP\n  switch (bals.icp) {\n    case (#ok(e8s)) {\n      if (e8s > 100_000_000) {\n        ignore await menese.sendICP(Principal.fromText(icpTreasury), e8s - 100_000);\n      };\n    };\n    case (#err(_)) {};\n  };\n\n  // Sweep ETH if > 0.1 ETH\n  switch (await menese.getMyEvmBalance(ethRpc)) {\n    case (#ok(wei)) {\n      if (wei > 100_000_000_000_000_000) {\n        ignore await menese.sendEvmNativeTokenAutonomous(\n          ethTreasury, wei - 50_000_000_000_000_000, ethRpc, 1, null\n        );\n      };\n    };\n    case (#err(_)) {};\n  };\n};\n```\n\n### Example 6: DeFi Yield Rebalancer (Aave + Lido + LP)\n\nAllocate idle ETH across DeFi protocols on a timer.\n\n```motoko\n// Tools: getMyEvmBalance + getAWethBalance + getStEthBalance (all FREE)\n//        + aaveSupplyEth + stakeEthForStEth + wrapStEth ($0.10 each)\n\nfunc rebalanceCycle() : async () {\n  let evmAddr = (await menese.getMyEvmAddress()).evmAddress;  // Cached ideally\n  let ethBal = switch (await menese.getMyEvmBalance(ethRpc)) { case (#ok(v)) v; case _ 0 };\n  let aaveBal = switch (await menese.getAWethBalance(evmAddr, ethRpc)) { case (#ok(v)) v; case _ 0 };\n  let lidoBal = switch (await menese.getStEthBalance(evmAddr, ethRpc)) { case (#ok(v)) v; case _ 0 };\n\n  let reserve = 50_000_000_000_000_000;  // 0.05 ETH for gas\n  if (ethBal <= reserve) return;\n  let deployable = ethBal - reserve;\n\n  // 50% Aave, 50% Lido\n  let aaveTarget = deployable / 2;\n  let lidoTarget = deployable / 2;\n\n  if (aaveTarget > aaveBal and aaveTarget - aaveBal > 10_000_000_000_000_000) {\n    ignore await menese.aaveSupplyEth(aaveTarget - aaveBal, ethRpc, null);\n  };\n  if (lidoTarget > lidoBal and lidoTarget - lidoBal > 10_000_000_000_000_000) {\n    ignore await menese.stakeEthForStEth(lidoTarget - lidoBal, ethRpc, null);\n    ignore await menese.wrapStEth(lidoTarget - lidoBal, ethRpc, null);\n  };\n};\n\n// Run every 6 hours\nlet timerId = Timer.recurringTimer<system>(#seconds(21600), rebalanceCycle);\n```\n\n### Example 7: Cross-Chain Arbitrage (Bridge + Swap)\n\nMove funds between Ethereum and Solana to capture price differences.\n\n```motoko\n// Tools: getTokenQuote (FREE) + getRaydiumQuote (FREE)\n//        + quickUltrafastEthToSol ($0.10) + swapRaydiumApiUser ($0.075)\n\n// 1. Check ETH USDC price on Uniswap\nlet ethQuote = await menese.getTokenQuote(\"USDC\", \"WETH\", 1000_000_000, ethRpc);\n\n// 2. Check SOL USDC price on Raydium\nlet solQuote = await menese.getRaydiumQuote(USDC_MINT, SOL_MINT, 1000_000_000, 100);\n\n// 3. If profitable, bridge and swap\n// Bridge ETH → SOL: quickUltrafastEthToSol\n// Swap on Raydium: swapRaydiumApiUser\n// Bridge back: quickSolToEth\n```\n\n### Example 8: Merchant Payment Flow (Address + Balance + Sweep)\n\nAccept payments and auto-sweep to treasury.\n\n```motoko\n// Tools: getMySolanaAddress (FREE, cached) + getMySolanaBalance (FREE)\n//        + sendSolTransaction ($0.05)\n\n// 1. Show payment address to customer (from cache)\nlet payAddr = cachedAddresses.solana;\n\n// 2. Periodically check if payment arrived (FREE)\nlet bal = switch (await menese.getMySolanaBalance()) { case (#ok(v)) v; case _ 0 };\nif (bal >= invoiceAmount) {\n  // 3. Mark paid, sweep to treasury\n  ignore await menese.sendSolTransaction(treasury, bal - 50_000_000);\n};\n```\n\n### Example 9: Scheduled Weekly Swap (Strategy Engine)\n\nUse `#Scheduled` rule type for time-based operations without custom timers.\n\n```motoko\nlet weekly : Menese.Rule = {\n  id = 0;\n  ruleType = #Scheduled;\n  status = #Active;\n  chainType = #Solana;\n  triggerPrice = 0; sizePct = 100; positionId = 0;\n  createdAt = Time.now();\n  dcaConfig = null;\n  scheduledConfig = ?{};  // SDK handles scheduling details\n  lpConfig = null; apyMigrationConfig = null; volatilityConfig = null;\n  swapAmountLamports = ?500_000_000;  // 0.5 SOL\n  swapAmountWei = null;\n};\nignore await menese.addStrategyRule(weekly);\n```\n\n### Example 10: Monitor + React to Volatility\n\nUse `#VolatilityTrigger` or custom timer with price feeds.\n\n```motoko\n// Strategy engine approach:\nlet volRule : Menese.Rule = {\n  id = 0;\n  ruleType = #VolatilityTrigger;\n  status = #Active;\n  chainType = #EVM;\n  triggerPrice = 0; sizePct = 50; positionId = 0;\n  createdAt = Time.now();\n  dcaConfig = null; lpConfig = null; scheduledConfig = null;\n  apyMigrationConfig = null;\n  volatilityConfig = ?{};  // SDK evaluates volatility conditions\n  swapAmountLamports = null;\n  swapAmountWei = ?500_000_000_000_000_000;  // 0.5 ETH\n};\n\n// Custom approach: read Chainlink price feed + react\nfunc checkVolatility() : async () {\n  let price = await menese.callEvmContractRead(\n    \"0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419\",  // ETH/USD Chainlink\n    \"feaf968c\", [], ethRpc\n  );\n  // Parse price, compare to threshold, execute swap if needed\n};\n```\n\n---\n\n## Unit Conversion Quick Reference\n\n| Chain | Unit | Decimals | 1 Token = |\n|-------|------|----------|-----------|\n| Solana | lamports | 9 | 1,000,000,000 |\n| ICP | e8s | 8 | 100,000,000 |\n| Bitcoin | satoshis | 8 | 100,000,000 |\n| Litecoin | litoshis | 8 | 100,000,000 |\n| EVM | wei | 18 | 10^18 |\n| XRP | drops (Text) | 6 | \"1.0\" |\n| SUI | mist | 9 | 1,000,000,000 |\n| TON | nanotons | 9 | 1,000,000,000 |\n| Cardano | lovelace | 6 | 1,000,000 |\n| Aptos | octas | 8 | 100,000,000 |\n| NEAR | yoctoNEAR | 24 | 10^24 |\n| Tron | sun | 6 | 1,000,000 |\n| CloakCoin | units | 6 | 1,000,000 |\n| THORChain | units | 8 | 100,000,000 |\n\n---\n\n## Common Pitfalls\n\n1. **Wrong field names** — `evmAddress` not `address`, `suiAddress` not `address`, `nonBounceable` not `address`, `implicitAccountId` not `accountId`, `base58Address` not `base58`\n2. **Flat vs variant returns** — XRP and TON send return FLAT records (check `.success`). Raydium swap also returns FLAT. Everything else uses `Result<T, Text>` with `#ok/#err`.\n3. **Litecoin ≠ Bitcoin return type** — Litecoin = `SendResult` (`.txHash`), Bitcoin = `SendResultBtcLtc` (`.txid` + `.fee`)\n4. **CloakCoin = 6 decimals**, never 8\n5. **EVM needs your RPC** — configure endpoints before any EVM operation\n6. **XRP amount is Text** — pass `\"1.5\"` not `1500000`\n7. **Cache addresses** — deterministic per principal, fetch once and store\n8. **Always keep a reserve** — leave min balance for rent/fees (0.05 SOL, 0.001 ICP, 0.05 ETH)\n9. **Get quotes before swaps** — all quote functions are FREE\n10. **Strategy rules are FREE to create** — you only pay when execution happens\n\n---\n\n## Pricing Summary\n\n| Operation | Client Mode | Agent Mode |\n|-----------|------------|------------|\n| Addresses/Balances/Quotes | FREE | FREE |\n| Strategy rule CRUD | FREE | FREE |\n| Send/Transfer | $0.05 | $0.10 |\n| DEX Swap | $0.075 | $0.15 |\n| Bridge | $0.10 | $0.20 |\n| DeFi (Aave/Lido/LP/Custom) | — | $0.10 |\n\n| Tier | Price | Actions/Month |\n|------|-------|---------------|\n| Free | $0 | 5 (lifetime) |\n| Developer | $35/mo | 1,000 |\n| Pro | $99/mo | 5,000 |\n| Enterprise | $249/mo | Unlimited |\n\n---\n\n## Files in This Skill\n\n| File | Purpose |\n|------|---------|\n| `SKILL.md` | This guide — all tools, examples, best practices |\n| `WalletBot.mo` | ICP canister wrapping MeneseSDK (production use) |\n| `scripts/wallet_commands.py` | Python CLI for dfx calls (prototyping/testing) |\n| `references/api-surface.md` | Full API — every type definition and function signature |\n| `references/automation.md` | Deep dive — timer bots, DeFi yield, strategy patterns, custom contracts |\n","tags":{"latest":"1.0.0"},"stats":{"comments":0,"downloads":348,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":1},"createdAt":1771445832531,"updatedAt":1779077099050},"latestVersion":{"version":"1.0.0","createdAt":1771445832531,"changelog":"- Initial release of multichain-protocol skill v1.0.0.\n- Instantly turn any AI agent into a wallet for 19 blockchain networks via MeneseSDK on ICP.\n- Supports cross-chain token transfers, swaps on popular DEXes (Raydium, Uniswap, ICPSwap, KongSwap, Cetus, Minswap), bridging, DeFi management (Aave, Lido, LPs), trading automation (DCA, stop-loss, rebalancing), and payment processing.\n- Free to use for first 5 transactions; read-only operations are always free.\n- Provides both canister and CLI integration modes, with detailed quickstart instructions and best practices for address caching.\n- Requires installation of dfx and python3; EVM operations require user-supplied RPC endpoints.","license":null},"metadata":{"setup":[],"os":null,"systems":null},"owner":{"handle":"kyounesmercatura","userId":"s17eatn1x84nmfbf82d54rwsh188509p","displayName":"KYounesMercatura","image":"https://avatars.githubusercontent.com/u/209348522?v=4"},"moderation":{"isSuspicious":false,"isMalwareBlocked":false,"verdict":"clean","reasonCodes":["review.llm_review"],"summary":"Review: review.llm_review","engineVersion":"v2.4.24","updatedAt":1779932766172}}