Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions apps/lcp-quickstart/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.PHONY: test lint fmt

test:
go test ./...

lint:
golangci-lint run $(shell go list -f '{{.Dir}}' ./...)

fmt:
golangci-lint fmt $(shell go list -f '{{.Dir}}' ./...)

118 changes: 118 additions & 0 deletions apps/lcp-quickstart/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# lcp-quickstart

`lcp-quickstart` is a small CLI that bootstraps a local “Requester” stack:

- your local `lnd` (managed by you; optionally started by the tool)
- `lcpd-grpcd` (Requester) from `go-lcpd/`
- `openai-serve` (OpenAI-compatible HTTP) from `apps/openai-serve/`

It targets only `testnet` and `mainnet`.

## Build / Install

```sh
cd apps/lcp-quickstart
go install ./cmd/lcp-quickstart
```

## Prerequisites

- `lcp-quickstart` will auto-install `lnd` + `lncli` (downloaded into `~/.lcp-quickstart/bin/`) if they are missing.
- If you prefer a system-installed `lncli`, pass `--lncli <path>`.
- Wallet creation/unlock is **not** automated (seed safety). The tool will tell you when to run:
- `lcp-quickstart <testnet|mainnet> lncli create`
- `lcp-quickstart <testnet|mainnet> lncli unlock`

## Run (testnet)

`testnet` requires an explicit Provider:

```sh
lcp-quickstart testnet up --provider "<pubkey>@<host:port>"
```

If you need to open a channel (you see a “channel/route required” error):

```sh
lcp-quickstart testnet up \
--provider "<pubkey>@<host:port>" \
--open-channel --channel-sats <sats>
```

## Run (mainnet)

Mainnet is dangerous by default; you must explicitly opt in:

```sh
lcp-quickstart mainnet up --i-understand-mainnet
```

By default, mainnet uses this Provider node (override with `--provider`):

```text
03737b4a2e44b45f786a18e43c3cf462ab97891e9f8992a0d493394691ac0db983@54.214.32.132:20309
```

## Status / Logs / Down / Reset

```sh
lcp-quickstart <testnet|mainnet> status
lcp-quickstart <testnet|mainnet> lncli <args...>
lcp-quickstart <testnet|mainnet> logs <lnd|lcpd-grpcd|openai-serve>
lcp-quickstart <testnet|mainnet> down
lcp-quickstart <testnet|mainnet> reset --force
```

`status` prints “next steps” guidance (unlock wallet, connect Provider, open a channel, etc).

## Verify (HTTP)

Health check:

```sh
curl -sS http://127.0.0.1:8080/healthz
```

Expected output:

```text
ok
```

Chat completions:

```sh
curl -sS http://127.0.0.1:8080/v1/chat/completions \
-H 'content-type: application/json' \
-H 'authorization: Bearer lcp-dev' \
-d '{"model":"gpt-5.2","messages":[{"role":"user","content":"Say hello."}]}'
```

## Workspace layout

By default the app writes to `~/.lcp-quickstart/`:

- `state.json`: machine-readable state snapshot
- `logs/<component>.log`: logs (components: `lnd`, `lcpd-grpcd`, `openai-serve`)
- `pids/<component>.pid`: PID tracking (for managed processes)
- `bin/`: managed binaries (`lnd`, `lncli`, `lcpd-grpcd`, `openai-serve`)

Override the workspace location with `--home <dir>`.

## Safety notes

- `lcpd-grpcd` is always required to bind to loopback (`127.0.0.1` / `localhost`).
- `openai-serve` binds to `127.0.0.1:8080` by default.
- If you bind it to a non-loopback address, you must pass `--i-understand-exposing-openai` **and** set `--openai-api-keys` non-empty.
- Mainnet defaults `OPENAI_SERVE_MAX_PRICE_MSAT` to a conservative cap; override with `--openai-max-price-msat`.

## Development

```sh
cd apps/lcp-quickstart
make test
make lint
make fmt
```

This repo expects `golangci-lint v2` installed locally.
12 changes: 12 additions & 0 deletions apps/lcp-quickstart/cmd/lcp-quickstart/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import (
"os"

"github.com/bruwbird/lcp/apps/lcp-quickstart/internal/cli"
)

func main() {
os.Exit(cli.Main(os.Args[1:]))
}

4 changes: 4 additions & 0 deletions apps/lcp-quickstart/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module github.com/bruwbird/lcp/apps/lcp-quickstart

go 1.24.4

28 changes: 28 additions & 0 deletions apps/lcp-quickstart/internal/build/go_build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package build

import (
"bytes"
"context"
"fmt"
"os/exec"
"strings"
)

func GoBinary(ctx context.Context, moduleDir, pkg, outPath string) error {
cmd := exec.CommandContext(ctx, "go", "build", "-o", outPath, pkg)
cmd.Dir = moduleDir

var combined bytes.Buffer
cmd.Stdout = &combined
cmd.Stderr = &combined

if err := cmd.Run(); err != nil {
out := strings.TrimSpace(combined.String())
if out != "" {
return fmt.Errorf("go build failed: %w\n%s", err, out)
}
return fmt.Errorf("go build failed: %w", err)
}
return nil
}

Loading