Skip to content

Commit

Permalink
Merge pull request #190 from synonymdev/scorer-download
Browse files Browse the repository at this point in the history
feat: pre-populated scorer download
  • Loading branch information
Jasonvdb authored Nov 14, 2023
2 parents 5ae3b9a + 330530e commit b65af23
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 319 deletions.
74 changes: 2 additions & 72 deletions example/Dev.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,7 @@ import {
View,
} from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import {
backupAccount,
getAddressBalance,
importAccount,
setupLdk,
syncLdk,
updateHeader,
} from './ldk';
import { getAddressBalance, setupLdk, syncLdk, updateHeader } from './ldk';
import { connectToElectrum, subscribeToHeader } from './electrum';
import ldk from '@synonymdev/react-native-ldk/dist/ldk';
import lm, {
Expand All @@ -31,20 +24,14 @@ import lm, {
TChannelUpdate,
} from '@synonymdev/react-native-ldk';
import { backupServerDetails, peers } from './utils/constants';
import {
createNewAccount,
getAccount,
getAddress,
simulateStaleRestore,
} from './utils/helpers';
import { createNewAccount, getAccount, getAddress } from './utils/helpers';
import RNFS from 'react-native-fs';

let logSubscription: EmitterSubscription | undefined;
let paymentSubscription: EmitterSubscription | undefined;
let onChannelSubscription: EmitterSubscription | undefined;
let paymentFailedSubscription: EmitterSubscription | undefined;
let paymentPathSuccess: EmitterSubscription | undefined;
let backupSubscriptionId: string | undefined;

const Dev = (): ReactElement => {
const [message, setMessage] = useState('...');
Expand Down Expand Up @@ -144,25 +131,12 @@ const Dev = (): ReactElement => {
);
}

if (!backupSubscriptionId) {
backupSubscriptionId = lm.subscribeToBackups((backupRes) => {
if (backupRes.isErr()) {
return alert('Backup required but failed to export account');
}

console.log(
`Backup updated for account ${backupRes.value.account.name}`,
);
});
}

return (): void => {
logSubscription && logSubscription.remove();
paymentSubscription && paymentSubscription.remove();
paymentFailedSubscription && paymentFailedSubscription.remove();
paymentPathSuccess && paymentPathSuccess.remove();
onChannelSubscription && onChannelSubscription.remove();
backupSubscriptionId && lm.unsubscribeFromBackups(backupSubscriptionId);
};
}, []);

Expand Down Expand Up @@ -589,50 +563,6 @@ const Dev = (): ReactElement => {
}}
/>

<Button
title={'Backup Current Account'}
onPress={async (): Promise<void> => {
const backupResponse = await backupAccount();
if (backupResponse.isErr()) {
setMessage(backupResponse.error.message);
return;
}
console.log(backupResponse.value);
Clipboard.setString(JSON.stringify(backupResponse.value));
setMessage(
`Backup of the following account copied to clipboard:\n${JSON.stringify(
backupResponse.value.account,
)}`,
);
}}
/>
<Button
title={'Import Account From Clipboard'}
onPress={async (): Promise<void> => {
setMessage('Importing Account...');
const clipboardBackup = await Clipboard.getString();
const importResponse = await importAccount(clipboardBackup);
if (importResponse.isErr()) {
setMessage(importResponse.error.message);
return;
}
const accountData = JSON.stringify(importResponse.value);
setMessage(
`Successfully imported the following account: ${accountData}`,
);
}}
/>
<Button
title={'Simulate stale backup restore'}
onPress={async (): Promise<void> => {
try {
await simulateStaleRestore((msg) => setMessage(msg));
} catch (e) {
setMessage(e.message);
return;
}
}}
/>
<Button
title={'Restore backup from server'}
onPress={async (): Promise<void> => {
Expand Down
43 changes: 0 additions & 43 deletions example/ldk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import {
import lm, {
DefaultTransactionDataShape,
defaultUserConfig,
TAccount,
TAccountBackup,
THeader,
TTransactionData,
TTransactionPosition,
Expand All @@ -28,9 +26,7 @@ import {
getAddress,
getNetwork,
ldkNetwork,
setAccount,
} from '../utils/helpers';
import { EAccount } from '../utils/types';
import * as bitcoin from 'bitcoinjs-lib';

/**
Expand Down Expand Up @@ -324,42 +320,3 @@ export const broadcastTransaction = async (rawTx: string): Promise<string> => {
return '';
}
};

/**
* Used to backup a given account.
* @param {TAccount} [account]
* @returns {Promise<Result<string>>}
*/
export const backupAccount = async (
account?: TAccount,
): Promise<Result<TAccountBackup>> => {
if (!account) {
account = await getAccount();
}
return await lm.backupAccount({
account,
});
};

/**
* Used to import an account using the backup JSON string or TAccountBackup object.
* @param {string | TAccountBackup} backup
* @returns {Promise<Result<TAccount>>}
*/
export const importAccount = async (
backup: string | TAccountBackup,
forceCloseAllChannels = false,
): Promise<Result<TAccount>> => {
const importResponse = await lm.importAccount({
backup,
overwrite: true,
});
if (importResponse.isErr()) {
return err(importResponse.error.message);
}
await setAccount(importResponse.value);
await setItem(EAccount.currentAccountKey, importResponse.value.name);
await setupLdk(forceCloseAllChannels);
await syncLdk();
return ok(importResponse.value);
};
20 changes: 18 additions & 2 deletions example/tests/lnd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,15 @@ describe('LND', function () {
// - force close channel from LDK
// - check everything is ok

let fees = { highPriority: 3, normal: 2, background: 1, mempoolMinimum: 1 };
let fees = {
nonAnchorChannelFee: 5,
anchorChannelFee: 5,
maxAllowedNonAnchorChannelRemoteFee: 5,
channelCloseMinimum: 5,
minAllowedAnchorChannelRemoteFee: 5,
minAllowedNonAnchorChannelRemoteFee: 5,
onChainSweep: 5,
};

const lmStart = await lm.start({
...profile.getStartParams(),
Expand Down Expand Up @@ -656,7 +664,15 @@ describe('LND', function () {
);

// set height fees and restart LDK so it catches up
fees = { highPriority: 30, normal: 20, background: 10, mempoolMinimum: 1 };
fees = {
nonAnchorChannelFee: 30,
anchorChannelFee: 30,
maxAllowedNonAnchorChannelRemoteFee: 30,
channelCloseMinimum: 5,
minAllowedAnchorChannelRemoteFee: 5,
minAllowedNonAnchorChannelRemoteFee: 5,
onChainSweep: 30,
};
const syncRes0 = await lm.syncLdk();
await lm.setFees();
if (syncRes0.isErr()) {
Expand Down
11 changes: 7 additions & 4 deletions example/tests/unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,13 @@ describe('Unit', function () {
getScriptPubKeyHistory: async () => [],
getFees: () => {
return Promise.resolve({
highPriority: 10,
normal: 5,
background: 2,
mempoolMinimum: 1,
nonAnchorChannelFee: 5,
anchorChannelFee: 5,
maxAllowedNonAnchorChannelRemoteFee: 5,
channelCloseMinimum: 5,
minAllowedAnchorChannelRemoteFee: 5,
minAllowedNonAnchorChannelRemoteFee: 5,
onChainSweep: 5,
});
},
getTransactionData: async () => ({
Expand Down
85 changes: 2 additions & 83 deletions example/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import Keychain from 'react-native-keychain';
import {
EEventTypes,
TAccount,
TAvailableNetworks,
} from '@synonymdev/react-native-ldk';
import { backupAccount, getItem, importAccount, setItem } from '../ldk';
import { TAccount, TAvailableNetworks } from '@synonymdev/react-native-ldk';
import { getItem, setItem } from '../ldk';
import { EAccount } from './types';
import { err, ok, Result } from './result';
import { randomBytes } from 'react-native-randombytes';
Expand All @@ -15,8 +11,6 @@ import * as bip32 from 'bip32';
import * as bip39 from 'bip39';
import { ENetworks } from '@synonymdev/react-native-ldk/dist/utils/types';
import networks from '@synonymdev/react-native-ldk/dist/utils/networks';
import ldk from '@synonymdev/react-native-ldk/dist/ldk';
import Clipboard from '@react-native-clipboard/clipboard';

/**
* Use Keychain to save LDK name & seed.
Expand Down Expand Up @@ -216,78 +210,3 @@ export const ldkNetwork = (network: TAvailableNetworks): ENetworks => {
return ENetworks.signet;
}
};

export const simulateStaleRestore = async (
onUpdate: (string) => void,
): Promise<void> => {
const channels = await ldk.listChannels();
if (channels.isErr()) {
throw channels.error;
}
if (channels.value.filter((c) => c.is_usable).length === 0) {
throw new Error('No usable channels. Open a channel first.');
}

onUpdate('Backing up...');
const backupResponse = await backupAccount();
if (backupResponse.isErr()) {
throw backupResponse.error;
}

const timeoutSeconds = 30;
const invoice = await ldk.createPaymentRequest({
amountSats: 12,
description: 'crash test',
expiryDeltaSeconds: timeoutSeconds,
});
if (invoice.isErr()) {
throw invoice.error;
}

let paymentClaimed = false;
let paymentSubscription = ldk.onEvent(
EEventTypes.channel_manager_payment_claimed,
() => (paymentClaimed = true),
);

Clipboard.setString(invoice.value.to_str);

//Keep checking if we got the payment
for (let i = 0; i < timeoutSeconds; i++) {
onUpdate(
`Please pay invoice in clipboard to continue (${timeoutSeconds - i})...`,
);

if (paymentClaimed) {
onUpdate('Payment claimed! Testing stale restore...');
break;
}

await new Promise((resolve) => setTimeout(resolve, 1000));
}

paymentSubscription.remove();

if (!paymentClaimed) {
throw new Error('No payment claimed. Timeout out.');
}

onUpdate('Importing stale backup and force closing all channels...');

await new Promise((resolve) => setTimeout(resolve, 2500));

await ldk.stop();
const forceCloseAllChannels = true; //To test the crash restore set to false
const importResponse = await importAccount(
backupResponse.value,
forceCloseAllChannels,
);
if (importResponse.isErr()) {
throw importResponse.error;
}

await new Promise((resolve) => setTimeout(resolve, 2500));
onUpdate(
"If this didn't crash and you can see your claimable balance, you're good!",
);
};
Loading

0 comments on commit b65af23

Please sign in to comment.