sparkbtcbot-proxy
Use a Spark Bitcoin L2 wallet proxy for AI agents via HTTP API. Check balances, send payments, create invoices, pay L402 paywalls — all without holding the mnemonic. Use when user mentions "Spark proxy," "wallet API," "L402," "proxy payment," "bearer token auth," or wants secured Bitcoin capabilities for an agent.
安装 / 下载方式
TotalClaw CLI推荐
totalclaw install clawskills:clawskills~echennells-sparkbtcbot-proxycURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/clawskills%3Aclawskills~echennells-sparkbtcbot-proxy/file -o echennells-sparkbtcbot-proxy.md# Spark Bitcoin L2 Proxy for AI Agents
You are an expert in using the sparkbtcbot-proxy — a serverless HTTP API that gives AI agents scoped access to a Spark Bitcoin L2 wallet without exposing the private key.
## Why Use the Proxy Instead of Direct SDK
| Concern | Direct SDK (sparkbtcbot-skill) | Proxy (this skill) |
|---------|-------------------------------|-------------------|
| Mnemonic location | Agent holds it | Server holds it |
| Spending limits | None (agent decides) | Per-tx and daily caps |
| Access revocation | Move funds to new wallet | Revoke bearer token |
| Role-based access | No | Yes (admin, invoice, pay-only, read-only) |
| Setup complexity | npm install + mnemonic | HTTP calls + bearer token |
**Use the proxy when:**
- You don't trust the agent with full wallet control
- You need spending limits or audit logs
- You want to revoke access without moving funds
- Multiple agents share one wallet with different permissions
**Use direct SDK when:**
- Testing or development
- Agent needs offline signing
- You're building the proxy itself
## Before You Start
1. **Deploy your own proxy** — see [sparkbtcbot-proxy](https://github.com/echennells/sparkbtcbot-proxy) for setup instructions. The proxy runs on Vercel (free tier works) with Upstash Redis.
2. **Use HTTPS only** — never connect to a proxy over plain HTTP. All Vercel deployments use HTTPS by default.
3. **Create least-privilege tokens** — don't give agents admin tokens. Use the most restrictive role that works:
- `read-only` for monitoring/dashboard agents
- `invoice` for agents that receive payments but don't spend
- `pay-only` for agents that pay L402 paywalls but don't create invoices
- `admin` only for your own management scripts
4. **Set spending limits** — configure `maxTxSats` and `dailyBudgetSats` when creating tokens. The proxy enforces these server-side.
5. **Test with small amounts** — start with a few hundred sats until you trust your agent's behavior.
6. **Have a revocation plan** — know how to revoke tokens via `DELETE /api/tokens` if an agent is compromised.
## Token Roles
| Role | Permissions |
|------|-------------|
| `admin` | Full access: read, create invoices, pay, transfer, manage tokens |
| `invoice` | Read + create invoices. Cannot pay or transfer. |
| `pay-only` | Read + pay invoices and L402. Cannot create invoices or transfer. |
| `read-only` | Read only (balance, info, transactions, logs). Cannot pay or create invoices. |
## Base URL
The proxy runs on Vercel. Your base URL will look like:
```
https://your-deployment.vercel.app
```
All requests require authentication:
```
Authorization: Bearer <your-token>
```
## API Reference
### Read Operations (any role)
#### Get Balance
```bash
curl -H "Authorization: Bearer $TOKEN" \
"$PROXY_URL/api/balance"
```
Response:
```json
{
"success": true,
"data": {
"balance": "50000",
"tokenBalances": {
"btkn1...": {
"balance": "1000",
"tokenMetadata": {
"tokenName": "Example Token",
"tokenTicker": "EXT",
"decimals": 0
}
}
}
}
}
```
#### Get Wallet Info
```bash
curl -H "Authorization: Bearer $TOKEN" \
"$PROXY_URL/api/info"
```
Response:
```json
{
"success": true,
"data": {
"sparkAddress": "sp1p...",
"identityPublicKey": "02abc..."
}
}
```
#### Get Deposit Address (L1 Bitcoin)
```bash
curl -H "Authorization: Bearer $TOKEN" \
"$PROXY_URL/api/deposit-address"
```
Response:
```json
{
"success": true,
"data": {
"address": "bc1p..."
}
}
```
#### Get Transaction History
```bash
curl -H "Authorization: Bearer $TOKEN" \
"$PROXY_URL/api/transactions?limit=10&offset=0"
```
#### Get Fee Estimate
```bash
curl -H "Authorization: Bearer $TOKEN" \
"$PROXY_URL/api/fee-estimate?invoice=lnbc..."
```
Response:
```json
{
"success": true,
"data": {
"feeSats": 5
}
}
```
#### Get Activity Logs
```bash
curl -H "Authorization: Bearer $TOKEN" \
"$PROXY_URL/api/logs?limit=20"
```
### Invoice Operations (admin or invoice role)
#### Create Lightning Invoice (BOLT11)
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"amountSats": 1000, "memo": "Payment for service", "expirySeconds": 3600}' \
"$PROXY_URL/api/invoice/create"
```
Response:
```json
{
"success": true,
"data": {
"encodedInvoice": "lnbc10u1p..."
}
}
```
#### Create Spark Invoice
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"amount": 1000, "memo": "Spark payment"}' \
"$PROXY_URL/api/invoice/spark"
```
### Payment Operations (admin or pay-only role)
#### Pay Lightning Invoice
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"invoice": "lnbc10u1p...", "maxFeeSats": 10}' \
"$PROXY_URL/api/pay"
```
Response:
```json
{
"success": true,
"data": {
"id": "payment-id-123",
"status": "LIGHTNING_PAYMENT_SUCCEEDED",
"paymentPreimage": "abc123..."
}
}
```
#### Transfer to Spark Address
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"receiverSparkAddress": "sp1p...", "amountSats": 1000}' \
"$PROXY_URL/api/transfer"
```
### L402 Paywall Operations (admin or pay-only role)
L402 lets you pay for API access with Lightning. The proxy handles the full flow automatically.
#### Pay L402 and Fetch Content
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://lightningfaucet.com/api/l402/joke", "maxFeeSats": 50}' \
"$PROXY_URL/api/l402"
```
Response (immediate success):
```json
{
"success": true,
"data": {
"status": 200,
"paid": true,
"priceSats": 21,
"preimage": "be2ebe7c...",
"data": {"setup": "Why do programmers...", "punchline": "..."}
}
}
```
Response (cached token reused):
```json
{
"success": true,
"data": {
"status": 200,
"paid": false,
"cached": true,
"data": {"setup": "...", "punchline": "..."}
}
}
```
#### Preview L402 Cost (any role)
Check what an L402 resource costs without paying:
```bash
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://lightningfaucet.com/api/l402/joke"}' \
"$PROXY_URL/api/l402/preview"
```
Response:
```json
{
"success": true,
"data": {
"requires_payment": true,
"invoice_amount_sats": 21,
"invoice": "lnbc210n1p...",
"macaroon": "AgELbGlnaHRuaW5n..."
}
}
```
#### Handling Pending L402 Payments (IMPORTANT)
Lightning payments are asynchronous. If the preimage isn't available within ~7.5 seconds, the proxy returns a pending status:
```json
{
"success": true,
"data": {
"status": "pending",
"pendingId": "a1b2c3d4...",
"message": "Payment sent but preimage not yet available. Poll GET /api/l402/status?id=<pendingId> to complete.",
"priceSats": 21
}
}
```
**You MUST handle this case.** The payment has been sent — if you don't poll, you lose sats without getting content.
Poll for completion:
```bash
curl -H "Authorization: Bearer $TOKEN" \
"$PROXY_URL/api/l402/status?id=a1b2c3d4..."
```
**Recommended retry logic:**
```javascript
async function fetchL402(proxyUrl, token, targetUrl, maxFeeSats = 50) {
const response = await fetch(`${proxyUrl}/api/l402`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url: targetUrl, maxFeeSats }),
});
const result = await response.json();
if (result.data?.status === 'pending') {
const pendingId = result.data.pendingId;
for (let i = 0; i < 10; i++) {
await new Promise(r => setTimeout(r, 3000));
const statusResponse = await fetch(
`${proxyUrl}/api/l402/status?id=${pendingId}`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);