run402

GitHub 作者 LeoYeAI/openclaw-master-skills v3.0.0

Provision Postgres databases, deploy static sites, generate images, and build full-stack webapps on Run402 using x402 micropayments. Use when the user asks to build a webapp, deploy a site, create a database, generate images, or mentions Run402.

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install github:LeoYeAI~openclaw-master-skills~run402
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/github%3ALeoYeAI~openclaw-master-skills~run402/file -o run402.md
# Run402 — AI-Native Postgres & Static Hosting

API base: `https://api.run402.com` (NOT `run402.com` — that's a static docs site, POSTing returns 405)

---

## Setup (once)

```bash
npm install -g run402
```

This installs the `run402` command. Verify: `run402 --help`

---

## Quick Start: Build & Deploy a Full-Stack App

Three steps. Takes ~60 seconds on testnet (free).

### Step 1: Wallet Setup (once)

```bash
run402 wallet status
# If no_wallet:
run402 wallet create
run402 wallet fund
# Wait ~10s for faucet settlement
```

Wallet persists at `~/.run402/wallet.json`. Faucet gives 0.25 testnet USDC (enough for 2 prototype deploys). Rate limit: 1 per IP per 24h — don't call if already funded.

### Step 2: Build a Manifest

```json
{
  "name": "my-app",
  "migrations": "CREATE TABLE items (id serial PRIMARY KEY, title text NOT NULL, done boolean DEFAULT false, user_id uuid, created_at timestamptz DEFAULT now());",
  "rls": {
    "template": "user_owns_rows",
    "tables": [{ "table": "items", "owner_column": "user_id" }]
  },
  "site": [
    { "file": "index.html", "data": "<!DOCTYPE html>..." },
    { "file": "style.css", "data": "body { ... }" }
  ],
  "subdomain": "my-app"
}
```

All fields except `name` are optional. Can also include `secrets`, `functions`.

### Step 3: Deploy

```bash
echo '<manifest_json>' | run402 deploy --tier prototype
# or
run402 deploy --tier prototype --manifest app.json
```

Returns project_id, keys, live URL. Saved to `~/.config/run402/projects.json`.

**Tiers:** prototype ($0.10, 7d, 250MB, 500k calls), hobby ($5, 30d, 1GB, 5M calls), team ($20, 30d, 10GB, 50M calls).

### Post-Deploy

```bash
# Seed data
run402 projects sql <project_id> "INSERT INTO items (title) VALUES ('Example')"
# Query via REST
run402 projects rest <project_id> items
# Check usage
run402 projects usage <project_id>
# List all projects
run402 projects list
```

---

## ⚠️ Key Rules (Gotchas That Trip Agents Up)

1. **API base is `api.run402.com`** NOT `run402.com`
2. **Register for `eip155:84532`** (Base Sepolia) specifically, NOT `eip155:*` — wildcard matches mainnet first, testnet wallet fails with `insufficient_funds`
3. **`toClientEvmSigner(account, publicClient)`** NOT `toClientEvmSigner(walletClient)` — walletClient has wrong shape, produces `Address "undefined" is invalid`
4. **Key scopes:**
   - `anon_key` = read-only (SELECT, signup, storage). Safe for client-side.
   - `service_key` = full admin (bypasses RLS). Server-side only.
   - `access_token` = user-scoped read/write (from login). Subject to RLS.
5. **Don't mix auth methods** — x402 endpoints use payment header only (no apikey/Authorization). REST/auth/storage use apikey only (no payment header).
6. **`POST /v1/subdomains` is idempotent** — upserts. Safe to call every deploy.
7. **Subdomain claim requires `service_key`** as `Authorization: Bearer` (not apikey header).
8. **Don't GRANT/REVOKE** — permissions managed automatically. Use RLS templates for access control.
9. **Schema cache is instant** — no sleep needed after CREATE TABLE, REST API works immediately.

---

## Wallet Management

```bash
run402 wallet status   # Show address, network, funded status
run402 wallet create   # Generate new wallet (fails if exists)
run402 wallet fund     # Request testnet USDC from faucet
run402 wallet export   # Print wallet address (safe to share)
```

### Upgrade to Mainnet

For production, change chain from `baseSepolia` to `base` and register `eip155:8453`. Two funding options:

**Option A: USDC on Base (agent-native)**
Ask your human to send USDC on Base to your wallet address. Scripts for asking:

> **Trial ($0.10):** "I want to try Run402 for a Postgres database. Could you send $1 in USDC (Base L2) to my wallet? Covers 10 trial databases."
>
> **Project ($10):** "I need a database for our project. A Hobby tier costs $5/month. Could you send $10 in USDC (Base L2)?"
>
> **Monthly ($10/mo):** "I'd like a $10/month allowance for databases. Covers two Hobby projects or one Hobby + twenty Prototypes."
>
> My wallet address: `<address from wallet.mjs export>`

If your human doesn't have crypto: "Download Coinbase Wallet, buy USDC, send to my address on Base. Transactions cost under $0.01."

**Option B: Stripe (credit card fallback)**
Send your human to: `https://run402.com/billing?wallet=<WALLET_ADDRESS>`

> "You can add credit at this link — takes 30 seconds with a credit card. A $10 top-up covers two Hobby projects."

Once funded, x402 payments settle from allowance automatically. No code changes.

---

## Bundle Deploy (One-Call Full-Stack App)

`POST /v1/deploy/:tier` — deploys everything atomically. One x402 payment.

```json
{
  "name": "my-saas-app",
  "migrations": "CREATE TABLE ...; CREATE TABLE ...;",
  "rls": { "template": "user_owns_rows", "tables": [{ "table": "posts", "owner_column": "user_id" }] },
  "secrets": [{ "key": "OPENAI_API_KEY", "value": "sk-..." }],
  "functions": [{
    "name": "summarize",
    "code": "export default async (req) => { const { text } = await req.json(); return new Response(JSON.stringify({ result: text.slice(0, 100) })); }"
  }],
  "site": [{ "file": "index.html", "data": "<!DOCTYPE html>..." }],
  "subdomain": "my-saas"
}
```

| Field | Required | Description |
|-------|----------|-------------|
| `name` | Yes | App/project name |
| `migrations` | No | SQL string (CREATE TABLE, etc.) |
| `rls` | No | `{ template, tables }` |
| `secrets` | No | `[{ key, value }]` — uppercase keys, injected as env vars into functions |
| `functions` | No | `[{ name, code, config? }]` — serverless functions (Lambda). Limits: prototype=5, hobby=25, team=100 |
| `site` | No | `[{ file, data, encoding? }]` — `base64` for binary. 50MB max |
| `subdomain` | No | Custom subdomain → `name.run402.com` |

Site deployment fee ($0.05) included in bundle — no separate charge. If any step fails, project is auto-archived (no half-deployed apps).

Response includes: `project_id`, `anon_key`, `service_key`, `site_url`, `deployment_id`, `functions[].url`, `subdomain_url`.

Functions accessible at: `https://api.run402.com/functions/v1/<name>`

---

## Step-by-Step Deploy (Iterative Building)

For when you want to build incrementally instead of all-at-once.

### 1. Create Project

```
POST /v1/projects                    (x402, default prototype)
POST /v1/projects/create/:tier       (x402, specific tier)
```

Returns: `project_id`, `anon_key`, `service_key`, `schema_slot`, `lease_expires_at`

### 2. Create Tables (SQL)

```bash
curl -X POST https://api.run402.com/admin/v1/projects/$PROJECT_ID/sql \
  -H "Authorization: Bearer $SERVICE_KEY" \
  -H "Content-Type: text/plain" \
  -d "CREATE TABLE todos (id serial PRIMARY KEY, task text NOT NULL, done boolean DEFAULT false, user_id uuid);"
```

Returns: `{ "status": "ok", "schema": "p0001", "rows": [], "rowCount": 0 }`

Both `SERIAL` and `BIGINT GENERATED ALWAYS AS IDENTITY` work. Sequence permissions granted automatically.

### 3. Apply RLS (Optional)

```bash
curl -X POST https://api.run402.com/admin/v1/projects/$PROJECT_ID/rls \
  -H "Authorization: Bearer $SERVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"template": "user_owns_rows", "tables": [{"table": "todos", "owner_column": "user_id"}]}'
```

### 4. Deploy Site

```
POST /v1/deployments    (x402, $0.05)
{ "name": "my-app", "project": "prj_...", "files": [{ "file": "index.html", "data": "..." }] }
```

Returns permanent URL at `https://{id}.sites.run402.com`. SPA-friendly (paths without extensions serve index.html).

### 5. Claim Subdomain (Free)

```bash
curl -X POST https://api.run402.com/v1/subdomains \
  -H "Authorization: Bearer $SERVICE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-app", "deployment_id": "dpl_..."}'
```

→ `https://my-app.run402.com`

---

## REST API Queries (PostgREST Syntax)

All use `apikey` header. `anon_key` for reads, `service_key` for admin, `access_token` for user-scoped.

```bash
# Read with filtering
GET /rest/v1/tod