Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions e2e/lnurl.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ d('LNURL', () => {
.toBeVisible()
.withTimeout(10000);
await element(by.id('Close')).tap();
// check if comment is displayed
await element(by.id('WalletsScrollView')).scrollTo('bottom', NaN, 0.85);
await element(by.id('ActivityShort-1')).tap();
await expect(element(by.id('InvoiceComment'))).toHaveText('test comment');
await element(by.id('NavigationClose')).tap();

// test lnurl-pay, with min == max amount, no comment
const payRequest2 = await lnurl.generateNewUrl('payRequest', {
Expand Down
34 changes: 31 additions & 3 deletions src/screens/Activity/ActivityDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ import {
} from '../../store/slices/metadata';
import { getTransactions } from '../../utils/wallet/electrum';
import { ITransaction, ITxHash } from '../../utils/wallet';
import { ellipsis, getDurationForBlocks, openURL } from '../../utils/helpers';
import {
ellipsis,
getDurationForBlocks,
openURL,
vibrate,
} from '../../utils/helpers';
import { getBoostedTransactionParents } from '../../utils/boost';
import { showToast } from '../../utils/notifications';
import {
Expand All @@ -81,6 +86,7 @@ import {
transferSelector,
} from '../../store/reselect/wallet';
import {
commentSelector,
slashTagsUrlSelector,
tagSelector,
} from '../../store/reselect/metadata';
Expand Down Expand Up @@ -684,6 +690,7 @@ const LightningActivityDetail = ({

const dispatch = useAppDispatch();
const tags = useAppSelector((state) => tagSelector(state, id));
const comment = useAppSelector((state) => commentSelector(state, id));
const slashTagsUrl = useAppSelector((state) => {
return slashTagsUrlSelector(state, id);
});
Expand Down Expand Up @@ -717,6 +724,7 @@ const LightningActivityDetail = ({

const onCopy = (text: string): void => {
Clipboard.setString(text);
vibrate();
showToast({
type: 'success',
title: t('copied'),
Expand Down Expand Up @@ -910,7 +918,9 @@ const LightningActivityDetail = ({
)}

{message ? (
<View style={styles.invoiceNote}>
<TouchableOpacity
style={styles.invoiceNote}
onPress={(): void => onCopy(message)}>
<Caption13Up style={styles.sText} color="secondary">
{t('activity_invoice_note')}
</Caption13Up>
Expand All @@ -922,7 +932,25 @@ const LightningActivityDetail = ({
<Title testID="InvoiceNote">{message}</Title>
</View>
</ThemedView>
</View>
</TouchableOpacity>
) : null}

{comment ? (
<TouchableOpacity
style={styles.invoiceNote}
onPress={(): void => onCopy(comment)}>
<Caption13Up style={styles.sText} color="secondary">
{t('activity_invoice_comment')}
</Caption13Up>
<ThemedView color="white10">
<Canvas style={styles.zRoot}>
<ZigZag color={colors.background} />
</Canvas>
<View style={styles.note}>
<Title testID="InvoiceComment">{comment}</Title>
</View>
</ThemedView>
</TouchableOpacity>
) : null}

<View>
Expand Down
10 changes: 10 additions & 0 deletions src/screens/Wallets/LNURLPay/Confirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
settingsSelector,
} from '../../../store/reselect/settings';
import { addPendingPayment } from '../../../store/slices/lightning';
import { updateMetaTxComment } from '../../../store/slices/metadata';
import { EActivityType } from '../../../store/types/activity';
import { AnimatedView, BottomSheetTextInput } from '../../../styles/components';
import { Checkmark, LightningHollow } from '../../../styles/icons';
Expand Down Expand Up @@ -111,6 +112,15 @@ const LNURLConfirm = ({

setIsLoading(false);

if (comment) {
dispatch(
updateMetaTxComment({
txId: decodedInvoice.payment_hash,
comment,
}),
);
}

if (payInvoiceResponse.isErr()) {
const errorMessage = payInvoiceResponse.error.message;
if (errorMessage === 'Timed Out.') {
Expand Down
2 changes: 1 addition & 1 deletion src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const persistConfig = {
key: 'root',
storage: reduxStorage,
// increase version after store shape changes
version: 46,
version: 47,
stateReconciler: autoMergeLevel2,
blacklist: ['receive', 'ui'],
migrate: createMigrate(migrations, { debug: __ENABLE_MIGRATION_DEBUG__ }),
Expand Down
9 changes: 9 additions & 0 deletions src/store/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ const migrations = {
},
};
},
47: (state): PersistedState => {
return {
...state,
metadata: {
...state.metadata,
comments: {},
},
};
},
};

export default migrations;
4 changes: 4 additions & 0 deletions src/store/reselect/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ export const slashTagsUrlSelector = createSelector(
return metadata.slashTagsUrls[id];
},
);
export const commentSelector = createSelector(
[metadataState, (_state, txId: string): string => txId],
(metadata, txId): string => metadata.comments[txId] ?? '',
);
12 changes: 12 additions & 0 deletions src/store/slices/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const initialMetadataState: TMetadataState = {
lastUsedTags: [],
pendingInvoices: [],
slashTagsUrls: {},
comments: {},
};

export const metadataSlice = createSlice({
Expand All @@ -26,6 +27,16 @@ export const metadataSlice = createSlice({
state.tags[action.payload.txId] = action.payload.tags;
}
},
updateMetaTxComment: (
state,
action: PayloadAction<{ txId: string; comment: string }>,
) => {
if (action.payload.comment.length === 0) {
delete state.comments[action.payload.txId];
} else {
state.comments[action.payload.txId] = action.payload.comment;
}
},
addMetaTxTag: (
state,
action: PayloadAction<{ txId: string; tag: string }>,
Expand Down Expand Up @@ -120,6 +131,7 @@ const { actions, reducer } = metadataSlice;
export const {
updateMetadata,
updateMetaTxTags,
updateMetaTxComment,
addMetaTxTag,
deleteMetaTxTag,
updatePendingInvoice,
Expand Down
2 changes: 2 additions & 0 deletions src/store/types/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type TTags = { [txId: string]: string[] };
export type TLastUsedTags = string[];
export type TSlashTagsUrls = { [txId: string]: string | undefined };
export type TTxComments = { [txId: string]: string };

export type TPendingInvoice = {
id: string; // uuid used to identify the invoice 'session'
Expand All @@ -16,4 +17,5 @@ export type TMetadataState = {
// Keep track of pending invoices, right now this is only used to map tags to incoming transactions
pendingInvoices: TPendingInvoice[];
slashTagsUrls: TSlashTagsUrls;
comments: TTxComments;
};
5 changes: 5 additions & 0 deletions src/store/utils/backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ const performMetadataRestore = async (): Promise<
return ok({ backupExists: false });
}

// apply migrations
if (backupRes.value.metadata.version < 47) {
backup.comments = {};
}

dispatch(updateMetadata({ ...expectedBackupShape, ...backup }));
dispatch(backupSuccess({ category: EBackupCategories.metadata }));

Expand Down
3 changes: 3 additions & 0 deletions src/utils/i18n/locales/en/wallet.json
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@
"activity_invoice_note": {
"string": "Invoice note"
},
"activity_invoice_comment": {
"string": "Comment"
},
"activity_invoice": {
"string": "Invoice"
},
Expand Down