-
Notifications
You must be signed in to change notification settings - Fork 2
ai: blocktank lsp api plugin + agent control interface #860
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ovitrif
wants to merge
3
commits into
master
Choose a base branch
from
ai/lsp-skill
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "name": "blocktank-api", | ||
| "description": "Interact with the Blocktank LSP API for Lightning testing during bitkit development." | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Blocktank API Plugin | ||
|
|
||
| A Claude Code plugin that gives Claude knowledge of the full Blocktank LSP API, enabling it to autonomously create channels, fund them, mine blocks, pay invoices, and close channels during Blocktank LSP testing. | ||
|
|
||
| ## Usage | ||
|
|
||
| Once installed, the skill auto-triggers when you mention things like: | ||
| - "mine blocks", "deposit sats", "pay invoice", "force close" | ||
| - "channel order", "CJIT", "blocktank", "LSP" | ||
|
|
||
| Claude will use the `./lsp` wrapper at the repo root to make API calls directly. | ||
|
|
||
| ## Configuration | ||
|
|
||
| The default API base URL is `https://api.stag0.blocktank.to/blocktank/api/v2` (staging). | ||
|
|
||
| To override (e.g., for a local instance): | ||
|
|
||
| ```bash | ||
| export BLOCKTANK_API_URL=http://localhost:9000/api | ||
| ``` | ||
|
|
||
| ## Cross-project reuse | ||
|
|
||
| To use this plugin from another repo (e.g. bitkit-ios), symlink it into that project's `.claude/plugins/`: | ||
|
|
||
| ```bash | ||
| ln -s /path/to/bitkit-android/.claude/plugins/blocktank-api /path/to/other-repo/.claude/plugins/blocktank-api | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| --- | ||
| name: lsp | ||
| description: > | ||
| This skill should be used when the user asks to interact with the Blocktank LSP API, | ||
| "mine blocks", "deposit sats", "pay invoice", "force close a channel", "create a channel order", | ||
| "open a channel", "estimate fees", "create a CJIT channel", or mentions "blocktank", "regtest", | ||
| "LSP", or Lightning channel testing workflows during bitkit development. | ||
| version: 0.1.0 | ||
| --- | ||
|
|
||
| # Blocktank LSP API | ||
|
|
||
| Blocktank is the Lightning Service Provider (LSP) used by Bitkit. This skill provides full knowledge of its REST API and a utility script to call any endpoint from the command line. | ||
|
|
||
| No authentication is required. All requests and responses use JSON. | ||
|
|
||
| ## Configuration | ||
|
|
||
| **Default base URL:** `https://api.stag0.blocktank.to/blocktank/api/v2` (staging) | ||
|
|
||
| Override with the `BLOCKTANK_API_URL` environment variable: | ||
| - Local instance: `http://localhost:9000/api` | ||
|
|
||
| ## API Script | ||
|
|
||
| Call any endpoint using the `./lsp` wrapper at the repo root: | ||
|
|
||
| ```bash | ||
| ./lsp <GET|POST> <path> [json_body] | ||
| ``` | ||
|
|
||
| Examples: | ||
|
|
||
| ```bash | ||
| # Get service info | ||
| ./lsp GET /info | ||
|
|
||
| # Create a channel order | ||
| ./lsp POST /channels '{"lspBalanceSat":100000,"channelExpiryWeeks":12}' | ||
|
|
||
| # Mine 6 blocks | ||
| ./lsp POST /regtest/chain/mine '{"count":6}' | ||
|
|
||
| # Deposit to an address | ||
| ./lsp POST /regtest/chain/deposit '{"address":"bcrt1q...","amountSat":500000}' | ||
| ``` | ||
|
|
||
| The script outputs raw JSON. Pipe to `jq` for formatting if needed. | ||
|
|
||
| On HTTP errors (4xx/5xx), the script prints the status code to stderr and the error response body to stdout, then exits with code 1. | ||
|
|
||
| ## Endpoint Quick Reference | ||
|
|
||
| ### Service Info | ||
|
|
||
| | Method | Path | Description | | ||
| |--------|------|-------------| | ||
| | GET | `/info` | Service info, LSP nodes, channel size limits, fee rates | | ||
|
|
||
| ### Channel Orders | ||
|
|
||
| | Method | Path | Description | | ||
| |--------|------|-------------| | ||
| | POST | `/channels` | Create a channel order | | ||
| | GET | `/channels/:id` | Get order by ID | | ||
| | GET | `/channels?ids[]=` | Get multiple orders (1-50 IDs) | | ||
| | POST | `/channels/:id/open` | Open a paid channel | | ||
| | GET | `/channels/:id/min-0conf-tx-fee` | Get 0-conf fee window | | ||
| | POST | `/channels/estimate-fee` | Estimate order fee | | ||
| | POST | `/channels/estimate-fee-full` | Estimate fee with breakdown | | ||
|
|
||
| ### CJIT (Just-In-Time Channels) | ||
|
|
||
| | Method | Path | Description | | ||
| |--------|------|-------------| | ||
| | POST | `/cjit` | Create a JIT channel entry | | ||
| | GET | `/cjit/:id` | Get CJIT entry status | | ||
|
|
||
| ### Gift | ||
|
|
||
| | Method | Path | Description | | ||
| |--------|------|-------------| | ||
| | POST | `/gift/pay` | Pay a gift invoice | | ||
| | POST | `/gift/order` | Create a gift order | | ||
| | GET | `/gift/:id` | Get gift info | | ||
|
|
||
| ### Regtest Tools (regtest only) | ||
|
|
||
| | Method | Path | Description | | ||
| |--------|------|-------------| | ||
| | POST | `/regtest/chain/mine` | Mine blocks (default: 1) | | ||
| | POST | `/regtest/chain/deposit` | Deposit sats to address (default: 100,000) | | ||
| | POST | `/regtest/channel/pay` | Pay a Lightning invoice | | ||
| | GET | `/regtest/channel/pay/:id` | Get payment status | | ||
| | POST | `/regtest/channel/close` | Force close a channel | | ||
|
|
||
| ## Common Workflows | ||
|
|
||
| ### Workflow A: Purchase a Channel | ||
|
|
||
| 1. **Get service info** — `GET /info` to retrieve LSP node pubkeys and channel size limits | ||
| 2. **Create order** — `POST /channels` with `lspBalanceSat`, `channelExpiryWeeks`, and optional `clientBalanceSat` | ||
| 3. **Extract payment info** — from response: `payment.onchain.address` (bitcoin address) and `feeSat` (amount to pay) | ||
| 4. **Fund the order** — `POST /regtest/chain/deposit` with the payment address and fee amount | ||
| 5. **Confirm payment** — `POST /regtest/chain/mine` with `count: 1` to mine a block | ||
| 6. **Poll order status** — `GET /channels/:id` until `state2` becomes `paid` | ||
| 7. **Open channel** — `POST /channels/:id/open` with the client's `connectionStringOrPubkey` | ||
| 8. **Confirm channel** — `POST /regtest/chain/mine` with `count: 6` to fully confirm | ||
|
|
||
| ### Workflow B: CJIT Channel (Just-In-Time) | ||
|
|
||
| 1. **Get service info** — `GET /info` for node pubkeys and limits | ||
| 2. **Create CJIT entry** — `POST /cjit` with `channelSizeSat`, `invoiceSat`, `nodeId`, `channelExpiryWeeks` | ||
| 3. **Extract invoice** — from response: `invoice.request` (bolt11 invoice string) | ||
| 4. **Client pays invoice** — the mobile app pays the invoice, triggering automatic channel opening | ||
| 5. **Poll status** — `GET /cjit/:id` until `state` becomes `completed` | ||
|
|
||
| ### Workflow C: Force Close a Channel | ||
|
|
||
| 1. **Get order info** — `GET /channels/:id` to find `channel.fundingTx.id` and `channel.fundingTx.vout` | ||
| 2. **Close channel** — `POST /regtest/channel/close` with `fundingTxId`, `vout`, and `forceCloseAfterSec: 0` for immediate close | ||
| 3. **Mine blocks** — `POST /regtest/chain/mine` with `count: 6` to finalize the closure | ||
|
|
||
| ### Workflow D: Automated Invoice Payments | ||
|
|
||
| Bulk-create and pay invoices to populate the app with payment activity. | ||
|
|
||
| **Prerequisites:** Dev debug build installed, wallet set up, LDK node running, open channel with inbound capacity, ADB connected. | ||
|
|
||
| **Run with defaults** (21 invoices of 1..21 sats, mine 150 blocks in batches of 10): | ||
|
|
||
| ```bash | ||
| "${CLAUDE_PLUGIN_ROOT}/skills/lsp/scripts/pay-invoices.sh" | ||
| ``` | ||
|
|
||
| **Custom parameters** via env vars: | ||
|
|
||
| ```bash | ||
| INVOICE_COUNT=10 DESCRIPTION="test-ovi-{i}" MINE_TOTAL=60 MINE_BATCH=10 \ | ||
| "${CLAUDE_PLUGIN_ROOT}/skills/lsp/scripts/pay-invoices.sh" | ||
| ``` | ||
|
|
||
| - `DESCRIPTION` — invoice description; `{i}` is replaced with the invoice index (default: `dev-payment-{i}`) | ||
|
|
||
| The script uses the `DevToolsProvider` ContentProvider (dev builds only) to create invoices on the app's LDK node via `adb shell content call`, then pays each via the LSP's `POST /regtest/channel/pay` endpoint. | ||
|
|
||
| **Create a single invoice manually:** | ||
|
|
||
| ```bash | ||
| adb shell "content call --uri content://to.bitkit.dev.devtools \ | ||
| --method createInvoice --arg '{\"amount\":1000,\"description\":\"test\"}'" | ||
| ``` | ||
|
|
||
| ## State Machines | ||
|
|
||
| ### Order States (`state2`) | ||
|
|
||
| ``` | ||
| created → paid → executed | ||
| ↘ expired | ||
| ``` | ||
|
|
||
| - `created` — waiting for payment | ||
| - `paid` — payment confirmed, ready to open channel | ||
| - `executed` — channel opened successfully | ||
| - `expired` — order timed out | ||
|
|
||
| ### Payment States (`payment.state2`) | ||
|
|
||
| ``` | ||
| created → paid → refundAvailable → refunded | ||
| ↘ canceled | ||
| ``` | ||
|
|
||
| ### Channel States (`channel.state`) | ||
|
|
||
| ``` | ||
| opening → open → closed | ||
| ``` | ||
|
|
||
| ### CJIT States (`state`) | ||
|
|
||
| ``` | ||
| created → completed | ||
| ↘ expired | ||
| ↘ failed | ||
| ``` | ||
|
|
||
| ## Detailed API Reference | ||
|
|
||
| For full request/response schemas, field constraints, and error codes for every endpoint, consult: | ||
|
|
||
| - **`references/api-reference.md`** — Complete API reference with all fields, types, defaults, and validation rules |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: The plugin needs to be manually enabled in
.claude/settings.local.jsonbefore it shows up as a/lspskill in Claude Code:Without this, Claude can't discover the skill and falls back to "Unknown skill: lsp". Could we add this setup step to the README or the PR description QA notes? It would save other devs from hitting the same issue.
Also worth noting that a Claude Code restart is needed after enabling the plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@claude address this concern and update the PR.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude finished @ovitrif's task in 2m 0s —— View job
Addressing plugin setup documentation concern
The
.claude/directory requires interactive approval that isn't available in the CI context. Here is the exact change to apply to.claude/plugins/blocktank-api/README.md:Add a Setup section after the intro paragraph and before Usage:
Then restart Claude Code. After restart the
/lspskill will be available.Then restart Claude Code. After restart the
/lspskill will be available.Usage
Once installed, the skill auto-triggers when you mention things like:
Claude will use the
./lspwrapper at the repo root to make API calls directly.Configuration
The default API base URL is
https://api.stag0.blocktank.to/blocktank/api/v2(staging).To override (e.g., for a local instance):
export BLOCKTANK_API_URL=http://localhost:9000/apiCross-project reuse
To use this plugin from another repo (e.g. bitkit-ios), symlink it into that project's
.claude/plugins/:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@claude how can we get rid of the issue that blocked the commit of updates in
.claude?!And, split the commits for now , so you can already cover the changes outside the .claude folder.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude finished @ovitrif's task in 3m 22s —— View job
Addressing
.claude/commit block + split commits.claude/permission issue.claude/changes to commitRoot cause of the
.claude/blockThe Claude Code action protects the
.claude/directory by default — writes to it require interactive user approval, which isn't available in CI. A previous CI run attempted to add the Setup section toREADME.md, was blocked mid-operation, and left the.claude/files deleted from the local working tree (unstaged, so the remote branch is unaffected — those files are still committed there).Fix: allow CI to write to
.claude/Add a
claude_argsline to.github/workflows/claude.ymlunder theRun Claude Codestep:This pre-approves Edit and Write operations on
.claude/paths, removing the need for interactive approval in CI. Once that change is merged (even tomaster— the workflow applies globally), tag me again and I'll add the Setup section to.claude/plugins/blocktank-api/README.mdin one commit.Split commits — nothing to split
All non-
.claude/changes (README.md,lsp,app/src/debug/AndroidManifest.xml,DevToolsProvider.kt) are already committed on this branch. There are no pending non-.claude/changes for me to commit separately right now.Pending work (blocked by the permission issue above)
Add a Setup section to
.claude/plugins/blocktank-api/README.mdbetween the intro and Usage:Then restart Claude Code. After restart the
/lspskill will be available.