sync up with master

This commit is contained in:
Ivan Vershigora 2020-11-22 10:07:27 +03:00
commit c61ca124c4
12 changed files with 470 additions and 430 deletions

View file

@ -144,42 +144,41 @@ export const BlueButtonHook = props => {
); );
}; };
export class SecondButton extends Component { export const SecondButton = props => {
render() { const { colors } = useTheme();
let backgroundColor = this.props.backgroundColor ? this.props.backgroundColor : BlueCurrentTheme.colors.buttonBlueBackgroundColor; let backgroundColor = props.backgroundColor ? props.backgroundColor : colors.buttonBlueBackgroundColor;
let fontColor = BlueCurrentTheme.colors.buttonTextColor; let fontColor = colors.buttonTextColor;
if (this.props.disabled === true) { if (props.disabled === true) {
backgroundColor = BlueCurrentTheme.colors.buttonDisabledBackgroundColor; backgroundColor = colors.buttonDisabledBackgroundColor;
fontColor = BlueCurrentTheme.colors.buttonDisabledTextColor; fontColor = colors.buttonDisabledTextColor;
}
// let buttonWidth = this.props.width ? this.props.width : width / 1.5;
// if ('noMinWidth' in this.props) {
// buttonWidth = 0;
// }
return (
<TouchableOpacity
style={{
flex: 1,
borderWidth: 0.7,
borderColor: 'transparent',
backgroundColor: backgroundColor,
minHeight: 45,
height: 45,
maxHeight: 45,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
}}
{...this.props}
>
<View style={{ flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
{this.props.icon && <Icon name={this.props.icon.name} type={this.props.icon.type} color={this.props.icon.color} />}
{this.props.title && <Text style={{ marginHorizontal: 8, fontSize: 16, color: fontColor }}>{this.props.title}</Text>}
</View>
</TouchableOpacity>
);
} }
} // let buttonWidth = this.props.width ? this.props.width : width / 1.5;
// if ('noMinWidth' in this.props) {
// buttonWidth = 0;
// }
return (
<TouchableOpacity
style={{
flex: 1,
borderWidth: 0.7,
borderColor: 'transparent',
backgroundColor: backgroundColor,
minHeight: 45,
height: 45,
maxHeight: 45,
borderRadius: 25,
justifyContent: 'center',
alignItems: 'center',
}}
{...props}
>
<View style={{ flexDirection: 'row', justifyContent: 'center', alignItems: 'center' }}>
{props.icon && <Icon name={props.icon.name} type={props.icon.type} color={props.icon.color} />}
{props.title && <Text style={{ marginHorizontal: 8, fontSize: 16, color: fontColor }}>{props.title}</Text>}
</View>
</TouchableOpacity>
);
};
export const BitcoinButton = props => { export const BitcoinButton = props => {
const { colors } = useTheme(); const { colors } = useTheme();

View file

@ -147,7 +147,7 @@ const WalletsRoot = () => (
component={LNDViewInvoice} component={LNDViewInvoice}
options={LNDViewInvoice.navigationOptions} options={LNDViewInvoice.navigationOptions}
swipeEnabled={false} swipeEnabled={false}
gesturesEnabled={false} gestureEnabled={false}
/> />
<WalletsStack.Screen <WalletsStack.Screen
name="LNDViewAdditionalInvoiceInformation" name="LNDViewAdditionalInvoiceInformation"
@ -191,7 +191,14 @@ const SendDetailsRoot = () => (
/> />
<SendDetailsStack.Screen name="CreateTransaction" component={SendCreate} options={SendCreate.navigationOptions} /> <SendDetailsStack.Screen name="CreateTransaction" component={SendCreate} options={SendCreate.navigationOptions} />
<SendDetailsStack.Screen name="PsbtMultisig" component={PsbtMultisig} options={PsbtMultisig.navigationOptions} /> <SendDetailsStack.Screen name="PsbtMultisig" component={PsbtMultisig} options={PsbtMultisig.navigationOptions} />
<SendDetailsStack.Screen name="Success" component={Success} options={Success.navigationOptions} /> <SendDetailsStack.Screen
name="Success"
component={Success}
options={{
headerShown: false,
gestureEnabled: false,
}}
/>
<SendDetailsStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} /> <SendDetailsStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} />
<SendDetailsStack.Screen name="CoinControl" component={CoinControl} options={CoinControl.navigationOptions} /> <SendDetailsStack.Screen name="CoinControl" component={CoinControl} options={CoinControl.navigationOptions} />
</SendDetailsStack.Navigator> </SendDetailsStack.Navigator>
@ -207,7 +214,7 @@ const LNDCreateInvoiceRoot = () => (
component={LNDViewInvoice} component={LNDViewInvoice}
options={LNDViewInvoice.navigationOptions} options={LNDViewInvoice.navigationOptions}
swipeEnabled={false} swipeEnabled={false}
gesturesEnabled={false} gestureEnabled={false}
/> />
<LNDCreateInvoiceStack.Screen <LNDCreateInvoiceStack.Screen
name="LNDViewAdditionalInvoiceInformation" name="LNDViewAdditionalInvoiceInformation"
@ -223,7 +230,7 @@ const ScanLndInvoiceRoot = () => (
<ScanLndInvoiceStack.Navigator screenOptions={defaultStackScreenOptions}> <ScanLndInvoiceStack.Navigator screenOptions={defaultStackScreenOptions}>
<ScanLndInvoiceStack.Screen name="ScanLndInvoice" component={ScanLndInvoice} options={ScanLndInvoice.navigationOptions} /> <ScanLndInvoiceStack.Screen name="ScanLndInvoice" component={ScanLndInvoice} options={ScanLndInvoice.navigationOptions} />
<ScanLndInvoiceStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} /> <ScanLndInvoiceStack.Screen name="SelectWallet" component={SelectWallet} options={SelectWallet.navigationOptions} />
<ScanLndInvoiceStack.Screen name="Success" component={Success} options={Success.navigationOptions} /> <ScanLndInvoiceStack.Screen name="Success" component={Success} options={{ headerShown: false, gestureEnabled: false }} />
<ScanLndInvoiceStack.Screen name="LnurlPay" component={LnurlPay} options={LnurlPay.navigationOptions} /> <ScanLndInvoiceStack.Screen name="LnurlPay" component={LnurlPay} options={LnurlPay.navigationOptions} />
<ScanLndInvoiceStack.Screen name="LnurlPaySuccess" component={LnurlPaySuccess} options={LnurlPaySuccess.navigationOptions} /> <ScanLndInvoiceStack.Screen name="LnurlPaySuccess" component={LnurlPaySuccess} options={LnurlPaySuccess.navigationOptions} />
</ScanLndInvoiceStack.Navigator> </ScanLndInvoiceStack.Navigator>

View file

@ -136,7 +136,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1 versionCode 1
versionName "5.6.6" versionName "5.6.7"
multiDexEnabled true multiDexEnabled true
missingDimensionStrategy 'react-native-camera', 'general' missingDimensionStrategy 'react-native-camera', 'general'
testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type

View file

@ -1485,7 +1485,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
"-ObjC", "-ObjC",
@ -1528,7 +1528,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
OTHER_LDFLAGS = ( OTHER_LDFLAGS = (
"$(inherited)", "$(inherited)",
"-ObjC", "-ObjC",
@ -1569,7 +1569,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension;
@ -1608,7 +1608,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.TodayExtension;
PRODUCT_NAME = "BlueWallet - Bitcoin Price"; PRODUCT_NAME = "BlueWallet - Bitcoin Price";
@ -1647,7 +1647,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.PriceWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.PriceWidget;
@ -1689,7 +1689,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.PriceWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.PriceWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -1729,7 +1729,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget;
@ -1772,7 +1772,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.MarketWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -1813,7 +1813,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationAndMarketWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationAndMarketWidget;
@ -1857,7 +1857,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationAndMarketWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationAndMarketWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -1898,7 +1898,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationWidget;
@ -1941,7 +1941,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationWidget; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.WalletInformationWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@ -2083,7 +2083,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch.extension; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch.extension;
@ -2123,7 +2123,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch.extension; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch.extension;
PRODUCT_NAME = "${TARGET_NAME}"; PRODUCT_NAME = "${TARGET_NAME}";
@ -2157,7 +2157,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
IBSC_MODULE = BlueWalletWatch_Extension; IBSC_MODULE = BlueWalletWatch_Extension;
INFOPLIST_FILE = BlueWalletWatch/Info.plist; INFOPLIST_FILE = BlueWalletWatch/Info.plist;
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch;
@ -2193,7 +2193,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
IBSC_MODULE = BlueWalletWatch_Extension; IBSC_MODULE = BlueWalletWatch_Extension;
INFOPLIST_FILE = BlueWalletWatch/Info.plist; INFOPLIST_FILE = BlueWalletWatch/Info.plist;
MARKETING_VERSION = 5.6.6; MARKETING_VERSION = 5.6.7;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch; PRODUCT_BUNDLE_IDENTIFIER = io.bluewallet.bluewallet.watch;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View file

@ -752,6 +752,6 @@ SPEC CHECKSUMS:
Yoga: 7d13633d129fd179e01b8953d38d47be90db185a Yoga: 7d13633d129fd179e01b8953d38d47be90db185a
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 0f43ca714eccbe358757a45c664df8e25bc7c146 PODFILE CHECKSUM: b3a4c68ed1fc7dace2357d96ad07c3e104e0afe2
COCOAPODS: 1.9.3 COCOAPODS: 1.9.3

View file

@ -1,3 +1,15 @@
v5.6.6
======
* FIX: camera is not closing after QR with PSBT (UR) scanned from hw wallet
* FIX: Input amount can now start with dot for fractional values
* ADD: ARS fiat currency
* FIX: locales nl_NL, sl_SI, es_ES
* FIX: Dim nonselected wallets on additional screens
* FIX: Use numberformatter for properly displaying the wallet balance on widget
* REF: new wallets now generate 12 words mnemonic seed instead of 24, same security, but easier to manage
v5.6.5 v5.6.5
====== ======
@ -61,21 +73,3 @@ v.5.6.0
* FIX: rare crash on watch-only receive button * FIX: rare crash on watch-only receive button
* FIX: RBF cancel style * FIX: RBF cancel style
* REF: updated languages sl_SI, de_DE, fi_FI, es_ES * REF: updated languages sl_SI, de_DE, fi_FI, es_ES
v5.5.9
=======
* ADD: Arabic language
* ADD: new choose fee workflow
* FIX: broken LN -> manage funds -> refill
* FIX: camera wont scan QR with airgapped HW wallet flow
* FIX: Refresh from notification
* FIX: transaction not updating on refresh
* FIX: textAlign: right for custom fee in CPFP/RBF form
* FIX: set default fee in CPFP/RBF fee-selection component
* FIX: update recalculate fee on send screen with custom sat/byte fee rate
* FIX: broken sendMAX if units are changed several times
* FIX: validation allows user to create transaction even without valid address & amount
* FIX: Only send wallets to watch app if installed
* FIX: Send Max not working
* FIX: Reorder screen is broken

View file

@ -212,6 +212,7 @@
"psbt_clipboard": "Copy to Clipboard", "psbt_clipboard": "Copy to Clipboard",
"psbt_this_is_psbt": "This is a partially signed bitcoin transaction (PSBT). Please finish signing it with your hardware wallet.", "psbt_this_is_psbt": "This is a partially signed bitcoin transaction (PSBT). Please finish signing it with your hardware wallet.",
"psbt_tx_export": "Export to file", "psbt_tx_export": "Export to file",
"no_tx_signing_in_progress": "There is no transaction signing in progress",
"psbt_tx_open": "Open Signed Transaction", "psbt_tx_open": "Open Signed Transaction",
"psbt_tx_scan": "Scan Signed Transaction", "psbt_tx_scan": "Scan Signed Transaction",
"qr_error_no_qrcode": "The selected image does not contain a QR Code.", "qr_error_no_qrcode": "The selected image does not contain a QR Code.",
@ -420,7 +421,7 @@
"native_segwit_title": "Best practice", "native_segwit_title": "Best practice",
"wrapped_segwit_title": "Best compatibility", "wrapped_segwit_title": "Best compatibility",
"legacy_title": "Legacy", "legacy_title": "Legacy",
"co_sign_transaction": "Co-sign QR-airgapped transaction", "co_sign_transaction": "Sign a transaction",
"what_is_vault": "A Vault is a", "what_is_vault": "A Vault is a",
"what_is_vault_numberOfWallets": " {m}-of-{n} multisig ", "what_is_vault_numberOfWallets": " {m}-of-{n} multisig ",
"what_is_vault_wallet": "wallet", "what_is_vault_wallet": "wallet",

View file

@ -8,7 +8,15 @@
"of": "{number} de {total}", "of": "{number} de {total}",
"ok": "OK", "ok": "OK",
"storage_is_encrypted": "Os arquivos estão criptografados, uma senha é necessária para descriptografá-los", "storage_is_encrypted": "Os arquivos estão criptografados, uma senha é necessária para descriptografá-los",
"yes": "Sim" "allow": "Permitir",
"dont_allow": "Não Permitir",
"yes": "Sim",
"no": "Não",
"save": "Salvar",
"seed": "Seed",
"wallet_key": "Wallet key",
"invalid_animated_qr_code_fragment" : "Código QR animado inválido, tente novamente",
"file_saved": "O arquivo ({filePath}) foi salvo na pasta Downloads."
}, },
"azteco": { "azteco": {
"codeIs": "Seu código voucher é", "codeIs": "Seu código voucher é",
@ -204,12 +212,14 @@
"psbt_clipboard": "Copiar para área de transferência", "psbt_clipboard": "Copiar para área de transferência",
"psbt_this_is_psbt": "Esta é uma transação bitcoin parcialmente assinada (PSBT). Por favor, termine de assiná-la com sua carteira de hardware.", "psbt_this_is_psbt": "Esta é uma transação bitcoin parcialmente assinada (PSBT). Por favor, termine de assiná-la com sua carteira de hardware.",
"psbt_tx_export": "Exportar para arquivo", "psbt_tx_export": "Exportar para arquivo",
"no_tx_signing_in_progress": "Não há assinatura de transação em andamento",
"psbt_tx_open": "Abrir transação assinada", "psbt_tx_open": "Abrir transação assinada",
"psbt_tx_scan": "Scanear transação assinada", "psbt_tx_scan": "Scanear transação assinada",
"qr_error_no_qrcode": "A imagem selecionada não contém um Código QR", "qr_error_no_qrcode": "A imagem selecionada não contém um Código QR",
"qr_error_no_wallet": "O arquivo selecionado não contém uma carteira que possa ser importada.", "qr_error_no_wallet": "O arquivo selecionado não contém uma carteira que possa ser importada.",
"success_done": "Enviado", "success_done": "Enviado",
"txSaved": "O arquivo de transação ({filePath}) foi salvo na pasta Downloads." "txSaved": "O arquivo de transação ({filePath}) foi salvo na pasta Downloads.",
"problem_with_psbt": "Problema com a PSBT"
}, },
"settings": { "settings": {
"about": "Sobre", "about": "Sobre",
@ -269,11 +279,23 @@
"password_explain": "Definir a senha para descriptografar os arquivos", "password_explain": "Definir a senha para descriptografar os arquivos",
"passwords_do_not_match": "Senhas não conferem", "passwords_do_not_match": "Senhas não conferem",
"plausible_deniability": "Negação plausível...", "plausible_deniability": "Negação plausível...",
"privacy": "Privacidade",
"privacy_read_clipboard": "Leia a área de transferência",
"privacy_read_clipboard_alert": "A BlueWallet exibirá atalhos para lidar com um boleto ou endereço encontrado em sua área de transferência.",
"privacy_system_settings": "Configurações do sistema",
"privacy_quickactions": "Atalhos da carteira",
"privacy_quickactions_explanation": "Toque e segure o ícone do aplicativo BlueWallet em sua tela inicial para visualizar rapidamente o saldo de sua carteira.",
"privacy_clipboard_explanation": "Fornece atalhos se um endereço ou boleto for encontrado em sua área de transferência.",
"push_notifications": "Notificações via push", "push_notifications": "Notificações via push",
"retype_password": "Inserir senha novamente", "retype_password": "Inserir senha novamente",
"save": "Salvar", "save": "Salvar",
"saved": "Salvo" "saved": "Salvo"
}, },
"notifications": {
"would_you_like_to_receive_notifications": "Gostaria de receber notificações quando receber pagamentos?",
"no_and_dont_ask": "Não e não perguntar",
"ask_me_later": "Me pergunte mais tarde"
},
"transactions": { "transactions": {
"cancel_explain": "Substituiremos esta transação por aquela que lhe paga e tem taxas mais altas. Isso efetivamente cancela a transação. Isso é chamado de RBF - Substituir por Taxa.", "cancel_explain": "Substituiremos esta transação por aquela que lhe paga e tem taxas mais altas. Isso efetivamente cancela a transação. Isso é chamado de RBF - Substituir por Taxa.",
"cancel_no": "Esta transação não é substituível", "cancel_no": "Esta transação não é substituível",
@ -282,6 +304,8 @@
"cpfp_exp": "Criaremos outra transação que gasta sua transação não confirmada. A taxa total será maior do que a taxa de transação original, portanto, deve ser confirmada mais rapidamente. Isso é chamado de CPFP - Child Pays For Parent.", "cpfp_exp": "Criaremos outra transação que gasta sua transação não confirmada. A taxa total será maior do que a taxa de transação original, portanto, deve ser confirmada mais rapidamente. Isso é chamado de CPFP - Child Pays For Parent.",
"cpfp_no_bump": "Esta transação não pode ser Bumpeada", "cpfp_no_bump": "Esta transação não pode ser Bumpeada",
"cpfp_title": "Aumento de taxa (CPFP)", "cpfp_title": "Aumento de taxa (CPFP)",
"details_balance_hide": "Esconder Saldo",
"details_balance_show": "Mostrar Saldo",
"details_block": "Block Height", "details_block": "Block Height",
"details_copy": "Copiar", "details_copy": "Copiar",
"details_from": "De", "details_from": "De",
@ -292,8 +316,9 @@
"details_title": "Transação", "details_title": "Transação",
"details_to": "Para", "details_to": "Para",
"details_transaction_details": "Detalhes", "details_transaction_details": "Detalhes",
"enable_hw": "Esta carteira não está sendo usada em conjunto com uma carteira de hardware. Gostaria de habilitar o uso de carteira de hardware?", "enable_hw": "Esta carteira não está sendo usada em conjunto com uma carteira de hardware. Gostaria de habilitar o uso da carteira de hardware?",
"list_conf": "conf: {number}", "list_conf": "conf: {number}",
"pending": "Pendente",
"list_title": "Transações", "list_title": "Transações",
"rbf_explain": "Substituiremos essa transação por outra com uma taxa mais alta, portanto, ela deve ser confirmada mais rapidamente. Isso é chamado de RBF - Substituir por Taxa.", "rbf_explain": "Substituiremos essa transação por outra com uma taxa mais alta, portanto, ela deve ser confirmada mais rapidamente. Isso é chamado de RBF - Substituir por Taxa.",
"rbf_title": "Aumento de taxa (RBF)", "rbf_title": "Aumento de taxa (RBF)",
@ -302,7 +327,7 @@
"transactions_count": "contagem de transações" "transactions_count": "contagem de transações"
}, },
"wallets": { "wallets": {
"add_bitcoin_explain": "Simple and powerful Bitcoin wallet", "add_bitcoin_explain": "Carteira Bitcoin simples e poderosa",
"add_bitcoin": "Bitcoin", "add_bitcoin": "Bitcoin",
"add_create": "Criar", "add_create": "Criar",
"add_entropy_generated": "{gen} bytes de entropia gerada", "add_entropy_generated": "{gen} bytes de entropia gerada",
@ -311,7 +336,7 @@
"add_import_wallet": "Importar carteira", "add_import_wallet": "Importar carteira",
"import_file": "Importar arquivo", "import_file": "Importar arquivo",
"add_lightning": "Lightning", "add_lightning": "Lightning",
"add_lightning_explain": "For spending with instant transactions", "add_lightning_explain": "Enviar com transações instantâneas",
"add_lndhub": "Conectar ao seu LNDHub", "add_lndhub": "Conectar ao seu LNDHub",
"add_lndhub_error": "O endereço fornecido não é um LNDHub válido", "add_lndhub_error": "O endereço fornecido não é um LNDHub válido",
"add_lndhub_placeholder": "seu endereço de nó", "add_lndhub_placeholder": "seu endereço de nó",
@ -347,11 +372,12 @@
"import_imported": "Importada", "import_imported": "Importada",
"import_scan_qr": "Ler um código QR ou arquivo", "import_scan_qr": "Ler um código QR ou arquivo",
"import_success": "Sucesso", "import_success": "Sucesso",
"looks_like_bip38": "Parece uma chave privada protegida por senha (BIP38)",
"enter_bip38_password": "Digite a senha para descriptografar",
"import_title": "importar", "import_title": "importar",
"list_create_a_button": "Criar agora", "list_create_a_button": "Criar agora",
"list_create_a_wallet": "Criar uma carteira", "list_create_a_wallet": "Criar uma carteira",
"list_create_a_wallet1": "é grátis e você pode criar", "list_create_a_wallet_text": "É grátis e você pode criar\nquantas você quiser",
"list_create_a_wallet2": "quantas desejar",
"list_empty_txs1": "Suas transações aparecerão aqui,", "list_empty_txs1": "Suas transações aparecerão aqui,",
"list_empty_txs1_lightning": "A carteira Relâmpago faz transações super rápidas (coisa de segundos) e tem taxas ridiculamente baratas, ideal para transações diárias e de baixo valor.", "list_empty_txs1_lightning": "A carteira Relâmpago faz transações super rápidas (coisa de segundos) e tem taxas ridiculamente baratas, ideal para transações diárias e de baixo valor.",
"list_empty_txs2": "nenhuma no momento", "list_empty_txs2": "nenhuma no momento",
@ -373,5 +399,58 @@
"select_wallet": "Escolher carteira", "select_wallet": "Escolher carteira",
"xpub_copiedToClipboard": "Copiado para a área de transferência", "xpub_copiedToClipboard": "Copiado para a área de transferência",
"xpub_title": "XPUB" "xpub_title": "XPUB"
},
"multisig": {
"multisig_vault": "Cofre",
"multisig_vault_explain": "Segurança para grandes quantidades",
"provide_signature": "Fornece assinatura",
"vault_key": "Chave do cofre {número}",
"required_keys_out_of_total": "Chaves obrigatórias do total",
"fee": "Taxa: {number}",
"fee_btc": "{number} BTC",
"confirm": "Confirmar",
"header": "Enviar",
"share": "Ver",
"how_many_signatures_can_bluewallet_make": "quantas assinaturas o bluewallet pode fazer",
"scan_or_import_file": "Scan ou importar arquivo",
"export_coordination_setup": "exportação de \"apenas assistir\"",
"cosign_this_transaction": "Assinar esta transação?",
"lets_start": "Vamos começar",
"create": "Criar",
"provide_key": "Forneça a chave",
"native_segwit_title": "Melhor prática",
"wrapped_segwit_title": "Melhor compatibilidade",
"legacy_title": "Antigo",
"co_sign_transaction": "Assinar transação por QR",
"what_is_vault": "Um Cofre é um",
"what_is_vault_numberOfWallets": "{m}-de-{n} multisig",
"what_is_vault_wallet": "wallet",
"vault_advanced_customize": "Configurações do Cofre...",
"needs": "Necessita",
"what_is_vault_description_number_of_vault_keys": "{m} chaves do cofre",
"what_is_vault_description_to_spend": "para gastar e um terceiro você\npode usar como backup.",
"quorum": "{m} de {n} quorum",
"quorum_header": "Quorum",
"of": "de",
"wallet_type": "Tipo de carteira",
"view_key": "ver",
"invalid_mnemonics": "Esta frase mnemônica não parece ser válida",
"invalid_cosigner": "Dados não válidos de assinante",
"invalid_cosigner_format": "Signatário incorreto: este não é um signatário para o formato {format}",
"create_new_key": "Criar nova",
"scan_or_open_file": "Scan ou abrir arquivo",
"i_have_mnemonics": "Eu tenho uma seed para esta chave...",
"please_write_down_mnemonics": "Escreva esta frase mnemônica no papel. Não se preocupe, você pode escrever mais tarde.",
"i_wrote_it_down": "Ok, eu anotei",
"type_your_mnemonics": "Insira uma seed para importar a sua chave do cofre",
"this_is_cosigners_xpub": "Esta é a chave da carteira do co-signatário, pronta para ser importada para outra carteira. É seguro compartilhá-lo.",
"wallet_key_created": "Sua chave do cofre foi criada. Reserve um momento para fazer backup com segurança de sua seed.",
"are_you_sure_seed_will_be_lost": "Você tem certeza? Sua seed mnemônica será perdida se você não tiver um backup",
"forget_this_seed": "Remover seed e use a chave (xpub)",
"invalid_fingerprint": "A \"fingerprint\" desta seed não corresponde à \"fingerprint\" do co-signatário ",
"view_edit_cosigners": "Ver/editar chaves do cofre",
"this_cosigner_is_already_imported": "Este co-signatário já foi importado",
"export_signed_psbt": "Exportar PSBT assinado",
"view_edit_cosigners_title": "Editar co-signatários"
} }
} }

107
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "bluewallet", "name": "bluewallet",
"version": "5.6.6", "version": "5.6.7",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -6382,30 +6382,21 @@
"integrity": "sha512-8IeHfDwJ9/CTUwFs6x90VlobV3BfuPgNLjTgC6dRZovfCWigaZwVNIFFJnHBakK3pW2xErAPwhdvNR4JeNoYbw==" "integrity": "sha512-8IeHfDwJ9/CTUwFs6x90VlobV3BfuPgNLjTgC6dRZovfCWigaZwVNIFFJnHBakK3pW2xErAPwhdvNR4JeNoYbw=="
}, },
"@react-navigation/core": { "@react-navigation/core": {
"version": "5.13.3", "version": "5.14.4",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.13.3.tgz", "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-5.14.4.tgz",
"integrity": "sha512-7p7AJIBARiNzZwcKjInMjbqHDrIub5d0UmGD5ADk+cJqEgE6rCrjyvJBK05QPekuyNI2AFV1CicI0Lnc6hv8EA==", "integrity": "sha512-MzZU9PO1a/6f9KdN04dC/E4BNl6M1Ba0Tb4sQdl/32y0hM2ToxlrKcERnTLWGFIbQV+9ZV1GTrp3mlGS6U9Jpw==",
"requires": { "requires": {
"@react-navigation/routers": "^5.5.1", "@react-navigation/routers": "^5.6.2",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.15", "nanoid": "^3.1.15",
"query-string": "^6.13.6", "query-string": "^6.13.6",
"react-is": "^16.13.0", "react-is": "^16.13.0"
"use-subscription": "^1.5.0"
}, },
"dependencies": { "dependencies": {
"escape-string-regexp": { "escape-string-regexp": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
},
"use-subscription": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.0.tgz",
"integrity": "sha512-/FVRiB2I7NDjzWoNBYPt6YkkvleMm/lFtxj1hH6nX2TVrJ/5UTbovw9OE1efv2Zl0HoAYuTjM7zHd9OsABn5sg==",
"requires": {
"object-assign": "^4.1.1"
}
} }
} }
}, },
@ -6444,29 +6435,57 @@
} }
}, },
"@react-navigation/native": { "@react-navigation/native": {
"version": "5.7.6", "version": "5.8.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.7.6.tgz", "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-5.8.2.tgz",
"integrity": "sha512-u+o9Ifs4//Ah6UczXiaAV+hiWPL0NyTbErj5WayeQUd6K5IIbA1UwumRVWs2Xp8q/4Q9h6FpPHUcKOyiTxhaqA==", "integrity": "sha512-1UzngCpEN2I7ppMw8sN1mcI7SdrOKhQJykzakWCDMonTbOFMpc2fMlPbLa0dLIZMRlp6i3wSd2sD41QqRh29nA==",
"requires": { "requires": {
"@react-navigation/core": "^5.12.5", "@react-navigation/core": "^5.13.2",
"nanoid": "^3.1.12" "escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.15"
},
"dependencies": {
"escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
}
} }
}, },
"@react-navigation/routers": { "@react-navigation/routers": {
"version": "5.5.1", "version": "5.6.2",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.5.1.tgz", "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-5.6.2.tgz",
"integrity": "sha512-Unn2T5+xnolyGzEhiuFnHEGfgvh7+1OJ5KzBY7T65e4gHWT7E1CO8unRbDxRI0KYkXflmRPCfuDjobVTj5xepw==", "integrity": "sha512-XBcDKXS5s4MaHFufN44LtbXqFDH/nUHfHjbwG85fP3k772oRyPRgbnUb2mbw5MFGqORla9T7uymR6Gh6uwIwVw==",
"requires": { "requires": {
"nanoid": "^3.1.15" "nanoid": "^3.1.15"
} }
}, },
"@react-navigation/stack": { "@react-navigation/stack": {
"version": "5.9.3", "version": "5.11.1",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.9.3.tgz", "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-5.11.1.tgz",
"integrity": "sha512-/CJ5Rsrc9bMI20dD8oC/QSZHARMFuUv8DeoiYE7R2N0M44cFupF1CrzaZBBC/S4Zi1ahZ0A+Hj/gAzAEQrNTvA==", "integrity": "sha512-wxGxnQnktf0ByicDAVAQnf6bazC7FynvPYY3o5Zf31i1Ucb+xJcSesDbl5wyeaW1YGiCfFs/K8fUVko3K7fxQA==",
"requires": { "requires": {
"color": "^3.1.2", "color": "^3.1.3",
"react-native-iphone-x-helper": "^1.2.1" "react-native-iphone-x-helper": "^1.3.0"
},
"dependencies": {
"color": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
"integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
"requires": {
"color-convert": "^1.9.1",
"color-string": "^1.5.4"
}
},
"color-string": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz",
"integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==",
"requires": {
"color-name": "^1.0.0",
"simple-swizzle": "^0.2.2"
}
}
} }
}, },
"@remobile/react-native-qrcode-local-image": { "@remobile/react-native-qrcode-local-image": {
@ -9313,9 +9332,9 @@
"dev": true "dev": true
}, },
"detox": { "detox": {
"version": "17.10.2", "version": "17.10.5",
"resolved": "https://registry.npmjs.org/detox/-/detox-17.10.2.tgz", "resolved": "https://registry.npmjs.org/detox/-/detox-17.10.5.tgz",
"integrity": "sha512-gKJgtdJfNk4ZHobd0S93F5i0LH9WthYPZ41fsa+8uA1bEnLKknGTBV3iG+YdHXGRRa7ZkAh0A2SAuwnl0z6P+Q==", "integrity": "sha512-g8ZJrADT3c2wRp1sq/Tt5I6e8Bm8voHij+tQxfo2AXJLrCD09nt02ifjcvPo3CxDO968Q59ZZwsyCLJZVvTFuA==",
"requires": { "requires": {
"bunyan": "^1.8.12", "bunyan": "^1.8.12",
"bunyan-debug-stream": "^1.1.0", "bunyan-debug-stream": "^1.1.0",
@ -9467,16 +9486,16 @@
"integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg=="
}, },
"yargs": { "yargs": {
"version": "16.1.0", "version": "16.1.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.0.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz",
"integrity": "sha512-upWFJOmDdHN0syLuESuvXDmrRcWd1QafJolHskzaw79uZa7/x53gxQKiR07W59GWY1tFhhU/Th9DrtSfpS782g==", "integrity": "sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w==",
"requires": { "requires": {
"cliui": "^7.0.2", "cliui": "^7.0.2",
"escalade": "^3.1.1", "escalade": "^3.1.1",
"get-caller-file": "^2.0.5", "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1", "require-directory": "^2.1.1",
"string-width": "^4.2.0", "string-width": "^4.2.0",
"y18n": "^5.0.2", "y18n": "^5.0.5",
"yargs-parser": "^20.2.2" "yargs-parser": "^20.2.2"
} }
}, },
@ -17262,9 +17281,9 @@
"integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==" "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
}, },
"nanoid": { "nanoid": {
"version": "3.1.16", "version": "3.1.18",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.16.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.18.tgz",
"integrity": "sha512-+AK8MN0WHji40lj8AEuwLOvLSbWYApQpre/aFJZD71r43wVRLrOYS4FmJOPQYon1TqB462RzrrxlfA74XRES8w==" "integrity": "sha512-rndlDjbbHbcV3xi+R2fpJ+PbGMdfBxz5v1fATIQFq0DP64FsicQdwnKLy47K4kZHdRpmQXtz24eGsxQqamzYTA=="
}, },
"nanomatch": { "nanomatch": {
"version": "1.2.13", "version": "1.2.13",
@ -18368,9 +18387,9 @@
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==" "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
}, },
"query-string": { "query-string": {
"version": "6.13.6", "version": "6.13.7",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.6.tgz", "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.7.tgz",
"integrity": "sha512-/WWZ7d9na6s2wMEGdVCVgKWE9Rt7nYyNIf7k8xmHXcesPMlEzicWo3lbYwHyA4wBktI2KrXxxZeACLbE84hvSQ==", "integrity": "sha512-CsGs8ZYb39zu0WLkeOhe0NMePqgYdAuCqxOYKDR5LVCytDZYMGx3Bb+xypvQvPHVPijRXB0HZNFllCzHRe4gEA==",
"requires": { "requires": {
"decode-uri-component": "^0.2.0", "decode-uri-component": "^0.2.0",
"split-on-first": "^1.0.0", "split-on-first": "^1.0.0",
@ -18978,9 +18997,9 @@
} }
}, },
"react-native-iphone-x-helper": { "react-native-iphone-x-helper": {
"version": "1.2.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz", "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.3.1.tgz",
"integrity": "sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ==" "integrity": "sha512-HOf0jzRnq2/aFUcdCJ9w9JGzN3gdEg0zFE4FyYlp4jtidqU03D5X7ZegGKfT1EWteR0gPBGp9ye5T5FvSWi9Yg=="
}, },
"react-native-is-catalyst": { "react-native-is-catalyst": {
"version": "git+https://github.com/BlueWallet/react-native-is-catalyst.git#a665155424ae5b865971f71ba2625b2c53983364", "version": "git+https://github.com/BlueWallet/react-native-is-catalyst.git#a665155424ae5b865971f71ba2625b2c53983364",

View file

@ -1,6 +1,6 @@
{ {
"name": "bluewallet", "name": "bluewallet",
"version": "5.6.6", "version": "5.6.7",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.10.4", "@babel/core": "^7.10.4",
@ -74,8 +74,8 @@
"@react-native-community/push-notification-ios": "1.7.1", "@react-native-community/push-notification-ios": "1.7.1",
"@react-native-community/slider": "3.0.3", "@react-native-community/slider": "3.0.3",
"@react-navigation/drawer": "5.10.0", "@react-navigation/drawer": "5.10.0",
"@react-navigation/native": "5.7.6", "@react-navigation/native": "5.8.2",
"@react-navigation/stack": "5.9.3", "@react-navigation/stack": "5.11.1",
"@remobile/react-native-qrcode-local-image": "git+https://github.com/BlueWallet/react-native-qrcode-local-image.git", "@remobile/react-native-qrcode-local-image": "git+https://github.com/BlueWallet/react-native-qrcode-local-image.git",
"@sentry/react-native": "1.9.0", "@sentry/react-native": "1.9.0",
"amplitude-js": "7.3.0", "amplitude-js": "7.3.0",
@ -95,7 +95,7 @@
"coinselect": "3.1.12", "coinselect": "3.1.12",
"crypto-js": "3.1.9-1", "crypto-js": "3.1.9-1",
"dayjs": "1.9.4", "dayjs": "1.9.4",
"detox": "17.10.2", "detox": "17.10.5",
"ecurve": "1.0.6", "ecurve": "1.0.6",
"electrum-client": "git+https://github.com/BlueWallet/rn-electrum-client.git#f9a827e724a5a2e578fdfdb483f83793af55b030", "electrum-client": "git+https://github.com/BlueWallet/rn-electrum-client.git#f9a827e724a5a2e578fdfdb483f83793af55b030",
"electrum-mnemonic": "2.0.0", "electrum-mnemonic": "2.0.0",

View file

@ -1,11 +1,10 @@
/* global alert */ /* global alert */
import React, { Component } from 'react'; import React, { useContext, useEffect, useRef, useState } from 'react';
import { import {
ActivityIndicator, ActivityIndicator,
TouchableOpacity, TouchableOpacity,
ScrollView, ScrollView,
View, View,
Dimensions,
TextInput, TextInput,
Linking, Linking,
Platform, Platform,
@ -16,7 +15,6 @@ import {
import ImagePicker from 'react-native-image-picker'; import ImagePicker from 'react-native-image-picker';
import Clipboard from '@react-native-community/clipboard'; import Clipboard from '@react-native-community/clipboard';
import { import {
BlueButton,
SecondButton, SecondButton,
BlueText, BlueText,
SafeBlueArea, SafeBlueArea,
@ -24,257 +22,166 @@ import {
BlueNavigationStyle, BlueNavigationStyle,
BlueSpacing20, BlueSpacing20,
BlueCopyToClipboardButton, BlueCopyToClipboardButton,
BlueBigCheckmark,
DynamicQRCode, DynamicQRCode,
} from '../../BlueComponents'; } from '../../BlueComponents';
import PropTypes from 'prop-types';
import Share from 'react-native-share'; import Share from 'react-native-share';
import { getSystemName } from 'react-native-device-info'; import { getSystemName } from 'react-native-device-info';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import RNFS from 'react-native-fs'; import RNFS from 'react-native-fs';
import DocumentPicker from 'react-native-document-picker'; import DocumentPicker from 'react-native-document-picker';
import loc from '../../loc'; import loc from '../../loc';
import { BlueCurrentTheme } from '../../components/themes';
import ScanQRCode from './ScanQRCode'; import ScanQRCode from './ScanQRCode';
import { BlueStorageContext } from '../../blue_modules/storage-context'; import { BlueStorageContext } from '../../blue_modules/storage-context';
import Notifications from '../../blue_modules/notifications'; import Notifications from '../../blue_modules/notifications';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
const BlueElectrum = require('../../blue_modules/BlueElectrum'); const BlueElectrum = require('../../blue_modules/BlueElectrum');
/** @type {AppStorage} */ /** @type {AppStorage} */
const bitcoin = require('bitcoinjs-lib'); const bitcoin = require('bitcoinjs-lib');
const LocalQRCode = require('@remobile/react-native-qrcode-local-image'); const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const { height, width } = Dimensions.get('window');
const isDesktop = getSystemName() === 'Mac OS X'; const isDesktop = getSystemName() === 'Mac OS X';
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
scrollViewContent: {
flexGrow: 1,
justifyContent: 'space-between',
},
container: {
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 16,
paddingBottom: 16,
},
rootCamera: {
flex: 1,
justifyContent: 'space-between',
},
rootPadding: {
flex: 1,
paddingTop: 20,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
closeCamera: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
right: 16,
top: 64,
},
closeCameraImage: {
alignSelf: 'center',
},
blueBigCheckmark: {
marginTop: 143,
marginBottom: 53,
},
hexWrap: {
alignItems: 'center',
flex: 1,
backgroundColor: BlueCurrentTheme.colors.elevated,
},
hexLabel: {
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
},
hexInput: {
borderColor: BlueCurrentTheme.colors.formBorder,
backgroundColor: BlueCurrentTheme.colors.inputBackgroundColor,
borderRadius: 4,
marginTop: 20,
color: BlueCurrentTheme.colors.foregroundColor,
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
},
hexTouch: {
marginVertical: 24,
},
hexText: {
color: BlueCurrentTheme.colors.foregroundColor,
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
},
copyToClipboard: {
justifyContent: 'center',
alignItems: 'center',
},
hidden: {
width: 0,
height: 0,
},
});
export default class PsbtWithHardwareWallet extends Component { const PsbtWithHardwareWallet = () => {
cameraRef = null; const { txMetadata, fetchAndSaveWalletTransactions } = useContext(BlueStorageContext);
static contextType = BlueStorageContext; const navigation = useNavigation();
const route = useRoute();
const { fromWallet, memo, psbt, deepLinkPSBT } = route.params;
const routeParamsPSBT = useRef(route.params.psbt);
const routeParamsTXHex = route.params.txhex;
const { colors } = useTheme();
const [isLoading, setIsLoading] = useState(false);
const [txHex, setTxHex] = useState(route.params.txhex);
_combinePSBT = receivedPSBT => { const stylesHook = StyleSheet.create({
return this.state.fromWallet.combinePsbt(this.state.psbt, receivedPSBT); root: {
backgroundColor: colors.elevated,
},
rootPadding: {
backgroundColor: colors.elevated,
},
hexWrap: {
backgroundColor: colors.elevated,
},
hexLabel: {
color: colors.foregroundColor,
},
hexInput: {
borderColor: colors.formBorder,
backgroundColor: colors.inputBackgroundColor,
color: colors.foregroundColor,
},
hexText: {
color: colors.foregroundColor,
},
});
const _combinePSBT = receivedPSBT => {
return fromWallet.combinePsbt(psbt, receivedPSBT);
}; };
onBarScanned = ret => { const onBarScanned = ret => {
if (ret && !ret.data) ret = { data: ret }; if (ret && !ret.data) ret = { data: ret };
if (ret.data.toUpperCase().startsWith('UR')) { if (ret.data.toUpperCase().startsWith('UR')) {
alert('BC-UR not decoded. This should never happen'); alert('BC-UR not decoded. This should never happen');
} }
if (ret.data.indexOf('+') === -1 && ret.data.indexOf('=') === -1 && ret.data.indexOf('=') === -1) { if (ret.data.indexOf('+') === -1 && ret.data.indexOf('=') === -1 && ret.data.indexOf('=') === -1) {
// this looks like NOT base64, so maybe its transaction's hex // this looks like NOT base64, so maybe its transaction's hex
this.setState({ txhex: ret.data }); setTxHex(ret.data);
return; return;
} }
try { try {
const Tx = this._combinePSBT(ret.data); const Tx = _combinePSBT(ret.data);
this.setState({ txhex: Tx.toHex() }); setTxHex(Tx.toHex());
} catch (Err) { } catch (Err) {
alert(Err); alert(Err);
} }
}; };
constructor(props) { useEffect(() => {
super(props); if (!psbt && !route.params.txhex) {
this.state = { alert(loc.send.no_tx_signing_in_progress);
isLoading: false,
qrCodeHeight: height > width ? width - 40 : width / 3,
memo: props.route.params.memo,
psbt: props.route.params.psbt,
fromWallet: props.route.params.fromWallet,
isSecondPSBTAlreadyBase64: false,
deepLinkPSBT: undefined,
txhex: props.route.params.txhex || undefined,
animatedQRCodeData: [],
};
this.fileName = `${Date.now()}.psbt`;
}
static getDerivedStateFromProps(nextProps, prevState) {
if (!prevState.psbt && !nextProps.route.params.txhex) {
alert('There is no transaction signing in progress');
return {
...prevState,
isLoading: true,
};
} }
const deepLinkPSBT = nextProps.route.params.deepLinkPSBT;
const txhex = nextProps.route.params.txhex;
if (deepLinkPSBT) { if (deepLinkPSBT) {
const psbt = bitcoin.Psbt.fromBase64(deepLinkPSBT); const psbt = bitcoin.Psbt.fromBase64(deepLinkPSBT);
try { try {
const Tx = prevState.fromWallet.combinePsbt(prevState.psbt, psbt); const Tx = fromWallet.combinePsbt(routeParamsPSBT.current, psbt);
return { setTxHex(Tx.toHex());
...prevState,
txhex: Tx.toHex(),
};
} catch (Err) { } catch (Err) {
alert(Err); alert(Err);
} }
} else if (txhex) { } else if (routeParamsTXHex) {
return { setTxHex(routeParamsTXHex);
...prevState,
txhex: txhex,
};
} }
return prevState; // eslint-disable-next-line react-hooks/exhaustive-deps
} }, [deepLinkPSBT, routeParamsTXHex]);
componentDidMount() { const broadcast = async () => {
console.log('send/psbtWithHardwareWallet - componentDidMount'); setIsLoading(true);
} try {
await BlueElectrum.ping();
broadcast = () => { await BlueElectrum.waitTillConnected();
this.setState({ isLoading: true }, async () => { const result = await fromWallet.broadcastTx(txHex);
try { if (result) {
await BlueElectrum.ping(); setIsLoading(false);
await BlueElectrum.waitTillConnected(); const txDecoded = bitcoin.Transaction.fromHex(txHex);
const result = await this.state.fromWallet.broadcastTx(this.state.txhex); const txid = txDecoded.getId();
if (result) { Notifications.majorTomToGroundControl([], [], [txid]);
this.setState({ success: true, isLoading: false }); if (memo) {
const txDecoded = bitcoin.Transaction.fromHex(this.state.txhex); txMetadata[txid] = { memo };
const txid = txDecoded.getId();
Notifications.majorTomToGroundControl([], [], [txid]);
if (this.state.memo) {
this.context.txMetadata[txid] = { memo: this.state.memo };
}
} else {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
this.setState({ isLoading: false });
alert(loc.errors.broadcast);
} }
} catch (error) { fetchAndSaveWalletTransactions(fromWallet.getID());
navigation.navigate('Success', { amount: undefined });
} else {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false }); ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
this.setState({ isLoading: false }); setIsLoading(false);
alert(error.message); alert(loc.errors.broadcast);
} }
}); } catch (error) {
ReactNativeHapticFeedback.trigger('notificationError', { ignoreAndroidSystemSettings: false });
setIsLoading(false);
alert(error.message);
}
}; };
_renderSuccess() { const handleOnVerifyPressed = () => {
return ( Linking.openURL('https://coinb.in/?verify=' + txHex);
<SafeBlueArea style={styles.root}> };
<BlueBigCheckmark style={styles.blueBigCheckmark} />
<BlueCard>
<BlueButton onPress={() => this.props.navigation.dangerouslyGetParent().pop()} title={loc.send.success_done} />
</BlueCard>
</SafeBlueArea>
);
}
_renderBroadcastHex() { const copyHexToClipboard = () => {
return ( Clipboard.setString(txHex);
<View style={styles.rootPadding}> };
<BlueCard style={styles.hexWrap}>
<BlueText style={styles.hexLabel}>{loc.send.create_this_is_hex}</BlueText>
<TextInput style={styles.hexInput} height={112} multiline editable value={this.state.txhex} />
<TouchableOpacity style={styles.hexTouch} onPress={() => Clipboard.setString(this.state.txhex)}> const _renderBroadcastHex = () => {
<Text style={styles.hexText}>{loc.send.create_copy}</Text> return (
<View style={[styles.rootPadding, stylesHook.rootPadding]}>
<BlueCard style={[styles.hexWrap, stylesHook.hexWrap]}>
<BlueText style={[styles.hexLabel, stylesHook.hexLabel]}>{loc.send.create_this_is_hex}</BlueText>
<TextInput style={[styles.hexInput, stylesHook.hexInput]} height={112} multiline editable value={txHex} />
<TouchableOpacity style={styles.hexTouch} onPress={copyHexToClipboard}>
<Text style={[styles.hexText, stylesHook.hexText]}>{loc.send.create_copy}</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity style={styles.hexTouch} onPress={() => Linking.openURL('https://coinb.in/?verify=' + this.state.txhex)}> <TouchableOpacity style={styles.hexTouch} onPress={handleOnVerifyPressed}>
<Text style={styles.hexText}>{loc.send.create_verify}</Text> <Text style={[styles.hexText, stylesHook.hexText]}>{loc.send.create_verify}</Text>
</TouchableOpacity> </TouchableOpacity>
<BlueSpacing20 /> <BlueSpacing20 />
<SecondButton <SecondButton onPress={broadcast} title={loc.send.confirm_sendNow} testID="PsbtWithHardwareWalletBroadcastTransactionButton" />
onPress={this.broadcast}
title={loc.send.confirm_sendNow}
testID="PsbtWithHardwareWalletBroadcastTransactionButton"
/>
</BlueCard> </BlueCard>
</View> </View>
); );
} };
exportPSBT = async () => { const exportPSBT = async () => {
const fileName = `${Date.now()}.psbt`;
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
const filePath = RNFS.TemporaryDirectoryPath + `/${this.fileName}`; const filePath = RNFS.TemporaryDirectoryPath + `/${fileName}`;
await RNFS.writeFile(filePath, typeof this.state.psbt === 'string' ? this.state.psbt : this.state.psbt.toBase64()); await RNFS.writeFile(filePath, typeof psbt === 'string' ? psbt : psbt.toBase64());
Share.open({ Share.open({
url: 'file://' + filePath, url: 'file://' + filePath,
saveToFiles: isDesktop, saveToFiles: isDesktop,
}) })
.catch(error => { .catch(error => {
console.log(error); console.log(error);
alert(error.message);
}) })
.finally(() => { .finally(() => {
RNFS.unlink(filePath); RNFS.unlink(filePath);
@ -290,25 +197,24 @@ export default class PsbtWithHardwareWallet extends Component {
if (granted === PermissionsAndroid.RESULTS.GRANTED) { if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Storage Permission: Granted'); console.log('Storage Permission: Granted');
const filePath = RNFS.DownloadDirectoryPath + `/${this.fileName}`; const filePath = RNFS.DownloadDirectoryPath + `/${fileName}`;
await RNFS.writeFile(filePath, typeof this.state.psbt === 'string' ? this.state.psbt : this.state.psbt.toBase64()); await RNFS.writeFile(filePath, typeof psbt === 'string' ? psbt : psbt.toBase64());
alert(loc.formatString(loc.send.txSaved, { filePath: this.fileName })); alert(loc.formatString(loc.send.txSaved, { filePath: fileName }));
} else { } else {
console.log('Storage Permission: Denied'); console.log('Storage Permission: Denied');
} }
} }
}; };
openSignedTransaction = async () => { const openSignedTransaction = async () => {
try { try {
const res = await DocumentPicker.pick({ const res = await DocumentPicker.pick({
type: Platform.OS === 'ios' ? ['io.bluewallet.psbt', 'io.bluewallt.psbt.txn'] : [DocumentPicker.types.allFiles], type: Platform.OS === 'ios' ? ['io.bluewallet.psbt', 'io.bluewallt.psbt.txn'] : [DocumentPicker.types.allFiles],
}); });
const file = await RNFS.readFile(res.uri); const file = await RNFS.readFile(res.uri);
if (file) { if (file) {
this.setState({ isSecondPSBTAlreadyBase64: true }, () => this.onBarScanned({ data: file })); onBarScanned({ data: file });
} else { } else {
this.setState({ isSecondPSBTAlreadyBase64: false });
throw new Error(); throw new Error();
} }
} catch (err) { } catch (err) {
@ -318,7 +224,7 @@ export default class PsbtWithHardwareWallet extends Component {
} }
}; };
openScanner = () => { const openScanner = () => {
if (isDesktop) { if (isDesktop) {
ImagePicker.launchCamera( ImagePicker.launchCamera(
{ {
@ -331,7 +237,7 @@ export default class PsbtWithHardwareWallet extends Component {
const uri = Platform.OS === 'ios' ? response.uri.toString().replace('file://', '') : response.path.toString(); const uri = Platform.OS === 'ios' ? response.uri.toString().replace('file://', '') : response.path.toString();
LocalQRCode.decode(uri, (error, result) => { LocalQRCode.decode(uri, (error, result) => {
if (!error) { if (!error) {
this.onBarScanned(result); onBarScanned(result);
} else { } else {
alert(loc.send.qr_error_no_qrcode); alert(loc.send.qr_error_no_qrcode);
} }
@ -342,99 +248,134 @@ export default class PsbtWithHardwareWallet extends Component {
}, },
); );
} else { } else {
this.props.navigation.navigate('ScanQRCodeRoot', { navigation.navigate('ScanQRCodeRoot', {
screen: 'ScanQRCode', screen: 'ScanQRCode',
params: { params: {
launchedBy: this.props.route.name, launchedBy: route.name,
showFileImportButton: false, showFileImportButton: false,
onBarScanned: this.onBarScanned, onBarScanned,
}, },
}); });
} }
}; };
render() { if (txHex) return _renderBroadcastHex();
if (this.state.isLoading) {
return ( return isLoading ? (
<View style={styles.rootPadding}> <View style={[styles.rootPadding, stylesHook.rootPadding]}>
<ActivityIndicator /> <ActivityIndicator />
</View>
) : (
<SafeBlueArea style={[styles.root, stylesHook.root]}>
<ScrollView centerContent contentContainerStyle={styles.scrollViewContent} testID="PsbtWithHardwareScrollView">
<View style={styles.container}>
<BlueCard>
<BlueText testID="TextHelperForPSBT">{loc.send.psbt_this_is_psbt}</BlueText>
<BlueSpacing20 />
<Text testID="PSBTHex" style={styles.hidden}>
{psbt.toHex()}
</Text>
<DynamicQRCode value={psbt.toHex()} capacity={200} />
<BlueSpacing20 />
<SecondButton
testID="PsbtTxScanButton"
icon={{
name: 'qrcode',
type: 'font-awesome',
color: colors.buttonTextColor,
}}
onPress={openScanner}
title={loc.send.psbt_tx_scan}
/>
<BlueSpacing20 />
<SecondButton
icon={{
name: 'file-import',
type: 'material-community',
color: colors.buttonTextColor,
}}
onPress={openSignedTransaction}
title={loc.send.psbt_tx_open}
/>
<BlueSpacing20 />
<SecondButton
icon={{
name: 'share-alternative',
type: 'entypo',
color: colors.buttonTextColor,
}}
onPress={exportPSBT}
title={loc.send.psbt_tx_export}
/>
<BlueSpacing20 />
<View style={styles.copyToClipboard}>
<BlueCopyToClipboardButton
stringToCopy={typeof psbt === 'string' ? psbt : psbt.toBase64()}
displayText={loc.send.psbt_clipboard}
/>
</View>
</BlueCard>
</View> </View>
); </ScrollView>
} </SafeBlueArea>
);
if (this.state.success) return this._renderSuccess();
if (this.state.txhex) return this._renderBroadcastHex();
return (
<SafeBlueArea style={styles.root}>
<ScrollView centerContent contentContainerStyle={styles.scrollViewContent} testID="PsbtWithHardwareScrollView">
<View style={styles.container}>
<BlueCard>
<BlueText testID="TextHelperForPSBT">{loc.send.psbt_this_is_psbt}</BlueText>
<BlueSpacing20 />
<Text testID="PSBTHex" style={styles.hidden}>
{this.state.psbt.toHex()}
</Text>
<DynamicQRCode value={this.state.psbt.toHex()} capacity={200} />
<BlueSpacing20 />
<SecondButton
testID="PsbtTxScanButton"
icon={{
name: 'qrcode',
type: 'font-awesome',
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={this.openScanner}
title={loc.send.psbt_tx_scan}
/>
<BlueSpacing20 />
<SecondButton
icon={{
name: 'file-import',
type: 'material-community',
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={this.openSignedTransaction}
title={loc.send.psbt_tx_open}
/>
<BlueSpacing20 />
<SecondButton
icon={{
name: 'share-alternative',
type: 'entypo',
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={this.exportPSBT}
title={loc.send.psbt_tx_export}
/>
<BlueSpacing20 />
<View style={styles.copyToClipboard}>
<BlueCopyToClipboardButton
stringToCopy={typeof this.state.psbt === 'string' ? this.state.psbt : this.state.psbt.toBase64()}
displayText={loc.send.psbt_clipboard}
/>
</View>
</BlueCard>
</View>
</ScrollView>
</SafeBlueArea>
);
}
}
PsbtWithHardwareWallet.propTypes = {
navigation: PropTypes.shape({
goBack: PropTypes.func,
navigate: PropTypes.func,
dangerouslyGetParent: PropTypes.func,
}),
route: PropTypes.shape({
params: PropTypes.object,
name: PropTypes.string,
}),
}; };
export default PsbtWithHardwareWallet;
PsbtWithHardwareWallet.navigationOptions = () => ({ PsbtWithHardwareWallet.navigationOptions = () => ({
...BlueNavigationStyle(null, false), ...BlueNavigationStyle(null, false),
title: loc.send.header, title: loc.send.header,
}); });
const styles = StyleSheet.create({
root: {
flex: 1,
},
scrollViewContent: {
flexGrow: 1,
justifyContent: 'space-between',
},
container: {
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 16,
paddingBottom: 16,
},
rootPadding: {
flex: 1,
paddingTop: 20,
},
hexWrap: {
alignItems: 'center',
flex: 1,
},
hexLabel: {
fontWeight: '500',
},
hexInput: {
borderRadius: 4,
marginTop: 20,
fontWeight: '500',
fontSize: 14,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 16,
},
hexTouch: {
marginVertical: 24,
},
hexText: {
fontSize: 15,
fontWeight: '500',
alignSelf: 'center',
},
copyToClipboard: {
justifyContent: 'center',
alignItems: 'center',
},
hidden: {
width: 0,
height: 0,
},
});

View file

@ -1,9 +1,9 @@
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef } from 'react';
import LottieView from 'lottie-react-native'; import LottieView from 'lottie-react-native';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback'; import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { View, StyleSheet } from 'react-native'; import { View, StyleSheet, SafeAreaView } from 'react-native';
import { Text } from 'react-native-elements'; import { Text } from 'react-native-elements';
import { BlueButton, SafeBlueArea, BlueCard } from '../../BlueComponents'; import { BlueButton, BlueCard } from '../../BlueComponents';
import { BitcoinUnit } from '../../models/bitcoinUnits'; import { BitcoinUnit } from '../../models/bitcoinUnits';
import loc from '../../loc'; import loc from '../../loc';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native'; import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
@ -11,7 +11,7 @@ import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
const Success = () => { const Success = () => {
const { colors } = useTheme(); const { colors } = useTheme();
const { dangerouslyGetParent } = useNavigation(); const { dangerouslyGetParent } = useNavigation();
const { amount, fee = 0, amountUnit = BitcoinUnit.BTC, invoiceDescription = '' } = useRoute().params; const { amount = 0, fee = 0, amountUnit = BitcoinUnit.BTC, invoiceDescription = '' } = useRoute().params;
const animationRef = useRef(); const animationRef = useRef();
const stylesHook = StyleSheet.create({ const stylesHook = StyleSheet.create({
root: { root: {
@ -39,14 +39,16 @@ const Success = () => {
}, [colors]); }, [colors]);
return ( return (
<SafeBlueArea style={[styles.root, stylesHook.root]}> <SafeAreaView style={[styles.root, stylesHook.root]}>
<BlueCard style={styles.amout}> <BlueCard style={styles.amount}>
{amount > 0 && ( <View style={styles.view}>
<View style={styles.view}> {amount > 0 && (
<Text style={[styles.amountValue, stylesHook.amountValue]}>{amount}</Text> <>
<Text style={[styles.amountUnit, stylesHook.amountUnit]}>{' ' + amountUnit}</Text> <Text style={[styles.amountValue, stylesHook.amountValue]}>{amount}</Text>
</View> <Text style={[styles.amountUnit, stylesHook.amountUnit]}>{' ' + amountUnit}</Text>
)} </>
)}
</View>
{fee > 0 && ( {fee > 0 && (
<Text style={styles.feeText}> <Text style={styles.feeText}>
{loc.send.create_fee}: {fee} {BitcoinUnit.BTC} {loc.send.create_fee}: {fee} {BitcoinUnit.BTC}
@ -81,28 +83,26 @@ const Success = () => {
]} ]}
/> />
</View> </View>
<BlueCard> <View style={styles.buttonContainer}>
<BlueButton onPress={pop} title={loc.send.success_done} /> <BlueButton onPress={pop} title={loc.send.success_done} />
</BlueCard> </View>
</SafeBlueArea> </SafeAreaView>
); );
}; };
Success.navigationOptions = {
headerShown: false,
gesturesEnabled: false,
};
export default Success; export default Success;
const styles = StyleSheet.create({ const styles = StyleSheet.create({
root: { root: {
flex: 1, flex: 1,
paddingTop: 19, paddingTop: 19,
justifyContent: 'space-between',
}, },
amout: { buttonContainer: {
padding: 58,
},
amount: {
alignItems: 'center', alignItems: 'center',
flex: 1,
}, },
view: { view: {
flexDirection: 'row', flexDirection: 'row',