From a129cb4a238e5eaf72c3cffe7f380719e3d7ae88 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 07:50:41 -0300 Subject: [PATCH 01/32] fix: add react context getter to LdkEventEmitter --- lib/android/src/main/java/com/reactnativeldk/LdkModule.kt | 4 ++++ .../src/main/java/com/reactnativeldk/classes/LdkPersister.kt | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/android/src/main/java/com/reactnativeldk/LdkModule.kt b/lib/android/src/main/java/com/reactnativeldk/LdkModule.kt index e16d74de..8b48b850 100644 --- a/lib/android/src/main/java/com/reactnativeldk/LdkModule.kt +++ b/lib/android/src/main/java/com/reactnativeldk/LdkModule.kt @@ -1730,6 +1730,10 @@ object LdkEventEmitter { this.reactContext = reactContext } + fun getReactContext(): ReactContext? { + return this.reactContext + } + fun send(eventType: EventTypes, body: Any) { if (this.reactContext === null) { return diff --git a/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt b/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt index 713190c3..36c02c6e 100644 --- a/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt +++ b/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt @@ -39,7 +39,7 @@ class LdkPersister { file.writeBytes(serialized) // Update chain monitor on main thread - LdkModule.reactContext?.runOnUiThread { + LdkModule.getReactContext()?.runOnUiThread { val res = LdkModule.chainMonitor?.channel_monitor_updated(channelFundingOutpoint, data._latest_update_id) if (res == null || !res.is_ok) { LdkEventEmitter.send(EventTypes.native_log, "Failed to update chain monitor with persisted channel (${channelId})") @@ -75,7 +75,7 @@ class LdkPersister { } //Update chain monitor with successful persist on main thread - LdkModule.reactContext?.runOnUiThread { + LdkModule.getReactContext()?.runOnUiThread { val res = LdkModule.chainMonitor?.channel_monitor_updated(channelFundingOutpoint, data._latest_update_id) if (res == null || !res.is_ok) { LdkEventEmitter.send(EventTypes.native_log, "Failed to update chain monitor with persisted channel (${channelId})") From 43e58e2dec73f61f91c7add96c3b99944d1f07a7 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 07:55:35 -0300 Subject: [PATCH 02/32] fix: ReactContext doesn't have a runOnUiThread() method in React Native 0.78. The correct method is runOnUiQueueThread() --- .../src/main/java/com/reactnativeldk/classes/LdkPersister.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt b/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt index 36c02c6e..61914c69 100644 --- a/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt +++ b/lib/android/src/main/java/com/reactnativeldk/classes/LdkPersister.kt @@ -39,7 +39,7 @@ class LdkPersister { file.writeBytes(serialized) // Update chain monitor on main thread - LdkModule.getReactContext()?.runOnUiThread { + LdkEventEmitter.getReactContext()?.runOnUiQueueThread { val res = LdkModule.chainMonitor?.channel_monitor_updated(channelFundingOutpoint, data._latest_update_id) if (res == null || !res.is_ok) { LdkEventEmitter.send(EventTypes.native_log, "Failed to update chain monitor with persisted channel (${channelId})") @@ -75,7 +75,7 @@ class LdkPersister { } //Update chain monitor with successful persist on main thread - LdkModule.getReactContext()?.runOnUiThread { + LdkEventEmitter.getReactContext()?.runOnUiQueueThread { val res = LdkModule.chainMonitor?.channel_monitor_updated(channelFundingOutpoint, data._latest_update_id) if (res == null || !res.is_ok) { LdkEventEmitter.send(EventTypes.native_log, "Failed to update chain monitor with persisted channel (${channelId})") From b6dc606efe347db7fbc9f76f186556b0e7b68b8c Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 08:42:20 -0300 Subject: [PATCH 03/32] chore: version number --- .gitignore | 3 +++ lib/package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4b9f3d03..bf70bcda 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ example/.watchman* # docker example/docker/lnd/ example/docker/clightning/ + +#AI +CLAUDE.md \ No newline at end of file diff --git a/lib/package.json b/lib/package.json index 8bf4b949..75c6e003 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,7 +1,7 @@ { "name": "@synonymdev/react-native-ldk", "title": "React Native LDK", - "version": "0.0.161", + "version": "0.0.162", "description": "React Native wrapper for LDK", "main": "./dist/index.js", "types": "./dist/index.d.ts", From 27ae87e610889c2d4fc50eb53f93072bd5f2aad2 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 08:59:05 -0300 Subject: [PATCH 04/32] fix: lint missing comma --- example/tests/eclair.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/tests/eclair.ts b/example/tests/eclair.ts index 4da4f0a8..1ecdafef 100644 --- a/example/tests/eclair.ts +++ b/example/tests/eclair.ts @@ -113,7 +113,7 @@ describe('Eclair', function () { channelCloseMinimum: 5, outputSpendingFee: 10, urgentOnChainSweep: 30, - maximumFeeEstimate: 30 + maximumFeeEstimate: 30, }); }, }); From 9d515df473374ad9654f805141921b01d1a7f384 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 09:24:23 -0300 Subject: [PATCH 05/32] fix: implement docker compose cli, use direct homebrew instalation instead of broken third-paty, add retry logic --- .github/workflows/e2e-android.yml | 36 +++++++++++++++++++++++++++-- .github/workflows/e2e-ios.yml | 2 +- .github/workflows/mocha-android.yml | 2 +- .github/workflows/mocha-ios.yml | 27 +++++++--------------- 4 files changed, 44 insertions(+), 23 deletions(-) diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml index 5f18c990..96e962d3 100644 --- a/.github/workflows/e2e-android.yml +++ b/.github/workflows/e2e-android.yml @@ -111,7 +111,9 @@ jobs: - name: Kill java processes run: pkill -9 -f java || true - - name: run tests + - name: Run tests attempt 1 + id: attempt1 + continue-on-error: true uses: reactivecircus/android-emulator-runner@v2 with: avd-name: Pixel_API_31_AOSP @@ -122,7 +124,37 @@ jobs: arch: x86_64 disable-animations: true working-directory: example - script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts || yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifactsyarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts || yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts + script: yarn e2e:test:android-release --timeout 200000 --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts + + - name: Run tests attempt 2 + if: steps.attempt1.outcome != 'success' + id: attempt2 + continue-on-error: true + uses: reactivecircus/android-emulator-runner@v2 + with: + avd-name: Pixel_API_31_AOSP + profile: 5.4in FWVGA + api-level: 31 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047 + arch: x86_64 + disable-animations: true + working-directory: example + script: yarn e2e:test:android-release --timeout 200000 --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts + + - name: Run tests attempt 3 (final) + if: steps.attempt2.outcome != 'success' + uses: reactivecircus/android-emulator-runner@v2 + with: + avd-name: Pixel_API_31_AOSP + profile: 5.4in FWVGA + api-level: 31 + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047 + arch: x86_64 + disable-animations: true + working-directory: example + script: yarn e2e:test:android-release --timeout 200000 --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts - uses: actions/upload-artifact@v4 if: failure() diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index e12d999e..78137a5e 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -51,7 +51,7 @@ jobs: working-directory: example run: | gem update cocoapods xcodeproj - pod install --project-directory=ios + pod install --project-directory=ios || (pod repo update && pod install --project-directory=ios --clean-install) - name: Install applesimutils run: | diff --git a/.github/workflows/mocha-android.yml b/.github/workflows/mocha-android.yml index 3aedf38a..5e2d74d8 100644 --- a/.github/workflows/mocha-android.yml +++ b/.github/workflows/mocha-android.yml @@ -73,7 +73,7 @@ jobs: mkdir lnd mkdir clightning chmod 777 lnd clightning - docker-compose up -d --quiet-pull + docker compose up -d --quiet-pull - name: Wait for electrum server timeout-minutes: 2 diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index b8dacfe3..541c7c14 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -22,23 +22,12 @@ jobs: with: fetch-depth: 1 - - name: Setup Docker Colima 1 - uses: douglascamata/setup-docker-macos-action@v1-alpha.13 - - id: docker1 - continue-on-error: true - with: - lima: v0.18.0 - colima: v0.5.6 - - - name: Setup Docker Colima 2 - if: steps.docker1.outcome != 'success' - uses: douglascamata/setup-docker-macos-action@v1-alpha.13 - - id: docker2 - with: - lima: v0.18.0 - colima: v0.5.6 + - name: Setup Docker Colima + run: | + brew install docker docker-compose colima + mkdir -p ~/.docker/cli-plugins + ln -sfn /opt/homebrew/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose || true + colima start --cpu 4 --memory 8 --disk 100 - name: Install backup-server dependencies working-directory: backup-server @@ -50,7 +39,7 @@ jobs: mkdir lnd mkdir clightning chmod 777 lnd clightning - docker-compose up -d --quiet-pull + docker compose up -d --quiet-pull - name: Wait for electrum server timeout-minutes: 2 @@ -85,7 +74,7 @@ jobs: working-directory: example run: | gem update cocoapods xcodeproj - pod install --project-directory=ios + pod install --project-directory=ios || (pod repo update && pod install --project-directory=ios --clean-install) - name: Install applesimutils run: | From 9e36e3745bb84f4013d76046c28cc92e724205de Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 09:53:55 -0300 Subject: [PATCH 06/32] fix: Exclude nested node_modules in the lib package to avoid bundling conflicts --- .github/workflows/e2e-ios.yml | 2 +- .github/workflows/mocha-ios.yml | 2 +- example/metro.config.js | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index 78137a5e..aa78a3a5 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -51,7 +51,7 @@ jobs: working-directory: example run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (pod repo update && pod install --project-directory=ios --clean-install) + pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) - name: Install applesimutils run: | diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 541c7c14..63513b69 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -74,7 +74,7 @@ jobs: working-directory: example run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (pod repo update && pod install --project-directory=ios --clean-install) + pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) - name: Install applesimutils run: | diff --git a/example/metro.config.js b/example/metro.config.js index 32860c78..e0401a6a 100644 --- a/example/metro.config.js +++ b/example/metro.config.js @@ -20,6 +20,10 @@ const config = { vm: path.resolve(__dirname, 'node_modules/vm-browserify/'), process: path.resolve(__dirname, 'node_modules/process/'), }, + blockList: [ + // Exclude nested node_modules in the lib package to avoid bundling conflicts + /node_modules\/@synonymdev\/react-native-ldk\/node_modules\/.*/, + ], }, }; From 9cc8fe11dc5a61bdb21957cb220cfc434724cc7a Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 09:56:42 -0300 Subject: [PATCH 07/32] chore: update mocha cli --- example/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/example/package.json b/example/package.json index e0e13f7b..7977bc8e 100644 --- a/example/package.json +++ b/example/package.json @@ -40,7 +40,7 @@ "chai": "^4.3.7", "crypto-browserify": "^3.12.0", "events": "^3.3.0", - "mocha-remote-client": "^1.6.1", + "mocha-remote-client": "^1.13.2", "process": "^0.11.10", "query-string": "^8.1.0", "react": "18.2.0", @@ -84,7 +84,7 @@ "jest": "^29.3.1", "metro-react-native-babel-preset": "0.76.8", "mocha": "^10.2.0", - "mocha-remote-cli": "^1.6.1", + "mocha-remote-cli": "^1.13.2", "newline-decoder": "^1.0.0", "prettier": "2.7.1", "react-test-renderer": "18.2.0", @@ -95,7 +95,7 @@ "node": ">=16" }, "resolutions": { - "**/ws": "^7.5.10", + "**/ws": "^8.17.1", "**/semver": "^6.3.1", "**/brace-expansion": "^1.1.12", "**/cipher-base": "^1.0.5", From c61f6c3e7a9772848d78462b677496eb39eef76a Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 10:26:35 -0300 Subject: [PATCH 08/32] fix: timeout --- .github/workflows/e2e-android.yml | 6 +++--- .github/workflows/e2e-ios.yml | 2 +- .github/workflows/mocha-ios.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml index 96e962d3..061226a8 100644 --- a/.github/workflows/e2e-android.yml +++ b/.github/workflows/e2e-android.yml @@ -124,7 +124,7 @@ jobs: arch: x86_64 disable-animations: true working-directory: example - script: yarn e2e:test:android-release --timeout 200000 --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts + script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts - name: Run tests attempt 2 if: steps.attempt1.outcome != 'success' @@ -140,7 +140,7 @@ jobs: arch: x86_64 disable-animations: true working-directory: example - script: yarn e2e:test:android-release --timeout 200000 --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts + script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts - name: Run tests attempt 3 (final) if: steps.attempt2.outcome != 'success' @@ -154,7 +154,7 @@ jobs: arch: x86_64 disable-animations: true working-directory: example - script: yarn e2e:test:android-release --timeout 200000 --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts + script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts - uses: actions/upload-artifact@v4 if: failure() diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index aa78a3a5..47d6bd1a 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -51,7 +51,7 @@ jobs: working-directory: example run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) + pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && COCOAPODS_DISABLE_CHECKSUM=true pod install --project-directory=ios) - name: Install applesimutils run: | diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 63513b69..24e37dbf 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -74,7 +74,7 @@ jobs: working-directory: example run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) + pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && COCOAPODS_DISABLE_CHECKSUM=true pod install --project-directory=ios) - name: Install applesimutils run: | From 20293741b5ac4ce27c6d92cf36fac6d999c40278 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 11:21:14 -0300 Subject: [PATCH 09/32] fix: update yarn --- example/yarn.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/example/yarn.lock b/example/yarn.lock index 8b269f95..c77ead88 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -1837,7 +1837,7 @@ bitcoinjs-lib "6.1.4" "@synonymdev/react-native-ldk@../lib": - version "0.0.160" + version "0.0.162" dependencies: "@synonymdev/raw-transaction-decoder" "1.1.0" bech32 "^2.0.0" @@ -6585,7 +6585,7 @@ mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "^1.2.6" -mocha-remote-cli@^1.6.1: +mocha-remote-cli@^1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/mocha-remote-cli/-/mocha-remote-cli-1.13.2.tgz#464a89081256f62a4720674caa5bc06cc84bc2ab" integrity sha512-Jly/TCM1BAhk3isQ4VzvHEfR5raRacjA9dqfvijN9X3/Gx+bJxQN+96AS41HiEi10PShrg6hWO2KvR49BlO68Q== @@ -6595,7 +6595,7 @@ mocha-remote-cli@^1.6.1: mocha-remote-server "1.13.2" yargs "^17.7.2" -mocha-remote-client@^1.6.1: +mocha-remote-client@^1.13.2: version "1.13.2" resolved "https://registry.yarnpkg.com/mocha-remote-client/-/mocha-remote-client-1.13.2.tgz#db5ea0d1263f5fa38df7e5f8c62f1caa3007ff7f" integrity sha512-XDzWQrjA1/CmrNg0TipFOL4xK5xkjWjpwv8INKwA2pQ0QUckRWcnhEQZO78EFI5+pLu4fTAl79at6Z0Cks7orA== @@ -8784,10 +8784,10 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^6.2.2, ws@^7, ws@^7.0.0, ws@^7.5.1, ws@^7.5.10, ws@^8.17.1: - version "7.5.10" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" - integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== +ws@^6.2.2, ws@^7, ws@^7.0.0, ws@^7.5.1, ws@^8.17.1: + version "8.18.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" From 8b5d49d148b3e2944cb9bff989ff14e2f7b60c28 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 11:51:59 -0300 Subject: [PATCH 10/32] fix: update iOS deployment target to 13.0 and fix boost checksum issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Set minimum iOS version to 13.0 (required by react-native-ldk) - Add pre_install hook to patch boost podspec to use sourceforge mirror - Add post_install hook to enforce iOS 13.0 deployment target for all pods - Fixes CI failures in e2e-ios, mocha-ios workflows Related: https://github.com/facebook/react-native/issues/37748 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- example/ios/Podfile | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index 2b2f715e..14294320 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,9 +5,26 @@ require Pod::Executable.execute_command('node', ['-p', {paths: [process.argv[1]]}, )', __dir__]).strip -platform :ios, min_ios_version_supported +platform :ios, '13.0' prepare_react_native_project! +# Fix boost checksum issue by using sourceforge mirror +# https://github.com/facebook/react-native/issues/37748 +pre_install do |installer| + boost_path = File.join(installer.sandbox.root, '../node_modules/react-native/third-party-podspecs/boost.podspec') + if File.exist?(boost_path) + boost_spec = File.read(boost_path) + if boost_spec.include?('boostorg.jfrog.io') + boost_spec = boost_spec.gsub( + 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', + 'https://sourceforge.net/projects/boost/files/boost/1.76.0/boost_1_76_0.tar.bz2/download' + ) + File.write(boost_path, boost_spec) + Pod::UI.puts 'Patched boost podspec to use sourceforge mirror'.green + end + end +end + # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded # @@ -58,5 +75,12 @@ target 'exmpl' do :mac_catalyst_enabled => false ) __apply_Xcode_12_5_M1_post_install_workaround(installer) + + # Fix iOS deployment target to 13.0 (required by react-native-ldk) + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + end + end end end From f546797fe1d66a1978605a1a80d22bf8914d664f Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 11:55:35 -0300 Subject: [PATCH 11/32] fix: unit tests --- example/tests/unit.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/tests/unit.ts b/example/tests/unit.ts index 8e5ff158..9de4db91 100644 --- a/example/tests/unit.ts +++ b/example/tests/unit.ts @@ -104,8 +104,8 @@ describe('Unit', function () { '027f921585f2ac0c7c70e36110adecfd8fd14b8a99bfb3d000a283fcac358fce88', ); - expect(lm.getLdkPaymentsSent()).to.eventually.be.an('array').that.is.empty; - expect(lm.getLdkPaymentsClaimed()).to.eventually.be.an('array').that.is + await expect(lm.getLdkPaymentsSent()).to.eventually.be.an('array').that.is.empty; + await expect(lm.getLdkPaymentsClaimed()).to.eventually.be.an('array').that.is .empty; const claimableBalances = await ldk.claimableBalances(false); From b63a95d4ce410b8db31991e531d8da6938c992bb Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 12:15:41 -0300 Subject: [PATCH 12/32] fix: lint --- example/tests/unit.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/example/tests/unit.ts b/example/tests/unit.ts index 9de4db91..d112b2f8 100644 --- a/example/tests/unit.ts +++ b/example/tests/unit.ts @@ -104,9 +104,10 @@ describe('Unit', function () { '027f921585f2ac0c7c70e36110adecfd8fd14b8a99bfb3d000a283fcac358fce88', ); - await expect(lm.getLdkPaymentsSent()).to.eventually.be.an('array').that.is.empty; - await expect(lm.getLdkPaymentsClaimed()).to.eventually.be.an('array').that.is + await expect(lm.getLdkPaymentsSent()).to.eventually.be.an('array').that.is .empty; + await expect(lm.getLdkPaymentsClaimed()).to.eventually.be.an('array').that + .is.empty; const claimableBalances = await ldk.claimableBalances(false); if (claimableBalances.isErr()) { From aad7436a563f9576b6f27e3e1c91b8a30f031ab9 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 12:24:07 -0300 Subject: [PATCH 13/32] fix: boost checksum issue before CocoaPods loads the podspec --- example/ios/Podfile | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index 14294320..e358ff6d 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,26 +5,24 @@ require Pod::Executable.execute_command('node', ['-p', {paths: [process.argv[1]]}, )', __dir__]).strip -platform :ios, '13.0' -prepare_react_native_project! - -# Fix boost checksum issue by using sourceforge mirror +# Fix boost checksum issue BEFORE CocoaPods loads the podspec # https://github.com/facebook/react-native/issues/37748 -pre_install do |installer| - boost_path = File.join(installer.sandbox.root, '../node_modules/react-native/third-party-podspecs/boost.podspec') - if File.exist?(boost_path) - boost_spec = File.read(boost_path) - if boost_spec.include?('boostorg.jfrog.io') - boost_spec = boost_spec.gsub( - 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', - 'https://sourceforge.net/projects/boost/files/boost/1.76.0/boost_1_76_0.tar.bz2/download' - ) - File.write(boost_path, boost_spec) - Pod::UI.puts 'Patched boost podspec to use sourceforge mirror'.green - end +boost_path = File.join(__dir__, '../node_modules/react-native/third-party-podspecs/boost.podspec') +if File.exist?(boost_path) + boost_spec = File.read(boost_path) + if boost_spec.include?('boostorg.jfrog.io') + boost_spec = boost_spec.gsub( + 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', + 'https://sourceforge.net/projects/boost/files/boost/1.76.0/boost_1_76_0.tar.bz2/download' + ) + File.write(boost_path, boost_spec) + puts '✅ Patched boost podspec to use sourceforge mirror' end end +platform :ios, '13.0' +prepare_react_native_project! + # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded # From 20753717c1a1322265e02791e1254fc1f0074334 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 12:25:05 -0300 Subject: [PATCH 14/32] fix: remove sha checksum temporarilly --- example/ios/Podfile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index e358ff6d..2438628f 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,18 +5,19 @@ require Pod::Executable.execute_command('node', ['-p', {paths: [process.argv[1]]}, )', __dir__]).strip -# Fix boost checksum issue BEFORE CocoaPods loads the podspec +# Fix boost checksum issue by removing SHA verification # https://github.com/facebook/react-native/issues/37748 boost_path = File.join(__dir__, '../node_modules/react-native/third-party-podspecs/boost.podspec') if File.exist?(boost_path) boost_spec = File.read(boost_path) - if boost_spec.include?('boostorg.jfrog.io') + if boost_spec.include?(':sha256') + # Remove the sha256 checksum to avoid verification errors boost_spec = boost_spec.gsub( - 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', - 'https://sourceforge.net/projects/boost/files/boost/1.76.0/boost_1_76_0.tar.bz2/download' + /,\s*:sha256\s*=>\s*['"][^'"]*['"]/, + '' ) File.write(boost_path, boost_spec) - puts '✅ Patched boost podspec to use sourceforge mirror' + puts '✅ Patched boost podspec to skip checksum verification' end end From c75913c5aacb6e3ed9fa3721a227de911a5f7ed9 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 12:27:32 -0300 Subject: [PATCH 15/32] chore: cancel in porgress run --- .github/workflows/e2e-android.yml | 4 ++++ .github/workflows/e2e-ios.yml | 4 ++++ .github/workflows/example-lint-check.yml | 4 ++++ .github/workflows/lib-lint-check.yml | 4 ++++ .github/workflows/mocha-android.yml | 4 ++++ .github/workflows/mocha-ios.yml | 4 ++++ 6 files changed, 24 insertions(+) diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml index 061226a8..37ae156b 100644 --- a/.github/workflows/e2e-android.yml +++ b/.github/workflows/e2e-android.yml @@ -8,6 +8,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: e2e-android: runs-on: ubuntu-latest diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index 47d6bd1a..6805e48c 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -11,6 +11,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: e2e-ios: runs-on: macos-14 diff --git a/.github/workflows/example-lint-check.yml b/.github/workflows/example-lint-check.yml index 64dff573..483ce0f8 100644 --- a/.github/workflows/example-lint-check.yml +++ b/.github/workflows/example-lint-check.yml @@ -5,6 +5,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + defaults: run: working-directory: example diff --git a/.github/workflows/lib-lint-check.yml b/.github/workflows/lib-lint-check.yml index 0207a7ae..5ebd710b 100644 --- a/.github/workflows/lib-lint-check.yml +++ b/.github/workflows/lib-lint-check.yml @@ -5,6 +5,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + defaults: run: working-directory: lib diff --git a/.github/workflows/mocha-android.yml b/.github/workflows/mocha-android.yml index 5e2d74d8..28442ad4 100644 --- a/.github/workflows/mocha-android.yml +++ b/.github/workflows/mocha-android.yml @@ -8,6 +8,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: mocha-android: runs-on: ubuntu-latest diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 24e37dbf..763d48a3 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -11,6 +11,10 @@ on: branches: - 'master' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: mocha-ios: runs-on: macos-13 From 5e1aacddcb6fe2ee778c90d2efd220d0a769b7a3 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 13:35:11 -0300 Subject: [PATCH 16/32] fix: set COCOAPODS_DISABLE_CHECKSUM env var for iOS workflows --- .github/workflows/e2e-ios.yml | 4 +++- .github/workflows/mocha-ios.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index 6805e48c..56e4f9bf 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -53,9 +53,11 @@ jobs: - name: Install pods working-directory: example + env: + COCOAPODS_DISABLE_CHECKSUM: true run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && COCOAPODS_DISABLE_CHECKSUM=true pod install --project-directory=ios) + pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) - name: Install applesimutils run: | diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 763d48a3..8d7ff83e 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -76,9 +76,11 @@ jobs: - name: Install pods working-directory: example + env: + COCOAPODS_DISABLE_CHECKSUM: true run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && COCOAPODS_DISABLE_CHECKSUM=true pod install --project-directory=ios) + pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) - name: Install applesimutils run: | From b38a021835390c9fd0db20387b68b2dd30019b18 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 13:45:28 -0300 Subject: [PATCH 17/32] fix: proactively clean CocoaPods cache to prevent boost archive corruption --- .github/workflows/e2e-ios.yml | 7 ++++++- .github/workflows/mocha-ios.yml | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index 56e4f9bf..383657ed 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -51,13 +51,18 @@ jobs: path: example/ios/Pods key: pods-${{ hashFiles('**/Podfile.lock') }} + - name: Clean CocoaPods cache + run: | + rm -rf ~/Library/Caches/CocoaPods + pod cache clean --all || true + - name: Install pods working-directory: example env: COCOAPODS_DISABLE_CHECKSUM: true run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) + pod install --project-directory=ios || pod install --project-directory=ios - name: Install applesimutils run: | diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 8d7ff83e..54990a96 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -74,13 +74,18 @@ jobs: path: example/ios/Pods key: pods-${{ hashFiles('**/Podfile.lock') }} + - name: Clean CocoaPods cache + run: | + rm -rf ~/Library/Caches/CocoaPods + pod cache clean --all || true + - name: Install pods working-directory: example env: COCOAPODS_DISABLE_CHECKSUM: true run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || (rm -rf ~/Library/Caches/CocoaPods && pod cache clean --all && pod install --project-directory=ios) + pod install --project-directory=ios || pod install --project-directory=ios - name: Install applesimutils run: | From 5cf5bd8c49bde0021d9312c3a98b07b53092b17e Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 14:04:06 -0300 Subject: [PATCH 18/32] fix:boost download issue by using SourceForge mirror instead of JFrog --- example/ios/Podfile | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index 2438628f..50523e05 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,19 +5,31 @@ require Pod::Executable.execute_command('node', ['-p', {paths: [process.argv[1]]}, )', __dir__]).strip -# Fix boost checksum issue by removing SHA verification +# Fix boost download issue by using SourceForge mirror instead of JFrog # https://github.com/facebook/react-native/issues/37748 boost_path = File.join(__dir__, '../node_modules/react-native/third-party-podspecs/boost.podspec') if File.exist?(boost_path) boost_spec = File.read(boost_path) + + # Replace JFrog URL with SourceForge mirror + if boost_spec.include?('boostorg.jfrog.io') + boost_spec = boost_spec.gsub( + 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', + 'https://archives.boost.io/release/1.76.0/source/boost_1_76_0.tar.bz2' + ) + File.write(boost_path, boost_spec) + puts '✅ Patched boost podspec to use archives.boost.io mirror' + end + + # Remove checksum as backup measure + boost_spec = File.read(boost_path) if boost_spec.include?(':sha256') - # Remove the sha256 checksum to avoid verification errors boost_spec = boost_spec.gsub( /,\s*:sha256\s*=>\s*['"][^'"]*['"]/, '' ) File.write(boost_path, boost_spec) - puts '✅ Patched boost podspec to skip checksum verification' + puts '✅ Removed boost checksum verification' end end From 2252f272c3a69cb1265a869b7c38c5d9df6bd919 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 14:25:37 -0300 Subject: [PATCH 19/32] chore: chage ios device to iPhone 15 --- .github/workflows/mocha-ios.yml | 2 +- example/.detoxrc.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 54990a96..46f42dfa 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -94,7 +94,7 @@ jobs: - name: Build working-directory: example - run: npx react-native run-ios --no-packager --simulator='iPhone 14' + run: npx react-native run-ios --no-packager --simulator='iPhone 15' - name: Test iOS app working-directory: example diff --git a/example/.detoxrc.js b/example/.detoxrc.js index d11b3e9f..f14a8165 100644 --- a/example/.detoxrc.js +++ b/example/.detoxrc.js @@ -38,7 +38,7 @@ module.exports = { simulator: { type: 'ios.simulator', device: { - type: 'iPhone 14' + type: 'iPhone 15' } }, attached: { From 42ebec58037ceb6e2de129b8917044e34869a043 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 14:33:21 -0300 Subject: [PATCH 20/32] fix: Setup chai-as-promised for mocha tests --- example/shim.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/example/shim.js b/example/shim.js index 7f50f203..35466543 100644 --- a/example/shim.js +++ b/example/shim.js @@ -34,3 +34,8 @@ if (typeof localStorage !== 'undefined') { // If using the crypto shim, uncomment the following line to ensure // crypto is loaded first, so it can populate global.crypto require('crypto'); + +// Setup chai-as-promised for mocha tests +const chai = require('chai'); +const chaiAsPromised = require('chai-as-promised'); +chai.use(chaiAsPromised); From e9b5db85278908e61dc456ae0ef385245a3b0a66 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 15:09:49 -0300 Subject: [PATCH 21/32] chore: update detox --- .../app/src/androidTest/java/com/exmpl/DetoxTest.java | 6 +++--- example/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java b/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java index c3fc085b..0bdcc673 100644 --- a/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java +++ b/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java @@ -20,9 +20,9 @@ public class DetoxTest { @Test public void runDetoxTests() { DetoxConfig detoxConfig = new DetoxConfig(); - detoxConfig.idlePolicyConfig.masterTimeoutSec = 90; - detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60; - detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 180 : 60); + detoxConfig.idlePolicyConfig.masterTimeoutSec = 120; + detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 90; + detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 240 : 120); Detox.runTests(mActivityRule, detoxConfig); } diff --git a/example/package.json b/example/package.json index 7977bc8e..68cec54e 100644 --- a/example/package.json +++ b/example/package.json @@ -76,7 +76,7 @@ "bitcoin-json-rpc": "^1.3.2", "chai-as-promised": "^7.1.1", "concurrently": "^8.2.0", - "detox": "20.20.2", + "detox": "20.23.3", "electrum-client": "github:BlueWallet/rn-electrum-client#47acb51149e97fab249c3f8a314f708dbee4fb6e", "eslint": "8.27.0", "eslint-config-prettier": "^8.5.0", From 28ac6ee7d597e33782c3c60135d040cc74e31cd1 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 15:17:10 -0300 Subject: [PATCH 22/32] fix: mocha tests --- example/Tests.tsx | 19 +++++++++++-------- example/docker/docker-compose.yml | 14 ++++++-------- example/package.json | 6 +++--- example/tests/context.js | 18 ++++++++++++++++++ 4 files changed, 38 insertions(+), 19 deletions(-) create mode 100644 example/tests/context.js diff --git a/example/Tests.tsx b/example/Tests.tsx index 3fd88fad..a78e357a 100644 --- a/example/Tests.tsx +++ b/example/Tests.tsx @@ -128,14 +128,17 @@ class Tests extends Component { }); // global.fs = require("react-native-fs"); // global.path = require("path-browserify"); - global.environment = { - // Default to the host machine when running on Android - // realmBaseUrl: Platform.OS === "android" ? "http://10.0.2.2:9090" : undefined, - ...context, - // reactNative: Platform.OS, - // android: Platform.OS === "android", - // ios: Platform.OS === "ios", - }; + // global.environment = { + // Default to the host machine when running on Android + // realmBaseUrl: Platform.OS === "android" ? "http://10.0.2.2:9090" : undefined, + // ...context, + // reactNative: Platform.OS, + // android: Platform.OS === "android", + // ios: Platform.OS === "ios", + // }; + (global as any).environment = JSON.parse( + Buffer.from(context.c as string, 'hex').toString('utf-8'), + ); // Make the tests reinitializable, to allow test running on changes to the "realm" package // Probing the existance of `getModules` as this only exists in debug mode // if ("getModules" in require) { diff --git a/example/docker/docker-compose.yml b/example/docker/docker-compose.yml index 7b7366fe..779eb964 100644 --- a/example/docker/docker-compose.yml +++ b/example/docker/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3' services: bitcoind: container_name: bitcoin @@ -112,12 +111,10 @@ services: depends_on: - bitcoind expose: - - '18080' # REST - - '18081' # DOCPORT + - '18081' # REST - '9736' # P2P - '11001' # RPC ports: - - '18080:18080' - '18081:18081' - '9736:9736' - '11001:11001' @@ -135,11 +132,12 @@ services: - '--dev-bitcoind-poll=2' - '--dev-fast-gossip' - '--grpc-port=11001' + - '--log-file=-' - '--bitcoin-rpcport=18443' - - '--plugin=/opt/c-lightning-rest/plugin.js' - - '--rest-port=18080' - - '--rest-protocol=http' - - '--rest-docport=18081' + - '--clnrest-port=18081' + - '--clnrest-protocol=http' + - '--clnrest-host=0.0.0.0' + - '--developer' eclair: container_name: eclair diff --git a/example/package.json b/example/package.json index 68cec54e..11c41127 100644 --- a/example/package.json +++ b/example/package.json @@ -20,9 +20,9 @@ "reinstall": "cd ../lib/ && yarn install && yarn build && cd ../example/ && yarn add ../lib && yarn rn-setup", "clean": "rm -rf node_modules ios/Pods ios/Podfile.lock ios/build && yarn install && cd ios && pod deintegrate && pod install && cd ../", "rn-setup": "node rn-setup.js", - "test:mocha": "mocha-remote --context lndmacaroon=$(xxd -ps -u -c 1000 docker/lnd/admin.macaroon) clmacaroon=$(xxd -ps -u -c 1000 docker/clightning/access.macaroon)", - "test:mocha:ios": "mocha-remote --context lndmacaroon=$(xxd -ps -u -c 1000 docker/lnd/admin.macaroon) clmacaroon=$(xxd -ps -u -c 1000 docker/clightning/access.macaroon) -- concurrently --kill-others-on-fail npm:m npm:runner-ios", - "test:mocha:android": "mocha-remote --context lndmacaroon=$(xxd -ps -u -c 1000 docker/lnd/admin.macaroon) clmacaroon=$(xxd -ps -u -c 1000 docker/clightning/access.macaroon) -- concurrently --kill-others-on-fail npm:m npm:runner-android", + "test:mocha": "mocha-remote --context c=$(node ./tests/context.js)", + "test:mocha:ios": "mocha-remote --context c=$(node ./tests/context.js) -- concurrently --kill-others-on-fail npm:m npm:runner-ios", + "test:mocha:android": "mocha-remote --context c=$(node ./tests/context.js) -- concurrently --kill-others-on-fail npm:m npm:runner-android", "m": "react-native start --reset-cache", "runner-ios": "react-native run-ios --simulator='iPhone 14' --no-packager", "runner-android": "react-native run-android --no-packager" diff --git a/example/tests/context.js b/example/tests/context.js new file mode 100644 index 00000000..bdaee4a8 --- /dev/null +++ b/example/tests/context.js @@ -0,0 +1,18 @@ +const fs = require('fs'); +const run = require('child_process').execSync; + +// read lnd macaroon +const lndmacaroon = fs + .readFileSync('docker/lnd/admin.macaroon') + .toString('hex') + .toUpperCase(); + +// run command to read clightnng rune +const clightning = run( + 'cd docker; docker compose exec --user clightning clightning lightning-cli createrune --regtest', +); +const lcrune = JSON.parse(clightning).rune; + +const context = { lndmacaroon, lcrune }; +const encoded = Buffer.from(JSON.stringify(context)).toString('hex'); +console.log(encoded); From 8b024351611958e0ca07190ab627622bc05b514d Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Mon, 17 Nov 2025 15:25:08 -0300 Subject: [PATCH 23/32] fix: detox version --- example/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/package.json b/example/package.json index 11c41127..3ce6406b 100644 --- a/example/package.json +++ b/example/package.json @@ -76,7 +76,7 @@ "bitcoin-json-rpc": "^1.3.2", "chai-as-promised": "^7.1.1", "concurrently": "^8.2.0", - "detox": "20.23.3", + "detox": "20.23.1", "electrum-client": "github:BlueWallet/rn-electrum-client#47acb51149e97fab249c3f8a314f708dbee4fb6e", "eslint": "8.27.0", "eslint-config-prettier": "^8.5.0", From 2cdba31c1909f8e00c259e1d562738fe3198dbb3 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 07:04:37 -0300 Subject: [PATCH 24/32] fix: context.js tried to read docker/lnd/admin.macaroon before LND finished initializing --- .github/workflows/mocha-android.yml | 27 +++++++++-- .github/workflows/mocha-ios.yml | 30 ++++++++++-- example/tests/context.js | 72 +++++++++++++++++++++++------ 3 files changed, 110 insertions(+), 19 deletions(-) diff --git a/.github/workflows/mocha-android.yml b/.github/workflows/mocha-android.yml index 28442ad4..ca6d8fca 100644 --- a/.github/workflows/mocha-android.yml +++ b/.github/workflows/mocha-android.yml @@ -79,9 +79,29 @@ jobs: chmod 777 lnd clightning docker compose up -d --quiet-pull - - name: Wait for electrum server - timeout-minutes: 2 - run: while ! nc -z '127.0.0.1' 60001; do sleep 1; done + - name: Wait for electrum server, LND and CLightning + timeout-minutes: 5 + run: | + # Wait for Electrum + while ! nc -z '127.0.0.1' 60001; do + echo "Waiting for Electrum..." + sleep 1 + done + echo "Electrum is ready!" + + # Wait for LND macaroon file + sudo bash -c "while [ ! -f example/docker/lnd/admin.macaroon ]; do echo 'Waiting for LND macaroon...'; sleep 2; done" + sudo chmod -R 777 example/docker/lnd + echo "LND macaroon found!" + + # Wait for CLightning to be ready + while ! docker logs clightning 2>&1 | grep -q "Server started with public key"; do + echo "Waiting for CLightning..." + sleep 2 + done + echo "CLightning is ready!" + + echo "All services ready!" - name: Install lib dependencies working-directory: lib @@ -122,6 +142,7 @@ jobs: npx react-native run-android --no-packager - name: run tests + timeout-minutes: 30 uses: reactivecircus/android-emulator-runner@v2 with: api-level: 34 diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 46f42dfa..0b220e53 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -45,9 +45,32 @@ jobs: chmod 777 lnd clightning docker compose up -d --quiet-pull - - name: Wait for electrum server - timeout-minutes: 2 - run: while ! nc -z '127.0.0.1' 60001; do sleep 1; done + - name: Wait for electrum server, LND and CLightning + timeout-minutes: 5 + run: | + # Wait for Electrum + while ! nc -z '127.0.0.1' 60001; do + echo "Waiting for Electrum..." + sleep 1 + done + echo "Electrum is ready!" + + # Wait for LND macaroon file + cd example + while [ ! -f docker/lnd/admin.macaroon ]; do + echo "Waiting for LND macaroon..." + sleep 2 + done + echo "LND macaroon found!" + + # Wait for CLightning to be ready + while ! docker logs clightning 2>&1 | grep -q "Server started with public key"; do + echo "Waiting for CLightning..." + sleep 2 + done + echo "CLightning is ready!" + + echo "All services ready!" - name: Node uses: actions/setup-node@v4 @@ -97,6 +120,7 @@ jobs: run: npx react-native run-ios --no-packager --simulator='iPhone 15' - name: Test iOS app + timeout-minutes: 30 working-directory: example run: yarn test:mocha:ios diff --git a/example/tests/context.js b/example/tests/context.js index bdaee4a8..95d9ad6b 100644 --- a/example/tests/context.js +++ b/example/tests/context.js @@ -1,18 +1,64 @@ const fs = require('fs'); const run = require('child_process').execSync; -// read lnd macaroon -const lndmacaroon = fs - .readFileSync('docker/lnd/admin.macaroon') - .toString('hex') - .toUpperCase(); +// Helper function to retry file reads +function readFileWithRetry(path, maxRetries = 30, delay = 1000) { + for (let i = 0; i < maxRetries; i++) { + try { + return fs.readFileSync(path); + } catch (err) { + if (i === maxRetries - 1) { + console.error(`Failed to read ${path} after ${maxRetries} attempts`); + throw err; + } + console.error( + `Attempt ${i + 1}/${maxRetries}: Waiting for ${path}...`, + ); + // Sleep synchronously (only works on Unix-like systems) + run(`sleep ${delay / 1000}`); + } + } +} -// run command to read clightnng rune -const clightning = run( - 'cd docker; docker compose exec --user clightning clightning lightning-cli createrune --regtest', -); -const lcrune = JSON.parse(clightning).rune; +// Helper function to retry docker commands +function runWithRetry(cmd, maxRetries = 30, delay = 1000) { + for (let i = 0; i < maxRetries; i++) { + try { + return run(cmd, { encoding: 'utf8' }); + } catch (err) { + if (i === maxRetries - 1) { + console.error(`Failed to run command after ${maxRetries} attempts: ${cmd}`); + throw err; + } + console.error( + `Attempt ${i + 1}/${maxRetries}: Command failed, retrying: ${cmd}`, + ); + run(`sleep ${delay / 1000}`); + } + } +} -const context = { lndmacaroon, lcrune }; -const encoded = Buffer.from(JSON.stringify(context)).toString('hex'); -console.log(encoded); +try { + // Read lnd macaroon with retry + console.log('Waiting for LND macaroon...'); + const lndmacaroon = readFileWithRetry('docker/lnd/admin.macaroon') + .toString('hex') + .toUpperCase(); + console.log('LND macaroon loaded successfully'); + + // Run command to read clightning rune with retry + console.log('Waiting for CLightning to be ready...'); + const clightning = runWithRetry( + 'cd docker; docker compose exec --user clightning clightning lightning-cli createrune --regtest', + ); + const lcrune = JSON.parse(clightning).rune; + console.log('CLightning rune generated successfully'); + + const context = { lndmacaroon, lcrune }; + const encoded = Buffer.from(JSON.stringify(context)).toString('hex'); + console.log(encoded); +} catch (error) { + console.error('Failed to prepare test context:', error.message); + console.error(error.stack); + process.exit(1); +} From 48bca5664526edeb88b4b1e82b019f935ceef2bb Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 07:08:52 -0300 Subject: [PATCH 25/32] chore: lint --- example/tests/context.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/example/tests/context.js b/example/tests/context.js index 95d9ad6b..ebe28eda 100644 --- a/example/tests/context.js +++ b/example/tests/context.js @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ const fs = require('fs'); const run = require('child_process').execSync; @@ -11,9 +12,7 @@ function readFileWithRetry(path, maxRetries = 30, delay = 1000) { console.error(`Failed to read ${path} after ${maxRetries} attempts`); throw err; } - console.error( - `Attempt ${i + 1}/${maxRetries}: Waiting for ${path}...`, - ); + console.error(`Attempt ${i + 1}/${maxRetries}: Waiting for ${path}...`); // Sleep synchronously (only works on Unix-like systems) run(`sleep ${delay / 1000}`); } @@ -27,7 +26,9 @@ function runWithRetry(cmd, maxRetries = 30, delay = 1000) { return run(cmd, { encoding: 'utf8' }); } catch (err) { if (i === maxRetries - 1) { - console.error(`Failed to run command after ${maxRetries} attempts: ${cmd}`); + console.error( + `Failed to run command after ${maxRetries} attempts: ${cmd}`, + ); throw err; } console.error( From 0a82ef77e2016c4bed42278340ab21403db1857d Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 07:39:12 -0300 Subject: [PATCH 26/32] fix: Only output the encoded context to stdout --- example/tests/context.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/example/tests/context.js b/example/tests/context.js index ebe28eda..e2cf2a3b 100644 --- a/example/tests/context.js +++ b/example/tests/context.js @@ -41,22 +41,23 @@ function runWithRetry(cmd, maxRetries = 30, delay = 1000) { try { // Read lnd macaroon with retry - console.log('Waiting for LND macaroon...'); + console.error('Waiting for LND macaroon...'); const lndmacaroon = readFileWithRetry('docker/lnd/admin.macaroon') .toString('hex') .toUpperCase(); - console.log('LND macaroon loaded successfully'); + console.error('LND macaroon loaded successfully'); // Run command to read clightning rune with retry - console.log('Waiting for CLightning to be ready...'); + console.error('Waiting for CLightning to be ready...'); const clightning = runWithRetry( 'cd docker; docker compose exec --user clightning clightning lightning-cli createrune --regtest', ); const lcrune = JSON.parse(clightning).rune; - console.log('CLightning rune generated successfully'); + console.error('CLightning rune generated successfully'); const context = { lndmacaroon, lcrune }; const encoded = Buffer.from(JSON.stringify(context)).toString('hex'); + // Only output the encoded context to stdout - everything else goes to stderr console.log(encoded); } catch (error) { console.error('Failed to prepare test context:', error.message); From 512875e59895b202248191e36d36aad6015517ed Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 08:32:03 -0300 Subject: [PATCH 27/32] chore: restore test code to match master branch --- example/tests/eclair.ts | 2 +- example/tests/unit.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/example/tests/eclair.ts b/example/tests/eclair.ts index 1ecdafef..4da4f0a8 100644 --- a/example/tests/eclair.ts +++ b/example/tests/eclair.ts @@ -113,7 +113,7 @@ describe('Eclair', function () { channelCloseMinimum: 5, outputSpendingFee: 10, urgentOnChainSweep: 30, - maximumFeeEstimate: 30, + maximumFeeEstimate: 30 }); }, }); diff --git a/example/tests/unit.ts b/example/tests/unit.ts index d112b2f8..8e5ff158 100644 --- a/example/tests/unit.ts +++ b/example/tests/unit.ts @@ -104,10 +104,9 @@ describe('Unit', function () { '027f921585f2ac0c7c70e36110adecfd8fd14b8a99bfb3d000a283fcac358fce88', ); - await expect(lm.getLdkPaymentsSent()).to.eventually.be.an('array').that.is + expect(lm.getLdkPaymentsSent()).to.eventually.be.an('array').that.is.empty; + expect(lm.getLdkPaymentsClaimed()).to.eventually.be.an('array').that.is .empty; - await expect(lm.getLdkPaymentsClaimed()).to.eventually.be.an('array').that - .is.empty; const claimableBalances = await ldk.claimableBalances(false); if (claimableBalances.isErr()) { From 5ab9d6f47781a052bb878c85d5beece15689824e Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 08:34:16 -0300 Subject: [PATCH 28/32] chore: revert test code --- .github/workflows/e2e-android.yml | 40 +------------- .github/workflows/e2e-ios.yml | 13 +---- .github/workflows/example-lint-check.yml | 4 -- .github/workflows/lib-lint-check.yml | 4 -- .github/workflows/mocha-android.yml | 33 ++--------- .github/workflows/mocha-ios.yml | 70 ++++++++---------------- example/.detoxrc.js | 2 +- 7 files changed, 31 insertions(+), 135 deletions(-) diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml index 37ae156b..5f18c990 100644 --- a/.github/workflows/e2e-android.yml +++ b/.github/workflows/e2e-android.yml @@ -8,10 +8,6 @@ on: branches: - 'master' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - jobs: e2e-android: runs-on: ubuntu-latest @@ -115,9 +111,7 @@ jobs: - name: Kill java processes run: pkill -9 -f java || true - - name: Run tests attempt 1 - id: attempt1 - continue-on-error: true + - name: run tests uses: reactivecircus/android-emulator-runner@v2 with: avd-name: Pixel_API_31_AOSP @@ -128,37 +122,7 @@ jobs: arch: x86_64 disable-animations: true working-directory: example - script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts - - - name: Run tests attempt 2 - if: steps.attempt1.outcome != 'success' - id: attempt2 - continue-on-error: true - uses: reactivecircus/android-emulator-runner@v2 - with: - avd-name: Pixel_API_31_AOSP - profile: 5.4in FWVGA - api-level: 31 - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047 - arch: x86_64 - disable-animations: true - working-directory: example - script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts - - - name: Run tests attempt 3 (final) - if: steps.attempt2.outcome != 'success' - uses: reactivecircus/android-emulator-runner@v2 - with: - avd-name: Pixel_API_31_AOSP - profile: 5.4in FWVGA - api-level: 31 - force-avd-creation: false - emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -camera-back none -camera-front none -partition-size 2047 - arch: x86_64 - disable-animations: true - working-directory: example - script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts + script: yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts || yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifactsyarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts || yarn e2e:test:android-release --record-videos all --take-screenshots all --record-logs all --artifacts-location /mnt/artifacts - uses: actions/upload-artifact@v4 if: failure() diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index 383657ed..e12d999e 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -11,10 +11,6 @@ on: branches: - 'master' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - jobs: e2e-ios: runs-on: macos-14 @@ -51,18 +47,11 @@ jobs: path: example/ios/Pods key: pods-${{ hashFiles('**/Podfile.lock') }} - - name: Clean CocoaPods cache - run: | - rm -rf ~/Library/Caches/CocoaPods - pod cache clean --all || true - - name: Install pods working-directory: example - env: - COCOAPODS_DISABLE_CHECKSUM: true run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || pod install --project-directory=ios + pod install --project-directory=ios - name: Install applesimutils run: | diff --git a/.github/workflows/example-lint-check.yml b/.github/workflows/example-lint-check.yml index 483ce0f8..64dff573 100644 --- a/.github/workflows/example-lint-check.yml +++ b/.github/workflows/example-lint-check.yml @@ -5,10 +5,6 @@ on: branches: - 'master' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - defaults: run: working-directory: example diff --git a/.github/workflows/lib-lint-check.yml b/.github/workflows/lib-lint-check.yml index 5ebd710b..0207a7ae 100644 --- a/.github/workflows/lib-lint-check.yml +++ b/.github/workflows/lib-lint-check.yml @@ -5,10 +5,6 @@ on: branches: - 'master' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - defaults: run: working-directory: lib diff --git a/.github/workflows/mocha-android.yml b/.github/workflows/mocha-android.yml index ca6d8fca..3aedf38a 100644 --- a/.github/workflows/mocha-android.yml +++ b/.github/workflows/mocha-android.yml @@ -8,10 +8,6 @@ on: branches: - 'master' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - jobs: mocha-android: runs-on: ubuntu-latest @@ -77,31 +73,11 @@ jobs: mkdir lnd mkdir clightning chmod 777 lnd clightning - docker compose up -d --quiet-pull + docker-compose up -d --quiet-pull - - name: Wait for electrum server, LND and CLightning - timeout-minutes: 5 - run: | - # Wait for Electrum - while ! nc -z '127.0.0.1' 60001; do - echo "Waiting for Electrum..." - sleep 1 - done - echo "Electrum is ready!" - - # Wait for LND macaroon file - sudo bash -c "while [ ! -f example/docker/lnd/admin.macaroon ]; do echo 'Waiting for LND macaroon...'; sleep 2; done" - sudo chmod -R 777 example/docker/lnd - echo "LND macaroon found!" - - # Wait for CLightning to be ready - while ! docker logs clightning 2>&1 | grep -q "Server started with public key"; do - echo "Waiting for CLightning..." - sleep 2 - done - echo "CLightning is ready!" - - echo "All services ready!" + - name: Wait for electrum server + timeout-minutes: 2 + run: while ! nc -z '127.0.0.1' 60001; do sleep 1; done - name: Install lib dependencies working-directory: lib @@ -142,7 +118,6 @@ jobs: npx react-native run-android --no-packager - name: run tests - timeout-minutes: 30 uses: reactivecircus/android-emulator-runner@v2 with: api-level: 34 diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index 0b220e53..b8dacfe3 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -11,10 +11,6 @@ on: branches: - 'master' -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - jobs: mocha-ios: runs-on: macos-13 @@ -26,12 +22,23 @@ jobs: with: fetch-depth: 1 - - name: Setup Docker Colima - run: | - brew install docker docker-compose colima - mkdir -p ~/.docker/cli-plugins - ln -sfn /opt/homebrew/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose || true - colima start --cpu 4 --memory 8 --disk 100 + - name: Setup Docker Colima 1 + uses: douglascamata/setup-docker-macos-action@v1-alpha.13 + + id: docker1 + continue-on-error: true + with: + lima: v0.18.0 + colima: v0.5.6 + + - name: Setup Docker Colima 2 + if: steps.docker1.outcome != 'success' + uses: douglascamata/setup-docker-macos-action@v1-alpha.13 + + id: docker2 + with: + lima: v0.18.0 + colima: v0.5.6 - name: Install backup-server dependencies working-directory: backup-server @@ -43,34 +50,11 @@ jobs: mkdir lnd mkdir clightning chmod 777 lnd clightning - docker compose up -d --quiet-pull + docker-compose up -d --quiet-pull - - name: Wait for electrum server, LND and CLightning - timeout-minutes: 5 - run: | - # Wait for Electrum - while ! nc -z '127.0.0.1' 60001; do - echo "Waiting for Electrum..." - sleep 1 - done - echo "Electrum is ready!" - - # Wait for LND macaroon file - cd example - while [ ! -f docker/lnd/admin.macaroon ]; do - echo "Waiting for LND macaroon..." - sleep 2 - done - echo "LND macaroon found!" - - # Wait for CLightning to be ready - while ! docker logs clightning 2>&1 | grep -q "Server started with public key"; do - echo "Waiting for CLightning..." - sleep 2 - done - echo "CLightning is ready!" - - echo "All services ready!" + - name: Wait for electrum server + timeout-minutes: 2 + run: while ! nc -z '127.0.0.1' 60001; do sleep 1; done - name: Node uses: actions/setup-node@v4 @@ -97,18 +81,11 @@ jobs: path: example/ios/Pods key: pods-${{ hashFiles('**/Podfile.lock') }} - - name: Clean CocoaPods cache - run: | - rm -rf ~/Library/Caches/CocoaPods - pod cache clean --all || true - - name: Install pods working-directory: example - env: - COCOAPODS_DISABLE_CHECKSUM: true run: | gem update cocoapods xcodeproj - pod install --project-directory=ios || pod install --project-directory=ios + pod install --project-directory=ios - name: Install applesimutils run: | @@ -117,10 +94,9 @@ jobs: - name: Build working-directory: example - run: npx react-native run-ios --no-packager --simulator='iPhone 15' + run: npx react-native run-ios --no-packager --simulator='iPhone 14' - name: Test iOS app - timeout-minutes: 30 working-directory: example run: yarn test:mocha:ios diff --git a/example/.detoxrc.js b/example/.detoxrc.js index f14a8165..d11b3e9f 100644 --- a/example/.detoxrc.js +++ b/example/.detoxrc.js @@ -38,7 +38,7 @@ module.exports = { simulator: { type: 'ios.simulator', device: { - type: 'iPhone 15' + type: 'iPhone 14' } }, attached: { From 258adf5f50cf545a23e3cc65dd6cb7c87eecc19d Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 08:34:34 -0300 Subject: [PATCH 29/32] chore: revert test --- example/tests/context.js | 66 ---------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 example/tests/context.js diff --git a/example/tests/context.js b/example/tests/context.js deleted file mode 100644 index e2cf2a3b..00000000 --- a/example/tests/context.js +++ /dev/null @@ -1,66 +0,0 @@ -/* eslint-disable @typescript-eslint/explicit-function-return-type */ -const fs = require('fs'); -const run = require('child_process').execSync; - -// Helper function to retry file reads -function readFileWithRetry(path, maxRetries = 30, delay = 1000) { - for (let i = 0; i < maxRetries; i++) { - try { - return fs.readFileSync(path); - } catch (err) { - if (i === maxRetries - 1) { - console.error(`Failed to read ${path} after ${maxRetries} attempts`); - throw err; - } - console.error(`Attempt ${i + 1}/${maxRetries}: Waiting for ${path}...`); - // Sleep synchronously (only works on Unix-like systems) - run(`sleep ${delay / 1000}`); - } - } -} - -// Helper function to retry docker commands -function runWithRetry(cmd, maxRetries = 30, delay = 1000) { - for (let i = 0; i < maxRetries; i++) { - try { - return run(cmd, { encoding: 'utf8' }); - } catch (err) { - if (i === maxRetries - 1) { - console.error( - `Failed to run command after ${maxRetries} attempts: ${cmd}`, - ); - throw err; - } - console.error( - `Attempt ${i + 1}/${maxRetries}: Command failed, retrying: ${cmd}`, - ); - run(`sleep ${delay / 1000}`); - } - } -} - -try { - // Read lnd macaroon with retry - console.error('Waiting for LND macaroon...'); - const lndmacaroon = readFileWithRetry('docker/lnd/admin.macaroon') - .toString('hex') - .toUpperCase(); - console.error('LND macaroon loaded successfully'); - - // Run command to read clightning rune with retry - console.error('Waiting for CLightning to be ready...'); - const clightning = runWithRetry( - 'cd docker; docker compose exec --user clightning clightning lightning-cli createrune --regtest', - ); - const lcrune = JSON.parse(clightning).rune; - console.error('CLightning rune generated successfully'); - - const context = { lndmacaroon, lcrune }; - const encoded = Buffer.from(JSON.stringify(context)).toString('hex'); - // Only output the encoded context to stdout - everything else goes to stderr - console.log(encoded); -} catch (error) { - console.error('Failed to prepare test context:', error.message); - console.error(error.stack); - process.exit(1); -} From 5c0c1dfaed7d87c6c2e36f123a08f338408794a2 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 08:47:33 -0300 Subject: [PATCH 30/32] chore: lint --- example/tests/eclair.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/tests/eclair.ts b/example/tests/eclair.ts index 4da4f0a8..1ecdafef 100644 --- a/example/tests/eclair.ts +++ b/example/tests/eclair.ts @@ -113,7 +113,7 @@ describe('Eclair', function () { channelCloseMinimum: 5, outputSpendingFee: 10, urgentOnChainSweep: 30, - maximumFeeEstimate: 30 + maximumFeeEstimate: 30, }); }, }); From af908167bf515f842a6bad7d5b7e4694380365bc Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 08:54:01 -0300 Subject: [PATCH 31/32] chore: restore test code --- example/Tests.tsx | 19 ++++++++----------- .../androidTest/java/com/exmpl/DetoxTest.java | 6 +++--- example/docker/docker-compose.yml | 14 ++++++++------ example/package.json | 14 +++++++------- example/shim.js | 5 ----- example/yarn.lock | 14 +++++++------- 6 files changed, 33 insertions(+), 39 deletions(-) diff --git a/example/Tests.tsx b/example/Tests.tsx index a78e357a..3fd88fad 100644 --- a/example/Tests.tsx +++ b/example/Tests.tsx @@ -128,17 +128,14 @@ class Tests extends Component { }); // global.fs = require("react-native-fs"); // global.path = require("path-browserify"); - // global.environment = { - // Default to the host machine when running on Android - // realmBaseUrl: Platform.OS === "android" ? "http://10.0.2.2:9090" : undefined, - // ...context, - // reactNative: Platform.OS, - // android: Platform.OS === "android", - // ios: Platform.OS === "ios", - // }; - (global as any).environment = JSON.parse( - Buffer.from(context.c as string, 'hex').toString('utf-8'), - ); + global.environment = { + // Default to the host machine when running on Android + // realmBaseUrl: Platform.OS === "android" ? "http://10.0.2.2:9090" : undefined, + ...context, + // reactNative: Platform.OS, + // android: Platform.OS === "android", + // ios: Platform.OS === "ios", + }; // Make the tests reinitializable, to allow test running on changes to the "realm" package // Probing the existance of `getModules` as this only exists in debug mode // if ("getModules" in require) { diff --git a/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java b/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java index 0bdcc673..c3fc085b 100644 --- a/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java +++ b/example/android/app/src/androidTest/java/com/exmpl/DetoxTest.java @@ -20,9 +20,9 @@ public class DetoxTest { @Test public void runDetoxTests() { DetoxConfig detoxConfig = new DetoxConfig(); - detoxConfig.idlePolicyConfig.masterTimeoutSec = 120; - detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 90; - detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 240 : 120); + detoxConfig.idlePolicyConfig.masterTimeoutSec = 90; + detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60; + detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 180 : 60); Detox.runTests(mActivityRule, detoxConfig); } diff --git a/example/docker/docker-compose.yml b/example/docker/docker-compose.yml index 779eb964..7b7366fe 100644 --- a/example/docker/docker-compose.yml +++ b/example/docker/docker-compose.yml @@ -1,3 +1,4 @@ +version: '3' services: bitcoind: container_name: bitcoin @@ -111,10 +112,12 @@ services: depends_on: - bitcoind expose: - - '18081' # REST + - '18080' # REST + - '18081' # DOCPORT - '9736' # P2P - '11001' # RPC ports: + - '18080:18080' - '18081:18081' - '9736:9736' - '11001:11001' @@ -132,12 +135,11 @@ services: - '--dev-bitcoind-poll=2' - '--dev-fast-gossip' - '--grpc-port=11001' - - '--log-file=-' - '--bitcoin-rpcport=18443' - - '--clnrest-port=18081' - - '--clnrest-protocol=http' - - '--clnrest-host=0.0.0.0' - - '--developer' + - '--plugin=/opt/c-lightning-rest/plugin.js' + - '--rest-port=18080' + - '--rest-protocol=http' + - '--rest-docport=18081' eclair: container_name: eclair diff --git a/example/package.json b/example/package.json index 3ce6406b..e0e13f7b 100644 --- a/example/package.json +++ b/example/package.json @@ -20,9 +20,9 @@ "reinstall": "cd ../lib/ && yarn install && yarn build && cd ../example/ && yarn add ../lib && yarn rn-setup", "clean": "rm -rf node_modules ios/Pods ios/Podfile.lock ios/build && yarn install && cd ios && pod deintegrate && pod install && cd ../", "rn-setup": "node rn-setup.js", - "test:mocha": "mocha-remote --context c=$(node ./tests/context.js)", - "test:mocha:ios": "mocha-remote --context c=$(node ./tests/context.js) -- concurrently --kill-others-on-fail npm:m npm:runner-ios", - "test:mocha:android": "mocha-remote --context c=$(node ./tests/context.js) -- concurrently --kill-others-on-fail npm:m npm:runner-android", + "test:mocha": "mocha-remote --context lndmacaroon=$(xxd -ps -u -c 1000 docker/lnd/admin.macaroon) clmacaroon=$(xxd -ps -u -c 1000 docker/clightning/access.macaroon)", + "test:mocha:ios": "mocha-remote --context lndmacaroon=$(xxd -ps -u -c 1000 docker/lnd/admin.macaroon) clmacaroon=$(xxd -ps -u -c 1000 docker/clightning/access.macaroon) -- concurrently --kill-others-on-fail npm:m npm:runner-ios", + "test:mocha:android": "mocha-remote --context lndmacaroon=$(xxd -ps -u -c 1000 docker/lnd/admin.macaroon) clmacaroon=$(xxd -ps -u -c 1000 docker/clightning/access.macaroon) -- concurrently --kill-others-on-fail npm:m npm:runner-android", "m": "react-native start --reset-cache", "runner-ios": "react-native run-ios --simulator='iPhone 14' --no-packager", "runner-android": "react-native run-android --no-packager" @@ -40,7 +40,7 @@ "chai": "^4.3.7", "crypto-browserify": "^3.12.0", "events": "^3.3.0", - "mocha-remote-client": "^1.13.2", + "mocha-remote-client": "^1.6.1", "process": "^0.11.10", "query-string": "^8.1.0", "react": "18.2.0", @@ -76,7 +76,7 @@ "bitcoin-json-rpc": "^1.3.2", "chai-as-promised": "^7.1.1", "concurrently": "^8.2.0", - "detox": "20.23.1", + "detox": "20.20.2", "electrum-client": "github:BlueWallet/rn-electrum-client#47acb51149e97fab249c3f8a314f708dbee4fb6e", "eslint": "8.27.0", "eslint-config-prettier": "^8.5.0", @@ -84,7 +84,7 @@ "jest": "^29.3.1", "metro-react-native-babel-preset": "0.76.8", "mocha": "^10.2.0", - "mocha-remote-cli": "^1.13.2", + "mocha-remote-cli": "^1.6.1", "newline-decoder": "^1.0.0", "prettier": "2.7.1", "react-test-renderer": "18.2.0", @@ -95,7 +95,7 @@ "node": ">=16" }, "resolutions": { - "**/ws": "^8.17.1", + "**/ws": "^7.5.10", "**/semver": "^6.3.1", "**/brace-expansion": "^1.1.12", "**/cipher-base": "^1.0.5", diff --git a/example/shim.js b/example/shim.js index 35466543..7f50f203 100644 --- a/example/shim.js +++ b/example/shim.js @@ -34,8 +34,3 @@ if (typeof localStorage !== 'undefined') { // If using the crypto shim, uncomment the following line to ensure // crypto is loaded first, so it can populate global.crypto require('crypto'); - -// Setup chai-as-promised for mocha tests -const chai = require('chai'); -const chaiAsPromised = require('chai-as-promised'); -chai.use(chaiAsPromised); diff --git a/example/yarn.lock b/example/yarn.lock index c77ead88..8b269f95 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -1837,7 +1837,7 @@ bitcoinjs-lib "6.1.4" "@synonymdev/react-native-ldk@../lib": - version "0.0.162" + version "0.0.160" dependencies: "@synonymdev/raw-transaction-decoder" "1.1.0" bech32 "^2.0.0" @@ -6585,7 +6585,7 @@ mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "^1.2.6" -mocha-remote-cli@^1.13.2: +mocha-remote-cli@^1.6.1: version "1.13.2" resolved "https://registry.yarnpkg.com/mocha-remote-cli/-/mocha-remote-cli-1.13.2.tgz#464a89081256f62a4720674caa5bc06cc84bc2ab" integrity sha512-Jly/TCM1BAhk3isQ4VzvHEfR5raRacjA9dqfvijN9X3/Gx+bJxQN+96AS41HiEi10PShrg6hWO2KvR49BlO68Q== @@ -6595,7 +6595,7 @@ mocha-remote-cli@^1.13.2: mocha-remote-server "1.13.2" yargs "^17.7.2" -mocha-remote-client@^1.13.2: +mocha-remote-client@^1.6.1: version "1.13.2" resolved "https://registry.yarnpkg.com/mocha-remote-client/-/mocha-remote-client-1.13.2.tgz#db5ea0d1263f5fa38df7e5f8c62f1caa3007ff7f" integrity sha512-XDzWQrjA1/CmrNg0TipFOL4xK5xkjWjpwv8INKwA2pQ0QUckRWcnhEQZO78EFI5+pLu4fTAl79at6Z0Cks7orA== @@ -8784,10 +8784,10 @@ write-file-atomic@^4.0.2: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^6.2.2, ws@^7, ws@^7.0.0, ws@^7.5.1, ws@^8.17.1: - version "8.18.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" - integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== +ws@^6.2.2, ws@^7, ws@^7.0.0, ws@^7.5.1, ws@^7.5.10, ws@^8.17.1: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" From dc0f808c8f2af1c0da10a1dad3d38a4302ea92a7 Mon Sep 17 00:00:00 2001 From: jvsena42 Date: Tue, 18 Nov 2025 08:56:02 -0300 Subject: [PATCH 32/32] chore: restore test files --- example/ios/Podfile | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/example/ios/Podfile b/example/ios/Podfile index 50523e05..2b2f715e 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -5,35 +5,7 @@ require Pod::Executable.execute_command('node', ['-p', {paths: [process.argv[1]]}, )', __dir__]).strip -# Fix boost download issue by using SourceForge mirror instead of JFrog -# https://github.com/facebook/react-native/issues/37748 -boost_path = File.join(__dir__, '../node_modules/react-native/third-party-podspecs/boost.podspec') -if File.exist?(boost_path) - boost_spec = File.read(boost_path) - - # Replace JFrog URL with SourceForge mirror - if boost_spec.include?('boostorg.jfrog.io') - boost_spec = boost_spec.gsub( - 'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2', - 'https://archives.boost.io/release/1.76.0/source/boost_1_76_0.tar.bz2' - ) - File.write(boost_path, boost_spec) - puts '✅ Patched boost podspec to use archives.boost.io mirror' - end - - # Remove checksum as backup measure - boost_spec = File.read(boost_path) - if boost_spec.include?(':sha256') - boost_spec = boost_spec.gsub( - /,\s*:sha256\s*=>\s*['"][^'"]*['"]/, - '' - ) - File.write(boost_path, boost_spec) - puts '✅ Removed boost checksum verification' - end -end - -platform :ios, '13.0' +platform :ios, min_ios_version_supported prepare_react_native_project! # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. @@ -86,12 +58,5 @@ target 'exmpl' do :mac_catalyst_enabled => false ) __apply_Xcode_12_5_M1_post_install_workaround(installer) - - # Fix iOS deployment target to 13.0 (required by react-native-ldk) - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' - end - end end end