2018-10-30 10:35:24 +01:00
/* global alert */
2018-01-30 23:42:38 +01:00
import React , { Component } from 'react' ;
2019-09-27 16:49:56 +02:00
import {
ActivityIndicator ,
View ,
Text ,
TextInput ,
Alert ,
TouchableOpacity ,
Keyboard ,
TouchableWithoutFeedback ,
Switch ,
} from 'react-native' ;
2019-08-31 02:10:26 +02:00
import { BlueButton , SafeBlueArea , BlueCard , BlueSpacing20 , BlueNavigationStyle , BlueText } from '../../BlueComponents' ;
2018-03-18 03:48:23 +01:00
import PropTypes from 'prop-types' ;
2018-10-30 10:35:24 +01:00
import { LightningCustodianWallet } from '../../class/lightning-custodian-wallet' ;
2018-12-27 16:37:12 +01:00
import { HDLegacyBreadwalletWallet } from '../../class/hd-legacy-breadwallet-wallet' ;
import { HDLegacyP2PKHWallet } from '../../class/hd-legacy-p2pkh-wallet' ;
import { HDSegwitP2SHWallet } from '../../class/hd-segwit-p2sh-wallet' ;
2018-12-13 17:50:18 +01:00
import ReactNativeHapticFeedback from 'react-native-haptic-feedback' ;
2019-09-25 05:42:21 +02:00
import Biometric from '../../class/biometrics' ;
2019-09-27 16:49:56 +02:00
import { HDSegwitBech32Wallet , WatchOnlyWallet } from '../../class' ;
2018-03-17 21:39:21 +01:00
let EV = require ( '../../events' ) ;
2019-08-30 06:45:08 +02:00
let prompt = require ( '../../prompt' ) ;
2018-03-18 03:48:23 +01:00
/** @type {AppStorage} */
let BlueApp = require ( '../../BlueApp' ) ;
2018-05-28 21:18:11 +02:00
let loc = require ( '../../loc' ) ;
2018-01-30 23:42:38 +01:00
export default class WalletDetails extends Component {
2018-10-29 23:11:48 +01:00
static navigationOptions = ( { navigation } ) => ( {
2018-10-30 10:35:24 +01:00
... BlueNavigationStyle ( ) ,
2018-10-29 23:11:48 +01:00
title : loc . wallets . details . title ,
2018-10-30 10:35:24 +01:00
headerRight : (
2018-11-10 00:44:34 +01:00
< TouchableOpacity
2019-01-12 05:01:15 +01:00
disabled = { navigation . getParam ( 'isLoading' ) === true }
2019-10-17 03:33:00 +02:00
style = { { marginHorizontal : 16 , justifyContent : 'center' , alignItems : 'center' } }
2018-10-30 10:35:24 +01:00
onPress = { ( ) => {
2019-03-08 22:54:47 +01:00
if ( navigation . state . params . saveAction ) {
navigation . getParam ( 'saveAction' ) ( ) ;
}
2018-10-30 10:35:24 +01:00
} }
2018-11-10 00:44:34 +01:00
>
< Text style = { { color : '#0c2550' } } > { loc . wallets . details . save } < / T e x t >
< / T o u c h a b l e O p a c i t y >
2018-10-30 10:35:24 +01:00
) ,
2018-10-29 23:11:48 +01:00
} ) ;
2018-01-30 23:42:38 +01:00
constructor ( props ) {
super ( props ) ;
2019-01-07 05:54:22 +01:00
const wallet = props . navigation . getParam ( 'wallet' ) ;
2019-01-12 05:01:15 +01:00
const isLoading = true ;
2018-01-30 23:42:38 +01:00
this . state = {
2019-01-12 05:01:15 +01:00
isLoading ,
2018-10-30 10:35:24 +01:00
walletName : wallet . getLabel ( ) ,
2018-03-17 21:39:21 +01:00
wallet ,
2019-09-27 16:49:56 +02:00
useWithHardwareWallet : ! ! wallet . use _with _hardware _wallet ,
2018-03-17 21:39:21 +01:00
} ;
2019-01-12 05:01:15 +01:00
this . props . navigation . setParams ( { isLoading , saveAction : ( ) => this . setLabel ( ) } ) ;
2018-01-30 23:42:38 +01:00
}
2019-01-07 05:54:22 +01:00
componentDidMount ( ) {
2019-09-27 16:49:56 +02:00
console . log ( 'wallets/details componentDidMount' ) ;
2018-01-30 23:42:38 +01:00
this . setState ( {
isLoading : false ,
2018-03-17 21:39:21 +01:00
} ) ;
2019-01-12 05:01:15 +01:00
this . props . navigation . setParams ( { isLoading : false , saveAction : ( ) => this . setLabel ( ) } ) ;
2018-01-30 23:42:38 +01:00
}
2019-01-07 05:54:22 +01:00
setLabel ( ) {
2019-01-12 05:01:15 +01:00
this . props . navigation . setParams ( { isLoading : true } ) ;
2019-03-08 22:54:47 +01:00
this . setState ( { isLoading : true } , async ( ) => {
2019-01-07 05:54:22 +01:00
this . state . wallet . setLabel ( this . state . walletName ) ;
BlueApp . saveToDisk ( ) ;
alert ( 'Wallet updated.' ) ;
this . props . navigation . goBack ( null ) ;
} ) ;
2018-01-30 23:42:38 +01:00
}
2019-08-30 06:45:08 +02:00
async presentWalletHasBalanceAlert ( ) {
ReactNativeHapticFeedback . trigger ( 'notificationWarning' , { ignoreAndroidSystemSettings : false } ) ;
const walletBalanceConfirmation = await prompt (
'Wallet Balance' ,
` This wallet has a balance. Before proceeding, please be aware that you will not be able to recover the funds without this wallet's seed phrase. In order to avoid accidental removal this wallet, please enter your wallet's balance of ${ this . state . wallet . getBalance ( ) } satoshis. ` ,
true ,
'plain-text' ,
) ;
if ( Number ( walletBalanceConfirmation ) === this . state . wallet . getBalance ( ) ) {
this . props . navigation . setParams ( { isLoading : true } ) ;
this . setState ( { isLoading : true } , async ( ) => {
BlueApp . deleteWallet ( this . state . wallet ) ;
ReactNativeHapticFeedback . trigger ( 'notificationSuccess' , { ignoreAndroidSystemSettings : false } ) ;
await BlueApp . saveToDisk ( ) ;
EV ( EV . enum . TRANSACTIONS _COUNT _CHANGED ) ;
EV ( EV . enum . WALLETS _COUNT _CHANGED ) ;
this . props . navigation . navigate ( 'Wallets' ) ;
} ) ;
} else {
ReactNativeHapticFeedback . trigger ( 'notificationError' , { ignoreAndroidSystemSettings : false } ) ;
this . setState ( { isLoading : false } , async ( ) => {
alert ( "The provided balance amount does not match this wallet's balance. Please, try again" ) ;
} ) ;
}
}
2019-09-27 16:49:56 +02:00
async onUseWithHardwareWalletSwitch ( value ) {
this . setState ( ( state , props ) => {
let wallet = state . wallet ;
wallet . use _with _hardware _wallet = ! ! value ;
return { useWithHardwareWallet : ! ! value , wallet } ;
} ) ;
}
2018-01-30 23:42:38 +01:00
render ( ) {
if ( this . state . isLoading ) {
return (
2018-05-12 22:27:34 +02:00
< View style = { { flex : 1 } } >
2018-01-30 23:42:38 +01:00
< ActivityIndicator / >
< / V i e w >
) ;
}
return (
2018-05-12 22:27:34 +02:00
< SafeBlueArea style = { { flex : 1 } } >
2018-12-11 23:52:46 +01:00
< TouchableWithoutFeedback onPress = { Keyboard . dismiss } accessible = { false } >
< View style = { { flex : 1 } } >
< BlueCard style = { { alignItems : 'center' , flex : 1 } } >
{ ( ( ) => {
if ( this . state . wallet . getAddress ( ) ) {
return (
< React . Fragment >
< Text style = { { color : '#0c2550' , fontWeight : '500' , fontSize : 14 , marginVertical : 12 } } >
{ loc . wallets . details . address . toLowerCase ( ) }
< / T e x t >
< Text style = { { color : '#81868e' , fontWeight : '500' , fontSize : 14 } } > { this . state . wallet . getAddress ( ) } < / T e x t >
< / R e a c t . F r a g m e n t >
) ;
}
} ) ( ) }
< Text style = { { color : '#0c2550' , fontWeight : '500' , fontSize : 14 , marginVertical : 16 } } >
{ loc . wallets . add . wallet _name . toLowerCase ( ) }
< / T e x t >
< View
style = { {
flexDirection : 'row' ,
borderColor : '#d2d2d2' ,
borderBottomColor : '#d2d2d2' ,
borderWidth : 1.0 ,
borderBottomWidth : 0.5 ,
backgroundColor : '#f5f5f5' ,
minHeight : 44 ,
height : 44 ,
alignItems : 'center' ,
borderRadius : 4 ,
} }
>
< TextInput
placeholder = { loc . send . details . note _placeholder }
value = { this . state . walletName }
2019-12-21 20:35:34 +01:00
onChangeText = { text => {
if ( text . trim ( ) . length === 0 ) {
text = this . state . wallet . getLabel ( ) ;
}
this . setState ( { walletName : text } ) ;
} }
2018-12-11 23:52:46 +01:00
numberOfLines = { 1 }
style = { { flex : 1 , marginHorizontal : 8 , minHeight : 33 } }
editable = { ! this . state . isLoading }
underlineColorAndroid = "transparent"
/ >
< / V i e w >
< Text style = { { color : '#0c2550' , fontWeight : '500' , fontSize : 14 , marginVertical : 12 } } >
{ loc . wallets . details . type . toLowerCase ( ) }
< / T e x t >
2018-12-28 16:52:06 +01:00
< Text style = { { color : '#81868e' , fontWeight : '500' , fontSize : 14 } } > { this . state . wallet . typeReadable } < / T e x t >
2019-03-08 22:54:47 +01:00
{ this . state . wallet . type === LightningCustodianWallet . type && (
< React . Fragment >
< Text style = { { color : '#0c2550' , fontWeight : '500' , fontSize : 14 , marginVertical : 12 } } > { 'connected to' } < / T e x t >
< BlueText > { this . state . wallet . getBaseURI ( ) } < / B l u e T e x t >
< / R e a c t . F r a g m e n t >
) }
2019-01-25 07:12:07 +01:00
< View >
< BlueSpacing20 / >
2019-09-27 16:49:56 +02:00
{ this . state . wallet . type === WatchOnlyWallet . type && this . state . wallet . getSecret ( ) . startsWith ( 'zpub' ) && (
< React . Fragment >
< View style = { { flexDirection : 'row' , alignItems : 'center' , justifyContent : 'space-between' } } >
< BlueText > { 'Use with hardware wallet' } < / B l u e T e x t >
< Switch value = { this . state . useWithHardwareWallet } onValueChange = { value => this . onUseWithHardwareWalletSwitch ( value ) } / >
< / V i e w >
< BlueSpacing20 / >
< / R e a c t . F r a g m e n t >
) }
2019-01-25 07:12:07 +01:00
< BlueButton
onPress = { ( ) =>
this . props . navigation . navigate ( 'WalletExport' , {
address : this . state . wallet . getAddress ( ) ,
secret : this . state . wallet . getSecret ( ) ,
} )
}
title = { loc . wallets . details . export _backup }
/ >
< BlueSpacing20 / >
{ ( this . state . wallet . type === HDLegacyBreadwalletWallet . type ||
this . state . wallet . type === HDLegacyP2PKHWallet . type ||
2019-06-09 21:25:14 +02:00
this . state . wallet . type === HDSegwitBech32Wallet . type ||
2019-01-25 07:12:07 +01:00
this . state . wallet . type === HDSegwitP2SHWallet . type ) && (
< React . Fragment >
< BlueButton
onPress = { ( ) =>
this . props . navigation . navigate ( 'WalletXpub' , {
secret : this . state . wallet . getSecret ( ) ,
} )
}
title = { loc . wallets . details . show _xpub }
/ >
2018-12-11 23:52:46 +01:00
2019-01-25 07:12:07 +01:00
< BlueSpacing20 / >
< / R e a c t . F r a g m e n t >
) }
2018-12-11 23:52:46 +01:00
2019-01-25 07:12:07 +01:00
{ this . state . wallet . type !== LightningCustodianWallet . type && (
2018-12-28 16:53:02 +01:00
< BlueButton
2019-01-25 07:12:07 +01:00
icon = { {
name : 'shopping-cart' ,
type : 'font-awesome' ,
color : BlueApp . settings . buttonTextColor ,
} }
2018-12-28 16:53:02 +01:00
onPress = { ( ) =>
2019-01-25 07:12:07 +01:00
this . props . navigation . navigate ( 'BuyBitcoin' , {
address : this . state . wallet . getAddress ( ) ,
2018-12-28 16:53:02 +01:00
secret : this . state . wallet . getSecret ( ) ,
} )
}
2019-01-25 07:12:07 +01:00
title = { loc . wallets . details . buy _bitcoin }
2018-12-28 16:53:02 +01:00
/ >
2019-01-25 07:12:07 +01:00
) }
< BlueSpacing20 / >
2018-12-28 16:53:02 +01:00
2019-01-25 07:12:07 +01:00
< TouchableOpacity
style = { { alignItems : 'center' } }
onPress = { ( ) => {
2019-05-03 14:36:11 +02:00
ReactNativeHapticFeedback . trigger ( 'notificationWarning' , { ignoreAndroidSystemSettings : false } ) ;
2019-01-25 07:12:07 +01:00
Alert . alert (
loc . wallets . details . delete + ' ' + loc . wallets . details . title ,
loc . wallets . details . are _you _sure ,
[
{
text : loc . wallets . details . yes _delete ,
onPress : async ( ) => {
2019-10-17 03:33:00 +02:00
const isBiometricsEnabled = await Biometric . isBiometricUseCapableAndEnabled ( ) ;
if ( isBiometricsEnabled ) {
if ( ! ( await Biometric . unlockWithBiometrics ( ) ) ) {
return ;
}
}
2019-08-30 06:45:08 +02:00
if ( this . state . wallet . getBalance ( ) > 0 ) {
this . presentWalletHasBalanceAlert ( ) ;
} else {
this . props . navigation . setParams ( { isLoading : true } ) ;
this . setState ( { isLoading : true } , async ( ) => {
BlueApp . deleteWallet ( this . state . wallet ) ;
ReactNativeHapticFeedback . trigger ( 'notificationSuccess' , { ignoreAndroidSystemSettings : false } ) ;
await BlueApp . saveToDisk ( ) ;
EV ( EV . enum . TRANSACTIONS _COUNT _CHANGED ) ;
EV ( EV . enum . WALLETS _COUNT _CHANGED ) ;
this . props . navigation . navigate ( 'Wallets' ) ;
} ) ;
}
2019-01-25 07:12:07 +01:00
} ,
style : 'destructive' ,
2018-12-11 23:52:46 +01:00
} ,
2019-01-25 07:12:07 +01:00
{ text : loc . wallets . details . no _cancel , onPress : ( ) => { } , style : 'cancel' } ,
] ,
{ cancelable : false } ,
) ;
} }
>
< Text style = { { color : '#d0021b' , fontSize : 15 , fontWeight : '500' } } > { loc . wallets . details . delete } < / T e x t >
< / T o u c h a b l e O p a c i t y >
< / V i e w >
< / B l u e C a r d >
2018-10-30 10:35:24 +01:00
< / V i e w >
2018-12-11 23:52:46 +01:00
< / T o u c h a b l e W i t h o u t F e e d b a c k >
2018-01-30 23:42:38 +01:00
< / S a f e B l u e A r e a >
) ;
}
}
2018-03-18 03:48:23 +01:00
WalletDetails . propTypes = {
navigation : PropTypes . shape ( {
2019-01-12 05:01:15 +01:00
getParam : PropTypes . func ,
2018-03-18 03:48:23 +01:00
state : PropTypes . shape ( {
params : PropTypes . shape ( {
2018-07-22 16:49:59 +02:00
secret : PropTypes . string ,
2018-03-18 03:48:23 +01:00
} ) ,
} ) ,
navigate : PropTypes . func ,
goBack : PropTypes . func ,
2018-10-30 10:35:24 +01:00
setParams : PropTypes . func ,
2018-03-18 03:48:23 +01:00
} ) ,
} ;