Skip to content

Commit

Permalink
Merge branch 'master' into feature/rust-address-generator
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyphillips authored Apr 22, 2024
2 parents 8bfbd64 + 7294b44 commit 771c4b6
Show file tree
Hide file tree
Showing 19 changed files with 954 additions and 54 deletions.
11 changes: 3 additions & 8 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@

# More details are here: https://help.github.com/articles/about-codeowners/

/.github/workflows/ @limpbrains

#
# Github workflows need approval from the following users
#
/.github/workflows/ @limpbrains @rbndg
/e2e/ @limpbrains

#
# Github E2E need approval from the following user
#
/e2e/ @limpbrains @rbndg
/detox/ @limpbrains
2 changes: 2 additions & 0 deletions e2e/backup.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ d('Backup', () => {
await element(by.id('UnderstoodButton')).tap();
await sleep(1000); // animation
// get address from qrcode
await waitFor(element(by.id('QRCode'))).toBeVisible();
await sleep(100); // wait for qr code to render
let { label: wAddress } = await element(by.id('QRCode')).getAttributes();
wAddress = wAddress.replace('bitcoin:', '');

Expand Down
2 changes: 2 additions & 0 deletions e2e/channels.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ d('LN Channel Onboarding', () => {
await element(by.id('Receive')).tap();
await element(by.id('UnderstoodButton')).tap();
// get address from qrcode
await waitFor(element(by.id('QRCode'))).toBeVisible();
await sleep(100); // wait for qr code to render
let { label: wAddress } = await element(by.id('QRCode')).getAttributes();
wAddress = wAddress.replace('bitcoin:', '');

Expand Down
2 changes: 2 additions & 0 deletions e2e/onchain.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ d('Onchain', () => {
} catch (e) {}
await sleep(1000); // animation
// get address from qrcode
await waitFor(element(by.id('QRCode'))).toBeVisible();
await sleep(100); // wait for qr code to render
let { label: wAddress } = await element(by.id('QRCode')).getAttributes();
wAddress = wAddress.replace('bitcoin:', '');

Expand Down
2 changes: 2 additions & 0 deletions e2e/security.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ d('Settings Security And Privacy', () => {
} catch (e) {}
await sleep(100);
// get address from qrcode
await waitFor(element(by.id('QRCode'))).toBeVisible();
await sleep(100); // wait for qr code to render
let { label: wAddress } = await element(by.id('QRCode')).getAttributes();
wAddress = wAddress.replace('bitcoin:', '');
await rpc.sendToAddress(wAddress, '1');
Expand Down
2 changes: 2 additions & 0 deletions e2e/slashtags.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ d('Profile and Contacts', () => {
await element(by.id('Receive')).tap();
await element(by.id('UnderstoodButton')).tap();
await sleep(1000);
await waitFor(element(by.id('QRCode'))).toBeVisible();
await sleep(100); // wait for qr code to render
let { label: wAddress } = await element(by.id('QRCode')).getAttributes();
wAddress = wAddress.replace('bitcoin:', '');
await rpc.sendToAddress(wAddress, '1');
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"immer": "10.0.4",
"intl-messageformat": "10.5.11",
"jdenticon": "3.2.0",
"@synonymdev/ledger": "0.0.3",
"lodash": "4.17.21",
"lottie-react-native": "6.7.2",
"mime": "3.0.0",
Expand Down
1 change: 1 addition & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import AppOnboarded from './AppOnboarded';

import './utils/i18n';
import './utils/quick-actions';
import './utils/ledger';
import { useAppSelector } from './hooks/redux';
import { checkForAppUpdate } from './store/utils/ui';
import { themeSelector } from './store/reselect/settings';
Expand Down
6 changes: 6 additions & 0 deletions src/navigation/settings/SettingsNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import LightningNavigator, {
LightningStackParamList,
} from '../lightning/LightningNavigator';
import WebRelay from '../../screens/Settings/WebRelay';
import Ledger from '../../screens/Settings/Ledger';
import LedgerTransaction from '../../screens/Settings/Ledger/LedgerTransaction';
import { __E2E__ } from '../../constants/env';
import AppStatus from '../../screens/Settings/AppStatus';
import { TChannel } from '../../store/types/lightning';
Expand Down Expand Up @@ -107,6 +109,8 @@ export type SettingsStackParamList = {
AddressViewer: undefined;
FeeSettings: undefined;
WebRelay: undefined;
Ledger: undefined;
LedgerTransaction: { ledgerTxId: number };
};

const Stack = createStackNavigator<SettingsStackParamList>();
Expand Down Expand Up @@ -185,6 +189,8 @@ const SettingsNavigator = (): ReactElement => {
<Stack.Screen name="TagsSettings" component={TagsSettings} />
<Stack.Screen name="FeeSettings" component={FeeSettings} />
<Stack.Screen name="WebRelay" component={WebRelay} />
<Stack.Screen name="Ledger" component={Ledger} />
<Stack.Screen name="LedgerTransaction" component={LedgerTransaction} />
</Stack.Navigator>
);
};
Expand Down
3 changes: 3 additions & 0 deletions src/screens/Settings/AddressViewer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import { startWalletServices } from '../../../utils/startup';
import { updateOnchainFeeEstimates } from '../../../store/utils/fees';
import { viewControllerIsOpenSelector } from '../../../store/reselect/ui';
import { EAddressType, IAddress, IUtxo } from 'beignet';
import { setupLedger, syncLedger } from '../../../utils/ledger';

export type TAddressViewerData = {
[EAddressType.p2tr]: {
Expand Down Expand Up @@ -749,6 +750,7 @@ const AddressViewer = ({
if (selectedNetwork !== config.selectedNetwork) {
// Wipe existing activity
dispatch(resetActivityState());
setupLedger({ selectedWallet, selectedNetwork });
ldk.stop();
// Switch to new network.
updateWallet({ selectedNetwork: config.selectedNetwork });
Expand All @@ -763,6 +765,7 @@ const AddressViewer = ({
forceUpdate: true,
});
updateActivityList();
await syncLedger();
}

let _utxos: IUtxo[] = [];
Expand Down
8 changes: 8 additions & 0 deletions src/screens/Settings/DevSettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ const DevSettings = ({
navigation.navigate('FeeSettings');
},
},
{
title: 'Ledger',
type: EItemType.button,
testID: 'FeeSettings',
onPress: (): void => {
navigation.navigate('Ledger');
},
},
],
},
{
Expand Down
233 changes: 233 additions & 0 deletions src/screens/Settings/Ledger/LedgerTransaction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import Clipboard from '@react-native-clipboard/clipboard';
import React, { ReactElement, memo, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { StyleSheet, TouchableOpacity, View } from 'react-native';

import NavigationHeader from '../../../components/NavigationHeader';
import SafeAreaInset from '../../../components/SafeAreaInset';
import { SettingsScreenProps } from '../../../navigation/types';
import { ScrollView, View as ThemedView } from '../../../styles/components';
import { Caption13M, Caption13Up } from '../../../styles/text';
import { i18nTime } from '../../../utils/i18n';
import { bitkitLedger } from '../../../utils/ledger';
import { showToast } from '../../../utils/notifications';
import { accToEmoji } from '.';

const Section = memo(
({
name,
value,
testID,
onPress,
}: {
name: string;
value: ReactElement;
testID?: string;
onPress?: () => void;
}): ReactElement => {
return (
<TouchableOpacity
activeOpacity={onPress ? 0.5 : 1}
onPress={onPress}
style={styles.sectionRoot}>
<View style={styles.sectionName}>
<Caption13M>{name}</Caption13M>
</View>
<View style={styles.sectionValue} testID={testID}>
{value}
</View>
</TouchableOpacity>
);
},
);

const LedgerTransaction = ({
navigation,
route,
}: SettingsScreenProps<'LedgerTransaction'>): ReactElement => {
const { ledgerTxId } = route.params;
const { t } = useTranslation();
const { t: tTime } = useTranslation('intl', { i18n: i18nTime });

const tx = useMemo(
() => bitkitLedger?.ledger.getTransaction(ledgerTxId)!,
[ledgerTxId],
);
const { id, balancesBefore, amount, fromAcc, toAcc, metadata, timestamp } =
tx;
const meta = JSON.stringify(metadata, null, 2);
const fromText = accToEmoji(fromAcc);
const toText = accToEmoji(toAcc);

return (
<ThemedView style={styles.root}>
<SafeAreaInset type="top" />
<NavigationHeader
title={`${fromText}${toText}`}
onClosePress={(): void => navigation.goBack()}
/>
<ScrollView contentContainerStyle={styles.content}>
<View style={styles.section}>
<View style={styles.sectionTitle}>
<Caption13Up color="gray1">Details</Caption13Up>
</View>
<Section
name="id"
value={
<Caption13M ellipsizeMode="middle" numberOfLines={1}>
{id}
</Caption13M>
}
onPress={(): void => {
Clipboard.setString(String(id));
showToast({
type: 'success',
title: t('copied'),
description: String(id),
});
}}
/>
<Section
name="Time recorded"
value={
<Caption13M>
{tTime('dateTime', {
v: new Date(timestamp),
formatParams: {
v: {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
hour12: false,
},
},
})}
</Caption13M>
}
/>
<Section name="Amount" value={<Caption13M>{amount}</Caption13M>} />
<Section
name="From"
value={
<Caption13M>
{fromAcc.wallet} / {fromAcc.account}
</Caption13M>
}
/>
<Section
name="To"
value={
<Caption13M>
{toAcc.wallet} / {toAcc.account}
</Caption13M>
}
/>
</View>

<View style={styles.section}>
<View style={styles.row}>
<View style={styles.column}>
<View style={styles.sectionTitle}>
<Caption13Up color="gray1">Balance before From</Caption13Up>
</View>
<Section
name="Available"
value={
<Caption13M ellipsizeMode="middle" numberOfLines={1}>
{balancesBefore.fromWallet.available}
</Caption13M>
}
/>
<Section
name="Hodl"
value={
<Caption13M ellipsizeMode="middle" numberOfLines={1}>
{balancesBefore.fromWallet.hold}
</Caption13M>
}
/>
</View>
<View style={styles.column}>
<View style={styles.sectionTitle}>
<Caption13Up color="gray1">Balance before To</Caption13Up>
</View>
<Section
name="Available"
value={
<Caption13M ellipsizeMode="middle" numberOfLines={1}>
{balancesBefore.toWallet.available}
</Caption13M>
}
/>
<Section
name="Hodl"
value={
<Caption13M ellipsizeMode="middle" numberOfLines={1}>
{balancesBefore.toWallet.hold}
</Caption13M>
}
/>
</View>
</View>
</View>

<View style={styles.section}>
<View style={styles.sectionTitle}>
<Caption13Up color="gray1">Metadata</Caption13Up>
</View>

<Caption13M>{`${meta}`}</Caption13M>
</View>

<SafeAreaInset type="bottom" />
</ScrollView>
</ThemedView>
);
};

const styles = StyleSheet.create({
root: {
flex: 1,
justifyContent: 'space-between',
},
content: {
paddingHorizontal: 16,
flexGrow: 1,
},
section: {
marginTop: 16,
},
sectionTitle: {
marginBottom: 8,
flexDirection: 'row',
alignItems: 'center',
},
sectionRoot: {
height: 50,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
borderBottomWidth: 1,
borderBottomColor: 'rgba(255, 255, 255, 0.1)',
},
sectionName: {
flex: 1,
},
sectionValue: {
flex: 1.5,
alignItems: 'flex-end',
justifyContent: 'center',
},
row: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
column: {
width: '45%',
},
});

export default memo(LedgerTransaction);
Loading

0 comments on commit 771c4b6

Please sign in to comment.