From e915e9efdbc3cae9fa7ffc17eda2f069aabf7e06 Mon Sep 17 00:00:00 2001 From: automation Date: Sun, 2 Nov 2025 14:13:45 +0000 Subject: [PATCH 01/10] feat(mock): implement valid BOLT11 invoice generation for testing - Added a method to generate a minimally valid BOLT11 invoice with proper Bech32 encoding for mock purposes. - This includes a checksum calculation and random data generation to simulate real invoice behavior. --- .../tcheeric/phoenixd/mock/MockLnServer.java | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java index 9c0b2da..885933f 100644 --- a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java +++ b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java @@ -8,6 +8,7 @@ import java.io.OutputStream; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; @RequiredArgsConstructor public class MockLnServer { @@ -44,12 +45,94 @@ private void handlePayLightningAddress(HttpExchange exchange) throws IOException } private void handleCreateInvoice(HttpExchange exchange) throws IOException { - // Generate a unique mock bolt11 invoice + // Generate a unique mock bolt11 invoice with valid Bech32 encoding String invoiceId = Long.toHexString(System.nanoTime()); - String bolt11 = "lnbc1mock" + invoiceId; + String bolt11 = generateValidBolt11Invoice(); writeJson(exchange, "{\"amountSat\":10,\"paymentHash\":\"hash" + invoiceId + "\",\"serialized\":\"" + bolt11 + "\"}"); } + /** + * Generates a minimally valid BOLT11 invoice for testing purposes. + * Format: ln + currency + amount + separator + data + checksum + * + * This generates a mock invoice that passes basic Bech32 validation but is not + * cryptographically valid for actual Lightning Network payments. + */ + private String generateValidBolt11Invoice() { + // Human-readable part: ln + bc (bitcoin mainnet) + 10n (10 nanosats = ~0 sats for testing) + String hrp = "lnbc10n"; + + // Generate random payment hash (32 bytes = 52 chars in bech32, roughly) + // For a minimal valid invoice, we need at least timestamp + payment hash + // Bech32 charset: qpzry9x8gf2tvdw0s3jn54khce6mua7l + SecureRandom random = new SecureRandom(); + StringBuilder data = new StringBuilder(); + String charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; + + // Generate 52 random bech32 characters (represents ~32 bytes of data) + for (int i = 0; i < 52; i++) { + data.append(charset.charAt(random.nextInt(charset.length()))); + } + + // Calculate and append Bech32 checksum (6 characters) + String checksum = calculateBech32Checksum(hrp, data.toString()); + + return hrp + "1" + data.toString() + checksum; + } + + /** + * Calculates Bech32 checksum for the given HRP and data. + * Simplified implementation for mock purposes. + */ + private String calculateBech32Checksum(String hrp, String data) { + String charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; + + // Expand HRP + int[] values = new int[hrp.length() * 2 + 1 + data.length() + 6]; + int idx = 0; + for (int i = 0; i < hrp.length(); i++) { + values[idx++] = hrp.charAt(i) >> 5; + } + values[idx++] = 0; + for (int i = 0; i < hrp.length(); i++) { + values[idx++] = hrp.charAt(i) & 31; + } + for (int i = 0; i < data.length(); i++) { + values[idx++] = charset.indexOf(data.charAt(i)); + } + for (int i = 0; i < 6; i++) { + values[idx++] = 0; + } + + // Calculate checksum using Bech32 polymod + int polymod = polymod(values) ^ 1; + + StringBuilder checksum = new StringBuilder(); + for (int i = 0; i < 6; i++) { + checksum.append(charset.charAt((polymod >> (5 * (5 - i))) & 31)); + } + + return checksum.toString(); + } + + /** + * Bech32 polymod function for checksum calculation. + */ + private int polymod(int[] values) { + int[] gen = {0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}; + int chk = 1; + for (int value : values) { + int top = chk >> 25; + chk = (chk & 0x1ffffff) << 5 ^ value; + for (int i = 0; i < 5; i++) { + if (((top >> i) & 1) != 0) { + chk ^= gen[i]; + } + } + } + return chk; + } + private void handleDecodeInvoice(HttpExchange exchange) throws IOException { writeJson(exchange, "{\"amount\":1000,\"description\":\"1 Blockaccino\"}"); } From 905a6c54130b2c07740a548bb2f2410d05f6bf3d Mon Sep 17 00:00:00 2001 From: automation Date: Sun, 2 Nov 2025 14:13:59 +0000 Subject: [PATCH 02/10] docs: add CLAUDE.md for project guidance and configuration details - Introduce CLAUDE.md to provide comprehensive guidance for the phoenixd-java project, including build commands, module architecture, logging configuration, and testing notes. --- CLAUDE.md | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9025d64 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,148 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +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. + +## Maven Commands + +### Build & Test +```bash +# Clean build with unit tests +mvn clean install + +# Run all tests (unit + integration) +mvn -q verify + +# Build specific module +mvn clean install -pl phoenixd-rest -am +``` + +### Test Individual Modules +```bash +# Test specific module +mvn test -pl phoenixd-rest + +# Run single test class +mvn test -pl phoenixd-rest -Dtest=ClassName + +# Run single test method +mvn test -pl phoenixd-rest -Dtest=ClassName#methodName +``` + +### Code Coverage +```bash +# Generate coverage report (requires mvn verify) +mvn clean verify + +# View aggregated report at: +# target/site/jacoco-aggregate/index.html + +# Coverage threshold: 80% (enforced by jacoco-maven-plugin) +``` + +### Docker Build (Jib) +```bash +# Build and publish phoenixd-rest container +./mvnw deploy -pl phoenixd-rest -am + +# Build and publish phoenixd-mock container +./mvnw deploy -pl phoenixd-mock -am + +# Images are pushed to docker.398ja.xyz with version and 'latest' tags +``` + +## Module Architecture + +The project is a multi-module Maven build with a layered architecture: + +``` +phoenixd-java (parent) +├── phoenixd-base # Core abstractions and configuration +├── phoenixd-model # Request params and response DTOs +├── phoenixd-rest # HTTP client implementation +├── phoenixd-mock # Mock server for testing +└── phoenixd-test # Integration tests +``` + +### Module Dependencies +- **phoenixd-base**: Foundation layer with `Request`, `Operation`, `Response` interfaces and `Configuration` utility +- **phoenixd-model**: Depends on phoenixd-base; defines all param/response POJOs (e.g., `CreateInvoiceParam`, `PayInvoiceResponse`) +- **phoenixd-rest**: Depends on phoenixd-model and phoenixd-base; implements abstract operations (GET, POST, etc.) and concrete request classes +- **phoenixd-test**: Depends on phoenixd-rest; runs integration tests against a live phoenixd instance +- **phoenixd-mock**: Standalone mock server; no dependencies on other modules + +### Request-Operation Pattern + +The library uses a two-layer pattern: +1. **Request** layer (`AbstractRequest` + concrete implementations in `phoenixd-rest/request/impl/rest/`): + - Takes a `Param` object and an `Operation` + - Calls `operation.execute()` and deserializes the response body into a typed response object + - Example: `CreateBolt11InvoiceRequest`, `PayLightningAddressRequest` + +2. **Operation** layer (`AbstractOperation` + HTTP method implementations in `phoenixd-rest/operation/impl/`): + - Handles HTTP mechanics: building URIs, auth headers (Basic Auth), sending requests via `HttpClient` + - Replaces path variables (e.g., `{invoice}`) from `Param` fields + - Returns raw response body as string + - Example: `GetOperation`, `PostOperation` + +### PayRequestFactory +Located in `phoenixd-rest/request/impl/rest/PayRequestFactory.java`, this factory detects whether a payment string is: +- A Lightning address (contains `@`) +- A BOLT11 invoice (matches `^(lnbc|lntb|lnsb|lnbcrt)[0-9]*[a-z0-9]+$` case-insensitive) + +Returns the appropriate `BasePayRequest` subclass. + +## Configuration + +Tests require a running phoenixd instance and the following environment variables: +```bash +PHOENIXD_USERNAME=... +PHOENIXD_PASSWORD=... +PHOENIXD_BASE_URL=http://localhost:9740 # or your phoenixd URL +``` + +Additional test-specific config lives in `phoenixd-test/src/test/resources/app.properties` (e.g., `test.pay_lnaddress`). + +Configuration resolution follows: **ENV > system properties > app.properties**. The `Configuration` class in phoenixd-base handles this. + +## Logging + +Uses SLF4J with Lombok's `@Slf4j`. phoenixd-rest ships `simplelogger.properties` with: +- Default log level: INFO +- `xyz.tcheeric` package: DEBUG +- Date/time and thread name enabled + +Override at runtime: +```bash +JAVA_TOOL_OPTIONS="-Dorg.slf4j.simpleLogger.defaultLogLevel=info -Dorg.slf4j.simpleLogger.log.xyz.tcheeric=debug" +``` + +Or for Spring Boot apps, set in `application.properties`: +``` +logging.level.xyz.tcheeric=DEBUG +``` + +**Logged events**: +- HTTP request/response (method, URI, status, timeout) +- Configuration resolution (where values came from) +- Payment request detection logic (PayRequestFactory) +- Sensitive headers (Authorization) are redacted + +## Code Style & Conventions + +From `.github/copilot-instructions.md`: +- Commit messages follow `type: description` format (e.g., `fix: handle null node`, `feat: add invoice decoding`) +- Use present tense verbs for the description +- Breaking changes must be flagged with **BREAKING** in the PR/commit message +- All new code should have test coverage +- Use Lombok annotations (`@Data`, `@Slf4j`, `@NonNull`, `@SneakyThrows`) consistently + +## Testing Notes + +- Unit tests use JUnit 5 and AssertJ +- phoenixd-rest uses MockWebServer (OkHttp) for HTTP mocking +- Integration tests in phoenixd-test require a live phoenixd instance +- When tests fail, check that env vars are set and phoenixd is reachable From a87c076bf05d02defe5108c206a643de453a37c9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:31:54 +0000 Subject: [PATCH 03/10] Initial plan From 19b4b6b9d7b687f893b69f70fe839f6340c867fb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:32:03 +0000 Subject: [PATCH 04/10] Initial plan From 9bd948280355c99b98fcc9695b962566c4cd044c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:32:26 +0000 Subject: [PATCH 05/10] Initial plan From bf18f851fced5528c8fecc2013b4d6e95c08e6b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:34:46 +0000 Subject: [PATCH 06/10] refactor: make SecureRandom a static final field in MockLnServer Co-authored-by: tcheeric <6341500+tcheeric@users.noreply.github.com> --- .../main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java | 5 +++-- .../compile/default-compile/inputFiles.lst | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java index 885933f..211a5af 100644 --- a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java +++ b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java @@ -12,6 +12,8 @@ @RequiredArgsConstructor public class MockLnServer { + private static final SecureRandom SECURE_RANDOM = new SecureRandom(); + private HttpServer server; private final int port; @@ -65,13 +67,12 @@ private String generateValidBolt11Invoice() { // Generate random payment hash (32 bytes = 52 chars in bech32, roughly) // For a minimal valid invoice, we need at least timestamp + payment hash // Bech32 charset: qpzry9x8gf2tvdw0s3jn54khce6mua7l - SecureRandom random = new SecureRandom(); StringBuilder data = new StringBuilder(); String charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; // Generate 52 random bech32 characters (represents ~32 bytes of data) for (int i = 0; i < 52; i++) { - data.append(charset.charAt(random.nextInt(charset.length()))); + data.append(charset.charAt(SECURE_RANDOM.nextInt(charset.length()))); } // Calculate and append Bech32 checksum (6 characters) diff --git a/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..1616b0c --- /dev/null +++ b/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/Main.java From 393ca195b67ff715368e8d02731591a6e761b782 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:35:15 +0000 Subject: [PATCH 07/10] chore: fix .gitignore to exclude all target directories Co-authored-by: tcheeric <6341500+tcheeric@users.noreply.github.com> --- .gitignore | 2 +- .../compile/default-compile/inputFiles.lst | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/.gitignore b/.gitignore index b83d222..2f7896d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/target/ +target/ diff --git a/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index 1616b0c..0000000 --- a/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,2 +0,0 @@ -/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java -/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/Main.java From 316c3f2c5a2dd1a3e4b7e0c3ef6039aab5310cab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:35:35 +0000 Subject: [PATCH 08/10] refactor: extract Bech32 charset to class constant Co-authored-by: tcheeric <6341500+tcheeric@users.noreply.github.com> --- .../compile/default-compile/inputFiles.lst | 7 +++++++ .../xyz/tcheeric/phoenixd/mock/MockLnServer.java | 12 +++++------- .../xyz/tcheeric/phoenixd/mock/Main.class | Bin 0 -> 2963 bytes .../tcheeric/phoenixd/mock/MockLnServer.class | Bin 0 -> 6572 bytes .../compile/default-compile/createdFiles.lst | 2 ++ .../compile/default-compile/inputFiles.lst | 2 ++ 6 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 phoenixd-base/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 phoenixd-mock/target/classes/xyz/tcheeric/phoenixd/mock/Main.class create mode 100644 phoenixd-mock/target/classes/xyz/tcheeric/phoenixd/mock/MockLnServer.class create mode 100644 phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/phoenixd-base/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/phoenixd-base/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..a88bf28 --- /dev/null +++ b/phoenixd-base/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,7 @@ +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/Operation.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/VoidRequestParam.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/Request.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/Response.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/VoidResponse.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/util/Configuration.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-base/src/main/java/xyz/tcheeric/phoenixd/common/rest/util/Constants.java diff --git a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java index 885933f..aa0ce21 100644 --- a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java +++ b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java @@ -12,6 +12,8 @@ @RequiredArgsConstructor public class MockLnServer { + private static final String BECH32_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; + private HttpServer server; private final int port; @@ -64,14 +66,12 @@ private String generateValidBolt11Invoice() { // Generate random payment hash (32 bytes = 52 chars in bech32, roughly) // For a minimal valid invoice, we need at least timestamp + payment hash - // Bech32 charset: qpzry9x8gf2tvdw0s3jn54khce6mua7l SecureRandom random = new SecureRandom(); StringBuilder data = new StringBuilder(); - String charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; // Generate 52 random bech32 characters (represents ~32 bytes of data) for (int i = 0; i < 52; i++) { - data.append(charset.charAt(random.nextInt(charset.length()))); + data.append(BECH32_CHARSET.charAt(random.nextInt(BECH32_CHARSET.length()))); } // Calculate and append Bech32 checksum (6 characters) @@ -85,8 +85,6 @@ private String generateValidBolt11Invoice() { * Simplified implementation for mock purposes. */ private String calculateBech32Checksum(String hrp, String data) { - String charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; - // Expand HRP int[] values = new int[hrp.length() * 2 + 1 + data.length() + 6]; int idx = 0; @@ -98,7 +96,7 @@ private String calculateBech32Checksum(String hrp, String data) { values[idx++] = hrp.charAt(i) & 31; } for (int i = 0; i < data.length(); i++) { - values[idx++] = charset.indexOf(data.charAt(i)); + values[idx++] = BECH32_CHARSET.indexOf(data.charAt(i)); } for (int i = 0; i < 6; i++) { values[idx++] = 0; @@ -109,7 +107,7 @@ private String calculateBech32Checksum(String hrp, String data) { StringBuilder checksum = new StringBuilder(); for (int i = 0; i < 6; i++) { - checksum.append(charset.charAt((polymod >> (5 * (5 - i))) & 31)); + checksum.append(BECH32_CHARSET.charAt((polymod >> (5 * (5 - i))) & 31)); } return checksum.toString(); diff --git a/phoenixd-mock/target/classes/xyz/tcheeric/phoenixd/mock/Main.class b/phoenixd-mock/target/classes/xyz/tcheeric/phoenixd/mock/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..4ecc7042b20f7d9ddd02098b9edc53e9bfa1eb12 GIT binary patch literal 2963 zcmb7GYjYD-7=BKZcGGmBG*FNhXt@K^ z_dDX{gEP+fg>eR*fdVsr^n>G1a>VCs(so<0gCDY+b9vwQd7t-r&z?X3x&1qUNAW`x zbqHw)>!?SAz>@RExRERwRv~$O_`J+{0uB32%k&--2z6~9iXwtW4N)CU&;>dsCNCzv zTv1BL%q1&DTUzEsK3TSNqsc+Tv;?$*^iJ3g{m?ue0`A^zq>pADOVGl}l3fspWo)OA zbW0<<&L=Z=p&*@91WN_Brmb z@6O&RTCrTi3LOt&r9jJUDrw7;bV@XIHztpd2rTbPZ_eDaBh`dZRk@bhW7~V4n3H(<-C_GgbCdim|m=r(wO04cIt`;OwO9$+AFLPMG8;OhiK(HqrG$ ztdiP{m6gu8bfW0QW>vV2QEWj%!&V(VNX|+9_RWg<&3eW`@7Pa2ZWfK7soP&OOnOiBe2LVj(K_eg0;11+oMrz!y_t} zy#kwq)Dm3PC_rwFZbj}E?9-`Z%Cp(X=d(4JN9a+YHRz|Bj9-vW?ALKX$-Un749AP0 zj~bj-?>VL3b4qclbp1L8aF|^{`lK~3&>3_(4dh;IQKa#NhNC(%7@Wgu)rML$-TrdL zoAf*5j1up09VhUlK%`NPOS@BHUir^`M zJ=2WDU9(^rrMM$=(j1rho_N-?D;26X?)qYi+m_#Es>^zMR3AL8;~CWiVbdD1mDbMa zIICC-yEKj9IdWbVVq8sB=v0}VQ)Vyx2XqR2SYYWabe6@wphOWtUZA~SHCOyX(JaZT z(^-JZ_lW9C9vI#CDMFwIGfw?-n>epwR7VMHwiWX`dceqew!V#s-!4hHd;<{GU^ad2VA zp!8}+)c{8fD_@fCh71q4u}bh`Q{yC%%pAj0lNA}<{@{z%kPF)ePxzYWKBH91nx0H8 zK?7O&O5Ga1*6}9Z6428Yo5AlXNo`zZv)x0|{qoiDoxqxfw^F=Sa(Hk@c(DNl+SEmZ zZ;PV_zHPqi`Q~+p&k9FLzJ;3Yz6o)if9miepK2L&lb zcHhLqH;_u)z~d@>$Pd4cp}|{L7>kL&86C`HJ(eMX6*$QJ2C&YD7O#fK1x#>%7=4(; zMZ!(+xV(gy2=g-MHPrph`&J8H_BRQtraWD>B$<(Hqr!az$y}D)WEG_+F;1VgcKu;Rq9g5XB?{uv15k5IGK1G@AwQPeEMj{1QdN@n!a-y zj3(CP-5K4i^#f84vB(sPzhSW|o(O11BaZhtSBLlU0pE)44>|V*zU1!;XQG_>2H)a) Gto#=M*7_^} literal 0 HcmV?d00001 diff --git a/phoenixd-mock/target/classes/xyz/tcheeric/phoenixd/mock/MockLnServer.class b/phoenixd-mock/target/classes/xyz/tcheeric/phoenixd/mock/MockLnServer.class new file mode 100644 index 0000000000000000000000000000000000000000..c8436de643c51b1a3b7c26602538211223753cab GIT binary patch literal 6572 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 Date: Sun, 2 Nov 2025 21:35:46 +0000 Subject: [PATCH 09/10] refactor: extract Bech32 generator values as class constant Co-authored-by: tcheeric <6341500+tcheeric@users.noreply.github.com> --- .../java/xyz/tcheeric/phoenixd/mock/MockLnServer.java | 9 +++++++-- .../compile/default-compile/inputFiles.lst | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java index 885933f..0bde2c1 100644 --- a/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java +++ b/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java @@ -12,6 +12,12 @@ @RequiredArgsConstructor public class MockLnServer { + /** + * Bech32 generator values used in checksum calculation. + * These are fixed values defined by the Bech32 specification. + */ + private static final int[] BECH32_GENERATOR = {0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}; + private HttpServer server; private final int port; @@ -119,14 +125,13 @@ private String calculateBech32Checksum(String hrp, String data) { * Bech32 polymod function for checksum calculation. */ private int polymod(int[] values) { - int[] gen = {0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}; int chk = 1; for (int value : values) { int top = chk >> 25; chk = (chk & 0x1ffffff) << 5 ^ value; for (int i = 0; i < 5; i++) { if (((top >> i) & 1) != 0) { - chk ^= gen[i]; + chk ^= BECH32_GENERATOR[i]; } } } diff --git a/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..1616b0c --- /dev/null +++ b/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java +/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/Main.java From ee58de807719310b6059e1c444c58e878a16801f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 21:36:12 +0000 Subject: [PATCH 10/10] chore: remove build artifacts from repository Co-authored-by: tcheeric <6341500+tcheeric@users.noreply.github.com> --- .../compile/default-compile/inputFiles.lst | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index 1616b0c..0000000 --- a/phoenixd-mock/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,2 +0,0 @@ -/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/MockLnServer.java -/home/runner/work/phoenixd-java/phoenixd-java/phoenixd-mock/src/main/java/xyz/tcheeric/phoenixd/mock/Main.java