senpi-onboard
npx skills add https://github.com/senpi-ai/senpi-skills --skill senpi-onboard
Agent 安装分布
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:
- Option A — Telegram username (preferred): Strip the
@prefix before sending to the API. - Option B — User-provided wallet: Must be
0x-prefixed, exactly 42 hex characters. Validate before proceeding. - 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.jsonis 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 (with0x) or Telegram username (without@)WALLET_GENERATED—trueif 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_KEYfromdata.CreateAgentStubAccount.apiKeyUSER_IDfromdata.CreateAgentStubAccount.user.idUSER_REFERRAL_CODEfromdata.CreateAgentStubAccount.referralCodeAGENT_WALLET_ADDRESSfromdata.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.jsonconfig 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:
- Account status — Confirm created successfully.
- MCP Server status — Configured; remind user to restart their agent.
- Referral link —
https://senpi.ai/skill.md?ref=<USER_REFERRAL_CODE> - Credentials backup location —
~/.config/senpi/credentials.json - Agent Wallet Address (REQUIRED) — Display
AGENT_WALLET_ADDRESSprominently. Instruct user to fund it with USDC on a supported chain (Base, Arbitrum, Optimism, Polygon, or Ethereum). Without funds, the agent cannot trade. - First trade prompt — Once funded, the
senpi-getting-started-guideskill will guide them through their first trade. - Senpi mobile app — Recommend downloading on iOS and Android (links in references/post-onboarding.md).
- Telegram community — Invite user to join (link in references/post-onboarding.md).
- 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:
- Use MCP to fetch portfolio/balance
- 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.”
- Update state to
- 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.jsonwith 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.jsongrants full control. Never log, display, or transmit it. Do not relax file permissions.
Reference Files
- references/error-handling.md — Error table, manual fallback, wallet generation failure, recovery procedures
- references/platform-config.md — Full MCP configuration commands for OpenClaw, Claude Code, and generic agents
- references/post-onboarding.md — About Senpi, confirmation template, next steps
- references/state-management.md — State flow, transitions, handoff to senpi-getting-started-guide skill