mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 18:00:17 +01:00
Merge branch 'master' into fix-3-dots
This commit is contained in:
commit
c8e1f0921e
@ -11,6 +11,7 @@ import {
|
||||
Animated,
|
||||
ActivityIndicator,
|
||||
View,
|
||||
KeyboardAvoidingView,
|
||||
UIManager,
|
||||
StyleSheet,
|
||||
Dimensions,
|
||||
@ -765,16 +766,71 @@ export class BlueUseAllFundsButton extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<InputAccessoryView nativeID={BlueUseAllFundsButton.InputAccessoryViewID}>
|
||||
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Text style={{ color: BlueApp.settings.alternativeTextColor, fontSize: 16, marginHorizontal: 8 }}>
|
||||
Total: {this.props.wallet.getBalance()} {BitcoinUnit.BTC}
|
||||
const inputView = (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
maxHeight: 44,
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#eef0f4',
|
||||
}}
|
||||
>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'flex-start' }}>
|
||||
<Text
|
||||
style={{
|
||||
color: BlueApp.settings.alternativeTextColor,
|
||||
fontSize: 16,
|
||||
marginLeft: 8,
|
||||
marginRight: 0,
|
||||
paddingRight: 0,
|
||||
paddingLeft: 0,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
}}
|
||||
>
|
||||
Total:
|
||||
</Text>
|
||||
<BlueButtonLink title="Use All" onPress={this.props.onUseAllPressed} />
|
||||
{this.props.wallet.allowSendMax() && this.props.wallet.getBalance() > 0 ? (
|
||||
<BlueButtonLink
|
||||
onPress={this.props.onUseAllPressed}
|
||||
style={{ marginLeft: 8, paddingRight: 0, paddingLeft: 0, paddingTop: 12, paddingBottom: 12 }}
|
||||
title={`${loc.formatBalanceWithoutSuffix(this.props.wallet.getBalance(), BitcoinUnit.BTC, true).toString()} ${
|
||||
BitcoinUnit.BTC
|
||||
}`}
|
||||
/>
|
||||
) : (
|
||||
<Text
|
||||
style={{
|
||||
color: BlueApp.settings.alternativeTextColor,
|
||||
fontSize: 16,
|
||||
marginLeft: 8,
|
||||
marginRight: 0,
|
||||
paddingRight: 0,
|
||||
paddingLeft: 0,
|
||||
paddingTop: 12,
|
||||
paddingBottom: 12,
|
||||
}}
|
||||
>
|
||||
{loc.formatBalanceWithoutSuffix(this.props.wallet.getBalance(), BitcoinUnit.BTC, true).toString()} {BitcoinUnit.BTC}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
</InputAccessoryView>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'flex-end', alignItems: 'flex-end' }}>
|
||||
<BlueButtonLink
|
||||
style={{ paddingRight: 8, paddingLeft: 0, paddingTop: 12, paddingBottom: 12 }}
|
||||
title="Done"
|
||||
onPress={Keyboard.dismiss}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
if (Platform.OS === 'ios') {
|
||||
return <InputAccessoryView nativeID={BlueUseAllFundsButton.InputAccessoryViewID}>{inputView}</InputAccessoryView>;
|
||||
} else {
|
||||
return <KeyboardAvoidingView style={{ height: 44 }}>{inputView}</KeyboardAvoidingView>;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1923,6 +1979,7 @@ export class BlueBitcoinAmount extends Component {
|
||||
} else {
|
||||
localCurrency = loc.formatBalanceWithoutSuffix(amount.toString(), BitcoinUnit.LOCAL_CURRENCY, false);
|
||||
}
|
||||
if (amount === BitcoinUnit.MAX) localCurrency = ''; // we dont want to display NaN
|
||||
return (
|
||||
<TouchableWithoutFeedback disabled={this.props.pointerEvents === 'none'} onPress={() => this.textInput.focus()}>
|
||||
<View>
|
||||
@ -1939,6 +1996,12 @@ export class BlueBitcoinAmount extends Component {
|
||||
}
|
||||
this.props.onChangeText(text);
|
||||
}}
|
||||
onBlur={() => {
|
||||
if (this.props.onBlur) this.props.onBlur();
|
||||
}}
|
||||
onFocus={() => {
|
||||
if (this.props.onFocus) this.props.onFocus();
|
||||
}}
|
||||
placeholder="0"
|
||||
maxLength={10}
|
||||
ref={textInput => (this.textInput = textInput)}
|
||||
|
@ -68,6 +68,10 @@ export class AbstractWallet {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSendMax(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
allowRBF() {
|
||||
return false;
|
||||
}
|
||||
|
@ -36,6 +36,10 @@ export class HDSegwitBech32Wallet extends AbstractHDWallet {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSendMax(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
@ -5,6 +5,7 @@ import bip39 from 'bip39';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import b58 from 'bs58check';
|
||||
import signer from '../models/signer';
|
||||
import { BitcoinUnit } from '../models/bitcoinUnits';
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
const bitcoin5 = require('bitcoinjs5');
|
||||
const HDNode = require('bip32');
|
||||
@ -49,6 +50,10 @@ export class HDSegwitP2SHWallet extends AbstractHDWallet {
|
||||
return true;
|
||||
}
|
||||
|
||||
allowSendMax(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
async generate() {
|
||||
let that = this;
|
||||
return new Promise(function(resolve) {
|
||||
@ -255,12 +260,29 @@ export class HDSegwitP2SHWallet extends AbstractHDWallet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param utxos
|
||||
* @param amount Either float (BTC) or string 'MAX' (BitcoinUnit.MAX) to send all
|
||||
* @param fee
|
||||
* @param address
|
||||
* @returns {string}
|
||||
*/
|
||||
createTx(utxos, amount, fee, address) {
|
||||
for (let utxo of utxos) {
|
||||
utxo.wif = this._getWifForAddress(utxo.address);
|
||||
}
|
||||
|
||||
let amountPlusFee = parseFloat(new BigNumber(amount).plus(fee).toString(10));
|
||||
|
||||
if (amount === BitcoinUnit.MAX) {
|
||||
amountPlusFee = new BigNumber(0);
|
||||
for (let utxo of utxos) {
|
||||
amountPlusFee = amountPlusFee.plus(utxo.amount);
|
||||
}
|
||||
amountPlusFee = amountPlusFee.dividedBy(100000000).toString(10);
|
||||
}
|
||||
|
||||
return signer.createHDSegwitTransaction(
|
||||
utxos,
|
||||
address,
|
||||
|
@ -165,7 +165,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Přijmout částku...',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Koupit Bitcoin',
|
||||
|
@ -165,7 +165,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Modtag med beløb',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Køb Bitcoin',
|
||||
|
@ -167,7 +167,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Zu erhaltender Betrag',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Kaufe Bitcoin',
|
||||
|
@ -168,7 +168,7 @@ module.exports = {
|
||||
create: 'Δημιούργησε',
|
||||
setAmount: 'Λάβε με ποσό',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Αγόρασε Bitcoin',
|
||||
|
@ -166,7 +166,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Receive with amount',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Buy Bitcoin',
|
||||
|
@ -167,7 +167,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Receive with amount',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Buy Bitcoin',
|
||||
|
@ -168,7 +168,7 @@ module.exports = {
|
||||
create: 'Luo',
|
||||
setAmount: 'Vastaanotettava summa',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Osta Bitcoinia',
|
||||
|
@ -167,7 +167,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Revevoir avec montant',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Acheter du Bitcoin',
|
||||
|
@ -163,7 +163,7 @@ module.exports = {
|
||||
create: 'Stvori',
|
||||
setAmount: 'Odredi iznos za primiti',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Kupovina Bitcoina',
|
||||
|
@ -165,7 +165,7 @@ module.exports = {
|
||||
create: 'Létrehoz',
|
||||
setAmount: 'Fogadandó összeg',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Bitcoin vásárlása',
|
||||
|
@ -165,7 +165,7 @@ module.exports = {
|
||||
create: 'Buat',
|
||||
setAmount: 'Terima sejumlah',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Beli bitcoin',
|
||||
|
@ -168,7 +168,7 @@ module.exports = {
|
||||
create: 'Crea',
|
||||
setAmount: 'Ricevi con importo',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Compra Bitcoin',
|
||||
|
@ -165,7 +165,7 @@ module.exports = {
|
||||
create: '作成',
|
||||
setAmount: '入金額',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Bitcoin の購入',
|
||||
|
@ -166,7 +166,7 @@ module.exports = {
|
||||
create: 'Lag',
|
||||
setAmount: 'Motta med beløp',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Kjøp Bitcoin',
|
||||
|
@ -166,7 +166,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Ontvang met bedrag',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Koop Bitcoin',
|
||||
|
@ -169,7 +169,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Valor a receber',
|
||||
},
|
||||
scan_lnurl: 'Receber lendo QR'
|
||||
scan_lnurl: 'Receber lendo QR',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Comprar Bitcoin',
|
||||
|
@ -172,7 +172,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Receive with amount',
|
||||
},
|
||||
scan_lnurl: 'Receber lendo QR'
|
||||
scan_lnurl: 'Receber lendo QR',
|
||||
},
|
||||
settings: {
|
||||
tabBarLabel: 'Definições',
|
||||
|
@ -171,7 +171,7 @@ module.exports = {
|
||||
create: 'Создать',
|
||||
setAmount: 'Получить сумму',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
settings: {
|
||||
tabBarLabel: 'Настройки',
|
||||
|
@ -165,7 +165,7 @@ module.exports = {
|
||||
create: 'Skapa',
|
||||
setAmount: 'Ta emot med belopp',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Köp bitcoin',
|
||||
|
@ -165,7 +165,7 @@ module.exports = {
|
||||
create: 'สร้าง',
|
||||
setAmount: 'รับด้วยจำนวน',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'ซื้อบิตคอยน์',
|
||||
|
@ -166,7 +166,7 @@ module.exports = {
|
||||
create: 'Oluştur',
|
||||
setAmount: 'Miktar ile al',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Bitcoin Satın al',
|
||||
|
@ -166,7 +166,7 @@ module.exports = {
|
||||
create: 'Create',
|
||||
setAmount: 'Receive with amount',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: 'Buy Bitcoin',
|
||||
|
@ -163,7 +163,7 @@ module.exports = {
|
||||
create: '创建',
|
||||
setAmount: '收款金额',
|
||||
},
|
||||
scan_lnurl: 'Scan to receive'
|
||||
scan_lnurl: 'Scan to receive',
|
||||
},
|
||||
buyBitcoin: {
|
||||
header: '购买比特币',
|
||||
|
@ -2,6 +2,7 @@ export const BitcoinUnit = Object.freeze({
|
||||
BTC: 'BTC',
|
||||
SATS: 'sats',
|
||||
LOCAL_CURRENCY: 'local_currency',
|
||||
MAX: 'MAX',
|
||||
});
|
||||
|
||||
export const Chain = Object.freeze({
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -3956,8 +3956,8 @@
|
||||
"integrity": "sha512-SfD7WfmueKrtKeHUESLczuANgnpdnfrSz3ZzerLdtmZf2UBZmAB3z9Q525zI5p3n9I7ii/lllUlyKHm2pIG7QQ=="
|
||||
},
|
||||
"electrum-client": {
|
||||
"version": "git+https://github.com/Overtorment/rn-electrum-client.git#d194ff69195ccc86f72088ea3712179b4be9cbb4",
|
||||
"from": "git+https://github.com/Overtorment/rn-electrum-client.git"
|
||||
"version": "git+https://github.com/BlueWallet/rn-electrum-client.git#d194ff69195ccc86f72088ea3712179b4be9cbb4",
|
||||
"from": "git+https://github.com/BlueWallet/rn-electrum-client.git"
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.0",
|
||||
|
@ -65,7 +65,7 @@
|
||||
"coinselect": "3.1.11",
|
||||
"crypto-js": "3.1.9-1",
|
||||
"dayjs": "1.8.14",
|
||||
"electrum-client": "git+https://github.com/Overtorment/rn-electrum-client.git",
|
||||
"electrum-client": "git+https://github.com/BlueWallet/rn-electrum-client.git",
|
||||
"eslint-config-prettier": "6.0.0",
|
||||
"eslint-config-standard": "12.0.0",
|
||||
"eslint-config-standard-react": "7.0.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
module.exports = {
|
||||
dependencies: {
|
||||
'appcenter': {
|
||||
appcenter: {
|
||||
platforms: {
|
||||
android: null, // disable Android platform, other platforms will still autolink if provided
|
||||
},
|
||||
|
@ -1,6 +1,16 @@
|
||||
/* global alert */
|
||||
import React, { Component } from 'react';
|
||||
import { Dimensions, ActivityIndicator, View, TextInput, KeyboardAvoidingView, Keyboard, TouchableWithoutFeedback, TouchableOpacity, Text } from 'react-native';
|
||||
import {
|
||||
Dimensions,
|
||||
ActivityIndicator,
|
||||
View,
|
||||
TextInput,
|
||||
KeyboardAvoidingView,
|
||||
Keyboard,
|
||||
TouchableWithoutFeedback,
|
||||
TouchableOpacity,
|
||||
Text,
|
||||
} from 'react-native';
|
||||
import { BlueNavigationStyle, BlueButton, BlueBitcoinAmount, BlueDismissKeyboardInputAccessory } from '../../BlueComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
import bech32 from 'bech32';
|
||||
@ -42,9 +52,9 @@ export default class LNDCreateInvoice extends Component {
|
||||
|
||||
// send to lnurl-withdraw callback url if that exists
|
||||
if (this.state.lnurlParams) {
|
||||
let {callback, k1} = this.state.lnurlParams;
|
||||
let { callback, k1 } = this.state.lnurlParams;
|
||||
let callbackUrl = callback + (callback.indexOf('?') !== -1 ? '&' : '?') + 'k1=' + k1 + '&pr=' + invoiceRequest;
|
||||
let resp = await fetch(callbackUrl, {method: 'GET'});
|
||||
let resp = await fetch(callbackUrl, { method: 'GET' });
|
||||
if (resp.status >= 300) {
|
||||
let text = await resp.text();
|
||||
throw new Error(text);
|
||||
@ -91,9 +101,9 @@ export default class LNDCreateInvoice extends Component {
|
||||
|
||||
// calling the url
|
||||
try {
|
||||
let resp = await fetch(url, {method: 'GET'})
|
||||
let resp = await fetch(url, { method: 'GET' });
|
||||
if (resp.status >= 300) {
|
||||
throw new Error("Bad response from server");
|
||||
throw new Error('Bad response from server');
|
||||
}
|
||||
let reply = await resp.json();
|
||||
if (reply.status === 'ERROR') {
|
||||
@ -112,7 +122,7 @@ export default class LNDCreateInvoice extends Component {
|
||||
callback: reply.callback,
|
||||
fixed: reply.minWithdrawable === reply.maxWithdrawable,
|
||||
min: (reply.minWithdrawable || 0) / 1000,
|
||||
max: reply.maxWithdrawable / 1000
|
||||
max: reply.maxWithdrawable / 1000,
|
||||
},
|
||||
amount: (reply.maxWithdrawable / 1000).toString(),
|
||||
description: reply.defaultDescription,
|
||||
@ -124,7 +134,7 @@ export default class LNDCreateInvoice extends Component {
|
||||
alert(Err.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderCreateButton = () => {
|
||||
return (
|
||||
@ -142,18 +152,16 @@ export default class LNDCreateInvoice extends Component {
|
||||
return (
|
||||
<View style={{ marginHorizontal: 0, marginVertical: 16, minHeight: 25, alignContent: 'center' }}>
|
||||
<TouchableOpacity
|
||||
onPress={() => NavigationService.navigate('ScanQrAddress', { onBarScanned: this.processLnurl }) }
|
||||
onPress={() => NavigationService.navigate('ScanQrAddress', { onBarScanned: this.processLnurl })}
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
minWidth: width,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Text style={{color: BlueApp.settings.buttonTextColor, textAlign: 'center'}}>
|
||||
{loc.receive.scan_lnurl}
|
||||
</Text>
|
||||
<Text style={{ color: BlueApp.settings.buttonTextColor, textAlign: 'center' }}>{loc.receive.scan_lnurl}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
@ -179,12 +187,12 @@ export default class LNDCreateInvoice extends Component {
|
||||
onChangeText={text => {
|
||||
if (this.state.lnurlParams) {
|
||||
// in this case we prevent the user from changing the amount to < min or > max
|
||||
let {min, max} = this.state.lnurlParams;
|
||||
let nextAmount = parseInt(text)
|
||||
let { min, max } = this.state.lnurlParams;
|
||||
let nextAmount = parseInt(text);
|
||||
if (nextAmount < min) {
|
||||
text = min.toString()
|
||||
text = min.toString();
|
||||
} else if (nextAmount > max) {
|
||||
text = max.toString()
|
||||
text = max.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
ActivityIndicator,
|
||||
View,
|
||||
TextInput,
|
||||
Alert,
|
||||
StatusBar,
|
||||
TouchableOpacity,
|
||||
KeyboardAvoidingView,
|
||||
@ -22,6 +23,7 @@ import {
|
||||
BlueAddressInput,
|
||||
BlueDismissKeyboardInputAccessory,
|
||||
BlueLoading,
|
||||
BlueUseAllFundsButton,
|
||||
} from '../../BlueComponents';
|
||||
import Slider from '@react-native-community/slider';
|
||||
import PropTypes from 'prop-types';
|
||||
@ -71,14 +73,14 @@ export default class SendDetails extends Component {
|
||||
fromSecret = fromWallet.getSecret();
|
||||
}
|
||||
this.state = {
|
||||
isLoading: true,
|
||||
isLoading: false,
|
||||
showSendMax: false,
|
||||
isFeeSelectionModalVisible: false,
|
||||
fromAddress,
|
||||
fromWallet,
|
||||
fromSecret,
|
||||
address,
|
||||
memo,
|
||||
amount: 0,
|
||||
fee: 1,
|
||||
networkTransactionFees: new NetworkTransactionFee(1, 1, 1),
|
||||
feeSliderValue: 1,
|
||||
@ -466,6 +468,9 @@ export default class SendDetails extends Component {
|
||||
|
||||
let targets = [];
|
||||
targets.push({ address: this.state.address, value: satoshis });
|
||||
if (this.state.amount === BitcoinUnit.MAX) {
|
||||
targets = [{ address: this.state.address }];
|
||||
}
|
||||
|
||||
let { tx, fee } = wallet.createTransaction(wallet.getUtxo(), targets, requestedSatPerByte, changeAddress);
|
||||
|
||||
@ -627,9 +632,11 @@ export default class SendDetails extends Component {
|
||||
<KeyboardAvoidingView behavior="position">
|
||||
<BlueBitcoinAmount
|
||||
isLoading={this.state.isLoading}
|
||||
amount={this.state.amount.toString()}
|
||||
amount={this.state.amount ? this.state.amount.toString() : null}
|
||||
onChangeText={text => this.setState({ amount: text })}
|
||||
inputAccessoryViewID={BlueDismissKeyboardInputAccessory.InputAccessoryViewID}
|
||||
inputAccessoryViewID={this.state.fromWallet.allowSendMax() ? BlueUseAllFundsButton.InputAccessoryViewID : null}
|
||||
onFocus={() => this.setState({ isAmountToolbarVisibleForAndroid: true })}
|
||||
onBlur={() => this.setState({ isAmountToolbarVisibleForAndroid: false })}
|
||||
/>
|
||||
<BlueAddressInput
|
||||
onChangeText={text => {
|
||||
@ -714,6 +721,56 @@ export default class SendDetails extends Component {
|
||||
</KeyboardAvoidingView>
|
||||
</View>
|
||||
<BlueDismissKeyboardInputAccessory />
|
||||
{Platform.select({
|
||||
ios: (
|
||||
<BlueUseAllFundsButton
|
||||
onUseAllPressed={() => {
|
||||
ReactNativeHapticFeedback.trigger('notificationWarning');
|
||||
Alert.alert(
|
||||
'Use full balance',
|
||||
`Are you sure you want to use your wallet's full balance for this transaction?`,
|
||||
[
|
||||
{
|
||||
text: loc._.ok,
|
||||
onPress: async () => {
|
||||
this.setState({ amount: 'MAX' });
|
||||
},
|
||||
style: 'default',
|
||||
},
|
||||
{ text: loc.send.details.cancel, onPress: () => {}, style: 'cancel' },
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
Keyboard.dismiss();
|
||||
}}
|
||||
wallet={this.state.fromWallet}
|
||||
/>
|
||||
),
|
||||
android: this.state.isAmountToolbarVisibleForAndroid && (
|
||||
<BlueUseAllFundsButton
|
||||
onUseAllPressed={() => {
|
||||
Alert.alert(
|
||||
'Use all funds',
|
||||
`Are you sure you want to use your all of your wallet's funds for this transaction?`,
|
||||
[
|
||||
{
|
||||
text: loc._.ok,
|
||||
onPress: async () => {
|
||||
this.setState({ amount: 'MAX' });
|
||||
},
|
||||
style: 'default',
|
||||
},
|
||||
{ text: loc.send.details.cancel, onPress: () => {}, style: 'cancel' },
|
||||
],
|
||||
{ cancelable: false },
|
||||
);
|
||||
Keyboard.dismiss();
|
||||
}}
|
||||
wallet={this.state.fromWallet}
|
||||
/>
|
||||
),
|
||||
})}
|
||||
|
||||
{this.renderWalletSelectionButton()}
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
|
@ -1,15 +1,6 @@
|
||||
/* global alert */
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
Text,
|
||||
View,
|
||||
ActivityIndicator,
|
||||
InteractionManager,
|
||||
FlatList,
|
||||
RefreshControl,
|
||||
TouchableOpacity,
|
||||
StatusBar,
|
||||
} from 'react-native';
|
||||
import { Text, View, ActivityIndicator, InteractionManager, FlatList, RefreshControl, TouchableOpacity, StatusBar } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { NavigationEvents } from 'react-navigation';
|
||||
import { BlueSendButtonIcon, BlueReceiveButtonIcon, BlueTransactionListItem, BlueWalletNavigationHeader } from '../../BlueComponents';
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* global it, jasmine, afterAll, beforeAll */
|
||||
import { SegwitP2SHWallet, SegwitBech32Wallet, HDSegwitP2SHWallet, HDLegacyBreadwalletWallet, HDLegacyP2PKHWallet } from '../../class';
|
||||
import {BitcoinUnit} from "../../models/bitcoinUnits";
|
||||
global.crypto = require('crypto'); // shall be used by tests under nodejs CLI, but not in RN environment
|
||||
let assert = require('assert');
|
||||
let bitcoin = require('bitcoinjs-lib');
|
||||
@ -177,6 +178,35 @@ it('HD (BIP49) can create TX', async () => {
|
||||
chunksIn = bitcoin.script.decompile(tx.outs[0].script);
|
||||
toAddress = bitcoin.address.fromOutputScript(chunksIn);
|
||||
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', toAddress);
|
||||
|
||||
// testing sendMAX
|
||||
hd.utxo = [
|
||||
{
|
||||
txid: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
||||
vout: 0,
|
||||
amount: 26000,
|
||||
address: '3GgPyzKfWXiaXMbJ9LeEVGetvEXdrX9Ecj',
|
||||
wif: 'L3fg5Jb6tJDVMvoG2boP4u3CxjX1Er3e7Z4zDALQdGgVLLE8zVUr',
|
||||
},
|
||||
{
|
||||
txid: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
|
||||
vout: 0,
|
||||
amount: 26000,
|
||||
address: '3GgPyzKfWXiaXMbJ9LeEVGetvEXdrX9Ecj',
|
||||
wif: 'L3fg5Jb6tJDVMvoG2boP4u3CxjX1Er3e7Z4zDALQdGgVLLE8zVUr',
|
||||
},
|
||||
{
|
||||
txid: 'cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc',
|
||||
vout: 0,
|
||||
amount: 26000,
|
||||
address: '3GgPyzKfWXiaXMbJ9LeEVGetvEXdrX9Ecj',
|
||||
wif: 'L3fg5Jb6tJDVMvoG2boP4u3CxjX1Er3e7Z4zDALQdGgVLLE8zVUr',
|
||||
},
|
||||
];
|
||||
txhex = hd.createTx(hd.utxo, BitcoinUnit.MAX, 0.00003, '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK');
|
||||
tx = bitcoin.Transaction.fromHex(txhex);
|
||||
assert.strictEqual(tx.outs.length, 1);
|
||||
assert.strictEqual(tx.outs[0].value, 75000);
|
||||
});
|
||||
|
||||
it('Segwit HD (BIP49) can fetch UTXO', async function() {
|
||||
|
Loading…
Reference in New Issue
Block a user