@ -6,6 +6,7 @@ import {
Text ,
TextInput ,
Alert ,
KeyboardAvoidingView ,
TouchableOpacity ,
Keyboard ,
TouchableWithoutFeedback ,
@ -19,12 +20,13 @@ import { HDLegacyP2PKHWallet } from '../../class/hd-legacy-p2pkh-wallet';
import { HDSegwitP2SHWallet } from '../../class/hd-segwit-p2sh-wallet' ;
import ReactNativeHapticFeedback from 'react-native-haptic-feedback' ;
import Biometric from '../../class/biometrics' ;
import { HDSegwitBech32Wallet , WatchOnlyWallet } from '../../class' ;
let EV = require ( '../../events' ) ;
let prompt = require ( '../../prompt' ) ;
import { HDSegwitBech32Wallet , SegwitP2SHWallet , LegacyWallet , SegwitBech32Wallet , WatchOnlyWallet } from '../../class' ;
import { ScrollView } from 'react-native-gesture-handler' ;
const EV = require ( '../../events' ) ;
const prompt = require ( '../../prompt' ) ;
/** @type {AppStorage} */
le t BlueApp = require ( '../../BlueApp' ) ;
le t loc = require ( '../../loc' ) ;
cons t BlueApp = require ( '../../BlueApp' ) ;
cons t loc = require ( '../../loc' ) ;
export default class WalletDetails extends Component {
static navigationOptions = ( { navigation } ) => ( {
@ -54,7 +56,7 @@ export default class WalletDetails extends Component {
isLoading ,
walletName : wallet . getLabel ( ) ,
wallet ,
useWithHardwareWallet : ! ! wallet . use_with_hardware_wallet ,
useWithHardwareWallet : wallet . useWithHardwareWalletEnabled ( ) ,
} ;
this . props . navigation . setParams ( { isLoading , saveAction : ( ) => this . setLabel ( ) } ) ;
}
@ -70,7 +72,9 @@ export default class WalletDetails extends Component {
setLabel ( ) {
this . props . navigation . setParams ( { isLoading : true } ) ;
this . setState ( { isLoading : true } , async ( ) => {
this . state . wallet . setLabel ( this . state . walletName ) ;
if ( this . state . walletName . trim ( ) . length > 0 ) {
this . state . wallet . setLabel ( this . state . walletName ) ;
}
BlueApp . saveToDisk ( ) ;
alert ( 'Wallet updated.' ) ;
this . props . navigation . goBack ( null ) ;
@ -106,7 +110,7 @@ export default class WalletDetails extends Component {
async onUseWithHardwareWalletSwitch ( value ) {
this . setState ( ( state , props ) => {
let wallet = state . wallet ;
wallet . use_with_hardware_wallet = ! ! value ;
wallet . setUseWithHardwareWalletEnabled ( value ) ;
return { useWithHardwareWallet : ! ! value , wallet } ;
} ) ;
}
@ -122,170 +126,188 @@ export default class WalletDetails extends Component {
return (
< SafeBlueArea style = { { flex : 1 } } >
< 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 >
< KeyboardAvoidingView behavior = "position" >
< ScrollView contentContainerStyle = { { flexGrow : 1 } } >
< BlueCard style = { { alignItems : 'center' , flex : 1 } } >
{ ( ( ) => {
if (
[ LegacyWallet . type , SegwitBech32Wallet . type , SegwitP2SHWallet . type ] . includes ( this . state . wallet . type ) ||
( this . state . wallet . type === WatchOnlyWallet . type && ! this . state . wallet . isHd ( ) )
) {
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 }
onChangeText = { text => {
if ( text . trim ( ) . length === 0 ) {
text = this . state . wallet . getLabel ( ) ;
}
this . setState ( { walletName : text } ) ;
< View
style = { {
flexDirection : 'row' ,
borderColor : '#d2d2d2' ,
borderBottomColor : '#d2d2d2' ,
borderWidth : 1.0 ,
borderBottomWidth : 0.5 ,
backgroundColor : '#f5f5f5' ,
minHeight : 44 ,
height : 44 ,
alignItems : 'center' ,
borderRadius : 4 ,
} }
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 >
< Text style = { { color : '#81868e' , fontWeight : '500' , fontSize : 14 } } > { this . state . wallet . typeReadable } < / T e x t >
{ 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 >
) }
< View >
>
< TextInput
placeholder = { loc . send . details . note_placeholder }
value = { this . state . walletName }
onChangeText = { text => {
this . setState ( { walletName : text } ) ;
} }
onBlur = { ( ) => {
if ( this . state . walletName . trim ( ) . length === 0 ) {
const walletLabel = this . state . wallet . getLabel ( ) ;
this . setState ( { walletName : walletLabel } ) ;
}
} }
numberOfLines = { 1 }
style = { { flex : 1 , marginHorizontal : 8 , minHeight : 33 } }
editable = { ! this . state . isLoading }
underlineColorAndroid = "transparent"
/ >
< / V i e w >
< BlueSpacing20 / >
{ this . state . wallet . type === WatchOnlyWallet . type && this . state . wallet . getSecret ( ) . startsWith ( 'zpub' ) && (
< Text style = { { color : '#0c2550' , fontWeight : '500' , fontSize : 14 , marginVertical : 12 } } >
{ loc . wallets . details . type . toLowerCase ( ) }
< / T e x t >
< Text style = { { color : '#81868e' , fontWeight : '500' , fontSize : 14 } } > { this . state . wallet . typeReadable } < / T e x t >
{ this . state . wallet . type === LightningCustodianWallet . type && (
< 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 / >
< 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 >
) }
< View >
< BlueSpacing20 / >
{ this . state . wallet . type === WatchOnlyWallet . type && this . state . wallet . getSecret ( ) . startsWith ( 'zpub' ) && (
< >
< Text style = { { color : '#0c2550' , fontWeight : '500' , fontSize : 14 , marginVertical : 16 } } > { 'advanced' } < / T e x t >
< 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 >
< React . Fragment >
< Text style = { { color : '#0c2550' , fontWeight : '500' , fontSize : 14 , marginVertical : 12 } } >
{ loc . wallets . details . master_fingerprint . toLowerCase ( ) }
< / T e x t >
< Text style = { { color : '#81868e' , fontWeight : '500' , fontSize : 14 } } >
{ this . state . wallet . getMasterFingerprintHex ( ) }
< / T e x t >
< / R e a c t . F r a g m e n t >
< BlueSpacing20 / >
< / >
) }
< BlueButton
onPress = { ( ) =>
this . props . navigation . navigate ( 'WalletExport' , {
address : this . state . wallet . getAddress ( ) ,
secret : this . state . wallet . getSecret ( ) ,
} )
}
title = { loc . wallets . details . export_backup }
/ >
< BlueButton
onPress = { ( ) =>
this . props . navigation . navigate ( 'WalletExport' , {
address : this . state . wallet . getAddress ( ) ,
secret : this . state . wallet . getSecret ( ) ,
} )
}
title = { loc . wallets . details . export_backup }
/ >
< BlueSpacing20 / >
< BlueSpacing20 / >
{ ( this . state . wallet . type === HDLegacyBreadwalletWallet . type ||
this . state . wallet . type === HDLegacyP2PKHWallet . type ||
this . state . wallet . type === HDSegwitBech32Wallet . type ||
this . state . wallet . type === HDSegwitP2SHWallet . type ) && (
< React . Fragment >
{ ( this . state . wallet . type === HDLegacyBreadwalletWallet . type ||
this . state . wallet . type === HDLegacyP2PKHWallet . type ||
this . state . wallet . type === HDSegwitBech32Wallet . type ||
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 }
/ >
< BlueSpacing20 / >
< / R e a c t . F r a g m e n t >
) }
{ this . state . wallet . type !== LightningCustodianWallet . type && (
< BlueButton
icon = { {
name : 'shopping-cart' ,
type : 'font-awesome' ,
color : BlueApp . settings . buttonTextColor ,
} }
onPress = { ( ) =>
this . props . navigation . navigate ( 'WalletXpub' , {
this . props . navigation . navigate ( 'BuyBitcoin' , {
address : this . state . wallet . getAddress ( ) ,
secret : this . state . wallet . getSecret ( ) ,
} )
}
title = { loc . wallets . details . show_xpub }
title = { loc . wallets . details . buy_bitcoin }
/ >
) }
< BlueSpacing20 / >
< BlueSpacing20 / >
< / R e a c t . F r a g m e n t >
) }
{ this . state . wallet . type !== LightningCustodianWallet . type && (
< BlueButton
icon = { {
name : 'shopping-cart' ,
type : 'font-awesome' ,
color : BlueApp . settings . buttonTextColor ,
} }
onPress = { ( ) =>
this . props . navigation . navigate ( 'BuyBitcoin' , {
address : this . state . wallet . getAddress ( ) ,
secret : this . state . wallet . getSecret ( ) ,
} )
}
title = { loc . wallets . details . buy_bitcoin }
/ >
) }
< BlueSpacing20 / >
< TouchableOpacity
style = { { alignItems : 'center' } }
onPress = { ( ) => {
ReactNativeHapticFeedback . trigger ( 'notificationWarning' , { ignoreAndroidSystemSettings : false } ) ;
Alert . alert (
loc . wallets . details . delete + ' ' + loc . wallets . details . title ,
loc . wallets . details . are_you_sure ,
[
{
text : loc . wallets . details . yes_delete ,
onPress : async ( ) => {
const isBiometricsEnabled = await Biometric . isBiometricUseCapableAndEnabled ( ) ;
< TouchableOpacity
style = { { alignItems : 'center' } }
onPress = { ( ) => {
ReactNativeHapticFeedback . trigger ( 'notificationWarning' , { ignoreAndroidSystemSettings : false } ) ;
Alert . alert (
loc . wallets . details . delete + ' ' + loc . wallets . details . title ,
loc . wallets . details . are_you_sure ,
[
{
text : loc . wallets . details . yes_delete ,
onPress : async ( ) => {
const isBiometricsEnabled = await Biometric . isBiometricUseCapableAndEnabled ( ) ;
if ( isBiometricsEnabled ) {
if ( ! ( await Biometric . unlockWithBiometrics ( ) ) ) {
return ;
if ( isBiometricsEnabled ) {
if ( ! ( await Biometric . unlockWithBiometrics ( ) ) ) {
return ;
}
}
}
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 . TRANSACTION S_COUNT_CHANGED) ;
EV ( EV . enum . WALLETS_COUNT_CHANGED ) ;
this . props . navigation . navigate ( 'Wallets' ) ;
} ) ;
}
if ( this . state . wallet . getBalance ( ) > 0 && this . state . wallet . allowSend ( ) ) {
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' ) ;
} ) ;
}
} ,
} ,
style : 'destructive' ,
} ,
{ 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 >
< / V i e w >
{ 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 >
< / S c r o l l V i e w >
< / K e y b o a r d A v o i d i n g V i e w >
< / T o u c h a b l e W i t h o u t F e e d b a c k >
< / S a f e B l u e A r e a >
) ;