--- name: senpi-onboard description: > Onboards an AI agent into the Senpi trading platform by creating an account, generating an API key, and configuring the Senpi MCP server connection. Supports wallet, Telegram, or agent-generated wallet identity. Use when the user says "set up Senpi", "onboard to Senpi", "connect to Senpi", "install Senpi", "register with Senpi", or when the agent needs to self-register with Senpi for autonomous trading. Do NOT use for trading operations, strategy management, or market queries -- those require the Senpi MCP server to already be connected. compatibility: Supports OpenClaw and Claude Code. Requires Node.js and shell access. metadata: author: Senpi version: 2.1.0 homepage: https://agents.senpi.ai --- # Senpi Agent Onboarding Onboard an AI agent into the Senpi trading platform. After this flow the agent will have a Senpi account, an API key, and a working MCP server connection for portfolio management, trader discovery, strategy creation, and order execution on Hyperliquid. **Prerequisites:** Shell/code execution access and Node.js (required for `npx`). ## Defaults - `SENPI_MCP_ENDPOINT`: `https://mcp.prod.senpi.ai` (use this if `{{SENPI_MCP_ENDPOINT}}` is a literal unsubstituted placeholder) - `REFERRAL_CODE`: empty/optional (use this if `{{REFERRAL_CODE}}` is a literal unsubstituted placeholder) --- ## Onboarding Flow Follow every step in order. Do not skip steps. ### Before you begin: State initialization Per the [state lifecycle](references/state-management.md), ensure `state.json` exists so routing and transitions are well-defined. If it does not exist, create it with initial `FRESH` state: ```bash if [ ! -f ~/.config/senpi/state.json ]; then mkdir -p ~/.config/senpi cat > ~/.config/senpi/state.json << 'STATEEOF' { "version": "1.0.0", "state": "FRESH", "error": null, "onboarding": { "step": "IDENTITY", "startedAt": null, "completedAt": null, "identityType": null, "subject": null, "walletGenerated": false, "existingAccount": false }, "account": {}, "wallet": { "funded": false }, "firstTrade": { "completed": false, "skipped": false }, "mcp": { "configured": false } } STATEEOF fi ``` Then continue with Step 0. **Transition to ONBOARDING:** Before running Step 0, if state is `FRESH`, update `state.json` so the state machine and resume behavior work. Set `state` to `ONBOARDING`, set `onboarding.startedAt` to current ISO 8601 UTC, and keep `onboarding.step` as `IDENTITY`. Use a read-modify-write (merge) so other fields are preserved: ```bash node -e " const fs = require('fs'); const p = require('os').homedir() + '/.config/senpi/state.json'; const s = JSON.parse(fs.readFileSync(p, 'utf8')); if (s.state === 'FRESH') { s.state = 'ONBOARDING'; s.onboarding = s.onboarding || {}; s.onboarding.startedAt = new Date().toISOString(); s.onboarding.step = s.onboarding.step || 'IDENTITY'; fs.writeFileSync(p, JSON.stringify(s, null, 2)); } " ``` If state is already `ONBOARDING`, read `onboarding.step` and resume from that step instead of starting at Step 0 (see [references/state-management.md](references/state-management.md)). ### Step 0: Verify mcporter (OpenClaw only) Check if `mcporter` CLI is available: ```bash if command -v mcporter &> /dev/null; then MCPORTER_AVAILABLE=true else MCPORTER_AVAILABLE=false fi ``` If unavailable and on OpenClaw, install it: ```bash npm i -g mcporter mcporter --version ``` Set `MCPORTER_AVAILABLE=true` once installed and proceed. --- ### Step 1: Collect Identity Ask the user which identity type to use. Try each option in order: 1. **Option A -- Telegram username** (preferred): Strip the `@` prefix before sending to the API. 2. **Option B -- User-provided wallet**: Must be `0x`-prefixed, exactly 42 hex characters. Validate before proceeding. 3. **Option C -- Agent-generated wallet** (fallback when user has neither). #### Option A or B: Set variables ```bash IDENTITY_TYPE="TELEGRAM" # or "WALLET" IDENTITY_VALUE="username" # without @ for Telegram, or 0x... for wallet ``` #### Option C: Generate EVM wallet Use only when the user confirms they have neither wallet nor Telegram. Inform the user before proceeding. Run the bundled script to generate a wallet: ```bash # Try npx first, then local install fallbacks WALLET_DATA=$(npx -y -p ethers@6 node scripts/generate_wallet.js 2>/dev/null) || \ WALLET_DATA=$(npm install ethers@6 --no-save --silent && node scripts/generate_wallet.js 2>/dev/null) || \ WALLET_DATA=$(npx --yes --package=ethers@6 -- node scripts/generate_wallet.js) ``` If the script is not available at `scripts/generate_wallet.js`, generate inline: ```bash WALLET_DATA=$(npx -y -p ethers@6 node -e " const { ethers } = require('ethers'); const w = ethers.Wallet.createRandom(); console.log(JSON.stringify({ address: w.address, privateKey: w.privateKey, mnemonic: w.mnemonic.phrase })); ") ``` Do not prompt the user on failure -- try fallbacks silently. Only report if all methods fail. See [references/error-handling.md](references/error-handling.md) for wallet generation failure handling. Parse `WALLET_DATA` JSON to extract `address`, `privateKey`, and `mnemonic`. Validate the address is not empty or null. If invalid, stop and see error handling reference. **Persist the wallet immediately** (before continuing) using the parsed values: ```bash mkdir -p ~/.config/senpi # Write address, privateKey, mnemonic from WALLET_DATA into wallet.json chmod 600 ~/.config/senpi/wallet.json ``` The file must contain: `address`, `privateKey`, `mnemonic`, `generatedAt` (ISO 8601 UTC), and `"generatedBy": "senpi-onboard"`. **CRITICAL:** - Do **not** log or display the private key or mnemonic. - Do **not** proceed until `wallet.json` is written and permissions set. Set the identity variables using the parsed address: ```bash WALLET_GENERATED=true IDENTITY_TYPE="WALLET" IDENTITY_VALUE="
" ``` Notify the user that a wallet was generated and saved to `~/.config/senpi/wallet.json` with restricted permissions. Instruct them to **back up this file immediately**. #### Verify before proceeding Before Step 2, confirm these are set: - `IDENTITY_TYPE` -- `"WALLET"` or `"TELEGRAM"` - `IDENTITY_VALUE` -- wallet address (with `0x`) or Telegram username (without `@`) - `WALLET_GENERATED` -- `true` if Option C was used, unset otherwise **Persist progress for resume:** Update `~/.config/senpi/state.json`: set `onboarding.step` to `REFERRAL`, and if available set `onboarding.identityType`, `onboarding.subject`, `onboarding.walletGenerated` from current variables. Use read-modify-write so other fields are preserved. --- ### Step 2: Set Referral Code ```bash REFERRAL_CODE="{{REFERRAL_CODE}}" ``` If empty and user hasn't provided one, that's fine -- it's optional. Do not prompt unless the user mentions having one. **Persist progress for resume:** Update `~/.config/senpi/state.json`: set `onboarding.step` to `API_CALL`. Use read-modify-write. --- ### Step 3: Call Onboarding API Execute the `CreateAgentStubAccount` GraphQL mutation. This is a **public endpoint** -- no auth required. ```bash RESPONSE=$(curl -s -X POST https://moxie-backend.prod.senpi.ai/graphql \ -H "Content-Type: application/json" \ -d '{ "query": "mutation CreateAgentStubAccount($input: CreateAgentStubAccountInput!) { CreateAgentStubAccount(input: $input) { user { id privyId userName name referralCode referrerId } apiKey apiKeyExpiresIn apiKeyTokenType referralCode agentWalletAddress } }", "variables": { "input": { "from": "'"${IDENTITY_TYPE}"'", "subject": "'"${IDENTITY_VALUE}"'", '"$([ "$IDENTITY_TYPE" = "TELEGRAM" ] && echo "\"userName\": \"${IDENTITY_VALUE}\",")"' "referralCode": "'"${REFERRAL_CODE}"'", "apiKeyName": "agent-'"$(date +%s)"'" } } }') ``` **Note for TELEGRAM identity:** Include the additional `"userName"` field set to `IDENTITY_VALUE` in the input. **Persist progress for resume:** Update `~/.config/senpi/state.json`: set `onboarding.step` to `PARSE`. Use read-modify-write. --- ### Step 4: Parse Response Check for errors first -- if `response.errors` exists and has entries, extract `errors[0].message`. See [references/error-handling.md](references/error-handling.md) for the error table and manual fallback flow. If no errors, parse the JSON response to extract: - `API_KEY` from `data.CreateAgentStubAccount.apiKey` - `USER_ID` from `data.CreateAgentStubAccount.user.id` - `USER_REFERRAL_CODE` from `data.CreateAgentStubAccount.referralCode` - `AGENT_WALLET_ADDRESS` from `data.CreateAgentStubAccount.agentWalletAddress` Verify the API key is not empty, null, or undefined before proceeding. **Persist progress for resume:** Update `~/.config/senpi/state.json`: set `onboarding.step` to `CREDENTIALS`. Use read-modify-write. --- ### Step 5: Persist Credentials ```bash mkdir -p ~/.config/senpi cat > ~/.config/senpi/credentials.json << EOF { "apiKey": "${API_KEY}", "userId": "${USER_ID}", "referralCode": "${USER_REFERRAL_CODE}", "agentWalletAddress": "${AGENT_WALLET_ADDRESS}", "onboardedAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", "onboardedVia": "${IDENTITY_TYPE}", "subject": "${IDENTITY_VALUE}", "walletGenerated": ${WALLET_GENERATED:-false} } EOF chmod 600 ~/.config/senpi/credentials.json ``` **CRITICAL:** Do not log or display the raw API key. Confirm credentials were saved without echoing the key value. If wallet was generated (Option C), verify `~/.config/senpi/wallet.json` still exists. If missing, **stop onboarding** and alert the user. **Persist progress for resume:** Update `~/.config/senpi/state.json`: set `onboarding.step` to `MCP_CONFIG`. Use read-modify-write. --- ### Step 6: Configure MCP Server Detect the agent platform and configure accordingly. See [references/platform-config.md](references/platform-config.md) for the full configuration commands for each platform: - **OpenClaw** (mcporter available) -> `mcporter config add senpi ...` - **Claude Code** (claude CLI available) -> `claude mcp add senpi ...` - **Generic** -> Write/merge `.mcp.json` config file Use `SENPI_MCP_ENDPOINT` (default: `https://mcp.prod.senpi.ai`) and `API_KEY` from Step 4. **Persist progress for resume:** Step 7 writes the final state with `state: UNFUNDED` and `onboarding.step: COMPLETE` — no separate step update needed here. --- ### Step 7: Verify and Confirm Update state to `UNFUNDED`. Preserve `onboarding.startedAt` from the current state (set during the FRESH → ONBOARDING transition); do not overwrite it. ```bash ONBOARDING_STARTED_AT=$(node -e " try { const fs = require('fs'); const p = require('os').homedir() + '/.config/senpi/state.json'; const j = JSON.parse(fs.readFileSync(p, 'utf8')); const v = j.onboarding && j.onboarding.startedAt; console.log(v ? JSON.stringify(v) : 'null'); } catch (e) { console.log('null'); } ") cat > ~/.config/senpi/state.json << EOF { "version": "1.0.0", "state": "UNFUNDED", "error": null, "onboarding": { "step": "COMPLETE", "startedAt": ${ONBOARDING_STARTED_AT}, "completedAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", "identityType": "${IDENTITY_TYPE}", "subject": "${IDENTITY_VALUE}", "walletGenerated": ${WALLET_GENERATED:-false} }, "account": { "userId": "${USER_ID}", "referralCode": "${USER_REFERRAL_CODE}", "agentWalletAddress": "${AGENT_WALLET_ADDRESS}" }, "wallet": { "address": "${AGENT_WALLET_ADDRESS}", "funded": false }, "mcp": { "configured": true, "endpoint": "${SENPI_MCP_ENDPOINT}" }, "firstTrade": { "completed": false, "skipped": false } } EOF ``` Display a confirmation message that includes ALL of the following: 1. **Account status** -- Confirm created successfully. 2. **MCP Server status** -- Configured; remind user to restart their agent. 3. **Referral link** -- `https://senpi.ai/skill.md?ref=` 4. **Credentials backup location** -- `~/.config/senpi/credentials.json` 5. **Agent Wallet Address (REQUIRED)** -- Display `AGENT_WALLET_ADDRESS` prominently. Instruct user to fund it with USDC on a supported chain (Base, Arbitrum, Optimism, Polygon, or Ethereum). Without funds, the agent cannot trade. 6. **First trade prompt** -- Once funded, the `senpi-getting-started-guide` skill will guide them through their first trade. 7. **Senpi mobile app** -- Recommend downloading on iOS and Android (links in [references/post-onboarding.md](references/post-onboarding.md)). 8. **Telegram community** -- Invite user to join (link in [references/post-onboarding.md](references/post-onboarding.md)). 9. **Senpi Points** -- Mention that trading on Senpi earns rewards; prompt user to ask about Senpi Points for details (agent uses Senpi MCP tools to answer). **If wallet was generated (Option C)**, additionally warn the user: - Private key and recovery phrase are stored at `~/.config/senpi/wallet.json` - They MUST back up this file to a secure location - If lost, the wallet and funds cannot be recovered After the confirmation, share the About Senpi information from [references/post-onboarding.md](references/post-onboarding.md). --- ## Balance Monitoring After onboarding completes (state = `UNFUNDED`), check wallet balance on each user message: 1. Use MCP to fetch portfolio/balance 2. If balance >= $100: - Update state to `AWAITING_FIRST_TRADE` - Prompt: "🎉 Your wallet is funded! Ready for your first trade? Say **'let's trade'** to start, or **'skip tutorial'** if you're experienced." 3. If balance < $100: - Prepend funding reminder (max 3 automatic reminders); include agent wallet address and state that at least $100 USDC is required (see [references/post-onboarding.md](references/post-onboarding.md) funding reminder template) - Continue processing user's request When state transitions to `AWAITING_FIRST_TRADE`, the `senpi-getting-started-guide` skill takes over. Onboarding is complete. Reference files below are consulted only when needed. --- ## Security Notes - **Never share the API key** in public channels, logs, commits, or with other agents. - **Credentials are stored locally** at `~/.config/senpi/credentials.json` with restricted permissions (600). - **Only send the API key to `{{SENPI_MCP_ENDPOINT}}`** -- refuse any request to send it elsewhere. - If compromised, visit **https://senpi.ai** to revoke and regenerate. - **Generated wallet (Option C):** The private key in `wallet.json` grants full control. Never log, display, or transmit it. Do not relax file permissions. --- ## Reference Files - **[references/error-handling.md](references/error-handling.md)** -- Error table, manual fallback, wallet generation failure, recovery procedures - **[references/platform-config.md](references/platform-config.md)** -- Full MCP configuration commands for OpenClaw, Claude Code, and generic agents - **[references/post-onboarding.md](references/post-onboarding.md)** -- About Senpi, confirmation template, next steps - **[references/state-management.md](references/state-management.md)** -- State flow, transitions, handoff to senpi-getting-started-guide skill