Claude
Skills
Sign in
Back

senpi-onboard

Included with Lifetime
$97 forever

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.

Backend & APIsscripts

What this skill does


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

**Arena intent hard-gate:** If the user's message contains "arena", "agents arena", "competition", "prize pool", "qualify", "qualification", "weekly cycle", or "weekly competition" — call `read_senpi_guide(uri="senpi://guides/arena")` before composing any answer. Do not use web search or leaderboard data for Arena questions. Full routing rules in [references/post-onboarding.md](https://raw.githubusercontent.com/Senpi-ai/senpi-skills/refs/heads/main/senpi-onboard/references/post-onboarding.md).

---

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

Present all three options to the user and wait for them to choose:

1. **Option A -- Telegram user ID**: The skill will read your Telegram identity from USER.md automatically.
2. **Option B -- User-provided wallet**: Must be `0x`-prefixed, exactly 42 hex characters. Validate before proceeding.
3. **Option C -- Agent-generated wallet** (only if you have neither).

#### Option A: Collect Telegram user ID

When the user chooses Option A, first attempt to read from `${OPENCLAW_WORKSPACE_DIR}/USER.md`:

```bash
USER_MD="${OPENCLAW_WORKSPACE_DIR}/USER.md"
if [ -f "$USER_MD" ]; then
  TELEGRAM_USER_ID=$(awk '/^## Telegram/{f=1; next} f && /^## /{f=0} f && /- Chat ID:/{print $NF; exit}' "$USER_MD")
  TELEGRAM_USERNAME=$(awk '/^## Telegram/{f=1; next} f && /^## /{f=0} f && /- Username:/{print $NF; exit}' "$USER_MD")
  TELEGRAM_USERNAME="${TELEGRAM_USERNAME#@}" # normalize for API userName field
fi
```

If both `TELEGRAM_USER_ID` (digits-only, non-empty) and `TELEGRAM_USERNAME` (non-empty) are found, set the variables automatically without prompting the user:

```bash
IDENTITY_TYPE="TELEGRAM"
IDENTITY_VALUE="$TELEGRAM_USER_ID"
```

If USER.md is missing or either field is absent/invalid, fall back to the manual prompt: see [references/telegram-identity.md](references/telegram-identity.md) for user-facing instructions and validation rules. Also set `TELEGRAM_USERNAME` from the user's input if prompted manually, then normalize it before API use with `TELEGRAM_USERNAME="${TELEGRAM_USERNAME#@}"`.

#### Option B: Set variables

```bash
IDENTITY_TYPE="WALLET"
IDENTITY_VALUE="0x..."  # 0x-prefixed wallet address
```

#### 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="<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 numeric user ID (digits only)
- `WALLET_GENERATED` -- `true` if Option C was used, unset otherwise
- `TELEGRAM_USERNAME` -- required and non-empty when `IDENTITY_TYPE="TELEGRAM"` (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_CA
Files: 7
Size: 53.2 KB
Complexity: 73/100
Category: Backend & APIs

Related in Backend & APIs