Skill: manu-xmint/lobstercash (version 0.0.16)

--- name: lobstercash description: 'Use this skill when the user wants to spend money, make purchases, send crypto, pay for APIs, browse websites for shopping, complete checkout, or manage an AI agent''s payment wallet. Covers buying products online with credit cards (with browser-automated checkout when available, or driven by the agent''s own browser tooling otherwise), sending tokens, paying for x402 protocol APIs, checking balances, depositing funds, browsing available services, and signing on-chain transactions — all with secure guardrails, and appropriate human controls. Trigger on any spending, wallet, or shopping intent: "buy this", "pay for that", "send tokens", "how much do I have", "what can I buy", "top up my wallet", "get a card", "set up payments", "find me something to buy", "complete the checkout", or "browse that site" — even if the user doesn''t mention "lobster", "crypto", or "Solana" directly.' metadata: version: "0.0.16" --- # Lobster Cash CLI Skill The Lobster Cash CLI (`lobstercash`) gives AI agents payment tools — a blockchain wallet, virtual cards for buying anything online, optional cloud browser automation for browsing sites and completing checkout, and x402 protocol support for paying APIs — all with human approval in the loop. Use `lobstercash <command> --help` for full flag details on any command. ## Installation Install globally: ```bash npm install -g @crossmint/lobster-cli ``` After installation, all commands are available via the `lobstercash` binary. ## Steps to use this skill ### 1. Version check (automatic) The CLI automatically checks for updates on every API call. If an update notice appears in the command output, tell the user and offer to run `npm update -g @crossmint/lobster-cli`. If the notice says the update is **required**, you must also update the skill from https://www.lobster.cash/install before continuing. Do not run separate version-check commands. ### 2. Select lobstercash agent to use Every lobstercash command operates on the **active agent**. Before doing anything else, make sure the right agent is selected. ```bash lobstercash agents list ``` Then follow this decision tree: 1. **You see yourself in the list and it says `(active)`** → You're good. Move on. 2. **You see yourself in the list but it's NOT active** → Run `lobstercash agents set-active <agentId>` with the matching ID, then move on. 3. **No agent matches you** (or the list is empty) → Register a new one. Read the [agents reference](references/agents.md) for how to register one. **How to recognize yourself:** Match by name. If you are Claude Code, look for an agent named "Claude Code" or similar. Same for Cursor, Codex, Gemini, etc. If you aren't sure, ask the user which agent to use. ### 3. Route based on the user's intent Determine which scenario applies and follow the corresponding section: - **A) Buy something online** (product, subscription, domain, service) → [Buy something online](#a-buy-something-online) - **B) Pay for a paid API endpoint** (x402 protocol) → [Pay an API with x402](#b-pay-an-api-with-x402) - **C) Anything else** (check balance, send crypto, view status, link wallet, browse examples) → [Other actions](#c-other-actions) --- ## A) Buy something online Use when the user wants to purchase a product, subscription (not yet but comming soon), domain, or any item from an online store. The flow is the same either way: discover the product and price, size a virtual card, then drive checkout in a browser. What changes is **who drives the browser** for this install. Run: ```bash lobstercash config get browser-enabled ``` - `browser-enabled: true` → Lobster Cash's built-in browser automation (`purchase explore` / `purchase run`) drives the merchant site for you. Follow [references/purchase-flow.md](references/purchase-flow.md). - `browser-enabled: false` → Lobster Cash's built-in browser automation is **not** available for this install. Do not run `purchase explore` or `purchase run`. Follow [references/purchase-flow-byo.md](references/purchase-flow-byo.md) — the same flow, but you (the agent) drive the merchant site using whatever browser-automation tooling you already have available in this environment (your IDE's browser tool, an MCP browser server, OpenClaw, etc.), and use `cards reveal` to get the credentials to enter at checkout. If `browser-enabled: false` and you have **no** browser-automation tooling available in this environment, tell the user you can't drive the browser yourself and offer to run the checkout manually: you'll get the card credentials with `cards reveal` and walk them through entering them at the merchant's checkout page themselves. --- ## B) Pay an API with x402 Use when the user wants to call a paid API endpoint that uses the x402 payment protocol. The CLI handles the payment negotiation automatically: the server returns HTTP 402, the CLI pays with USDC from the agent wallet, and the server returns the content. ### Step 1: Ensure the wallet has funds ```bash lobstercash status ``` Route based on the result: - **Wallet configured + has enough funds** → proceed to step 2. - **Wallet configured + insufficient funds** → run `lobstercash crypto request --amount <needed> --description "<description>"` to top up, show the approval URL, wait for user confirmation, then proceed. - **Wallet not configured** → run `lobstercash crypto request --amount <needed> --description "<description>"` (bundles wallet creation + funding). Show the approval URL, wait for user confirmation, verify with `lobstercash status`, then proceed. The `--description` must explain what the agent will spend the funds on — derive it from the user's task, not generic filler like "top up wallet". See [crypto request reference](references/crypto-request.md) for the full crypto request flow. ### Step 2: Fetch the paid endpoint ```bash lobstercash crypto x402 fetch <url> ``` For POST requests add `--json '{"key": "value"}'`. For custom headers add `--header "Authorization: Bearer <token>"`. ### Step 3: Report the result Report what the API returned (the `body` field), not the payment mechanics. Only mention the payment if the user asks. If the fetch fails, add `--debug` and run again. See [x402 reference](references/x402.md) for output format and common failures. --- ## C) Other actions For everything else — checking balances, sending crypto, viewing wallet status, linking a wallet, or browsing examples — use the matching command from the Quick Reference below and read the corresponding reference file for details. **Run the command, report its output.** For read-only commands (`crypto balance`, `status`, `examples`), execute them directly and report what they say. Do not pre-check status and construct your own summary — the CLI output already handles unconfigured states with clear messaging. If a command fails with exit code 2 (wallet not set up), tell the user and offer to run `lobstercash setup` or the appropriate setup-bundling command. Common actions: - **Check balance:** `lobstercash crypto balance` → [balance reference](references/balance.md) - **Send tokens:** `lobstercash crypto send --to <addr> --amount <n> --token usdc` → [send reference](references/send.md) - **View wallet status:** `lobstercash status` → [status reference](references/status.md) - **Browse examples:** `lobstercash examples` → [examples reference](references/examples.md) - **Link wallet / configure agent (setup only):** `lobstercash setup` → [setup reference](references/setup.md). Use when the user says "configure", "set up", "link wallet", or similar — and isn't trying to make a purchase. - **Sign/submit a transaction:** `lobstercash crypto tx create` → [tx reference](references/tx.md) For crypto operations (`crypto send`, `crypto tx create`), always run `lobstercash status` first to confirm the wallet is configured and has sufficient funds. If not, use `lobstercash crypto request --amount <needed> --description "<description>"` to fund it — see [crypto request reference](references/crypto-request.md). ## Quick Reference ```bash lobstercash agents register --name "<name>" --description "<desc>" --image-url "<url>" # register a new agent lobstercash agents list # list all agents lobstercash agents set-active <agentId> # set active agent lobstercash config get browser-enabled # check which browser drives online purchases (used in Section A) lobstercash examples # browse working examples lobstercash status # check status & readiness & wallet address lobstercash setup # link agent to wallet (no purchase needed) lobstercash crypto balance # check balances lobstercash crypto send --to <addr> --amount <n> --token usdc # send tokens lobstercash crypto x402 fetch <url> # pay for API lobstercash crypto request --amount <n> --description "<desc>" # request crypto funding / top up (bundles wallet setup) lobstercash crypto tx create|approve|status # low-level transaction management lobstercash cards request --amount <n> --description "<desc>" # request virtual card (single-use; subscriptions/--period coming soon) lobstercash cards list # list cards (includes card-id, phase, mandates) — used in both purchase flows to check for a reusable card lobstercash cards reveal --card-id <id> --merchant-name "..." --merchant-url "https://..." --merchant-country US # checkout credentials (used by the BYO browser flow, and for manual checkout) ``` The `purchase explore` and `purchase run` commands exist only when `browser-enabled: true` is configured — see the relevant purchase-flow reference for usage. ## Output Contract - All commands produce human-readable output to stdout. - Errors go to stderr as plain text. - Exit 0 = success. Exit 1 = unexpected error. Exit 2 = wallet not set up (use `cards request` or `crypto request` to set up). ## Decision Tree - Read [examples](references/examples.md) if the user wants to browse working examples, or has no specific task yet - Read [status](references/status.md) if the user asks about agent status or payment readiness - Read [balance](references/balance.md) if the user wants to check token balances - Read [purchase-flow](references/purchase-flow.md) if the user wants to buy something online and `browser-enabled: true` — full flow using Lobster Cash's built-in browser automation - Read [purchase-flow-byo](references/purchase-flow-byo.md) if the user wants to buy something online and `browser-enabled: false` — same flow but the agent drives the browser with its own tooling - Read [purchase](references/purchase.md) if you need flag-level reference for `purchase explore` / `purchase run` (browser-enabled only) - Read [cards request](references/cards-request.md) if the user wants to create a new virtual card for a purchase - Read [crypto request](references/crypto-request.md) if the user wants to request USDC, top up their wallet, or fund a crypto operation - Read [cards](references/cards.md) if the user needs to list existing cards, reveal credentials, or check whether a card can be reused for a purchase - Read [send](references/send.md) if the user wants to send tokens to an address (Crypto Path) - Read [x402](references/x402.md) if the user wants to pay for an API via x402 protocol (Crypto Path) - Read [tx](references/tx.md) if the user needs to sign or submit a transaction from an external tool (Crypto Path) - Read [setup](references/setup.md) if the user wants to link the agent to a wallet without making a purchase - Read [agents](references/agents.md) if the user wants to register, list, or set the active agent ## Anti-Patterns - **Skipping the browser availability check before an online purchase:** Don't assume which purchase flow applies. When the user wants to buy something online, always run `lobstercash config get browser-enabled` first (Section A) before deciding which purchase-flow reference to load. The flag determines whether to use `purchase explore` / `purchase run` or to drive the browser yourself with `cards reveal` for credentials. - **Calling `purchase explore` / `purchase run` when `browser-enabled: false`:** Those commands require the built-in browser automation. If the flag is `false`, follow [references/purchase-flow-byo.md](references/purchase-flow-byo.md) instead. - **Running crypto commands without checking status first:** Always run `lobstercash status` before `crypto send`, `crypto x402 fetch`, or `crypto tx create`. If the wallet isn't configured or has insufficient funds, the command will fail with a confusing error. Check first, fund if needed, then execute. - **Running setup when the user wants to buy something:** If the user wants to make a purchase, don't run `setup` first — use `cards request` or `crypto request` which bundle setup automatically. Only use `lobstercash setup` when the user explicitly wants to link the agent to their wallet without buying anything. - **Re-running setup when the agent is already configured:** If `lobstercash status` shows the wallet is already configured, do not generate a new setup session. The existing configuration is valid. Only start a fresh setup if the user explicitly tells you their current configuration is broken and needs to be regenerated. - **Asking the user for info the CLI can fetch:** Check balance before sending. Check status before acting. Read command output before asking questions. - **Running write commands in loops:** One attempt, read the result, then decide. Read operations (`crypto balance`, `status`, `examples`) are idempotent and safe to repeat. Write operations (`crypto send`, `cards request`) are not. - **Ignoring terminal status:** A pending transaction is not a success. All write commands now wait for on-chain confirmation by default. - **Polling for HITL approval:** When a command returns an approval URL, the user must tell you they approved. Do not auto-poll. - **Running commands before registering an agent:** Always ensure an agent exists via `lobstercash agents list` before running any other command. If you need to work with a different agent, use `lobstercash agents set-active`. - **Asking the user which chain to use:** Agents default to Base silently. Do not ask "which chain do you want?" at registration — just register on Base. Only pass `--network solana` if the user has explicitly told you they need Solana, or when the context clearly implies the agent must operate on Solana (e.g. they already hold USDC on Solana, or the integration they want is Solana-only). Chain is fixed per agent; switching later means registering a new one. - **Recommending cards for crypto-only integrations:** If the integration only uses crypto, don't suggest a virtual card. - **Requiring USDC for card-supported integrations:** Virtual cards are backed by credit cards, not USDC. Don't tell the user to "add funds" when the integration accepts cards. - **Treating x402/send/tx as separate user flows:** They all go through the same Crypto Path. The only split is credit card vs crypto. - **Suggesting `crypto request` or `cards request` when the user just wants to connect:** If the user wants to check balance, run a crypto command, or simply link their wallet — without topping up or creating a card — guide them through `lobstercash setup` first. Don't jump to `crypto request` or `cards request` unless the user actually wants to fund the wallet or make a purchase. - **Jumping to readiness checks before showing options:** Show what's available first (via `examples`), then check payment readiness only when the user wants to try one. - **Assuming an integration's payment method:** Never guess whether a flow uses cards or crypto. Run `lobstercash status` and read the payment methods output before choosing a path.

path: references/purchase-flow-byo.md
content: # Buy something online — bring-your-own browser flow

This is the purchase flow when **`browser-enabled: false`** (see [SKILL.md](../SKILL.md) Section A). It is the same end-to-end flow as [purchase-flow.md](purchase-flow.md), with one difference: **you (the agent) drive the merchant browser using whatever browser-automation tooling you already have available** in this environment (your IDE's browser tool, an MCP browser server, OpenClaw, Playwright/Puppeteer access, etc.). Lobster Cash still provides the virtual card, the user-approval flow, and `cards reveal` for credentials at checkout — it just doesn't drive the browser.

If you have **no** browser-automation tooling available in this environment, stop and offer to run the checkout manually with the user — you'll get the card credentials with `cards reveal` and walk them through entering them at the merchant's checkout page themselves.

The flow: discover the real product and price first (with your browser), size a virtual card to that price (or reuse an existing one), get user approval, then complete checkout (with your browser, using credentials from `cards reveal`).

## Step 1: Gather info from the conversation

Check what you already know from prior turns before asking:

- shipping address
- contact email
- phone (if the merchant might require it)
- product preferences (size, color, brand, quantity, exclusions)

Only ask the user for fields you don't already have. If they say a field isn't needed (e.g. "no phone" or "digital product, no address"), believe them and skip it. Never re-ask for info already in the conversation.

## Step 2: Discover the product and price (your browser tool)

Use **your own browser tooling** to navigate the merchant's site, locate the product the user wants, add it to the cart (or get to a quote/total page), and capture the **final total** including tax and shipping. You need a real, current total so the next step can size the virtual card correctly.

While you work, share progress with the user — what site you're on, what you found, when you've reached the cart total. They should be able to follow along.

What you must come away with before moving on:

- The product (name, variant/size/color if applicable, quantity)
- The merchant (real store name, canonical URL, country)
- The cart total in USD (or the purchase currency)
- A way to resume checkout later — keep your browser session/tab parked on the cart, or note the cart URL / re-buildable cart so you can return to it after card approval

If you don't know which merchant the user wants, do a web search first to ground yourself in a real merchant — don't guess URLs from training data. Same rule as the native flow: navigate the site's UI, don't bake guessed paths like `/category/socks` into anything.

If the merchant requires the user to sign in or answer a question that you can't decide on your own (size, paid shipping speed, etc.), pause and ask the user — don't invent answers.

## Step 3: Check for an existing usable card (fork)

Before creating a new card, list current cards and look for one that already covers this purchase.

```bash
lobstercash cards list
```

> **Note:** Subscription / recurring cards are coming soon — for now every card is single-use. The matching rules below already account for this; period-based matching will become relevant once subscriptions ship.

Each card (order intent) carries these fields you can compare against:

- `phase` — only `active` is usable
- `mandates[type=maxAmount].value` — the spending cap (in `details.currency`, default USD)
- `mandates[type=maxAmount].details.period` — currently always absent (single-use). Will be `weekly | monthly | yearly` when subscriptions launch.
- `mandates[type=description].value` — what the user approved the card for (e.g. "AWS credits", "RHCP enamel pins")
- `mandates[type=prompt].value` — original natural-language request (richer context than description)
- `mandates[type=consumer].details.email` — consumer email scope (only matters if multi-user)

Fields **NOT** to rely on:

- **Remaining balance** — `cards list` only exposes the limit, not how much has been spent.
- **Whether the card has already been charged** — single-use cards can't be reused once they've been charged successfully, but `cards list` doesn't expose charge history. If the card looks unused (no purchase you initiated against it), assume it's available; otherwise request a new one.
- `agentId` / `paymentMethodId` — internal bindings, not user-facing match signals.

A card is **usable for this purchase** when **all** of the following are true:

1. `phase === active`
2. `maxAmount.value >= rounded total` (rounded up to the nearest $5)
3. `maxAmount.details.currency` matches the purchase currency (typically `USD`)
4. The card hasn't already been used. Today every card is single-use, so a card you (or a previous turn) already charged successfully is no longer usable.
5. `description` (and `prompt` if present) is **semantically compatible** with the purchase. Don't reuse a card whose description targets a different merchant or product category.

Fork:

- **Match found** → skip Step 3b and Step 4. Reuse its `card-id` and jump straight to **Step 5**. Tell the user briefly: "Reusing your existing $X card for [description]."
- **No match** → continue to Step 3b.

See [cards reference](cards.md) for the full `cards list` output format and field semantics.

## Step 3b: Request a new virtual card sized to the discovered total

Round the discovered total **up** to the nearest $5 so a small price drift at checkout doesn't decline the card (e.g. $47.23 → $50, $31.75 → $35). Tell the user the rounded amount and why.

```bash
lobstercash cards request --amount <rounded> --description "<short product name>"
```

Cards are currently single-use only. Subscription / recurring cards are coming soon — until then, omit `--period` (or rely on the default) and request a fresh card per purchase.

This command bundles wallet setup if needed. See [cards request reference](cards-request.md) for output format.

## Step 4: Get user approval

The `cards request` command outputs an `approvalUrl`. Show it to the user:

> To create this card I need your approval. Open this link:
>
> [approvalUrl]
>
> Come back here when you've approved it.

**Do not proceed until the user confirms they approved.** Do not poll. After they confirm, run `lobstercash cards list` once to verify the new card is `active`, then continue.

## Step 5: Complete the purchase (your browser tool + `cards reveal`)

Now the card is ready and the cart is parked. Two sub-steps:

### 5a — Reveal the card credentials

```bash
lobstercash cards reveal \
  --card-id <card-id> \
  --merchant-name "<merchant name>" \
  --merchant-url "<canonical merchant URL>" \
  --merchant-country <XX>
```

This prints the card number, expiry month/year, and CVC for that specific merchant. **Treat the output as highly sensitive.** Do not log or paste it anywhere outside of the merchant's checkout form. Do not share these details with the user; just use them yourself in the browser.

See [cards reveal section in cards reference](cards.md#revealing-card-credentials-checkout) for full flag details and security notes.

### 5b — Drive checkout with your browser tool

Return your browser to the parked cart (or rebuild it from the cart URL captured in Step 2) and complete the checkout form using the user's shipping/contact info from Step 1 and the revealed card details from Step 5a.

**Stop before final submit.** Reach the order-review screen and pause. Then ask the user to confirm: "Cart total is $X. Card ending in <last 4>. Shipping to <address>. Ready for me to place the order?" Only submit once the user has explicitly authorized this exact submission.

If the merchant total at checkout exceeds the card's hard cap, the card will decline. Don't try to charge more than the card limit — request a new card sized to the new total instead.

If the merchant asks for something you can't answer on your own (size choice, shipping option that costs extra, missing address field), pause and ask the user. Don't invent answers.

After the order is submitted, share the confirmation details (order number, total charged, ETA if shown) with the user.

## Anti-patterns (BYO browser flow)

- **Calling `purchase explore` or `purchase run`:** They require `browser-enabled: true`. In this flow you drive the browser yourself.
- **Skipping price discovery:** Always discover the real product and price (Step 2) before requesting a card. Without it you can't size the card and the merchant will decline.
- **Hallucinating product URLs or paths:** Same rule as the native flow — never guess URLs beyond the root domain. Either start from the merchant homepage and let your browser tool navigate the site's own UI, or ground yourself in a real URL pulled from web search results.
- **Placing orders without user authorization:** The card's hard cap is a backstop, not a green light. Always stop at the order-review screen and ask the user to confirm before submitting.
- **Requesting a new card without checking `cards list` first:** Always run `lobstercash cards list` after Step 2 and check whether an `active` card already covers this purchase. Reusing a usable card avoids spamming the user with another approval link.
- **Reusing a card whose description doesn't fit the purchase:** The user approved each card for a specific purpose. Don't reuse an "AWS credits" card to buy enamel pins — request a new card scoped to the new purpose.
- **Sharing revealed card details with the user or logs:** `cards reveal` output is sensitive. Use the values in the merchant's checkout form, then forget them. Don't echo them back to the user.
- **Guessing merchant questions you can't answer:** Same as the native flow — when you hit a required choice you can't make on your own (size, shipping option, missing address field), pause and ask the user. Don't invent answers.
- **Pretending you have a browser tool when you don't:** If this environment has no browser-automation tooling available, don't bluff your way through Step 2 or Step 5. Stop and offer the user a manual checkout instead — get the credentials with `cards reveal` and walk them through entering them at the merchant's checkout themselves.


path: references/examples.md
content: # Examples

Show real, working examples of what agents can do with lobster.cash. Each example has been verified end-to-end.

## When to use

- After setup completes and the user has no specific request.
- When the user asks "what can you do?" or "what can I buy?".
- Only show once per session — do not repeat if the user already saw it.

## Command

```
lobstercash examples
```

## Reading the output

Each example includes:

- `name` — example name
- `oneLiner` — short description
- `description` — how it works in a few lines
- `skillUrl` — link to the skill repo with full instructions

## Current examples

### xStocks

Buy tokenized stocks (Apple, Tesla, NVIDIA, S&P 500…) on Solana with USDC. The skill includes a local catalog of 104 tokens — no API calls needed to search or look up mint addresses. Purchases go through Jupiter swaps: the skill builds an unsigned transaction, lobster.cash signs it, and the agent owns fractional stock exposure on-chain.

Skill: https://github.com/manu-xmint/xstocks-skill

## How to present

Do not dump the raw output. Summarize conversationally:

"Here's something you can do right now:

- **Buy tokenized stocks** — trade Apple, Tesla, NVIDIA, and 100+ other stocks on Solana using USDC (xStocks)

Want to try it?"

## After the user picks

Once the user picks an example, check their balance (`lobstercash crypto balance`)
and proceed with the relevant skill. If they need funds, guide them to
the crypto request flow.


path: references/setup.md
content: # Setup — Link Agent to Wallet

Link this agent to your lobster.cash wallet. It gives the agent access to operate a blockchain wallet, as well as to request virtual cards and top ups. Use this when the user wants to connect the agent to their wallet **without** making a purchase. If the user wants to buy something, use `cards request` or `crypto request` instead — they bundle setup automatically.

## Prerequisite

An agent must exist before running setup. If you haven't registered one yet, register one with a descriptive name, description, and image URL:

```bash
lobstercash agents register --name "<descriptive name>" --description "<what the agent does>" --image-url "<avatar url>"
```

## Command

```bash
lobstercash setup
```

## Check first

Run `lobstercash status` and read the output:

- `wallet.configured: true` — wallet is ready, do not run setup.
- `wallet.configured: false` — wallet needs setup. Proceed to Step 1.

## Step 1 — Start setup

```bash
lobstercash setup
```

Parse the output:

- `outcome`: one of `already_active`, `pending`, `completed`
- `consentUrl`: the URL the user must open (present when `outcome` is `pending` and a new session was created)

If `outcome` is `already_active` or `completed`, stop — the wallet is ready.

## Step 2 — Guide the user to approve

When `outcome` is `pending` and the CLI prints a consent URL, show it to the user:

> To activate your wallet, open this link and approve it. Come back here when you're done.
>
> [consentUrl from CLI output]

Do not proceed until the user confirms they have approved.
Do not poll automatically. The user must tell you they approved.

## Step 3 — Finalize after approval

When the user says they approved, run:

```bash
lobstercash setup
```

The CLI checks the session status automatically. Parse the output:

- `"outcome": "completed"` — wallet is ready. Continue with the user's original task.
- `"outcome": "pending"` — not approved yet. Ask the user to approve the setup request.
- If the session was denied or expired, the CLI starts a fresh setup automatically.

## After setup completes

Say: "Wallet ready. Your address is [walletAddress]."

If the user originally asked for something specific (e.g. "buy X", "send tokens"), route to Branch 2 in the main skill file.

If the user did not have a specific task, run `lobstercash examples` and present working examples so they can pick what to do next.

## Anti-Patterns

- **Running setup when the user wants to buy:** Use `cards request` or `crypto request` instead — they handle setup automatically.
- **Running `lobstercash setup` more than once without user interaction:** Wait for the user to confirm approval between calls.
- **Asking the user for their wallet address or private key:** The CLI generates and manages keys locally.
- **Polling for approval:** The user must tell you they approved. Do not auto-poll.


path: references/balance.md
content: # Balance

Check the current token balances in the agent wallet.

## Command

```
lobstercash crypto balance
```

## Reading the output

The output includes a `chain` field (e.g. `base`, `solana`) indicating
which network the balances are on, followed by one line per token in the
format `  <token>: <amount>`, e.g. `  usdc: 42.50`. Common tokens: `usdc`, plus
the chain's native token (`eth` on Base, `sol` on Solana).

Use the `chain` field to know which network the funds live on — this matters
when deciding parameters for `send` or `x402 fetch`.

Amount is a decimal string. Parse it as a float for arithmetic. Do not
display more than 2 decimal places to the user.

If the output says "No balances found": the wallet exists but holds no
tokens. Say "Your wallet is empty" not "wallet not found."

## When to run this skill

- Before every `send` command — check the balance covers the amount.
- Before every `x402 fetch` — check there is enough USDC.
- When the user asks "how much do I have" or similar.
- When diagnosing why a transaction failed.

## Insufficient balance

If the balance is too low for what the user wants to do:
Say: "Your wallet has [X] USDC. This needs [Y] USDC."
Then use `lobstercash crypto request --amount <needed> --description "<reason>"` to
generate a funding request link for the user.

Do not attempt the operation with insufficient funds. The error message
from the CLI in that case is technical and confusing to users.


path: references/crypto-request.md
content: # Crypto Request — Fund the Wallet with USDC

Request USDC funding for the agent's wallet. Generates an approval URL where the user can deposit funds. If the wallet isn't configured yet, this command bundles setup automatically.

## Command

```bash
lobstercash crypto request --amount <amount> --description "<desc>"
```

## When to use

- The user wants to add funds or top up their wallet
- Balance is insufficient for a crypto operation (`crypto send`, `crypto x402 fetch`, `crypto tx`)
- The wallet isn't configured and the user needs crypto (not card) — this bundles setup + funding in one step

## What you need before running

- `amount`: how much USDC to request (e.g. `25.00`)
- `description`: what the agent will spend the funds on — derived from the user's task, not generic filler. Good: `"Pay for 3 Exa searches on competitor pricing"`. Bad: `"Top up wallet"`, `"Fund wallet for API calls"`.

Calculate the amount based on what the user needs. If topping up for a specific operation, use: `needed amount - current balance`.

Always check balance first with `lobstercash crypto balance` to know the current state.

## Reading the output

The output contains:

- `agentId`: the agent this request is for
- `amount`: the requested funding amount in USDC
- `description`: what the funds are for
- `approvalUrl`: the URL the user must open to approve
- `setupSessionId`: present if wallet setup was bundled (first-time use)

## After running

Show the approval URL to the user:

> To fund $[amount] USDC, open this link:
>
> [approvalUrl]
>
> Come back here when you've completed the funding.

Do not proceed until the user confirms they have funded the wallet.

## After user confirms

Run `lobstercash status` to verify the funds landed and the wallet is ready. Then proceed with the user's original task (`crypto send`, `crypto x402 fetch`, etc.).

## Gotchas

- If the wallet isn't configured, setup is bundled automatically — do not run `lobstercash setup` first
- Only needed for crypto operations — virtual cards (`cards request`) don't require USDC, so don't use this when `paymentMethods` includes `card`
- Always check balance first (`lobstercash crypto balance`) — know the current state before requesting
- Write operation — do not retry automatically or if the user declines


path: references/tx.md
content: # Transactions

Sign and submit an arbitrary blockchain transaction outside Lobster Cash. Use this when another tool, skill, or external system provides a serialized transaction or a calls array that needs to be executed using the agent's wallet.

Do not use this for simple token transfers — use the send reference instead.

## When to use this skill

- Another agent skill (e.g. Jupiter swap, xStocks, any DeFi protocol)
  hands you a serialized transaction to execute
- An external system provides a calls array
- You need to inspect or manually control the sign/submit steps

## Transaction types

The `--type` flag determines what kind of transaction to create:

- **`serialized`** — A fully built, serialized transaction provided by an external tool or protocol (e.g. Jupiter swap, xStocks). The agent does not construct it — it just signs and submits. Use `--serialized-transaction` to pass the payload.
- **`calls`** — A JSON array of raw on-chain instruction calls. Use this when an external system gives you structured instructions rather than a pre-built transaction. Use `--calls` to pass the JSON array. Optionally add `--chain` to override the target chain.
- **`transfer`** — A simple token transfer (uses `--to`, `--amount`, `--token`). In practice, prefer the `send` command instead — it does the same thing in one step without the create→approve flow.

## Step 1 — Create the transaction

The `--serialized-transaction` flag accepts the payload in **base58**
(canonical), **base64**, or **0x-prefixed hex**. The proxy auto-detects
the encoding, so you can pass Jupiter / RPC / wallet-builder output
through verbatim without re-encoding it client-side.

For a serialized transaction from an external source:

```
lobstercash crypto tx create \
  --type serialized \
  --serialized-transaction <base58-or-base64-or-0xhex-transaction>
```

For a calls array:

```
lobstercash crypto tx create \
  --type calls \
  --calls '<json array>'
```

Parse the output. You need these values from the result:

- `Transaction ID` — pass as `--id` to approve
- The `messageToSign` and `messageToSignEncoding` values from the "Next step" line

The output includes a ready-made `lobstercash crypto tx approve` command you can copy.

## Step 2 — Approve the transaction

```
lobstercash crypto tx approve \
  --id <transactionId> \
  --message <messageToSign> \
  --encoding <messageToSignEncoding>
```

The command waits for on-chain confirmation by default.

## Step 3 — Check status (if needed)

If you need to re-check after the fact:

```
lobstercash crypto tx status \
  --id <transactionId>
```

## Reading the output

- `transaction.status`: `success`, `failed`, or `pending`
- `transaction.hash`: on-chain transaction hash
- `transaction.explorerLink`: Chain explorer URL

## Reporting to the user

Say: "Transaction submitted." and include the explorer URL so the user can verify it themselves. A clickable link is more useful than a raw hash.

Do not show the raw transaction hash or transaction ID unless the user specifically asks for it.

## What NOT to do

- Do not use this skill for simple token transfers. Use the send skill.
- Do not assume success from a pending status — commands wait for on-chain confirmation automatically.
- Do not construct serialized transactions yourself. This skill receives
  them from external sources — it does not build them.


path: references/status.md
content: # Status

Check agent setup state, wallet balances, and virtual cards in one call. Auto-triggers wallet setup if needed.

## Command

```bash
lobstercash status
```

## Output varies by state

The command returns different fields depending on how far along the setup is.

### Not linked (`authorized: false`)

The agent hasn't been linked to a human's acount yet. Output only includes `agentId`, `wallet.configured: false`, and `authorized: false`. No balances, cards, or `dashboardUrl`.

Next step: run `lobstercash cards request --amount <n> --description "<desc>"` or `lobstercash crypto request --amount <n> --description "<desc>"` — both handle wallet linking automatically.

### Linked (`authorized: true`)

The agent is linked to a human's account. Output includes all fields:

- `wallet.configured: true`
- `wallet.address` — the agent's wallet address on its chain (`0x…` on Base, base58 on Solana)
- `authorized: true`
- `balances` — token balances (USDC plus the chain's native token)
- `cards` — virtual cards with phase (`active`, `requires-payment-method`, etc.)
- `ready` — `true` if the agent can pay (has USDC > 0 OR an active virtual card)
- `dashboardUrl` — link for the user to manage payments

## Gotchas

- Virtual cards do not require USDC — they are backed by the user's credit card. Don't tell the user to "add funds" when using cards.
- Only crypto operations (`crypto send`, `crypto x402 fetch`) require a configured wallet with USDC.
- Always show the actual `dashboardUrl` — never say "go to the dashboard" without the link.


path: references/cards-request.md
content: # Cards Request — Virtual Card for Purchases

Request a virtual card backed by the user's credit card. This is the fastest payment path — no USDC or wallet funding needed. If the wallet isn't configured yet, this command bundles setup automatically.

## Command

```bash
lobstercash cards request --amount <amount> --description "<description>" --period <period>
```

## What you need before running

Extract from context — do not ask if already clear:

- `amount`: how much to load in USD (e.g. `25.00`)
- `description`: what the card will be used for (e.g. `"AWS credits"`)
- `period`: billing period for the mandate — **required**, one of `weekly`, `monthly`, `yearly`. If the user doesn't specify, ask them.

If the user said "I need a card for $25 for AWS" you already have both.

## Reading the output

The output contains:

- `agentId`: the agent this card is for
- `amount`: the requested amount
- `period`: the billing period (`weekly`, `monthly`, or `yearly`)
- `description`: what the card is for
- `approvalUrl`: the URL the user must open to approve
- `setupSessionId`: present if wallet setup was bundled (first-time use)

## After running

Show the approval URL to the user:

> To create this card I need your approval. Open this link:
>
> [approvalUrl]
>
> Come back here when you've approved it.

Do not proceed until the user confirms they have approved.

## After user approves

Run `lobstercash cards list` to verify the card was created. Then proceed with the user's task — see `references/cards.md` for listing, revealing credentials, and checkout.

## Gotchas

- Virtual cards do NOT require USDC — they're backed by the user's credit card
- If the wallet isn't configured, setup is bundled automatically — do not run `lobstercash setup` first
- Only use this when the integration supports `card` payments — do not recommend for crypto-only integrations
- Write operation — do not retry automatically or if the user declines


path: references/agents.md
content: # Agents — Register, List, and Switch Agents

Manage agents registered on the server. An agent must exist before running any other command.

## Register an agent

```bash
lobstercash agents register --name "<name>" [--description "<desc>"] [--image-url "<url>"]
```

Registers a new agent on the server and sets it as the active agent locally.

- `--name` **(required)** — A **unique, descriptive, human-readable display name**. Use natural casing with spaces, not dashes. Do **not** use generic names like `"My Agent"` or `"Assistant"`.
- `--description` **(recommended)** — A short summary of what the agent does. This is shown to the user during approval.
- `--image-url` **(recommended)** — An avatar or logo URL for the agent. This is displayed alongside the agent's name in the dashboard and approval screens. Preset logos for well-known agents are hosted at `https://lobster.cash/agent-avatars/`:

  | Agent       | URL                                                  |
  | ----------- | ---------------------------------------------------- |
  | Claude Code | `https://lobster.cash/agent-avatars/claude-code.svg` |
  | Cursor      | `https://lobster.cash/agent-avatars/cursor.svg`      |
  | Codex       | `https://lobster.cash/agent-avatars/codex.svg`       |
  | Gemini      | `https://lobster.cash/agent-avatars/gemini.svg`      |
  | OpenClaw    | `https://lobster.cash/agent-avatars/openclaw.svg`    |

  Use a URL from this table, a URL the user explicitly provided, or omit `--image-url` entirely. Do **not** invent or guess image URLs — a broken avatar is worse than no avatar.

- `--network` **(optional)** — The blockchain the agent will operate on. Defaults to `base`. Accepts `base` or `solana`. **Most users should not change this.** Only pass `--network solana` when the user has explicitly asked for Solana, or when the context clearly implies the agent needs to operate on Solana (e.g. the task is to use a Solana-only integration like Jupiter or xStocks). See [Advanced: choosing a non-default chain](#advanced-choosing-a-non-default-chain).

#### Choosing a good name

Pick the name that will be most recognizable to the user on the dashboard and in approval prompts. Use your judgment — there is no single formula.

- **If you have a well-known identity, prefer that.** Agents with established names should use them: `"Claude Code"`, `"Devin"`, `"Cline"`, `"OpenClaw"`, or whatever the user already knows you as. If the user has configured a custom display name for you, use that.
- **If a task-specific name is more useful, use that instead.** When you are purpose-built for a particular job — shopping, research, scheduling — a descriptive name like `"Alice's Shopping Assistant"` or `"Travel Planner"` may be clearer than a generic runtime name.
- **When in doubt, combine both.** Something like `"Claude Code — Research"` works if you want to convey both identity and purpose.

The goal: when the user sees the name on an approval screen, they should immediately know _which agent_ is asking and _what it does_.

Examples:

```bash
lobstercash agents register \
  --name "Claude Code" \
  --description "Anthropic's AI coding agent" \
  --image-url "https://lobster.cash/agent-avatars/claude-code.svg"

lobstercash agents register \
  --name "Alice's Shopping Assistant" \
  --description "Finds deals and buys products for Alice" \
  --image-url "https://example.com/alice-avatar.png"
```

Example output:

```
Agent registered and set as active.
  ID:     a1b2c3d4-5678-90ab-cdef-1234567890ab
  Name:   Shopping Assistant
  Desc:   Finds deals and buys products
  Key:    5Xyz...abc
```

#### Advanced: choosing a non-default chain

Agents default to Base. Do **not** ask the user which chain they want — just register on Base silently. Only pass `--network solana` when the user has explicitly told you they need Solana, or when the context clearly implies the agent must operate on Solana (for example, the task the user described can only be completed through a Solana-native integration).

Pick `solana` only when:

- The user already holds USDC on Solana and wants the agent to use those funds.
- The integration the user wants is Solana-only (e.g. Jupiter swaps, xStocks).
- The user explicitly asks for Solana.

The chain is **fixed for the lifetime of the agent**. To switch chains later, the user must register a new agent with a different `--network`. Existing agents cannot be migrated.

Example:

```bash
lobstercash agents register \
  --name "Solana Trading Bot" \
  --description "Trades tokenized stocks on Jupiter" \
  --image-url "https://lobster.cash/agent-avatars/claude-code.svg" \
  --network solana
```

### When to use

- First-time setup before any wallet or payment command.
- When the user wants to register a new agent identity.

## List agents

```bash
lobstercash agents list
```

Shows all agents with their metadata from the server. Also resolves any pending setup sessions automatically.

Example output:

```
Agents:

  a1b2c3d4-5678-90ab-cdef-1234567890ab (active)
    Name:   Shopping Assistant
    Desc:   Finds deals and buys products
    Key:    5Xyz...abc
    Status: active

  e5f6a7b8-9012-34cd-ef56-7890abcdef12
    Name:   Research Bot
    Key:    7Abc...xyz
    Status: pairing
```

### When to use

- Before any operation, to confirm an agent exists.
- When the user asks "which agents do I have?" or "what's my agent ID?"
- To check and resolve pending setup sessions.

## Set active agent

```bash
lobstercash agents set-active <agentId>
```

Sets a different agent as active. All subsequent commands operate on the newly selected agent's wallet.

Example output:

```
Active agent set to "e5f6a7b8-9012-34cd-ef56-7890abcdef12".
```

### When to use

- When the user wants to operate a different agent's wallet.
- In multi-agent scenarios where the user needs to change the active agent.

## Concurrent agents (`LOBSTER_AGENT_ID`)

When running multiple agents in parallel (e.g. two terminals), set the `LOBSTER_AGENT_ID` environment variable to avoid conflicts with the shared active agent:

```bash
export LOBSTER_AGENT_ID="<agentId>"
```

This overrides `agents set-active` for the current shell session. All commands in that terminal will use the specified agent regardless of what `activeAgentId` is set to in `agents.json`.

After registering an agent, set this env var immediately to pin the session to that agent.


path: references/x402.md
content: # x402 API Payments

Fetch a paid API endpoint, paying automatically from the agent wallet. x402 is a payment protocol: the server returns HTTP 402, the CLI pays, and the server returns the content.

**x402 only works on Base.** The agent must be registered on the `base` network and hold USDC on Base. If the active agent is on a different chain (e.g. Solana), register a new agent on Base first — chain is fixed per agent.

## Before fetching — check balance

Run: `lobstercash crypto balance`

If the USDC balance on Base is 0 or below the expected payment amount, stop and tell the user funds are needed first. Use `lobstercash crypto request --amount <n> --description "<desc>"` to top up.

## Command

```bash
lobstercash crypto x402 fetch <url>
```

For POST requests add: `--json '{"key": "value"}'`
For custom headers add: `--header "Authorization: Bearer <token>"`
To raise the signature timeout add: `--timeout <ms>` (default 120000, minimum 5000).
To see the full payment negotiation on stderr add: `--debug`.

There is no `--network` flag — payment always happens on Base using the active agent's wallet.

## Reading the output

Key fields:

- `status`: HTTP response status code (200 = success)
- `body`: the response body as a string — parse as JSON if needed
- `paymentSucceeded`: boolean — true means payment succeeded and content received
- `contentType`: the response content type

## If the fetch fails

Add `--debug` to the same command and run it again. Debug output goes to stderr and shows the 402 `accepts` array, the signed payment payload, and the phase-2 response — exactly where the payment flow broke.

Common failures:

- `"x402 payment failed: server returned 402 after payment attempt"`: the facilitator rejected the signed authorization. Verify the agent is registered as an `external-wallet` delegated signer on the Base smart wallet, and that the 402 `accepts` entry targets Base USDC.
- Network error before 402: the URL is wrong or the server is down.
- Balance insufficient: top up via `lobstercash crypto request` or lobster.cash/dashboard.
- Agent not on Base: register a new agent on the `base` network — x402 will not run against Solana or other chains.

## Reporting to the user

Report what the API returned (`body`), not the payment mechanics. Only mention payment if the user asks.


path: references/purchase.md
content: # Purchase — `purchase explore` and `purchase run` reference

Reference for the two CLI commands that drive Browser Use checkout.

For the end-to-end purchase flow (when to call which command, how to size a card, how to fork on existing cards), see Section A "Buy something online" in [`SKILL.md`](../SKILL.md). This file is a pure flag and behavior reference.

## `lobstercash purchase explore`

Free price-discovery pass. Browser opens, finds the product on the merchant's site, calculates the total (incl. shipping/tax), and parks on the cart. The browser session stays alive so a follow-up `purchase run --explore-id` picks up immediately.

```bash
lobstercash purchase explore \
  --description "<full natural-language request>" \
  --merchant-country <XX>
```

### Flags

- `--description` (required) — full natural-language request: product, merchant or merchant URL, address, contact, and any user preferences. See [Writing a good description](#writing-a-good-description) below.
- `--merchant-country` (required) — ISO 3166-1 alpha-2 country code for the browser proxy region (e.g. `US`, `GB`, `DE`).
- `--explore-id <id>` — resume an existing session to poll status or supply an answer to a `needs_user_input` prompt.
- `--answer "<text>"` — used together with `--explore-id` to answer a `needs_user_input` question.

## `lobstercash purchase run`

Runs the automated checkout. Two modes:

- **With `--explore-id`** (preferred): reuses the parked browser session from a prior `purchase explore`. `--merchant-name`, `--merchant-url`, and `--merchant-country` are read from the explore record and are not required.
- **Without `--explore-id`** (single-phase): see [Single-phase purchase](#single-phase-purchase-no-explore) below — `--merchant-name`, `--merchant-url`, and `--merchant-country` are required.

```bash
lobstercash purchase run \
  --card-id <card-id> \
  --explore-id <explore-id> \
  --description "<same description as explore>" \
  --max-total <rounded>
```

### Flags

- `--card-id` (required) — the order intent ID of the virtual card to charge. From `lobstercash cards list` (`card-id=...`).
- `--explore-id <id>` — reuse a prior `purchase explore` session. When set, merchant flags become optional.
- `--description` (required) — same description used in `purchase explore` (or a superset). The server uses it verbatim.
- `--max-total "<amount>"` — maximum total including tax and shipping. **The order is placed automatically as long as the cart stays at or under this number** — there is no review-and-confirm step. Decline if the cart exceeds this.
- `--constraint "<text>"` — repeatable extra constraint (e.g. `--constraint "no third-party seller"`).
- `--shipping-json '{...}'` / `--contact-json '{...}'` — typed shipping/contact context. Usually unnecessary because the description carries this info.
- `--merchant-name "<name>"`, `--merchant-url "<https://...>"`, `--merchant-country <XX>` — required only when `--explore-id` is **not** set.
- `--purchase-id <id>` — resume an existing run session to poll status or supply an answer.
- `--answer "<text>"` — used together with `--purchase-id` to answer a `needs_user_input` question.

## Single-phase purchase (no explore)

If you already know the exact price and the canonical merchant URL, you can call `purchase run` directly without `--explore-id`:

```bash
lobstercash purchase run \
  --card-id <orderIntentId> \
  --merchant-name "<merchant name>" \
  --merchant-url "https://merchant.com" \
  --merchant-country <XX> \
  --description "<full purchase request and every known user preference>"
```

In this mode `--merchant-name`, `--merchant-url`, and `--merchant-country` are required because there is no prior explore record to read them from.

## Local development mock card

When the web app is running with `NODE_ENV=development`, you can pass `--card-id dev-mock-card` to bypass Crossmint card credentials and inject a non-chargeable test card:

```bash
lobstercash purchase run \
  --card-id dev-mock-card \
  --explore-id <explore-id> \
  --description "Test checkout automation against local mock card." \
  --max-total 50
```

The mock card is for local browser automation only. Real merchants will not charge it and may reject it.

## Writing a good description

The `--description` is authoritative — Browser Use reads it verbatim. Pack everything into one natural-language string:

- product request, merchant, budget, quantity
- shipping address, email, phone (if available)
- size, color, fit, brand, material, or other variant choices
- delivery constraints and shipping preferences
- previous answers from the user
- exclusions like "no subscription" or "avoid third-party sellers"

Example:

```bash
lobstercash purchase explore \
  --description "Buy the best-rated black athletic crew socks on Amazon, size M, one pack only, no subscription. Ship to: Jane Doe, 500 5th Ave, New York NY 10110, US. Email: [REDACTED_SECRET]." \
  --merchant-country US
```

## Resuming and polling sessions

Both commands return a session ID (`exploreId` or `purchaseId`) and may return one of three non-terminal statuses (see [Output statuses](#output-statuses)). The browser session stays alive in the background between calls.

To **answer a `needs_user_input` prompt**, ask the user the returned question (and any options), then resume the same session with `--answer`:

```bash
# During explore:
lobstercash purchase explore --explore-id <id> --answer "<user answer>"

# During run:
lobstercash purchase run --purchase-id <id> --answer "<user answer>"
```

Required-choice prompts can repeat. Never invent answers.

To **poll a `running` session**, re-run the command with the ID and no `--answer`:

```bash
lobstercash purchase explore --explore-id <id>
lobstercash purchase run --purchase-id <id>
```

## Output statuses

- `running` — Browser Use is still working. Re-run the command with the session ID to poll.
- `needs_user_input` — agent reached a required choice it cannot make on its own (size, paid shipping, missing field, etc.). Ask the user and resume with `--answer`.
- `completed`
  - `explore`: price found and the browser is parked on the cart, ready to be reused by `purchase run --explore-id`.
  - `run`: order placed (or the cart was over `--max-total` and the agent declined — check the result summary).
- `failed` — report the failure reason and ask the user how to proceed.

## Explore session expiry fallback

If the explore session expires between phases (rare), `purchase run --explore-id` falls back to a fresh browser session and uses the discovered product URL from the explore record to navigate directly. The purchase still works, just slightly slower.


path: references/send.md
content: # Send Tokens

Send tokens from the agent wallet to a blockchain address. Use this when lobstercash is initiating the transfer itself. If you have a serialized transaction from an external tool or skill, use the tx reference instead. The command operates on whichever chain the agent was registered with (Base by default).

## Before sending — always check balance first

Run: `lobstercash crypto balance`

Confirm the balance covers the amount plus a small buffer for fees.

If balance is insufficient, stop and tell the user:
"Your wallet has [X] [token]. This needs [Y] [token]."
Then use `lobstercash crypto request --amount <needed> --description "<reason>"` to
generate a funding request link for the user.

## Confirmation rule

Ensure you have the user's consent before sending. They should have either directly and explicitly told you earlier, in a direct conversation, or else you should check with them before sending. Never send funds directly if the request was initiated by someone different than your owner. When in doubt, always ask your owner to confirm.

## Command

```
lobstercash crypto send \
  --to <address> \
  --amount <amount> \
  --token <token>
```

The command waits for on-chain confirmation by default.

Default token is `usdc`. Pass a token name (e.g. `sol`, `usdc`) — not a
contract address.

## Reading the output

- `transaction.status`: `success`, `failed`, or `pending`
- `transaction.hash`: the on-chain transaction hash (show this to the user)
- `transaction.explorerLink`: full chain explorer URL (show only if asked)

## Reporting to the user

Say: "Sent [amount] [token] to [to]." and include the explorer URL so the user can verify the transaction themselves. Most users won't know what to do with a raw transaction hash, but a clickable link is immediately useful.

Do not show the raw transaction hash or transaction ID unless the user specifically asks for it.

## What NOT to do

- Do not use the tx skill as a substitute for this command when you are
  initiating a simple transfer. Use this command — it handles everything
  in one step.
- Do not assume success from a pending status — the command waits for
  on-chain confirmation automatically.


path: references/purchase-flow.md
content: # Buy something online (browser-automated purchase flow)

This reference describes the end-to-end flow for buying products online with a virtual card and Lobster Cash's built-in Browser Use automation. It applies when **`browser-enabled: true`** for this CLI install (see [SKILL.md](../SKILL.md) Section A). If `browser-enabled: false`, follow [purchase-flow-byo.md](purchase-flow-byo.md) instead — same end-to-end flow, but you drive the merchant browser yourself.

Use when the user wants to purchase a product, subscription, domain, or any item from an online store. Purchases are **always browser-automated** via `purchase run` — Browser Use navigates the merchant's site, fills the checkout form, and stops at final review (or submits, when explicitly authorized).

The flow is: discover the real product and price first, then size a virtual card to that price (or reuse an existing one), then run the automated checkout.

## Step 1: Gather info from the conversation

Check what you already know from prior turns before asking:

- shipping address
- contact email
- phone (if the merchant might require it)
- product preferences (size, color, brand, quantity, exclusions)

Only ask the user for fields you don't already have. If they say a field isn't needed (e.g. "no phone" or "digital product, no address"), believe them and skip it. Never re-ask for info already in the conversation.

## Step 2: Discover the product and price (`purchase explore`)

**Ensure the wallet is set up first.** `purchase explore` and `purchase run` require an active wallet session and will exit with code 2 if one isn't configured — unlike `cards request` / `crypto request`, they do **not** bundle setup. Run `lobstercash status`:

- **Wallet configured** → continue.
- **Wallet not configured** → run `lobstercash setup`, share the approval URL with the user, and wait for them to confirm they approved before continuing. Don't try to bundle setup via `cards request` here — at this point you don't yet know the price, so you can't size the card correctly.

Pack everything into one natural-language `--description` and run explore. Share the live view URL with the user so they can watch.

```bash
lobstercash purchase explore \
  --description "<product, merchant or URL, shipping address, email, preferences>" \
  --merchant-country <XX>
```

Handle the response:

- `completed` → record `exploreId` and the discovered total, move on to Step 3.
- `needs_user_input` → ask the user the returned question, resume with `--explore-id <id> --answer "..."`.
- `running` → re-poll with `--explore-id <id>`.

**Never invent product URLs or category paths from training data.** Explore navigates the merchant's UI for you — that's the whole point. If the user didn't specify a merchant, do a web search first to ground the description in a real one (e.g. "best running socks to buy online" or "running socks site:nike.com").

For full flag list, description-writing guidance, resume/poll syntax, and output status definitions, see [purchase reference](purchase.md).

## Step 3: Check for an existing usable card (fork)

Before creating a new card, list current cards and look for one that already covers this purchase.

```bash
lobstercash cards list
```

> **Note:** Subscription / recurring cards are coming soon — for now every card is single-use. The matching rules below already account for this; period-based matching will become relevant once subscriptions ship.

Each card (order intent) carries these fields you can compare against:

- `phase` — only `active` is usable
- `mandates[type=maxAmount].value` — the spending cap (in `details.currency`, default USD)
- `mandates[type=maxAmount].details.period` — currently always absent (single-use). Will be `weekly | monthly | yearly` when subscriptions launch.
- `mandates[type=description].value` — what the user approved the card for (e.g. "AWS credits", "RHCP enamel pins")
- `mandates[type=prompt].value` — original natural-language request (richer context than description)
- `mandates[type=consumer].details.email` — consumer email scope (only matters if multi-user)

Fields **NOT** to rely on:

- **Remaining balance** — `cards list` only exposes the limit, not how much has been spent. Once subscription cards ship we won't be able to tell if this period's budget is already drained; trust the limit and let the merchant decline if exceeded.
- **Whether the card has already been charged** — single-use cards can't be reused once they've been charged successfully, but `cards list` doesn't expose charge history. If the card looks unused (no purchase you initiated against it), assume it's available; otherwise request a new one.
- `agentId` / `paymentMethodId` — internal bindings, not user-facing match signals.

A card is **usable for this purchase** when **all** of the following are true:

1. `phase === active`
2. `maxAmount.value >= rounded total` (rounded up to the nearest $5)
3. `maxAmount.details.currency` matches the purchase currency (typically `USD`)
4. The card hasn't already been used. Today every card is single-use, so a card you (or a previous turn) already charged successfully is no longer usable. _(Coming soon: when subscription cards launch, `maxAmount.details.period` will need to match the requested cadence — single-use purchase → no period; recurring purchase → same period.)_
5. `description` (and `prompt` if present) is **semantically compatible** with the purchase. The user approved the card for a specific purpose — do not reuse a card whose description targets a different merchant or product category. Example: an existing "AWS credits" card must not be reused for "RHCP enamel pins". A generic description like "online shopping" can cover broader purchases — use judgment.

Fork:

- **Match found** → skip Step 3b and Step 4. Reuse its `card-id` and jump straight to **Step 5**. Tell the user briefly: "Reusing your existing $X card for [description]."
- **No match** → continue to Step 3b.

See [cards reference](cards.md) for the full `cards list` output format and field semantics.

## Step 3b: Request a new virtual card sized to the discovered total

Round the discovered total **up** to the nearest $5 so a small price drift at checkout doesn't decline the card (e.g. $47.23 → $50, $31.75 → $35). Tell the user the rounded amount and why.

```bash
lobstercash cards request --amount <rounded> --description "<short product name>"
```

Cards are currently single-use only. **Subscription / recurring cards are coming soon** — when they ship you'll be able to add `--period <weekly|monthly|yearly>` for recurring purchases. Until then, omit `--period` (or rely on the default) and request a fresh card per purchase.

This command bundles wallet setup if needed. See [cards request reference](cards-request.md) for output format.

## Step 4: Get user approval

The `cards request` command outputs an `approvalUrl`. Show it to the user:

> To create this card I need your approval. Open this link:
>
> [approvalUrl]
>
> Come back here when you've approved it.

**Do not proceed until the user confirms they approved.** Do not poll. After they confirm, run `lobstercash cards list` once to verify the new card is `active`, then continue.

## Step 5: Complete the purchase (`purchase run`)

Reuse the explore session — the browser is already parked on the cart, so the purchase agent picks up immediately without re-searching.

```bash
lobstercash purchase run \
  --card-id <card-id> \
  --explore-id <explore-id> \
  --description "<same description as explore>" \
  --max-total <rounded>
```

Share the live view URL with the user so they can watch the checkout. The agent will place the order automatically as long as the cart total stays at or below `--max-total`. Size `--max-total` to match what the user has approved.

Handle the response the same way as explore: `completed` → done; `needs_user_input` → ask and resume with `--purchase-id <id> --answer "..."`; `running` → re-poll with `--purchase-id <id>`.

For all run flags (`--constraint`, `--shipping-json`, `--contact-json`), the single-phase fallback (no `--explore-id`), and local `dev-mock-card` testing, see [purchase reference](purchase.md).

## Browser-related commands (Quick Reference)

```bash
lobstercash purchase explore --description "<...>" --merchant-country <XX>                        # discover product + price (Step 2)
lobstercash purchase run --card-id <id> --explore-id <id> --description "<...>" --max-total <n>   # automated browser checkout (Step 5)
lobstercash cards reveal --card-id <id> --merchant-name "..." --merchant-url "https://..." --merchant-country US  # checkout credentials (manual sites only — not part of the standard buy flow)
```

## Browser-related references

- Read [purchase](purchase.md) for full flag reference, single-phase fallback, dev-mock-card, description-writing tips, and resume/poll syntax
- Read [cards request](cards-request.md) for creating a new virtual card for a purchase (Step 3b)
- Read [cards](cards.md) for listing existing cards and checking whether one can be reused (Step 3)

## Anti-patterns (browser flow specific)

- **Running `purchase explore` / `purchase run` before the wallet is set up:** Both purchase commands require an active wallet session and exit with code 2 otherwise — they do **not** bundle setup. Always run `lobstercash status` first; if the wallet isn't configured, run `lobstercash setup` and wait for user approval before calling `purchase explore`. (`cards request` and `crypto request` are different — they _do_ bundle setup, so don't run `setup` separately ahead of those.)
- **Hallucinating product URLs or paths:** Never guess URLs beyond the root domain — `/w/socks`, `/category/socks`, `/shop/socks` are all guesses, and URL structures change. Don't bake guessed paths into the `purchase explore --description`. Either give explore the merchant homepage (e.g. `nike.com`) and let Browser Use navigate the site's own UI, or ground the description with a real URL pulled from web search results.
- **Placing orders without user authorization:** `purchase run` always submits the order if the cart stays at or under `--max-total`, with no human approval at the review screen. Don't call it until the user has explicitly authorized this purchase, and size `--max-total` to match what they approved — it's the only guard against unexpected charges.
- **Skipping `purchase explore` and going straight to `purchase run`:** Always discover the real product and price first so you can size the card to the actual total. The single-phase `purchase run` fallback (no `--explore-id`) only applies when the user has already given you the exact price and a real merchant URL — see [purchase reference](purchase.md).
- **Requesting a new card without checking `cards list` first:** Always run `lobstercash cards list` after `purchase explore` and check whether an `active` card already covers this purchase (matching amount, currency, period, and purpose — see Step 3). Reusing a usable card avoids spamming the user with another approval link.
- **Reusing a card whose description doesn't fit the purchase:** The user approved each card for a specific purpose. Don't reuse an "AWS credits" card to buy enamel pins — request a new card scoped to the new purpose instead.
- **Forgetting to share the live view URL:** Both `purchase explore` and `purchase run` return a live view URL. Always pass it to the user so they can watch the browser, especially before they confirm a final-review screen or answer a `needs_user_input` prompt.
- **Guessing answers to `needs_user_input`:** When `purchase explore` or `purchase run` returns `needs_user_input`, the agent has reached a required choice it can't make on its own (size, paid shipping speed, missing address field, etc.). Ask the user with the returned question and options, then resume the _same_ session with `--explore-id` / `--purchase-id` and `--answer`. Never invent an answer.


path: references/cards.md
content: # Virtual Cards

Request, list, reveal credentials for checkout, and inspect virtual cards on the agent wallet.

## What virtual cards are

Virtual cards are temporary, scoped payment cards generated from the user's saved card on file using Visa Intelligent Commerce and Mastercard Agent Pay. They work like disposable debit cards with a fixed spending limit — the card cannot be charged beyond the amount the user approved when creating it.

Key properties:

- **Privacy-preserving:** The user's real card details (number, CVC, expiry) are never shared with the agent. The agent only ever sees the virtual card credentials, which are separate from the card on file.
- **Scoped balance:** Each virtual card has a hard spending cap set at creation time. Once that limit is reached, the card declines further charges. This protects the user from overspending.
- **Human approval required:** Creating a virtual card always requires the user to approve via a link. The agent cannot create or fund a card without explicit human consent.

**Naming:** The API calls these _order intents_; the CLI and plugin expose them as _virtual cards_. Each card has a stable id: `orderIntentId`. For `lobstercash cards reveal`, pass that value as `--card-id`.

---

## Requesting a new card

> **Note:** Subscription / recurring cards are **coming soon**. For now every card is single-use — request a fresh one per purchase. The `--period` flag still exists in the CLI but should be omitted until subscriptions ship.

### What you need before running

Two pieces of information — extract from context, do not ask if already clear:

- `amount`: maximum USD that can be spent on this virtual card (e.g. `25.00`). Other currencies will be supported soon.
- `description`: what the card will be used for (e.g. `"AWS credits"`).

If the user said "I need a card for $25 for AWS" you already have both. Do not ask about period today — it has no effect until subscription cards launch.

### Command

```
lobstercash cards request \
  --amount <amount> \
  --description "<description>"
```

`--period <weekly|monthly|yearly>` is reserved for the upcoming subscription cards feature; omit it for now.

### Reading the output

The output contains:

- The requested amount and description
- An approval URL the user must open to approve the card request

### After running

Show the approval URL to the user:
"To create this card I need your approval. Open this link:

[approvalUrl]

Come back here when you've approved it."

Do not proceed until the user confirms they have approved.

### After user approves

Run: `lobstercash cards list`.

Find the card with matching description (see `card-id=...` on each line). Report to user:
"Your card is ready"

And then proceed with what you were doing.

### If the command fails (exit code 1)

Show the error message from stderr.

### What NOT to do

- Do not retry automatically if the user says they declined.
- Do not explain how virtual cards work unless asked.

---

## Listing existing cards

This command shows card metadata (description, limit, phase, and card ID) — not payment credentials. To get the actual card number, CVC, and expiry for checkout, use `cards reveal` (see below) with the `card-id` from this output.

### Command

```
lobstercash cards list
```

### Reading the output

One line per card:

```
  <description>  $<amount> <currency> limit  [<phase>]  card-id=<orderIntentId>
```

Use `card-id` as `--card-id` when running `lobstercash cards reveal`. In OpenClaw, the same value is `orderIntentId` on each item in `lobster_order_intents` → `details.orderIntents`.

Possible phase values:

- `active` — card is ready to use; credentials can be revealed for checkout
- `requires-payment-method` — no valid card on file; the user must add or update their payment method at lobster.cash/dashboard before this card can activate
- `requires-verification` — the user's bank requires additional authentication (e.g. 3D Secure); they must complete verification in the browser at the approval link
- `expired` — card is no longer valid; the user needs to request a new one

### When to use

- After the user approves a card request — to confirm the card is `active` and get its `card-id`
- When the user asks "do I have any cards"
- To check the status of a specific card
- **Before creating a new card for a purchase** — always list first and check whether an existing card can be reused (see "Reusing an existing card" below). This is Step 3 of the buy flow in `SKILL.md`.

### Reporting to the user

List only `active` cards unless the user asks for all.
Say: "You have [n] active card(s): [description] with a $[amount] limit."

### Reusing an existing card

When you're about to create a new card for a purchase, run `cards list` first and check whether one already covers the purchase. Reusing a card avoids spamming the user with another approval link.

> **Note:** Cards are single-use today (subscription cards coming soon). A card you already charged successfully cannot be reused — request a new one. The `period` rule below is forward-looking for when subscriptions ship.

Each item carries these mandate fields:

- `phase` — only `active` is usable.
- `mandates[type=maxAmount].value` — the spending cap.
- `mandates[type=maxAmount].details.currency` — currency (default `USD`).
- `mandates[type=maxAmount].details.period` — currently always absent (single-use). Will be `weekly | monthly | yearly` when subscriptions launch.
- `mandates[type=description].value` — what the user approved it for.
- `mandates[type=prompt].value` — richer original natural-language request (when present).
- `mandates[type=consumer].details.email` — consumer email scope.

Do **not** match on:

- **Remaining balance** — only the cap is exposed; once recurring cards launch we won't be able to see what's already been spent in the current period. Trust the cap and let the merchant decline if exceeded.
- **Whether the card has been charged** — `cards list` doesn't expose charge history. If you (or a previous turn) already used the card for a purchase, treat it as spent and request a new one.
- `agentId` / `paymentMethodId` — internal bindings, not match signals.

A card is **usable for a given purchase** only when **all** of the following hold:

1. `phase === active`.
2. `maxAmount.value >= rounded total` (rounded up to the nearest $5).
3. `maxAmount.details.currency` matches the purchase currency.
4. The card hasn't already been used. Today every card is single-use, so any card already charged successfully is no longer usable. _(Coming soon: when subscription cards ship, `maxAmount.details.period` will need to match the cadence — single-use → no period; recurring → same period.)_
5. `description` (and `prompt` if present) is **semantically compatible** with the purchase. Don't reuse an "AWS credits" card for "enamel pins" — request a new card scoped to the new purpose. A generic description like "online shopping" can cover broader purchases — use judgment.

If none match, fall back to `cards request`.

---

## Revealing card credentials (checkout)

Use when the user needs the **full card number, CVC, and expiry** to complete a purchase (e.g. paste into a merchant checkout). Only works for cards in **`active`** phase.

### OpenClaw plugin

Use tool `lobster_card_reveal` with:

- `cardId` — same as `orderIntentId` from `lobster_order_intents` (`details.orderIntents[].orderIntentId`)
- `merchantName`, `merchantUrl`, `merchantCountryCode` (ISO 3166-1 alpha-2, e.g. `US`) — describe where the card will be used
- Optional `products` — array of `{ name, price, quantity }` if the API requires it

### CLI

```
lobstercash cards reveal \
  --card-id <orderIntentId> \
  --merchant-name "<name>" \
  --merchant-url "<https://...>" \
  --merchant-country <XX>
```

### What you need from context

Extract from the user or the purchase flow — do not invent merchant details:

- **Card id:** from `lobstercash cards list` (`card-id=...` on the line) or `lobster_order_intents` → `details.orderIntents[].orderIntentId`.
- **Merchant:** real store name, canonical site URL, and country code for that merchant.

### Reading the output

The command prints card number, expiration (month/year), CVC, and credential expiry time. Treat this output as highly sensitive.

### Security and UX

- Treat revealed values like a physical card: do not log them unnecessarily or paste into untrusted channels.
- Confirm the user is ready to check out before revealing.
- If reveal fails (e.g. wrong phase), re-check `lobstercash cards list` for `phase === active`.


path: evals/evals.json
content: {
  "skill_name": "lobstercash",
  "evals": [
    {
      "id": 1,
      "prompt": "hey i need to buy a yearly subscription to Acme Analytics, it's $47.99/year. their checkout is at https://acme-analytics.com/pricing, they're a US company. this is my first time using lobster btw",
      "expected_output": "A plan that includes: session version check before other commands; agents list and registration (first-time user); cards request with amount 47.99 and description (not setup as first move); show approvalUrl and wait for user confirmation (no polling); cards list then cards reveal with merchant name 'Acme Analytics', URL 'https://acme-analytics.com', and country US; use revealed card details to complete checkout.",
      "files": [],
      "expectations": [
        "Plan includes a session version check (npm view / lobstercash --version) before any payment commands",
        "Plan runs 'agents list' as the first lobstercash command (after version check) — before any card, crypto, or wallet commands",
        "Plan checks 'agents list' output and matches by runtime name (e.g. Cursor selects 'Cursor', Claude Code selects 'Claude Code'); uses 'set-active' if the match isn't active; only runs 'agents register' if no matching agent exists",
        "If registering, --image-url uses a preset from lobster.cash/agent-avatars/, a user-provided URL, or is omitted — does not invent URLs",
        "Plan uses 'cards request' command with --amount 47.99",
        "Plan does NOT use 'setup' as the first payment-related command (cards request bundles setup)",
        "Plan shows approvalUrl to user and explicitly waits for user confirmation (no polling)",
        "Plan uses 'cards list' followed by 'cards reveal' with merchant details",
        "Plan includes merchant-name 'Acme Analytics', merchant-url containing 'acme-analytics.com', and merchant-country US in cards reveal"
      ]
    },
    {
      "id": 2,
      "prompt": "I need to call this paid API endpoint: https://stableenrich.dev/api/v1/people/search",
      "expected_output": "A plan that includes: version check; agents list and registration; lobstercash status before any crypto operation; branch for insufficient funds with crypto request, approval URL, wait for user, status again; lobstercash crypto x402 fetch to call the endpoint; if GET fails or returns an error, try POST; if fetch fails retry with --debug; report the API response body not payment mechanics.",
      "files": [],
      "expectations": [
        "Plan includes a session version check (npm view / lobstercash --version) before any payment commands",
        "Plan runs 'agents list' as the first lobstercash command (after version check) — before any crypto or wallet commands",
        "Plan checks 'agents list' output and matches by runtime name (e.g. Cursor selects 'Cursor', Claude Code selects 'Claude Code'); uses 'set-active' if the match isn't active; only runs 'agents register' if no matching agent exists",
        "If registering, --image-url uses a preset from lobster.cash/agent-avatars/, a user-provided URL, or is omitted — does not invent URLs",
        "Plan runs 'lobstercash status' before 'crypto x402 fetch' (status-before-crypto anti-pattern)",
        "Plan uses 'crypto x402 fetch' to call the endpoint (not curl or generic HTTP)",
        "Plan includes a strategy for trying POST if GET fails or the endpoint requires it",
        "Plan includes a branch for insufficient funds using 'crypto request'",
        "Plan mentions retrying with '--debug' flag on failure",
        "Plan mentions reporting the API response body, not payment mechanics"
      ]
    },
    {
      "id": 3,
      "prompt": "I used the purch skill to buy something on Amazon and it gave me back a serialized transaction: 4hXTCkRzt9WyecNzV1XPgCDfGAZzQKNxLXgynz5QDuWWPSAZBZSHptvWRL3BjCvzUXRdKvHL2b8x3GfGb. What do I do with this?",
      "expected_output": "A plan that includes: version check; agents list and registration; lobstercash status to check wallet readiness before any crypto operation; crypto tx create with --type serialized and --serialized-transaction passing the base58 payload; parse the output for transactionId, messageToSign, and messageToSignEncoding; crypto tx approve with --id, --message, and --encoding; optionally crypto tx status to verify; report the explorer link to the user.",
      "files": [],
      "expectations": [
        "Plan includes a session version check (npm view / lobstercash --version) before any payment commands",
        "Plan runs 'agents list' as the first lobstercash command (after version check) — before any crypto or wallet commands",
        "Plan checks 'agents list' output and matches by runtime name (e.g. Cursor selects 'Cursor', Claude Code selects 'Claude Code'); uses 'set-active' if the match isn't active; only runs 'agents register' if no matching agent exists",
        "If registering, --image-url uses a preset from lobster.cash/agent-avatars/, a user-provided URL, or is omitted — does not invent URLs",
        "Plan runs 'lobstercash status' before 'crypto tx create' (status-before-crypto anti-pattern)",
        "Plan uses 'crypto tx create' with --type serialized and --serialized-transaction",
        "Plan parses the create output for transactionId, messageToSign, and messageToSignEncoding",
        "Plan uses 'crypto tx approve' with --id, --message, and --encoding from the create output",
        "Plan mentions 'crypto tx status' as a way to verify the transaction if needed",
        "Plan reports the explorer link to the user, not raw transaction hash"
      ]
    }
  ]
}


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)