From ccbb8db025d9e0d92e7ca1c1e71922db929b764e Mon Sep 17 00:00:00 2001 From: Ivan Vershigora Date: Wed, 24 Jul 2024 19:26:05 +0300 Subject: [PATCH 1/3] fix: mocha tests --- example/Tests.tsx | 7 ++-- example/docker/docker-compose.yml | 14 ++++---- example/package.json | 6 ++-- example/tests/clightning.ts | 40 +++++++++++----------- example/tests/context.js | 18 ++++++++++ example/tests/eclair.ts | 49 +++++++++++++-------------- example/tests/utils/clightning-rpc.ts | 37 ++++++++++---------- example/tests/utils/eclair-rpc.ts | 4 +++ 8 files changed, 98 insertions(+), 77 deletions(-) create mode 100755 example/tests/context.js diff --git a/example/Tests.tsx b/example/Tests.tsx index 3fd88fad..f5c99ad0 100644 --- a/example/Tests.tsx +++ b/example/Tests.tsx @@ -128,14 +128,15 @@ class Tests extends Component { }); // global.fs = require("react-native-fs"); // global.path = require("path-browserify"); - global.environment = { + // global.environment = { // Default to the host machine when running on Android // realmBaseUrl: Platform.OS === "android" ? "http://10.0.2.2:9090" : undefined, - ...context, + // ...context, // reactNative: Platform.OS, // android: Platform.OS === "android", // ios: Platform.OS === "ios", - }; + // }; + global.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..d7490313 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=-' # log to stdo - '--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 2223c9fb..fc824ca8 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 --context c=$(node ./tests/context.js)", + "test:mocha:ios": "mocha-remote --context --context c=$(node ./tests/context.js) -- concurrently --kill-others-on-fail npm:m npm:runner-ios", + "test:mocha:android": "mocha-remote --context --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/clightning.ts b/example/tests/clightning.ts index b0c1200b..9843dbac 100644 --- a/example/tests/clightning.ts +++ b/example/tests/clightning.ts @@ -30,8 +30,8 @@ import { const bitcoinURL = 'http://polaruser:polarpass@localhost:9091'; const clConfig = { host: 'localhost', - port: 18080, - macaroon: global.environment.clmacaroon, + port: 18081, + rune: global.environment.lcrune, }; describe.skip('Clightning', function () { @@ -51,7 +51,7 @@ describe.skip('Clightning', function () { balance = await rpc.getBalance(); } - const { address: lndAddress } = await cl.newAddr(); + const { bech32: lndAddress } = await cl.newAddr(); await rpc.sendToAddress(lndAddress, '1'); await rpc.generateToAddress(1, await rpc.getNewAddress()); @@ -107,6 +107,18 @@ describe.skip('Clightning', function () { // - make a few payments await ldk.stop(); + + if (!skipRemoteBackups) { + const backupRes = await ldk.backupSetup({ + network: ENetworks.regtest, + seed: profile.getAccount().seed, + details: backupServerDetails, + }); + if (backupRes.isErr()) { + throw backupRes.error; + } + } + const lmStart = await lm.start({ ...profile.getStartParams(), // getBestBlock: getBestBlock, @@ -124,17 +136,6 @@ describe.skip('Clightning', function () { throw lmStart.error; } - if (!skipRemoteBackups) { - const backupRes = await ldk.backupSetup({ - network: ENetworks.regtest, - seed: profile.getAccount().seed, - details: backupServerDetails, - }); - if (backupRes.isErr()) { - throw backupRes.error; - } - } - const nodeId = await ldk.nodeId(); if (nodeId.isErr()) { throw nodeId.error; @@ -155,8 +156,9 @@ describe.skip('Clightning', function () { // wait for peer to be connected let n = 0; while (true) { - const peers = await cl.listPeers(); - if (peers.some((p) => p.id === nodeId.value)) { + const { peers } = await cl.listPeers(); + const peer = peers.find((p) => p.id === nodeId.value); + if (peer && peer.connected) { break; } await sleep(1000); @@ -166,10 +168,10 @@ describe.skip('Clightning', function () { } // open a channel - await cl.openChannel({ + await cl.fundchannel({ id: nodeId.value, - satoshis: '100000', - // private: true, + amount: '100000', + announce: false, }); await rpc.generateToAddress(10, await rpc.getNewAddress()); await waitForElectrum({ cl: true }); diff --git a/example/tests/context.js b/example/tests/context.js new file mode 100755 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); diff --git a/example/tests/eclair.ts b/example/tests/eclair.ts index ab356c15..623e7719 100644 --- a/example/tests/eclair.ts +++ b/example/tests/eclair.ts @@ -37,9 +37,9 @@ describe('Eclair', function () { balance = await rpc.getBalance(); } - // const ecAddress = await ec.getnewaddress(); - // await rpc.sendToAddress(ecAddress, '1'); - await rpc.generateToAddress(1, await rpc.getNewAddress()); + const ecAddress = await ec.getnewaddress(); + await rpc.sendToAddress(ecAddress, '1'); + await rpc.generateToAddress(6, await rpc.getNewAddress()); const storageRes = await lm.setBaseStoragePath( `${RNFS.DocumentDirectoryPath}/ldk/`, @@ -101,23 +101,6 @@ describe('Eclair', function () { // - make a few payments await ldk.stop(); - const lmStart = await lm.start({ - ...profile.getStartParams(), - getFees: () => { - return Promise.resolve({ - onChainSweep: 30, - maxAllowedNonAnchorChannelRemoteFee: Math.max(25, 30 * 10), - minAllowedAnchorChannelRemoteFee: 5, - minAllowedNonAnchorChannelRemoteFee: Math.max(5 - 1, 0), - anchorChannelFee: 10, - nonAnchorChannelFee: 20, - channelCloseMinimum: 5, - }); - }, - }); - if (lmStart.isErr()) { - throw lmStart.error; - } if (!skipRemoteBackups) { const backupRes = await ldk.backupSetup({ @@ -130,6 +113,13 @@ describe('Eclair', function () { } } + const lmStart = await lm.start({ + ...profile.getStartParams(), + }); + if (lmStart.isErr()) { + throw lmStart.error; + } + const nodeId = await ldk.nodeId(); if (nodeId.isErr()) { throw nodeId.error; @@ -160,12 +150,19 @@ describe('Eclair', function () { } // open a channel - await ec.open({ + const open = await ec.open({ nodeId: nodeId.value, - fundingSatoshis: 100000, + fundingSatoshis: 10000000, + fundingFeeBudgetSatoshis: 2000, + fundingFeerateSatByte: 1, announceChannel: false, + // channelType: 'anchor_outputs_zero_fee_htlc_tx', }); + if (open.includes('error')) { + throw open; + } + await rpc.generateToAddress(10, await rpc.getNewAddress()); await waitForElectrum({ ec: true }); @@ -191,7 +188,7 @@ describe('Eclair', function () { } } - // CL -> LDK, 0 sats + // Eclair -> LDK, 0 sats const inv1 = await lm.createAndStorePaymentRequest({ amountSats: 0, description: 'trololo', @@ -205,7 +202,7 @@ describe('Eclair', function () { amountMsat: 10000 * 1000, // milli-sats }); - // CL -> LDK, 1000 sats + // Eclair -> LDK, 1000 sats const inv2 = await lm.createAndStorePaymentRequest({ amountSats: 1000, description: 'ololo', @@ -218,7 +215,7 @@ describe('Eclair', function () { // FIXME LDK -> ECLAIR doesn't work - // // LDK -> CL, 0 sats + // LDK -> Eclair, 0 sats // const { serialized: invoice3 } = await ec.createinvoice({ // // amount: 0, // // label: 'payment3' + new Date(), @@ -233,7 +230,7 @@ describe('Eclair', function () { // throw pay3.error; // } - // LDK -> CL, 444 sats + // // LDK -> Eclair, 444 sats // const { serialized: invoice4 } = await ec.createinvoice({ // amountMsat: 444000, // milisats // // label: 'payment4' + new Date(), diff --git a/example/tests/utils/clightning-rpc.ts b/example/tests/utils/clightning-rpc.ts index d3f66557..e7472716 100644 --- a/example/tests/utils/clightning-rpc.ts +++ b/example/tests/utils/clightning-rpc.ts @@ -2,14 +2,14 @@ import queryString from 'query-string'; export default class ClightningRPC { destroyed: boolean = false; - macaroon: string; + rune: string; host: string; port: number; headers: {}; constructor(opts: any = {}) { - if (!opts.macaroon) { - throw new Error('macaroon is required'); + if (!opts.rune) { + throw new Error('rune is required'); } if (!opts.host) { throw new Error('host is required'); @@ -18,46 +18,47 @@ export default class ClightningRPC { throw new Error('port is required'); } - this.macaroon = opts.macaroon; + this.rune = opts.rune; this.host = opts.host; this.port = opts.port; this.headers = { + 'Accept': 'application/json', 'Content-type': 'application/json', - macaroon: Buffer.from(this.macaroon, 'hex').toString('base64'), + 'Rune': this.rune, }; } - getInfo(): Promise { - return this._get({ path: '/v1/getinfo' }); + getInfo(body?: any): Promise { + return this._post({ path: '/v1/getinfo', body }); } - pay(body): Promise { + pay(body?: any): Promise { return this._post({ path: '/v1/pay', body }); } - genInvoice(body): Promise { + genInvoice(body?: any): Promise { return this._post({ path: '/v1/invoice/genInvoice', body }); } - newAddr(): Promise { - return this._get({ path: '/v1/newaddr' }); + newAddr(body?: any): Promise { + return this._post({ path: '/v1/newaddr', body }); } - listPeers(): Promise { - return this._get({ path: '/v1/peer/listPeers' }); + listPeers(body?: any): Promise { + return this._post({ path: '/v1/listpeers', body }); } - openChannel(body): Promise { - return this._post({ path: '/v1/channel/openChannel', body }); + fundchannel(body?: any): Promise { + return this._post({ path: '/v1/fundchannel', body }); } destroy(): void { this.destroyed = true; } - async _post({ path, body }): Promise { - const jsonBody = JSON.stringify(body); + async _post({ path, body }: {path: string; body?: object}): Promise { + const jsonBody = JSON.stringify(body || {}); return await this._request({ method: 'POST', path, body: jsonBody }); } @@ -72,7 +73,7 @@ export default class ClightningRPC { return await this._request({ method: 'GET', path: pathWithParams }); } - async _request(opts): Promise { + async _request(opts: any): Promise { const { path, body, method } = opts; const fullPath = 'http://' + this.host + ':' + this.port + path; diff --git a/example/tests/utils/eclair-rpc.ts b/example/tests/utils/eclair-rpc.ts index ec5baa28..ebedb3f0 100644 --- a/example/tests/utils/eclair-rpc.ts +++ b/example/tests/utils/eclair-rpc.ts @@ -36,6 +36,10 @@ export default class EclairRPC { return this._post({ path: '/peers' }); } + onchainbalance(): Promise { + return this._post({ path: '/onchainbalance' }); + } + open(body): Promise { console.info('openChannel', body); return this._post({ path: '/open', body }); From 9cff5531f3d4db1c7d28a4071aafadf56eb918e2 Mon Sep 17 00:00:00 2001 From: Ivan Vershigora Date: Wed, 24 Jul 2024 19:30:17 +0300 Subject: [PATCH 2/3] fix: mocha tests --- example/Tests.tsx | 16 +++++++++------- example/tests/utils/clightning-rpc.ts | 6 +++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/example/Tests.tsx b/example/Tests.tsx index f5c99ad0..e7081424 100644 --- a/example/Tests.tsx +++ b/example/Tests.tsx @@ -129,14 +129,16 @@ 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", + // 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 = JSON.parse(Buffer.from(context.c as string, 'hex').toString('utf-8')); + global.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/tests/utils/clightning-rpc.ts b/example/tests/utils/clightning-rpc.ts index e7472716..f638c9ba 100644 --- a/example/tests/utils/clightning-rpc.ts +++ b/example/tests/utils/clightning-rpc.ts @@ -23,9 +23,9 @@ export default class ClightningRPC { this.port = opts.port; this.headers = { - 'Accept': 'application/json', + Accept: 'application/json', 'Content-type': 'application/json', - 'Rune': this.rune, + Rune: this.rune, }; } @@ -57,7 +57,7 @@ export default class ClightningRPC { this.destroyed = true; } - async _post({ path, body }: {path: string; body?: object}): Promise { + async _post({ path, body }: { path: string; body?: object }): Promise { const jsonBody = JSON.stringify(body || {}); return await this._request({ method: 'POST', path, body: jsonBody }); } From 45ec7897150d3d999f1aee1459a4d427ec37d989 Mon Sep 17 00:00:00 2001 From: Ivan Vershigora Date: Fri, 26 Jul 2024 09:54:45 +0300 Subject: [PATCH 3/3] fix: rm -rf lib/node_modules after the build --- .github/workflows/e2e-android.yml | 4 ++++ .github/workflows/e2e-ios.yml | 4 ++++ .github/workflows/mocha-android.yml | 4 ++++ .github/workflows/mocha-ios.yml | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/.github/workflows/e2e-android.yml b/.github/workflows/e2e-android.yml index 5f18c990..12d31d74 100644 --- a/.github/workflows/e2e-android.yml +++ b/.github/workflows/e2e-android.yml @@ -80,6 +80,10 @@ jobs: working-directory: lib run: yarn build + - name: Remove lib node_modules + working-directory: lib + run: rm -rf node_modules + - name: Use gradle caches uses: actions/cache@v4 with: diff --git a/.github/workflows/e2e-ios.yml b/.github/workflows/e2e-ios.yml index e12d999e..fb20420a 100644 --- a/.github/workflows/e2e-ios.yml +++ b/.github/workflows/e2e-ios.yml @@ -37,6 +37,10 @@ jobs: working-directory: lib run: yarn build + - name: Remove lib node_modules + working-directory: lib + run: rm -rf node_modules + - name: Install Dependencies working-directory: example run: (yarn || yarn) && yarn rn-setup diff --git a/.github/workflows/mocha-android.yml b/.github/workflows/mocha-android.yml index 3aedf38a..9c5e6c36 100644 --- a/.github/workflows/mocha-android.yml +++ b/.github/workflows/mocha-android.yml @@ -87,6 +87,10 @@ jobs: working-directory: lib run: yarn build + - name: Remove lib node_modules + working-directory: lib + run: rm -rf node_modules + - name: Use gradle caches uses: actions/cache@v4 with: diff --git a/.github/workflows/mocha-ios.yml b/.github/workflows/mocha-ios.yml index b8dacfe3..0b81b478 100644 --- a/.github/workflows/mocha-ios.yml +++ b/.github/workflows/mocha-ios.yml @@ -71,6 +71,10 @@ jobs: working-directory: lib run: yarn build + - name: Remove lib node_modules + working-directory: lib + run: rm -rf node_modules + - name: Install Dependencies working-directory: example run: (yarn || yarn) && yarn rn-setup