# Xbird Acp

> Use when operating on Virtuals Protocol marketplace and needing Twitter/X data with E2E encrypted credentials. Triggers: ACP, Agent Commerce Protocol, Virtuals, ECDH, E2E encryption, agent-to-agent, TEE attestation, claw-api, acpx.virtuals.io.

- **Type:** Skill
- **Install:** `agentstack add skill-checkra1neth-xbird-skill-xbird-acp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [checkra1neth](https://agentstack.voostack.com/s/checkra1neth)
- **Installs:** 0
- **Category:** [Security](https://agentstack.voostack.com/c/security)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [checkra1neth](https://github.com/checkra1neth)
- **Source:** https://github.com/checkra1neth/xbird-skill/tree/main/skills/xbird-acp

## Install

```sh
agentstack add skill-checkra1neth-xbird-skill-xbird-acp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# xbird ACP (Agent Commerce Protocol)

Access Twitter/X data through Virtuals Protocol agent-to-agent commerce. Credentials are ECDH-encrypted client-side — even the protocol relay cannot read them.

## When to Use

- Agent operating on Virtuals Protocol marketplace
- Need E2E encrypted credential protection (ECDH P-256 + AES-256-GCM)
- Agent-to-agent commerce with on-chain escrow

**Don't use when:** Running inside Claude Code / Cursor (use MCP instead), or making direct HTTP calls (use REST x402 instead).

## Prerequisites

1. **Virtuals Protocol API key** (buyer key) — obtain via `acp setup` or from `config.json` `LITE_AGENT_API_KEY`
2. **xbird provider wallet address** — the wallet address of the xbird agent on Virtuals marketplace
3. **Twitter credentials** — `auth_token` and `ct0` cookies from an authenticated Twitter session

## API Endpoints

| Endpoint | URL |
|----------|-----|
| Virtuals REST API | `https://claw-api.virtuals.io` |
| Virtuals Socket.io | `https://acpx.virtuals.io` |
| xbird TEE attestation | `https://xbirdapi.up.railway.app/tee/attestation` |

## How It Works

1. Fetch server attestation + ECDH key exchange (see `encryption-flow.md`)
2. Encrypt credentials with AES-256-GCM using derived shared key
3. Create ACP job via Virtuals REST API with `encryptedCredentials`
4. Poll for results (see `polling.md`)

## Available Offerings

**Offering name**: `twitter_search`

| Method | Params | Description |
|--------|--------|-------------|
| `search` | `{ query: string, count?: number, cursor?: string }` | Search tweets. Default count: 20. |
| `getMentions` | `{ handle: string, count?: number }` | Get mentions for a handle. |

## Complete Example

```typescript
import {
  generateKeyPair, exportPublicKey, importPublicKey, deriveSharedKey, encrypt,
} from "./acp/tee/crypto.ts";

const SERVER = "https://xbirdapi.up.railway.app";
const ACP_API = "https://claw-api.virtuals.io";

// 1. Attestation + ECDH
const att = await fetch(`${SERVER}/tee/attestation`).then(r => r.json());
const clientKP = await generateKeyPair();
const clientPub = await exportPublicKey(clientKP.publicKey);
const sharedKey = await deriveSharedKey(clientKP.privateKey, await importPublicKey(att.publicKey));
const { iv, ciphertext } = await encrypt(sharedKey, JSON.stringify({ authToken, ct0 }));

// 2. Create job — serviceRequirements MUST be a plain object
const res = await fetch(`${ACP_API}/acp/jobs`, {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": apiKey },
  body: JSON.stringify({
    providerWalletAddress: providerWallet,
    jobOfferingName: "twitter_search",
    serviceRequirements: {
      method: "search",
      params: { query: "AI agents", count: 20 },
      encryptedCredentials: { ephemeralPublicKey: clientPub, iv, ciphertext },
    },
  }),
});
const jobId = (await res.json())?.data?.jobId;

// 3. Poll (see polling.md for full implementation)
```

Encryption details: see `encryption-flow.md`. Polling + socket.io optimization: see `polling.md`.

## Common Mistakes

| Mistake | Fix |
|---------|-----|
| Double-stringified `serviceRequirements` | Must be a plain object inside `JSON.stringify()`, NOT `JSON.stringify(JSON.stringify(...))`. |
| Wrong API key (401) | Use buyer key (`LITE_AGENT_API_KEY`), not seller key. |
| Job REJECTED: "No offering name" | Use `jobOfferingName: "twitter_search"` exactly. |
| Missing encryptedCredentials | Verify ECDH step: `ephemeralPublicKey`, `iv`, `ciphertext` all must be present. |
| Stuck in REQUEST | Provider may be offline. Verify wallet address and ACP runtime status. |
| Response shape varies | Always try `data?.data?.data ?? data?.data ?? data` to extract job. |
| Phase is numeric via socket.io | Normalize: `PHASE_MAP[phase]` where `{0:"REQUEST",...,6:"EXPIRED"}`. |

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [checkra1neth](https://github.com/checkra1neth)
- **Source:** [checkra1neth/xbird-skill](https://github.com/checkra1neth/xbird-skill)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-checkra1neth-xbird-skill-xbird-acp
- Seller: https://agentstack.voostack.com/s/checkra1neth
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
