Skip to content

Commit a55be98

Browse files
committed
ai: accept json command inputs via --arg
1 parent 7313b35 commit a55be98

4 files changed

Lines changed: 40 additions & 33 deletions

File tree

.claude/plugins/blocktank-api/skills/lsp/SKILL.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ The script uses the `DevToolsProvider` ContentProvider (dev builds only) to crea
145145
**Create a single invoice manually:**
146146

147147
```bash
148-
adb shell content call --uri content://to.bitkit.dev.devtools --method createInvoice --arg 1000
148+
adb shell "content call --uri content://to.bitkit.dev.devtools \
149+
--method createInvoice --arg '{\"amount\":1000,\"description\":\"test\"}'"
149150
```
150151

151152
## State Machines

.claude/plugins/blocktank-api/skills/lsp/scripts/lsp.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ BODY="${3:-}"
2121

2222
URL="${BASE_URL}${API_PATH}"
2323

24+
tmpfile=$(mktemp)
25+
trap 'rm -f "$tmpfile"' EXIT
26+
2427
call_api() {
2528
local http_code
2629
local response
27-
local tmpfile
28-
tmpfile=$(mktemp)
29-
trap 'rm -f "$tmpfile"' EXIT
3030

3131
if [ "$METHOD" = "GET" ]; then
3232
http_code=$(curl -s -o "$tmpfile" -w "%{http_code}" "$URL")

.claude/plugins/blocktank-api/skills/lsp/scripts/pay-invoices.sh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ create_invoice() {
3636
local amount="$1"
3737
local index="$2"
3838
local raw
39-
raw=$(adb shell content call \
40-
--uri "content://$AUTHORITY" \
39+
raw=$(adb shell "content call --uri content://$AUTHORITY \
4140
--method createInvoice \
42-
--arg "$amount" \
43-
--extra "description:s:dev-payment-$index")
41+
--arg '{\"amount\":$amount,\"description\":\"dev-payment-$index\"}'")
4442

4543
# Extract JSON from Bundle output: Result: Bundle[{result={"bolt11":"..."}}]
4644
local json

app/src/debug/java/to/bitkit/dev/DevToolsProvider.kt

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,9 @@ import kotlinx.serialization.Serializable
1313
import kotlinx.serialization.json.Json
1414
import to.bitkit.async.ServiceQueue
1515
import to.bitkit.repositories.LightningRepo
16-
import to.bitkit.utils.Logger
1716

1817
class DevToolsProvider : ContentProvider() {
1918

20-
companion object {
21-
private const val TAG = "DevToolsProvider"
22-
private const val KEY_DESCRIPTION = "description"
23-
}
24-
2519
@EntryPoint
2620
@InstallIn(SingletonComponent::class)
2721
interface Dependencies {
@@ -33,28 +27,24 @@ class DevToolsProvider : ContentProvider() {
3327
}
3428

3529
override fun call(method: String, arg: String?, extras: Bundle?): Bundle {
36-
val command = DevCommand.from(method)
30+
val command = DevCommand.parse(method, arg)
3731
?: return DevResult.Error("Unknown method: '$method'").toBundle()
38-
return execute(command) { handle(command, arg, extras) }
32+
return execute { handle(command) }
3933
}
4034

41-
private fun execute(command: DevCommand, block: suspend () -> DevResult): Bundle = runCatching {
35+
private fun execute(block: suspend () -> DevResult): Bundle = runCatching {
4236
ServiceQueue.LDK.blocking { block() }
4337
}.getOrElse {
44-
Logger.error("${command.method} failed", it, context = TAG)
45-
DevResult.Error(it.message ?: "Failed command: '$command.method'")
38+
DevResult.Error(it.message)
4639
}.toBundle()
4740

48-
private suspend fun handle(command: DevCommand, arg: String?, extras: Bundle?): DevResult = when (command) {
49-
DevCommand.CREATE_INVOICE -> createInvoice(arg, extras)
50-
}
51-
52-
private suspend fun createInvoice(arg: String?, extras: Bundle?): DevResult {
53-
val amountSats = arg?.toULongOrNull()
54-
val description = extras?.getString(KEY_DESCRIPTION) ?: "dev-invoice"
55-
return lightningRepo.createInvoice(amountSats, description).fold(
41+
private suspend fun handle(command: DevCommand): DevResult = when (command) {
42+
is DevCommand.CreateInvoice -> lightningRepo.createInvoice(
43+
command.args.amount,
44+
command.args.description,
45+
).fold(
5646
onSuccess = { DevResult.Invoice(it) },
57-
onFailure = { DevResult.Error(it.message ?: "Failed command: 'createInvoice'.") },
47+
onFailure = { DevResult.Error(it.message) },
5848
)
5949
}
6050

@@ -66,25 +56,43 @@ class DevToolsProvider : ContentProvider() {
6656
override fun query(uri: Uri, proj: Array<String>?, sel: String?, args: Array<String>?, sort: String?) = null
6757
}
6858

69-
enum class DevCommand(val method: String) {
70-
CREATE_INVOICE("createInvoice");
59+
private sealed interface DevCommand {
60+
61+
val method: String
62+
63+
data class CreateInvoice(val args: Args) : DevCommand {
64+
companion object {
65+
const val METHOD = "createInvoice"
66+
}
67+
68+
override val method get() = METHOD
69+
70+
@Serializable
71+
data class Args(val amount: ULong? = null, val description: String = "dev-invoice")
72+
}
7173

7274
companion object {
73-
fun from(method: String) = entries.find { it.method == method }
75+
fun parse(method: String, arg: String?): DevCommand? = when (method) {
76+
CreateInvoice.METHOD -> CreateInvoice(arg.deserialize<CreateInvoice.Args>())
77+
else -> null
78+
}
7479
}
7580
}
7681

7782
@Serializable
78-
sealed interface DevResult {
83+
private sealed interface DevResult {
7984
@Serializable
8085
data class Invoice(val bolt11: String) : DevResult
8186

8287
@Serializable
83-
data class Error(val message: String) : DevResult
88+
data class Error(val message: String? = null) : DevResult
8489

8590
fun toBundle() = bundleOf(KEY_RESULT to Json.encodeToString(this))
8691

8792
companion object {
8893
private const val KEY_RESULT = "result"
8994
}
9095
}
96+
97+
private inline fun <reified T> String?.deserialize(): T =
98+
if (isNullOrBlank()) Json.decodeFromString("{}") else Json.decodeFromString(this)

0 commit comments

Comments
 (0)