import React, { useContext, useRef } from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { useNavigation } from '@react-navigation/native'; import { ListItem } from 'react-native-elements'; import PropTypes from 'prop-types'; import { AddressTypeBadge } from './AddressTypeBadge'; import loc, { formatBalance } from '../../loc'; import TooltipMenu from '../TooltipMenu'; import Clipboard from '@react-native-clipboard/clipboard'; import Share from 'react-native-share'; import { useTheme } from '../themes'; import { BitcoinUnit } from '../../models/bitcoinUnits'; import { BlueStorageContext } from '../../blue_modules/storage-context'; import Biometric from '../../class/biometrics'; import presentAlert from '../Alert'; import triggerHapticFeedback, { HapticFeedbackTypes } from '../../blue_modules/hapticFeedback'; import QRCodeComponent from '../QRCodeComponent'; const confirm = require('../../helpers/confirm'); interface AddressItemProps { // todo: fix `any` after addresses.js is converted to the church of holy typescript item: any; balanceUnit: BitcoinUnit; walletID: string; allowSignVerifyMessage: boolean; } const AddressItem = ({ item, balanceUnit, walletID, allowSignVerifyMessage }: AddressItemProps) => { const { wallets } = useContext(BlueStorageContext); const { colors } = useTheme(); const hasTransactions = item.transactions > 0; const stylesHook = StyleSheet.create({ container: { borderBottomColor: colors.lightBorder, backgroundColor: colors.elevated, }, list: { color: colors.buttonTextColor, }, index: { color: colors.alternativeTextColor, }, balance: { color: colors.alternativeTextColor, }, address: { color: hasTransactions ? colors.darkGray : colors.buttonTextColor, }, }); const { navigate } = useNavigation(); const menuRef = useRef(); const navigateToReceive = () => { // @ts-ignore wtf menuRef.current?.dismissMenu(); // @ts-ignore wtf navigate('ReceiveDetailsRoot', { screen: 'ReceiveDetails', params: { walletID, address: item.address, }, }); }; const navigateToSignVerify = () => { // @ts-ignore wtf menuRef.current?.dismissMenu(); // @ts-ignore wtf navigate('SignVerifyRoot', { screen: 'SignVerify', params: { walletID, address: item.address, }, }); }; const balance = formatBalance(item.balance, balanceUnit, true); const handleCopyPress = () => { Clipboard.setString(item.address); }; const handleSharePress = () => { Share.open({ message: item.address }).catch(error => console.log(error)); }; const handleCopyPrivkeyPress = () => { const wallet = wallets.find(w => w.getID() === walletID); if (!wallet) { presentAlert({ message: 'Internal error: cant find wallet' }); return; } try { const wif = wallet._getWIFbyAddress(item.address); if (!wif) { presentAlert({ message: 'Internal error: cant get WIF from the wallet' }); return; } triggerHapticFeedback(HapticFeedbackTypes.Selection); Clipboard.setString(wif); } catch (error: any) { presentAlert({ message: error.message }); } }; const onToolTipPress = async (id: string) => { if (id === AddressItem.actionKeys.CopyToClipboard) { handleCopyPress(); } else if (id === AddressItem.actionKeys.Share) { handleSharePress(); } else if (id === AddressItem.actionKeys.SignVerify) { navigateToSignVerify(); } else if (id === AddressItem.actionKeys.ExportPrivateKey) { if (await confirm(loc.addresses.sensitive_private_key)) { if (await Biometric.isBiometricUseCapableAndEnabled()) { if (!(await Biometric.unlockWithBiometrics())) { return; } } handleCopyPrivkeyPress(); } } }; const getAvailableActions = () => { const actions = [ { id: AddressItem.actionKeys.CopyToClipboard, text: loc.transactions.details_copy, icon: AddressItem.actionIcons.Clipboard, }, { id: AddressItem.actionKeys.Share, text: loc.receive.details_share, icon: AddressItem.actionIcons.Share, }, ]; if (allowSignVerifyMessage) { actions.push({ id: AddressItem.actionKeys.SignVerify, text: loc.addresses.sign_title, icon: AddressItem.actionIcons.Signature, }); } if (allowSignVerifyMessage) { actions.push({ id: AddressItem.actionKeys.ExportPrivateKey, text: loc.addresses.copy_private_key, icon: AddressItem.actionIcons.ExportPrivateKey, }); } return actions; }; const renderPreview = () => { return ; }; const render = () => { return ( {item.index + 1}{' '} {item.address} {balance} {loc.addresses.transactions}: {item.transactions} ); }; return render(); }; AddressItem.actionKeys = { Share: 'share', CopyToClipboard: 'copyToClipboard', SignVerify: 'signVerify', ExportPrivateKey: 'exportPrivateKey', }; AddressItem.actionIcons = { Signature: { iconType: 'SYSTEM', iconValue: 'signature', }, Share: { iconType: 'SYSTEM', iconValue: 'square.and.arrow.up', }, Clipboard: { iconType: 'SYSTEM', iconValue: 'doc.on.doc', }, ExportPrivateKey: { iconType: 'SYSTEM', iconValue: 'key', }, }; const styles = StyleSheet.create({ address: { fontWeight: 'bold', marginHorizontal: 40, }, index: { fontSize: 15, }, balance: { marginTop: 8, marginLeft: 14, }, subtitle: { flex: 1, flexDirection: 'row', justifyContent: 'space-between', width: '100%', }, }); AddressItem.propTypes = { item: PropTypes.shape({ key: PropTypes.string, index: PropTypes.number, address: PropTypes.string, isInternal: PropTypes.bool, transactions: PropTypes.number, balance: PropTypes.number, }), balanceUnit: PropTypes.string, }; export { AddressItem };