Skip to content

Commit f3248a8

Browse files
authored
Merge pull request #1333 from synonymdev/ldk-account-v2
fix(lightning): LDK Account V2 Migration
2 parents 6b12837 + abdad5d commit f3248a8

File tree

20 files changed

+619
-46
lines changed

20 files changed

+619
-46
lines changed

src/screens/Lightning/Introduction.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { useBalance } from '../../hooks/wallet';
1212
import { isGeoBlockedSelector } from '../../store/reselect/user';
1313
import { TRANSACTION_DEFAULTS } from '../../utils/wallet/constants';
1414
import type { LightningScreenProps } from '../../navigation/types';
15+
import { lightningSelector } from '../../store/reselect/lightning';
16+
import { showToast } from '../../utils/notifications';
1517

1618
const imageSrc = require('../../assets/illustrations/lightning.png');
1719

@@ -21,6 +23,7 @@ const Introduction = ({
2123
const { t } = useTranslation('lightning');
2224
const { onchainBalance } = useBalance();
2325
const isGeoBlocked = useSelector(isGeoBlockedSelector);
26+
const lightning = useSelector(lightningSelector);
2427

2528
const txt = useMemo(
2629
() => t(isGeoBlocked ? 'int_blocked' : 'int_text'),
@@ -68,6 +71,14 @@ const Introduction = ({
6871
disabled={isDisabled}
6972
testID="QuickSetupButton"
7073
onPress={(): void => {
74+
if (lightning.accountVersion < 2) {
75+
showToast({
76+
type: 'error',
77+
title: t('migrating_ldk_title'),
78+
description: t('migrating_ldk_description'),
79+
});
80+
return;
81+
}
7182
navigation.navigate('QuickSetup');
7283
}}
7384
/>
@@ -80,6 +91,14 @@ const Introduction = ({
8091
disabled={isDisabled}
8192
testID="CustomSetupButton"
8293
onPress={(): void => {
94+
if (lightning.accountVersion < 2) {
95+
showToast({
96+
type: 'error',
97+
title: t('migrating_ldk_title'),
98+
description: t('migrating_ldk_description'),
99+
});
100+
return;
101+
}
83102
navigation.navigate('CustomSetup', { spending: true });
84103
}}
85104
/>

src/screens/Settings/DevSettings/index.tsx

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ import {
1414
} from '../../../store/actions/wallet';
1515
import { resetUserStore } from '../../../store/actions/user';
1616
import { resetActivityStore } from '../../../store/actions/activity';
17-
import { resetLightningStore } from '../../../store/actions/lightning';
17+
import {
18+
resetLightningStore,
19+
updateLdkAccountVersion,
20+
updateLightningNodeId,
21+
} from '../../../store/actions/lightning';
1822
import { resetBlocktankStore } from '../../../store/actions/blocktank';
1923
import { resetSlashtagsStore } from '../../../store/actions/slashtags';
2024
import { resetWidgetsStore } from '../../../store/actions/widgets';
@@ -35,6 +39,12 @@ import { refreshWallet } from '../../../utils/wallet';
3539
import { runChecks } from '../../../utils/wallet/checks';
3640
import { getFakeTransaction } from '../../../utils/wallet/testing';
3741
import type { SettingsScreenProps } from '../../../navigation/types';
42+
import { lightningSelector } from '../../../store/reselect/lightning';
43+
import {
44+
createDefaultLdkAccount,
45+
getNodeId,
46+
setupLdk,
47+
} from '../../../utils/lightning';
3848

3949
const DevSettings = ({
4050
navigation,
@@ -44,6 +54,7 @@ const DevSettings = ({
4454
const selectedWallet = useSelector(selectedWalletSelector);
4555
const selectedNetwork = useSelector(selectedNetworkSelector);
4656
const addressType = useSelector(addressTypeSelector);
57+
const lightning = useSelector(lightningSelector);
4758
const warnings = useSelector((state) => {
4859
return warningsSelector(state, selectedWallet, selectedNetwork);
4960
});
@@ -181,6 +192,69 @@ const DevSettings = ({
181192
},
182193
],
183194
},
195+
{
196+
title: 'LDK Account Migration',
197+
data: [
198+
{
199+
title: `LDK Account Version: ${lightning.accountVersion}`,
200+
type: EItemType.textButton,
201+
value: '',
202+
testID: 'LDKAccountVersion',
203+
},
204+
{
205+
title: 'Force LDK V2 Account Migration',
206+
type: EItemType.button,
207+
onPress: async (): Promise<void> => {
208+
updateLdkAccountVersion(2);
209+
await createDefaultLdkAccount({
210+
version: 2,
211+
selectedWallet,
212+
selectedNetwork,
213+
});
214+
await setupLdk({
215+
selectedWallet,
216+
selectedNetwork,
217+
shouldRefreshLdk: true,
218+
});
219+
const newNodeId = await getNodeId();
220+
if (newNodeId.isOk()) {
221+
updateLightningNodeId({
222+
nodeId: newNodeId.value,
223+
selectedWallet,
224+
selectedNetwork,
225+
});
226+
}
227+
},
228+
testID: 'ForceV2Migration',
229+
},
230+
{
231+
title: 'Revert to LDK V1 Account',
232+
type: EItemType.button,
233+
onPress: async (): Promise<void> => {
234+
updateLdkAccountVersion(1);
235+
await createDefaultLdkAccount({
236+
version: 1,
237+
selectedWallet,
238+
selectedNetwork,
239+
});
240+
await setupLdk({
241+
selectedWallet,
242+
selectedNetwork,
243+
shouldRefreshLdk: true,
244+
});
245+
const newNodeId = await getNodeId();
246+
if (newNodeId.isOk()) {
247+
updateLightningNodeId({
248+
nodeId: newNodeId.value,
249+
selectedWallet,
250+
selectedNetwork,
251+
});
252+
}
253+
},
254+
testID: 'RevertToLDKV1',
255+
},
256+
],
257+
},
184258
{
185259
title: 'App Cache',
186260
data: [

src/screens/Settings/Lightning/Channels.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import {
5757
} from '../../../store/reselect/wallet';
5858
import {
5959
closedChannelsSelector,
60+
lightningSelector,
6061
openChannelsSelector,
6162
pendingChannelsSelector,
6263
} from '../../../store/reselect/lightning';
@@ -236,6 +237,7 @@ const Channels = ({
236237
const selectedWallet = useSelector(selectedWalletSelector);
237238
const selectedNetwork = useSelector(selectedNetworkSelector);
238239
const enableDevOptions = useSelector(enableDevOptionsSelector);
240+
const lightning = useSelector(lightningSelector);
239241

240242
const blocktankOrders = useSelector(blocktankOrdersSelector);
241243
const paidOrders = useSelector(blocktankPaidOrdersSelector);
@@ -254,14 +256,22 @@ const Channels = ({
254256
const pendingConnections = [...pendingOrders, ...pendingChannels];
255257

256258
const handleAdd = useCallback((): void => {
259+
if (lightning.accountVersion < 2) {
260+
showToast({
261+
type: 'error',
262+
title: t('migrating_ldk_title'),
263+
description: t('migrating_ldk_description'),
264+
});
265+
return;
266+
}
257267
navigation.navigate('LightningRoot', {
258268
screen: 'CustomSetup',
259269
params: { spending: true },
260270
});
261271

262272
// TODO: Update this view once we enable creating channels with nodes other than Blocktank.
263273
// navigation.navigate('LightningAddConnection');
264-
}, [navigation]);
274+
}, [lightning.accountVersion, navigation, t]);
265275

266276
const handleExportLogs = useCallback(async (): Promise<void> => {
267277
const result = await zipLogs({ includeJson: enableDevOptions });

src/screens/Wallets/Receive/ReceiveDetails.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import { DEFAULT_CHANNEL_DURATION } from '../../Lightning/CustomConfirm';
4545
import { blocktankInfoSelector } from '../../../store/reselect/blocktank';
4646
import { isGeoBlockedSelector } from '../../../store/reselect/user';
4747
import { useLightningBalance } from '../../../hooks/lightning';
48+
import { lightningSelector } from '../../../store/reselect/lightning';
4849

4950
const imageSrc = require('../../../assets/illustrations/coin-stack-4.png');
5051

@@ -67,6 +68,7 @@ const ReceiveDetails = ({
6768
const blocktank = useSelector(blocktankInfoSelector);
6869
const lightningBalance = useLightningBalance(false);
6970
const isGeoBlocked = useSelector(isGeoBlockedSelector);
71+
const lightning = useSelector(lightningSelector);
7072

7173
const { maxChannelSizeSat } = blocktank.options;
7274

@@ -82,7 +84,8 @@ const ReceiveDetails = ({
8284
if (
8385
!enableInstant ||
8486
isGeoBlocked ||
85-
lightningBalance.remoteBalance >= invoice.amount
87+
lightningBalance.remoteBalance >= invoice.amount ||
88+
lightning.accountVersion < 2
8689
) {
8790
return;
8891
}
@@ -113,6 +116,7 @@ const ReceiveDetails = ({
113116
invoice.amount,
114117
invoice.message,
115118
isGeoBlocked,
119+
lightning.accountVersion,
116120
lightningBalance.remoteBalance,
117121
navigation,
118122
]);

src/screens/Wallets/Receive/ReceiveQR.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import {
6161
import { receiveSelector } from '../../../store/reselect/receive';
6262
import { ReceiveScreenProps } from '../../../navigation/types';
6363
import { isGeoBlockedSelector } from '../../../store/reselect/user';
64+
import { lightningSelector } from '../../../store/reselect/lightning';
6465

6566
type Slide = () => ReactElement;
6667

@@ -83,6 +84,7 @@ const ReceiveQR = ({
8384
const selectedNetwork = useSelector(selectedNetworkSelector);
8485
const addressType = useSelector(addressTypeSelector);
8586
const isGeoBlocked = useSelector(isGeoBlockedSelector);
87+
const lightning = useSelector(lightningSelector);
8688
const { id, amount, message, tags, jitOrder } = useSelector(receiveSelector);
8789
const lightningBalance = useLightningBalance(false);
8890
const receiveNavigationIsOpen = useSelector((state) =>
@@ -110,7 +112,8 @@ const ReceiveQR = ({
110112
if (
111113
!receiveNavigationIsOpen ||
112114
!lightningBalance.remoteBalance ||
113-
lightningBalance.remoteBalance < amount
115+
lightningBalance.remoteBalance < amount ||
116+
lightning.accountVersion < 2
114117
) {
115118
return;
116119
}
@@ -310,8 +313,11 @@ const ReceiveQR = ({
310313
const qrSize = Math.min(qrMaxWidth, qrMaxHeight);
311314

312315
const displayReceiveInstantlySwitch = useMemo((): boolean => {
316+
if (lightning.accountVersion < 2) {
317+
return false;
318+
}
313319
return !(isGeoBlocked && !lightningBalance.remoteBalance);
314-
}, [isGeoBlocked, lightningBalance.remoteBalance]);
320+
}, [isGeoBlocked, lightning.accountVersion, lightningBalance.remoteBalance]);
315321

316322
const QrIcon = useCallback((): ReactElement => {
317323
return (

src/screens/Wallets/WalletsDetail/BitcoinBreakdown.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ import { TransferIcon, SavingsIcon, CoinsIcon } from '../../../styles/icons';
99
import { useBalance } from '../../../hooks/wallet';
1010
import { RootNavigationProp } from '../../../navigation/types';
1111
import { isGeoBlockedSelector } from '../../../store/reselect/user';
12+
import { lightningSelector } from '../../../store/reselect/lightning';
13+
import { showToast } from '../../../utils/notifications';
1214
import { openChannelIdsSelector } from '../../../store/reselect/lightning';
1315
import NetworkRow from './NetworkRow';
1416

1517
const BitcoinBreakdown = (): ReactElement => {
1618
const { t } = useTranslation('wallet');
1719
const navigation = useNavigation<RootNavigationProp>();
1820
const isGeoBlocked = useSelector(isGeoBlockedSelector);
21+
const lightning = useSelector(lightningSelector);
1922
const openChannelIds = useSelector(openChannelIdsSelector);
2023
const {
2124
onchainBalance,
@@ -28,6 +31,14 @@ const BitcoinBreakdown = (): ReactElement => {
2831
const isTransferToSavings = openChannelIds.length === 0;
2932

3033
const onRebalancePress = (): void => {
34+
if (lightning.accountVersion < 2) {
35+
showToast({
36+
type: 'error',
37+
title: t('migrating_ldk_title'),
38+
description: t('migrating_ldk_description'),
39+
});
40+
return;
41+
}
3142
if (lightningBalance && !isGeoBlocked) {
3243
navigation.navigate('Transfer', { screen: 'Setup' });
3344
} else {

src/store/actions/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const actions = {
6060
REMOVE_LIGHTNING_PEER: 'REMOVE_LIGHTNING_PEER',
6161
UPDATE_CLAIMABLE_BALANCE: 'UPDATE_CLAIMABLE_BALANCE',
6262
RESET_LIGHTNING_STORE: 'RESET_LIGHTNING_STORE',
63+
UPDATE_LDK_ACCOUNT_VERSION: 'UPDATE_LDK_ACCOUNT_VERSION',
6364

6465
// Activity
6566
UPDATE_ACTIVITY_ITEMS: 'UPDATE_ACTIVITY_ITEMS',

src/store/actions/backup.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import {
1212
import { bytesToString, stringToBytes } from '../../utils/converters';
1313
import { Slashtag } from '../../hooks/slashtags';
1414
import {
15+
checkAccountVersion,
1516
exportBackup,
16-
getAccount,
17+
getLdkAccount,
1718
setAccount,
1819
setLdkStoragePath,
1920
} from '../../utils/lightning';
@@ -197,7 +198,8 @@ export const performLdkRestore = async ({
197198
return err(storageRes.error);
198199
}
199200

200-
const lightningAccount = await getAccount({ selectedNetwork });
201+
const version = await checkAccountVersion();
202+
const lightningAccount = await getLdkAccount({ selectedNetwork, version });
201203
if (lightningAccount.isErr()) {
202204
return err(lightningAccount.error);
203205
}

src/store/actions/lightning.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
} from '../../utils/lightning';
2424
import {
2525
TCreateLightningInvoice,
26+
TLdkAccountVersions,
2627
TLightningNodeVersion,
2728
} from '../types/lightning';
2829
import { EPaymentType, TWalletName } from '../types/wallet';
@@ -437,3 +438,15 @@ export const moveMetaIncPaymentTags = (invoice: TInvoice): Result<string> => {
437438

438439
return ok('Metadata tags resynced with transactions.');
439440
};
441+
442+
export const updateLdkAccountVersion = (
443+
accountVersion: TLdkAccountVersions,
444+
): TLdkAccountVersions => {
445+
dispatch({
446+
type: actions.UPDATE_LDK_ACCOUNT_VERSION,
447+
payload: {
448+
accountVersion,
449+
},
450+
});
451+
return accountVersion;
452+
};

src/store/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const persistConfig = {
3737
key: 'root',
3838
storage: mmkvStorage,
3939
// increase version after store shape changes
40-
version: 26,
40+
version: 27,
4141
stateReconciler: autoMergeLevel2,
4242
blacklist: ['receive', 'ui'],
4343
migrate: createMigrate(migrations, { debug: __ENABLE_MIGRATION_DEBUG__ }),

src/store/migrations/index.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,15 @@ const migrations = {
232232
};
233233
},
234234
24: (state): PersistedState => {
235+
return {
236+
...state,
237+
lightning: {
238+
...state.lightning,
239+
accountVersion: 1,
240+
},
241+
};
242+
},
243+
25: (state): PersistedState => {
235244
return {
236245
...state,
237246
settings: {
@@ -240,7 +249,7 @@ const migrations = {
240249
},
241250
};
242251
},
243-
25: (state): PersistedState => {
252+
26: (state): PersistedState => {
244253
return {
245254
...state,
246255
blocktank: {
@@ -249,7 +258,7 @@ const migrations = {
249258
},
250259
};
251260
},
252-
26: (state): PersistedState => {
261+
27: (state): PersistedState => {
253262
return {
254263
...state,
255264
settings: {

0 commit comments

Comments
 (0)