Skill flagged — suspicious patterns detected

ClawHub Security flagged this skill as suspicious. Review the scan results before using.

Mpp mobula

v1.0.6

Pay-as-you-go Mobula API access — fetch crypto prices, wallet positions, and market data using a Tempo wallet that pays per call (~$0.0004) in USDC.e. No sub...

0· 152·0 current·0 all-time

Install

OpenClaw Prompt Flow

Install with OpenClaw

Best for remote or guided setup. Copy the exact prompt, then paste it into OpenClaw for flotapponnier/mobula-mpp.

Previewing Install & Setup.
Prompt PreviewInstall & Setup
Install the skill "Mpp mobula" (flotapponnier/mobula-mpp) from ClawHub.
Skill page: https://clawhub.ai/flotapponnier/mobula-mpp
Keep the work scoped to this skill only.
After install, inspect the skill metadata and help me finish setup.
Use only the metadata you can verify from ClawHub; do not invent missing requirements.
Ask before making any broader environment changes.

Command Line

CLI Commands

Use the direct CLI path if you want to install manually and keep every step visible.

OpenClaw CLI

Bare skill slug

openclaw skills install mobula-mpp

ClawHub CLI

Package manager switcher

npx clawhub@latest install mobula-mpp
Security Scan
Capability signals
CryptoRequires walletCan make purchasesRequires sensitive credentials
These labels describe what authority the skill may exercise. They are separate from suspicious or malicious moderation verdicts.
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
high confidence
Purpose & Capability
Name/description match the code: the code implements MPP/Tempo payment flow, constructs/broadcasts Tempo USDC.e transfers and retries requests. The dependencies (viem) and network endpoints (mpp.mobula.io, rpc.tempo.xyz, relay.link) are coherent with the stated purpose.
!
Instruction Scope
SKILL.md and the code instruct the agent to create wallets, fund them via a public bridge, and perform on-chain transfers. That is within scope, but the skill's runtime behavior includes creating files and secrets on disk (.claude/claudeclaw/* in process.cwd() for per-user wallets, and ~/.mpp-skill/wallet.json for the CLI), which the registry metadata did not declare. The programmatic examples instruct agents to manage per-user encrypted keys and may cause an agent to store many private keys locally.
Install Mechanism
There is no automatic install spec in the registry (instruction-only). The README and SKILL.md instruct users to git clone and run 'bun install', which pulls a standard npm dependency (viem). No downloads from untrusted URLs or archive extraction are present in the package files.
Credentials
The skill declares no required environment variables, and the code generally generates and uses a local wallet secret file instead of requiring WALLET_SECRET env. The SKILL.md mentions using process.env.TEMPO_PRIVATE_KEY for a direct low-level call, but that's optional. Still: secrets (private keys and wallet.secret) are created and stored on disk, and the manifest didn't list required config paths—this mismatch is important to notice because the skill will create sensitive files even though none were declared.
!
Persistence & Privilege
The skill persists sensitive material to disk: a CLI hot-wallet saved plaintext at ~/.mpp-skill/wallet.json, and per-user encrypted keys at .claude/claudeclaw/wallets/{userId}.json plus a local wallet.secret at .claude/claudeclaw/wallet.secret. These files are created by the skill (with best-effort chmod 600). The skill does not request 'always: true', but autonomous invocation plus on-disk persistence increases blast radius if the agent environment is shared or backups are accessible.
What to consider before installing
What to check and consider before installing: - This skill will create and store private keys locally. CLI mode writes an unencrypted hot wallet to ~/.mpp-skill/wallet.json. Multi-tenant mode stores per-user encrypted wallet files under .claude/claudeclaw/wallets/ and a single wallet.secret at .claude/claudeclaw/wallet.secret (the secret protects all per-user keys). If an attacker or backup gains access to that secret file and the wallet files they can decrypt the private keys. - The registry metadata declared no required config paths or credentials, but the code writes to process.cwd() + /.claude and the user's home dir. That mismatch means the skill will create sensitive files even though the manifest didn't state it — plan where the agent runs and who can access those directories. - The skill has network access to mpp.mobula.io, rpc.tempo.xyz and relay.link (expected for its purpose). Ensure you trust the upstream service and the GitHub repo before funding wallets used by the skill. - If you will run this in a multi-tenant or production agent, consider alternatives: use a dedicated, isolated machine account for the skill, restrict filesystem access (limit backups), rotate and protect the wallet.secret, or use an external signing service/hardware wallet so private keys are never stored on the agent host. - If you only need occasional CLI queries, prefer the CLI wallet on a trusted personal machine and keep only small USDC.e balances there. - If you want to proceed: audit the cloned repo yourself, verify the network endpoints, and confirm file locations and permissions after running the setup commands. If you do not trust storing private keys locally, do not install or use the per-user wallet features.
src/wallet.ts:34
Shell command execution detected (child_process).
Patterns worth reviewing
These patterns may indicate risky behavior. Check the VirusTotal and OpenClaw results above for context-aware analysis before installing.

Like a lobster shell, security has layers — review code before you run it.

latestvk97b844h2t9tx6908t9avgn45h85m3pa
152downloads
0stars
7versions
Updated 12h ago
v1.0.6
MIT-0

MPP (Machine Payments Protocol) Skill

Mobula's MPP API is pay-per-call : every request is settled on-chain from your own wallet using USDC.e on the Tempo chain (chainId 4217). No signup, no API key — just a funded wallet.

This skill gives you (the agent) everything needed to:

  1. Generate a Tempo wallet,
  2. Top it up via the public bridge,
  3. Make Mobula API calls and pay per-call automatically.

Setup (one-time, ~2 min)

# 1. Clone the skill (skip if already installed in your skills dir)
git clone https://github.com/Flotapponnier/mpp-skill.git
cd mpp-skill
bun install

# 2. Create a hot wallet (stored at ~/.mpp-skill/wallet.json, chmod 600)
bun run start wallet-create
# → prints address + bridge link

# 3. Fund the wallet with USDC.e on Tempo
#    Open: https://relay.link/bridge/tempo?toAddress=<your-address>
#    Bridge a few dollars of USDC from any chain (Base, Ethereum, …).
#    Tempo's gas token IS USDC, so $1 of USDC.e is enough to make ~2,500 calls.

# 4. Verify the balance
bun run start balance

Once funded, every subsequent call is automatic — no manual signing.

CLI commands

CommandWhat it does
bun run start wallet-createGenerate a new Tempo wallet (won't overwrite an existing one)
bun run start balanceShow wallet address, USDC.e balance, bridge link
bun run start price <asset>Token price — accepts name, symbol, or contract address
bun run start wallet <addr>Wallet portfolio positions
bun run start lighthouseTrending tokens
bun run start call <path> k=v…Generic call to any /api/2/* endpoint

Examples:

bun run start price bitcoin
bun run start price 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
bun run start wallet 0xd04b77bb40944110ec9c9e3165f67dadf9d52f21
bun run start lighthouse
bun run start call /api/2/wallet/activity wallet=0xabc...

Programmatic use (inside an agent)

Import directly from your TypeScript code — useful when each end-user has their own wallet (e.g. a Telegram bot where each Telegram ID gets a per-user encrypted wallet).

Per-user wallets (multi-tenant agents)

import { createUserWallet, getUserWalletAddress } from "mpp-skill/src/wallet";
import { userMobulaCall, getUserTempoBalance } from "mpp-skill/src/mpp/user-mpp";

// On first interaction with a Telegram user
const userId = 1162998296;  // Telegram numeric ID
let address = await getUserWalletAddress(userId);
if (!address) {
  const w = await createUserWallet(userId);
  address = w.address;
  // Tell the user to fund it:
  // https://relay.link/bridge/tempo?toAddress=${address}
}

// Check funds
const bal = await getUserTempoBalance(userId);
console.log(`User has $${bal?.usd ?? 0} USDC.e on Tempo`);

// Make an API call (paid from the user's own wallet)
const price = await userMobulaCall(userId, "/api/2/token/price", { asset: "bitcoin" });

Per-user wallets are stored at .claude/claudeclaw/wallets/{userId}.json, AES-256-GCM encrypted with a key derived from HMAC-SHA256(WALLET_SECRET, userId). The secret is auto-generated once at .claude/claudeclaw/wallet.secret (chmod 600). Different users cannot decrypt each other's keys.

Direct low-level call

If you already have a private key and want full control:

import { tempoFetch } from "mpp-skill/src/mpp/tempo-client";
import type { Hex } from "viem";

const data = await tempoFetch(
  "/api/2/token/price",
  { asset: "ethereum" },
  process.env.TEMPO_PRIVATE_KEY as Hex,
);

How the payment works (under the hood)

  1. Agent calls GET https://mpp.mobula.io/api/2/token/price?asset=bitcoin with no auth.
  2. Server returns HTTP 402 with WWW-Authenticate: Payment id="…", realm="mpp.mobula.io", method="tempo", request="<base64-json>". The decoded request specifies amount (in USDC.e atoms), currency: USDC.e, recipient, methodDetails.chainId: 4217, and optionally methodDetails.memo if the server pre-computes it.
  3. Skill signs and broadcasts transferWithMemo(recipient, amount, attributionMemo) on USDC.e (0x20c000000000000000000000b9537d11c60e8b50) on Tempo. attributionMemo is NOT the raw challenge id — it's a structured 32-byte memo (see "Memo layout" below) that the server's mppx lib uses to recognize and bind the payment to the challenge.
  4. Skill retries the same request with Authorization: Payment <base64url(credential)>, where credential references the tx hash.
  5. Server validates the tx (memo layout + tx hash + amount + recipient) and returns the data.

The skill does steps 2–4 automatically — agents only see the data response.

Memo layout (32 bytes)

Mobula uses the official mppx lib server-side. The bytes32 memo passed to transferWithMemo must follow the MPP attribution format, otherwise the server rejects with memo is not bound to this challenge:

BytesSizeFieldSource
0..44MPP tagkeccak256("mpp")[0..4] (constant 0xef1ed712)
4..51version0x01
5..1510server fingerprintkeccak256(realm)[0..10] (realm from WWW-Authenticate)
15..2510client fingerprintzeros for anonymous, else keccak256(clientId)[0..10]
25..327noncerandom 7 bytes, or keccak256(challengeId)[0..7] for a deterministic challenge-bound nonce

Common mistakes that produce a "memo is not bound" error: passing the raw challengeId (UTF-8 padded to 32), the base64url-decoded challengeId, keccak256(challengeId), or any value that doesn't start with the 4-byte MPP tag.

If methodDetails.memo is present in the challenge JSON, use that hex value directly (server pre-computed it) and skip the layout build.

Key facts

  • Chain: Tempo (chainId 4217, RPC https://rpc.tempo.xyz)
  • Token: USDC.e (0x20c000000000000000000000b9537d11c60e8b50)
  • Gas: paid in USDC (Tempo uses USDC as native gas token — no separate ETH needed)
  • Cost per call: ~$0.0004 typical, never above the amount specified in the 402 challenge
  • Bridge: https://relay.link/bridge/tempo — bridges from Base, Ethereum, Arbitrum, etc.

Common errors

ErrorCauseFix
No wallet foundFirst-time setup not donebun run start wallet-create
Insufficient Tempo balance: you have $0.0000…Wallet not funded yetBridge USDC.e via the printed link
Could not parse challenge from: …Server didn't return a Tempo WWW-Authenticate headerLikely an upstream issue — retry or report
Tempo tx failed: …RPC error or revert on-chainCheck balance and https://explorer.tempo.xyz for the address

When to use this vs a subscription

Mobula's subscription endpoints (/agent/x402/subscribe, etc.) are not currently configured in production. Until they are, this pay-per-call flow is the only way to call MPP API endpoints from an agent. The CLI returns a clear error if you try the legacy subscribe / status / topup / key-create commands.

Comments

Loading comments...