Skip to content

Commit 2e843c2

Browse files
committed
Merge branch 'master' into e2e-tests
2 parents 31d3e29 + 17c0e74 commit 2e843c2

27 files changed

+3703
-1892
lines changed

README.md

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,86 @@ yarn ios
3434
yarn android
3535
```
3636

37-
## Usage
38-
```javascript
39-
import ldk from '@synonymdev/react-native-ldk';
40-
```
37+
## Example Setup & Usage
4138

39+
To run the following example:
40+
1. Install & Run [Polar](https://github.com/jamaljsr/polar)
41+
2. Create a network and replace the `USER`, `PASS` & `HOST` variables with the correct info provided under the "Connect" tab for your Bitcoin instance in Polar.
42+
3. See [Notes](#notes) for additional instructions.
43+
4244
```javascript
43-
const res = await ldk.start();
44-
if (res.isErr()) {
45-
//LDK failed to start
46-
console.error(res.error)
45+
import lm, { ENetworks } from '@synonymdev/react-native-ldk';
46+
import AsyncStorage from '@react-native-async-storage/async-storage';
47+
import { encode as btoa } from 'js-base64';
48+
49+
const USER = 'polaruser';
50+
const PASS = 'polarpass';
51+
const HOST = 'http://127.0.0.1:18443/';
52+
53+
const bitcoinRPC = async (method, params) => {
54+
const data = { jsonrpc: '1.0', id: 'todo', method, params };
55+
const res = await fetch(HOST, {
56+
method: 'POST',
57+
headers: {
58+
Accept: 'application/json',
59+
'Content-Type': 'application/json',
60+
Authorization: `Basic ${btoa(`${USER}:${PASS}`)}`,
61+
},
62+
body: JSON.stringify(data),
63+
});
64+
const json = await res.json();
65+
if (json.error) {
66+
throw new Error(json.error);
67+
}
68+
return json.result;
69+
};
70+
71+
export const getBlockHeaderHexFromHash = async (hash) => await bitcoinRPC('getblockheader', [hash, false]);
72+
export const getBlockHeaderHashFromHeight = async (height) => await bitcoinRPC('getblockhash', [height]);
73+
export const getBlockHeight = async () => {
74+
const { blocks } = await bitcoinRPC('getblockchaininfo', []);
75+
return Number(blocks);
76+
};
77+
const getTxData = async (txid) => await bitcoinRPC('getrawtransaction', [txid, true]);
78+
79+
const seed = 'd88a2f0ab4aefd38d22a96ac556cafa419aed5e2782b6e7c816e4777a6bfbd56';
80+
const network = ENetworks.testnet;
81+
const genesisHash = await getBlockHeaderHashFromHeight(0);
82+
const setItem = async (key, value) => await AsyncStorage.setItem(key, value);
83+
const getItem = async (key) => await AsyncStorage.getItem(key);
84+
const getBestBlock = async () => {
85+
const height = await getBlockHeight();
86+
const hash = await getBlockHeaderHashFromHeight(height);
87+
const hex = await getBlockHeaderHexFromHash(hash);
88+
return { height, hash, hex };
89+
};
90+
const getTransactionData = async (txid) => {
91+
const txData = await getTxData(txid);
92+
const currentBlockHeight = await getBlockHeight();
93+
const height = txData.confirmations ? currentBlockHeight - txData.confirmations : 0;
94+
const header = txData.blockhash ? await getBlockHeaderHexFromHash(txData.blockhash) : '';
95+
const transaction = txData.hex;
96+
return { header, height, transaction };
97+
};
98+
99+
const startResponse = await lm.start({
100+
seed,
101+
network,
102+
genesisHash,
103+
getItem,
104+
setItem,
105+
getBestBlock,
106+
getTransactionData,
107+
});
108+
if (startResponse.isErr()) {
109+
//LDK failed to start
110+
console.error(startResponse.error);
111+
return;
112+
} else {
113+
// Sync when new blocks are detected.
114+
setInterval(async () => {
115+
await lm.syncLdk();
116+
}, 5000);
47117
}
48118

49119
//Subscribe to LDK logs
@@ -53,5 +123,4 @@ const logListener = ldk.addLogListener((message) => {
53123

54124
//Unsubscribe if listening component is unmounted
55125
ldk.removeLogListener(logListener);
56-
57126
```

example/.eslintrc.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,69 @@ module.exports = {
55
env: {
66
jest: true,
77
},
8+
plugins: ['@typescript-eslint'],
9+
globals: {
10+
localStorage: false,
11+
},
12+
rules: {
13+
semi: 'off',
14+
'@typescript-eslint/semi': ['error'],
15+
'no-shadow': 'off',
16+
'@typescript-eslint/no-shadow': 'error',
17+
'@typescript-eslint/no-unused-vars': 'error',
18+
'react-hooks/rules-of-hooks': 'error',
19+
'react-hooks/exhaustive-deps': 'warn',
20+
'no-console': 0,
21+
'no-empty': ['error', { allowEmptyCatch: true }],
22+
'no-buffer-constructor': 0,
23+
'no-case-declarations': 0,
24+
'no-useless-escape': 0,
25+
'react/jsx-no-duplicate-props': [2, { ignoreCase: true }],
26+
'react-native/no-unused-styles': 1,
27+
'react-native/no-raw-text': 0,
28+
'react/jsx-equals-spacing': [2, 'never'],
29+
'react/no-unsafe': [2, { checkAliases: true }],
30+
'react/jsx-curly-spacing': [
31+
2,
32+
{
33+
when: 'never',
34+
attributes: { allowMultiline: true },
35+
children: true,
36+
},
37+
],
38+
indent: [
39+
2,
40+
'tab',
41+
{ SwitchCase: 1, ignoredNodes: ['ConditionalExpression'] },
42+
],
43+
'object-curly-spacing': [
44+
'error',
45+
'always',
46+
{
47+
objectsInObjects: true,
48+
},
49+
],
50+
'react/jsx-uses-vars': 2,
51+
'react/jsx-wrap-multilines': 2,
52+
'react/jsx-tag-spacing': [
53+
2,
54+
{
55+
closingSlash: 'never',
56+
beforeSelfClosing: 'always',
57+
afterOpening: 'never',
58+
beforeClosing: 'never',
59+
},
60+
],
61+
'react/jsx-indent': [2, 'tab', { indentLogicalExpressions: false }],
62+
'react/jsx-child-element-spacing': 2,
63+
'react/no-unused-prop-types': 2,
64+
'react/prop-types': 0,
65+
'no-undef': 0,
66+
'react/display-name': 0,
67+
'require-atomic-updates': 0,
68+
'no-async-promise-executor': 0,
69+
'brace-style': [2, '1tbs', { allowSingleLine: true }],
70+
'@typescript-eslint/explicit-function-return-type': 'warn',
71+
'jest/no-disabled-tests': 0,
72+
},
873
};

0 commit comments

Comments
 (0)