# Obsidio Bots — Bot API & Registry

**Status:** Live — `bots.bot`, `shop.demo.bot`, `stake.bot`, `status.bot`; escrow, subscriptions (auto-renew ticker + RPC), Dilithium refunds (`EnsureKeys` + `RefundInvoice`). Remaining: richer OFAC provider sync.  
**Goal:** Telegram-like bots with **native OBS/wUSDC payments** and shared payment layer for **x402** (see [X402.md](./X402.md)).  
**Dev guide:** [https://obsidio.network/developers/](https://obsidio.network/developers/)

## Principles

1. **Bot = account + metadata.** Logic runs on the developer’s server; the node delivers events and settles payments.
2. **Name = `*.bot`.** Registered once (gas fee); cannot be spoofed if resolved via registry.
3. **Zero platform cut** on bot payments — only normal protocol gas / fee split.
4. **Same payment object** for chat invoices and x402 (`invoice_id` + `memo` + `tx_hash`).

## Roadmap

| Phase | Deliverable |
|-------|-------------|
| **1** | Registry, API key, webhook (message/callback/payment), `sendMessage`, inline keyboard, `sendInvoice`, `validatePayment`, demo shop bot |
| **2** | x402 HTTP 402 bridge (`PAYMENT-REQUIRED` / settle on Obsidio), wallet card, agent retry |
| **3** | `bots.bot` ✅, catalog ✅, escrow ✅, subscriptions ✅ (`subscription_period_secs`, auto-renew ~60s, `obsidio_botRenewSubscription`) |
| **3b** | Dilithium refunds ✅ — `obsidio_botEnsureKeys` (fund bot address) → `obsidio_botRefundInvoice` |
| **4** | Compliance hooks: travel-rule envelope for large invoices, sanctions check on `pay_to` / payer (see X402.md) |
| **5** | Product bots: stake.bot ✅, status.bot ✅ (airdrop.bot deferred) |

## Registry

```json
{
  "name": "shop.demo.bot",
  "address": "ons1…",
  "owner": "ons1…",
  "webhook_url": "https://dev.example/obsidio/webhook",
  "api_key_hash": "blake3…",
  "created_ts": 1769383050,
  "verified": true
}
```

- Register: `obsidio_botRegister` (owner pays ~$0.05 gas-equivalent; name must end with `.bot`).
- Rotate key: `obsidio_botRotateKey` (owner + old key or operator).
- Resolve: `obsidio_botResolve` / list: `obsidio_botList`.

## Webhook events (node → developer)

Signed with `X-Obsidio-Bot-Signature: blake3(api_key || body)` (MVP). Later: Dilithium.

### `message`
```json
{
  "type": "message",
  "bot": "shop.demo.bot",
  "chat_id": "ons1…",
  "text": "hi",
  "message_id": "…",
  "mode": "Fast",
  "ts": 1769383050
}
```

### `callback`
```json
{
  "type": "callback",
  "bot": "shop.demo.bot",
  "chat_id": "ons1…",
  "callback_data": "buy:item1",
  "message_id": "…",
  "ts": 1769383050
}
```

### `payment`
```json
{
  "type": "payment",
  "bot": "shop.demo.bot",
  "chat_id": "ons1…",
  "invoice_id": "inv_…",
  "memo": "order_1284",
  "amount_atto": "500000000000000000000",
  "asset": "OBS",
  "tx_hash": "…",
  "confirmed": true,
  "height": 8112000,
  "ts": 1769383050
}
```

## Bot HTTP API (developer → node)

Base: `POST https://obsidio.network/rpc/bot/<method>`  
Auth: `Authorization: Bearer <api_key>` **or** JSON-RPC with `api_key` param.

| Method | Purpose |
|--------|---------|
| `sendMessage` | Text + optional `inline_keyboard` |
| `answerCallback` | Ack callback (optional edit text) |
| `sendInvoice` | Create invoice + push pay card to chat (`escrow`, `subscription_period_secs` optional) |
| `getInvoice` | Status by `invoice_id` / `memo` |
| `releaseEscrow` | Clear escrow hold after delivery (`obsidio_botReleaseEscrow`) |
| `renewSubscription` | Spawn next-period invoice (`obsidio_botRenewSubscription`); node also auto-ticks |
| `ensureKeys` | Generate Dilithium keys + migrate `address` (`force=true` if address already set) |
| `refundInvoice` | Paid invoice → Dilithium transfer back to payer (`obsidio_botRefundInvoice`) |

### `sendMessage`
```json
{
  "chat_id": "ons1…",
  "text": "Cyberpunk — 500 OBS",
  "inline_keyboard": [[{ "text": "Buy", "callback_data": "buy:cyberpunk" }]]
}
```

Limits (Telegram-like): ≤3 buttons/row, ≤8 rows, `callback_data` ≤64 bytes.

### `sendInvoice`
```json
{
  "chat_id": "ons1…",
  "title": "Cyberpunk 2077",
  "amount_obs": "500",
  "asset": "OBS",
  "memo": "order_1284",
  "expires_in": 3600
}
```

Returns `{ invoice_id, memo, pay_to, amount_atto, expires_at }`.  
Wallet shows Face ID pay → L1 transfer → `obsidio_confirmInvoicePayment` (or auto-match) → webhook `payment`.

## Safety

| Risk | Mitigation |
|------|------------|
| Spoofed bot | Registry resolve + verified badge in UI |
| Spam | Bots may message only after user opens chat / `/start` |
| Paid / no goods | Optional escrow (phase 3); reputation later |
| Key leak | Rotate key; hash stored server-side |

## Demo

See `demos/bots/demo_shop.py` — catalog → invoice → deliver code on `payment` webhook.
