|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +phoenixd-java is a Java 21 client library for ACINQ's phoenixd REST API. It wraps HTTP endpoints for Lightning Network operations (invoices, payments, address handling) into typed Java requests and responses. |
| 8 | + |
| 9 | +## Maven Commands |
| 10 | + |
| 11 | +### Build & Test |
| 12 | +```bash |
| 13 | +# Clean build with unit tests |
| 14 | +mvn clean install |
| 15 | + |
| 16 | +# Run all tests (unit + integration) |
| 17 | +mvn -q verify |
| 18 | + |
| 19 | +# Build specific module |
| 20 | +mvn clean install -pl phoenixd-rest -am |
| 21 | +``` |
| 22 | + |
| 23 | +### Test Individual Modules |
| 24 | +```bash |
| 25 | +# Test specific module |
| 26 | +mvn test -pl phoenixd-rest |
| 27 | + |
| 28 | +# Run single test class |
| 29 | +mvn test -pl phoenixd-rest -Dtest=ClassName |
| 30 | + |
| 31 | +# Run single test method |
| 32 | +mvn test -pl phoenixd-rest -Dtest=ClassName#methodName |
| 33 | +``` |
| 34 | + |
| 35 | +### Code Coverage |
| 36 | +```bash |
| 37 | +# Generate coverage report (requires mvn verify) |
| 38 | +mvn clean verify |
| 39 | + |
| 40 | +# View aggregated report at: |
| 41 | +# target/site/jacoco-aggregate/index.html |
| 42 | + |
| 43 | +# Coverage threshold: 80% (enforced by jacoco-maven-plugin) |
| 44 | +``` |
| 45 | + |
| 46 | +### Docker Build (Jib) |
| 47 | +```bash |
| 48 | +# Build and publish phoenixd-rest container |
| 49 | +./mvnw deploy -pl phoenixd-rest -am |
| 50 | + |
| 51 | +# Build and publish phoenixd-mock container |
| 52 | +./mvnw deploy -pl phoenixd-mock -am |
| 53 | + |
| 54 | +# Images are pushed to docker.398ja.xyz with version and 'latest' tags |
| 55 | +``` |
| 56 | + |
| 57 | +## Module Architecture |
| 58 | + |
| 59 | +The project is a multi-module Maven build with a layered architecture: |
| 60 | + |
| 61 | +``` |
| 62 | +phoenixd-java (parent) |
| 63 | +├── phoenixd-base # Core abstractions and configuration |
| 64 | +├── phoenixd-model # Request params and response DTOs |
| 65 | +├── phoenixd-rest # HTTP client implementation |
| 66 | +├── phoenixd-mock # Mock server for testing |
| 67 | +└── phoenixd-test # Integration tests |
| 68 | +``` |
| 69 | + |
| 70 | +### Module Dependencies |
| 71 | +- **phoenixd-base**: Foundation layer with `Request`, `Operation`, `Response` interfaces and `Configuration` utility |
| 72 | +- **phoenixd-model**: Depends on phoenixd-base; defines all param/response POJOs (e.g., `CreateInvoiceParam`, `PayInvoiceResponse`) |
| 73 | +- **phoenixd-rest**: Depends on phoenixd-model and phoenixd-base; implements abstract operations (GET, POST, etc.) and concrete request classes |
| 74 | +- **phoenixd-test**: Depends on phoenixd-rest; runs integration tests against a live phoenixd instance |
| 75 | +- **phoenixd-mock**: Standalone mock server; no dependencies on other modules |
| 76 | + |
| 77 | +### Request-Operation Pattern |
| 78 | + |
| 79 | +The library uses a two-layer pattern: |
| 80 | +1. **Request** layer (`AbstractRequest` + concrete implementations in `phoenixd-rest/request/impl/rest/`): |
| 81 | + - Takes a `Param` object and an `Operation` |
| 82 | + - Calls `operation.execute()` and deserializes the response body into a typed response object |
| 83 | + - Example: `CreateBolt11InvoiceRequest`, `PayLightningAddressRequest` |
| 84 | + |
| 85 | +2. **Operation** layer (`AbstractOperation` + HTTP method implementations in `phoenixd-rest/operation/impl/`): |
| 86 | + - Handles HTTP mechanics: building URIs, auth headers (Basic Auth), sending requests via `HttpClient` |
| 87 | + - Replaces path variables (e.g., `{invoice}`) from `Param` fields |
| 88 | + - Returns raw response body as string |
| 89 | + - Example: `GetOperation`, `PostOperation` |
| 90 | + |
| 91 | +### PayRequestFactory |
| 92 | +Located in `phoenixd-rest/request/impl/rest/PayRequestFactory.java`, this factory detects whether a payment string is: |
| 93 | +- A Lightning address (contains `@`) |
| 94 | +- A BOLT11 invoice (matches `^(lnbc|lntb|lnsb|lnbcrt)[0-9]*[a-z0-9]+$` case-insensitive) |
| 95 | + |
| 96 | +Returns the appropriate `BasePayRequest` subclass. |
| 97 | + |
| 98 | +## Configuration |
| 99 | + |
| 100 | +Tests require a running phoenixd instance and the following environment variables: |
| 101 | +```bash |
| 102 | +PHOENIXD_USERNAME=... |
| 103 | +PHOENIXD_PASSWORD=... |
| 104 | +PHOENIXD_BASE_URL=http://localhost:9740 # or your phoenixd URL |
| 105 | +``` |
| 106 | + |
| 107 | +Additional test-specific config lives in `phoenixd-test/src/test/resources/app.properties` (e.g., `test.pay_lnaddress`). |
| 108 | + |
| 109 | +Configuration resolution follows: **ENV > system properties > app.properties**. The `Configuration` class in phoenixd-base handles this. |
| 110 | + |
| 111 | +## Logging |
| 112 | + |
| 113 | +Uses SLF4J with Lombok's `@Slf4j`. phoenixd-rest ships `simplelogger.properties` with: |
| 114 | +- Default log level: INFO |
| 115 | +- `xyz.tcheeric` package: DEBUG |
| 116 | +- Date/time and thread name enabled |
| 117 | + |
| 118 | +Override at runtime: |
| 119 | +```bash |
| 120 | +JAVA_TOOL_OPTIONS="-Dorg.slf4j.simpleLogger.defaultLogLevel=info -Dorg.slf4j.simpleLogger.log.xyz.tcheeric=debug" |
| 121 | +``` |
| 122 | + |
| 123 | +Or for Spring Boot apps, set in `application.properties`: |
| 124 | +``` |
| 125 | +logging.level.xyz.tcheeric=DEBUG |
| 126 | +``` |
| 127 | + |
| 128 | +**Logged events**: |
| 129 | +- HTTP request/response (method, URI, status, timeout) |
| 130 | +- Configuration resolution (where values came from) |
| 131 | +- Payment request detection logic (PayRequestFactory) |
| 132 | +- Sensitive headers (Authorization) are redacted |
| 133 | + |
| 134 | +## Code Style & Conventions |
| 135 | + |
| 136 | +From `.github/copilot-instructions.md`: |
| 137 | +- Commit messages follow `type: description` format (e.g., `fix: handle null node`, `feat: add invoice decoding`) |
| 138 | +- Use present tense verbs for the description |
| 139 | +- Breaking changes must be flagged with **BREAKING** in the PR/commit message |
| 140 | +- All new code should have test coverage |
| 141 | +- Use Lombok annotations (`@Data`, `@Slf4j`, `@NonNull`, `@SneakyThrows`) consistently |
| 142 | + |
| 143 | +## Testing Notes |
| 144 | + |
| 145 | +- Unit tests use JUnit 5 and AssertJ |
| 146 | +- phoenixd-rest uses MockWebServer (OkHttp) for HTTP mocking |
| 147 | +- Integration tests in phoenixd-test require a live phoenixd instance |
| 148 | +- When tests fail, check that env vars are set and phoenixd is reachable |
0 commit comments