Skip to content

Commit

Permalink
Merge pull request #268 from synonymdev/local-funded-channels
Browse files Browse the repository at this point in the history
Locally funded channels
  • Loading branch information
Jasonvdb authored Sep 5, 2024
2 parents 885ed8a + a90b556 commit 3767cc7
Show file tree
Hide file tree
Showing 17 changed files with 1,064 additions and 302 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vscode/
.idea/
**/.DS_Store
example/.watchman*
Expand Down
35 changes: 24 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ This library hopes to simplify the process of adding Lightning via LDK to any Re
yarn add @synonymdev/react-native-ldk
#or
npm i -S @synonymdev/react-native-ldk
````
```

### iOS installation
```bash
cd ios && pod install && cd ../
````
```

### Android installation
1. Add the following line to `dependencies` in `/android/app/build.gradle`
```
dependencies {
...
implementation files("../../node_modules/@synonymdev/react-native-ldk/android/libs/LDK-release.aar")
}
```
```groovy
dependencies {
//...
implementation files("../../node_modules/@synonymdev/react-native-ldk/android/libs/LDK-release.aar") // <- this
}
```
2. Ensure `minSdkVersion` is set to at least `24` in `/android/build.gradle`
## Development
Expand All @@ -40,19 +40,32 @@ dependencies {
5. In the popup that appears select `JavaDocs` and tap `OK` then `OK` again
## Running example app
See also [`./example/README.md`](./example/README.md)
```bash

#Build dist files
# Build dist files
git clone https://github.com/synonymdev/react-native-ldk.git
cd react-native-ldk/lib/ && yarn install && yarn build && cd ../
cd example/ && yarn install && yarn rn-setup
yarn ios
#or
# or
yarn android
```

### Update config to match your local setup
In `constants.ts` update `peers.lnd` if you're using Polar locally.
### Example for Android
```ts
// export const peers = {
// lnd: {
pubKey:
'_033f4d3032ce7f54224f4bd9747b50b7cd72074a859758e40e1ca46ffa79a34324_',
address: '10.0.2.2',
port: 9737,
// },
```

## Notes
- It is important to not mix and match account names and seeds when starting LDK. Doing so can result in a corrupt save.

Expand Down
100 changes: 80 additions & 20 deletions example/Dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ import lm, {
TChannelUpdate,
} from '@synonymdev/react-native-ldk';
import { backupServerDetails, peers } from './utils/constants';
import { createNewAccount, getAccount, getAddress } from './utils/helpers';
import {
createNewAccount,
getAccount,
getAddress,
getAddressFromScriptPubKey,
} from './utils/helpers';
import RNFS from 'react-native-fs';

let logSubscription: EmitterSubscription | undefined;
Expand All @@ -41,6 +46,7 @@ const Dev = (): ReactElement => {
const [nodeStarted, setNodeStarted] = useState(false);
const [showLogs, setShowLogs] = useState(false);
const [logContent, setLogContent] = useState('');
const [temporaryChannelId, setTemporaryChannelId] = useState(''); //For funding channels locally

useEffect(() => {
//Restarting LDK on each code update causes constant errors.
Expand Down Expand Up @@ -231,7 +237,6 @@ const Dev = (): ReactElement => {
}
}}
/>

<Button
title={'Get Node ID'}
onPress={async (): Promise<void> => {
Expand All @@ -246,7 +251,6 @@ const Dev = (): ReactElement => {
setMessage(`Node ID: ${nodeIdRes.value}`);
}}
/>

<Button
title={'Sync LDK'}
onPress={async (): Promise<void> => {
Expand All @@ -258,7 +262,6 @@ const Dev = (): ReactElement => {
setMessage(syncRes.value);
}}
/>

<View style={styles.buttonRow}>
<Button
title={'Add Peers'}
Expand Down Expand Up @@ -299,7 +302,6 @@ const Dev = (): ReactElement => {
}}
/>
</View>

<View style={styles.buttonRow}>
<Button
title={'List channels'}
Expand Down Expand Up @@ -393,7 +395,6 @@ const Dev = (): ReactElement => {
}}
/>
</View>

<View style={styles.buttonRow}>
<Button
title={'List watch transactions'}
Expand All @@ -409,7 +410,6 @@ const Dev = (): ReactElement => {
}}
/>
</View>

<Button
title={'🤑Get Address Balance'}
onPress={async (): Promise<void> => {
Expand All @@ -421,7 +421,6 @@ const Dev = (): ReactElement => {
);
}}
/>

<Button
title={'Recover all outputs attempt'}
onPress={async (): Promise<void> => {
Expand All @@ -435,7 +434,6 @@ const Dev = (): ReactElement => {
setMessage(res.value);
}}
/>

<View style={styles.buttonRow}>
<Button
title={'Get claimed payments'}
Expand All @@ -454,7 +452,6 @@ const Dev = (): ReactElement => {
}}
/>
</View>

<View style={styles.buttonRow}>
<Button
title={'Create invoice'}
Expand Down Expand Up @@ -548,7 +545,6 @@ const Dev = (): ReactElement => {
}}
/>
</View>

<Button
title={'Get network graph nodes'}
onPress={async (): Promise<void> => {
Expand All @@ -574,7 +570,6 @@ const Dev = (): ReactElement => {
setMessage(`${msg}`);
}}
/>

<Button
title={'Show claimable balances for closed/closing channels'}
onPress={async (): Promise<void> => {
Expand All @@ -586,7 +581,6 @@ const Dev = (): ReactElement => {
setMessage(JSON.stringify(balances.value));
}}
/>

<Button
title={'List channel monitors'}
onPress={async (): Promise<void> => {
Expand All @@ -604,6 +598,79 @@ const Dev = (): ReactElement => {
}}
/>

<Button
title={'Start manual channel open ⛓️'}
onPress={async (): Promise<void> => {
try {
const res = await lm.createChannel({
counterPartyNodeId: peers.lnd.pubKey,
channelValueSats: 20000,
pushSats: 5000,
});
if (res.isErr()) {
setMessage(res.error.message);
return;
}

const { value_satoshis, output_script, temp_channel_id } =
res.value;

setTemporaryChannelId(temp_channel_id);

console.log(res.value);

const address = getAddressFromScriptPubKey(output_script);
const btc = value_satoshis / 100000000;

console.log('***BITCOIND CLI***');
console.log('bitcoin-cli listunspent');
console.log(
`bitcoin-cli createrawtransaction '[{"txid":"<tx-id>","vout":<index>}]' '{"${address}":${btc}}'`,
);
console.log(
'bitcoin-cli signrawtransactionwithwallet "<raw-transaction-hex>"',
);
console.log('********');

setMessage(
`Create tx with ${value_satoshis} for address ${address}. See logs for bitcoin-cli commands needed to create funding tx.`,
);
} catch (e) {
setMessage(JSON.stringify(e));
}
}}
/>

{temporaryChannelId ? (
<Button
title={'Fund channel (paste psbt)'}
onPress={async (): Promise<void> => {
try {
if (!temporaryChannelId) {
return setMessage('Create channel first');
}

const pastedSignedTx = await Clipboard.getString();

const res = await ldk.fundChannel({
temporaryChannelId,
counterPartyNodeId: peers.lnd.pubKey,
fundingTransaction: pastedSignedTx,
});
if (res.isErr()) {
setMessage(res.error.message);
return;
}

setMessage('Channel funded');
setTemporaryChannelId('');
} catch (e) {
setMessage(JSON.stringify(e));
}
}}
/>
) : null}

<Button
title={'Show version'}
onPress={async (): Promise<void> => {
Expand All @@ -615,7 +682,6 @@ const Dev = (): ReactElement => {
setMessage(ldkVersion.value.ldk);
}}
/>

<Button
title={'Show LDK logs'}
onPress={async (): Promise<void> => {
Expand All @@ -631,7 +697,6 @@ const Dev = (): ReactElement => {
}
}}
/>

<Button
title={'Restore backup from server'}
onPress={async (): Promise<void> => {
Expand All @@ -658,7 +723,6 @@ const Dev = (): ReactElement => {
setMessage('Successfully restored wallet');
}}
/>

<Button
title={'Backup self check'}
onPress={async (): Promise<void> => {
Expand All @@ -671,7 +735,6 @@ const Dev = (): ReactElement => {
setMessage('Backup server check passed ✅');
}}
/>

<Button
title={'Restart node'}
onPress={async (): Promise<void> => {
Expand Down Expand Up @@ -699,7 +762,6 @@ const Dev = (): ReactElement => {
setMessage(res.value);
}}
/>

<Button
title={'Node state'}
onPress={async (): Promise<void> => {
Expand All @@ -712,7 +774,6 @@ const Dev = (): ReactElement => {
setMessage(res.value);
}}
/>

<Button
title={'List backed up files'}
onPress={async (): Promise<void> => {
Expand All @@ -726,7 +787,6 @@ const Dev = (): ReactElement => {
setMessage(JSON.stringify(res.value));
}}
/>

<Button
title={'Test file backup'}
onPress={async (): Promise<void> => {
Expand Down
5 changes: 5 additions & 0 deletions example/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
['@babel/plugin-transform-class-properties', { loose: false }],
['@babel/plugin-proposal-private-methods', { loose: false }],
['@babel/plugin-transform-private-property-in-object', { loose: false }],
],
};
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ PODS:
- React-jsinspector (0.72.4)
- React-logger (0.72.4):
- glog
- react-native-ldk (0.0.148):
- react-native-ldk (0.0.150):
- React
- react-native-randombytes (3.6.1):
- React-Core
Expand Down Expand Up @@ -621,7 +621,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: c7f826e40fa9cab5d37cab6130b1af237332b594
React-jsinspector: aaed4cf551c4a1c98092436518c2d267b13a673f
React-logger: da1ebe05ae06eb6db4b162202faeafac4b435e77
react-native-ldk: fda4d4381d40401bdc5c3a9965937d19b232ed08
react-native-ldk: 2b19de9eb94dcfd46f3f2a7191502292b75a5d7a
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-tcp-socket: c1b7297619616b4c9caae6889bcb0aba78086989
React-NativeModulesApple: edb5ace14f73f4969df6e7b1f3e41bef0012740f
Expand Down
21 changes: 18 additions & 3 deletions example/metro.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const path = require('path');

/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const config = {};
const defaultConfig = getDefaultConfig(__dirname);

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
const config = {
resolver: {
extraNodeModules: {
stream: path.resolve(__dirname, 'node_modules/stream-browserify'),
buffer: path.resolve(__dirname, 'node_modules/buffer/'),
assert: path.resolve(__dirname, 'node_modules/assert/'),
events: path.resolve(__dirname, 'node_modules/events/'),
crypto: path.resolve(__dirname, 'node_modules/crypto-browserify/'),
vm: path.resolve(__dirname, 'node_modules/vm-browserify/'),
process: path.resolve(__dirname, 'node_modules/process/'),
},
},
};

module.exports = mergeConfig(defaultConfig, config);
Loading

0 comments on commit 3767cc7

Please sign in to comment.