senpi-onboard

📁 senpi-ai/senpi-skills 📅 2 days ago
9
总安装量
7
周安装量
#31794
全站排名
安装命令
npx skills add https://github.com/senpi-ai/senpi-skills --skill senpi-onboard

Agent 安装分布

opencode 6
antigravity 6
github-copilot 6
codex 6
windsurf 6
kimi-cli 6

Skill 文档

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, ensure state.json exists so routing and transitions are well-defined. If it does not exist, create it with initial FRESH state:

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:

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

Step 0: Verify mcporter (OpenClaw only)

Check if mcporter CLI is available:

if command -v mcporter &> /dev/null; then
  MCPORTER_AVAILABLE=true
else
  MCPORTER_AVAILABLE=false
fi

If unavailable and on OpenClaw, install it:

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

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:

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

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

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:

WALLET_GENERATED=true
IDENTITY_TYPE="WALLET"
IDENTITY_VALUE="<address from WALLET_DATA>"

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

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.

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

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

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 linkhttps://senpi.ai/skill.md?ref=<USER_REFERRAL_CODE>
  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).
  8. Telegram community — Invite user to join (link in 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.


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