Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added
- Add Pubky marketplace test fixture behind the `marketplace` compose profile: Pubky testnet, Paykit Server `722ef268` built from pinned source, and the `pubky-marketplace` driver CLI (`up`, `seed`, `purchase`, `mine`, `verify`, `seller-auth`) for the Bitkit marketplace wallet journey with a headless or Bitkit-approved seller; see `docs/pubky-marketplace.md`
- Add opt-in rc56 Payment Request fixture services for linked-peer and deadline-history wallet journeys
- Homegate Docker Compose service with dedicated PostgreSQL storage, local homeserver admin mock, and README setup flow
- Repo-managed Trezor User Env Docker service and `scripts/trezor-emulator` helper for quickly smoke-testing Bitkit app Trezor PRs
- Support `amount_msat` query param in `/generate/bolt11` endpoint for sub-sat precision invoices
Expand Down
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ A complete Docker-based development environment for Bitcoin and Lightning Networ
- **VSS Server**: Versioned Storage Server for app and ldk-node state backups
- **Homegate**: Pubky Homeserver signup gatekeeper with local admin API mock
- **Pubky marketplace fixture** (opt-in `marketplace` profile): Pubky testnet, Paykit Server and a purchase driver for the marketplace wallet journey
- **Payment Request fixture** (opt-in `payment-requests` profile): rc56 issuer and controlled peer on the marketplace Pubky testnet

## Quick Start

Expand Down Expand Up @@ -210,6 +211,79 @@ docker compose logs -f bitcoind

### Bitkit Testing

#### Payment Requests and rc56 Deadline History

The `payment-requests` profile starts two disposable Paykit rc56 SDK peers on
the marketplace fixture's Pubky testnet. `fixture-issuer` publishes a regtest
Paykit endpoint and sends one-time requests. `rc56-peer` can accept, reject,
cancel and pay requests through the shared regtest Bitcoin node. Plain
`docker compose up -d` does not start either peer. The commands below need
`curl`, `jq` and `python3` on the host.

```bash
./pubky-marketplace up
./pubky-marketplace seed
docker compose --profile marketplace --profile payment-requests build fixture-issuer
docker compose --profile marketplace --profile payment-requests up -d --no-build fixture-issuer rc56-peer
for port in 3012 3013; do
until health=$(curl -fsS "http://127.0.0.1:$port/health"); do sleep 2; done
jq <<<"$health"
done
```

The peers sign up on the testnet and publish their endpoints before they listen,
so `/health` fails for a few seconds after `up`. The loop waits for them, and
`payment-requests/prepare` does the same for up to 150 seconds. A peer retries
its setup for two minutes and then exits; if the loop does not end, stop it and
read `docker compose --profile marketplace --profile payment-requests logs fixture-issuer rc56-peer`.

Each `/health` response gives the identity, receiver path and published
`btc-regtest-p2wpkh` address. Prepare and verify all one-time J1 states plus
an accepted monthly subscription with one paid period and a new monthly
proposal:

```bash
./payment-requests/prepare | jq
```

The command returns every request id and the regtest txids after checking the
peer's SDK states. `/pay` sends a transaction and a txid proof. If proof
delivery fails after the transaction was sent, retry queued delivery with
`POST /sync`; `/proof` accepts an existing wallet txid, address and amount.

To test Bitkit, use a disposable app identity on this local Pubky testnet.
Link it to the issuer's `pubky` and `receiver_path`, then `POST /link` with
`mode: "accept"` on the issuer using the wallet's `peer_pubky` and
`peer_path`. Call `POST /sync` while the app advances its handshake. Send
`POST /request` to the app identity; the default actual-payment deadline is
seven days ahead, or set `deadline_at` to a UTC RFC3339 timestamp. The app
must synchronize the request and verify its own history row. To prepare
rejected or canceled records, issue another request and call `/reject` or
`/cancel` with its id from the payer side. For monthly requests,
`POST /request` accepts `monthly_starts_at` (UTC RFC3339) and
`period_start_deadline_seconds`; `/pay` then needs
`billing_period_start` and `billing_period_end`.

Example one-time issuance to a linked app after both sides report `Linked`:

```bash
APP_PUBKY=pubky... # replace with the disposable app identity
curl -fsS -X POST http://127.0.0.1:3012/request -H 'content-type: application/json' \
-d "$(jq -nc --arg pubky "$APP_PUBKY" '{peer_pubky:$pubky,peer_path:"bitkit/wallet",amount_sats:15000,reference:"rc56-app-history"}')" | jq
```

These peers keep their identities and SDK records in memory and live in the
Pubky testnet's network namespace, so `./pubky-marketplace down` and `reset`
remove them together with the testnet. After `reset`, start them again with the
`up -d --no-build fixture-issuer rc56-peer` command above, wait for `/health`,
rerun `payment-requests/prepare` and relink the app. `./pubky-marketplace seed`
needs outbound internet for Paykit Server setup; the rc56 peer calls use the
local testnet. The lane still needs a Bitkit build pointed at the local Pubky
testnet and to verify the requested rows on device. The headless preparation
command does not populate a separate Bitkit identity's history; accepted and
paid app rows require the lane's controlled client to prepare those records
with the app's identity or an app build that supports importing fixture state.

#### Trezor Hardware PRs

Use this section as the entry point when checking Bitkit app PRs or merged features that need the official Trezor emulator. Start by preparing the deterministic Trezor User Env:
Expand Down
31 changes: 31 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ services:
- "127.0.0.1:6287:6287" # homeserver Pubky TLS
- "127.0.0.1:${MARKETPLACE_HOMESERVER_ADMIN_PORT:-16288}:6288" # homeserver admin (6288 is homegate's)
- "127.0.0.1:${MARKETPLACE_PAYKIT_PORT:-3001}:3001" # paykit-server, shares this namespace
- "127.0.0.1:3012:3012" # opt-in fixture-issuer, shares this namespace
- "127.0.0.1:3013:3013" # opt-in rc56-peer, shares this namespace

# Paykit Server 722ef268 (v0.1.0-rc4), built from source with the upstream
# Dockerfile.local. Its setup flow emits the Pubky grant auth URL (cid and cpk)
Expand Down Expand Up @@ -451,6 +453,35 @@ services:
- ./.marketplace/evidence:/evidence
entrypoint: ["node", "/app/driver.mjs"]

# The rc56 SDK peers share the marketplace testnet namespace and regtest chain.
fixture-issuer:
profiles: [payment-requests]
image: bitkit-docker/payment-request-fixture:rc56-24162ebb
build: ./payment-requests
restart: "no"
network_mode: service:pubky-testnet
Comment thread
ovitrif marked this conversation as resolved.
depends_on:
Comment thread
ovitrif marked this conversation as resolved.
- pubky-testnet
- bitcoind
environment:
FIXTURE_ROLE: fixture-issuer
FIXTURE_PORT: 3012
BITCOIN_RPC_URL: http://bitcoind:43782

rc56-peer:
profiles: [payment-requests]
image: bitkit-docker/payment-request-fixture:rc56-24162ebb
build: ./payment-requests
restart: "no"
network_mode: service:pubky-testnet
depends_on:
- pubky-testnet
- bitcoind
environment:
FIXTURE_ROLE: rc56-peer
FIXTURE_PORT: 3013
BITCOIN_RPC_URL: http://bitcoind:43782

volumes:
bitcoin_home:
postgres_data:
Expand Down
5 changes: 4 additions & 1 deletion docs/pubky-marketplace.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ these fixed ports:
| 15411, 15412 | PKARR relay, HTTP relay |
| 6881 (tcp and udp) | DHT bootstrap |
| 3001 | Paykit Server (`MARKETPLACE_PAYKIT_PORT`) |
| 3012, 3013 | `fixture-issuer` and `rc56-peer` of the opt-in `payment-requests` profile (see the README); nothing listens until they run |
| 16288 | homeserver admin (`MARKETPLACE_HOMESERVER_ADMIN_PORT`; the in-container 6288 is Homegate's host port) |
| 60001 | Electrum, from the base stack |

`paykit-server` and `marketplace-driver` share the `pubky-testnet` network namespace, as the upstream
Locks compose does, so their Pubky clients reach the testnet on localhost.
Locks compose does, so their Pubky clients reach the testnet on localhost. The `payment-requests` profile's `fixture-issuer`
and `rc56-peer` join it too. They sign up on the testnet homeserver and use its HTTP relay, and do not talk
to Paykit Server, so its pin does not affect them.

## Roles

Expand Down
1 change: 1 addition & 0 deletions payment-requests/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target
Loading