mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-01-19 05:45:15 +01:00
FIX: crash on send from watch-only wallet (closes #1023)
This commit is contained in:
parent
92cc2c8411
commit
c157b108ef
@ -67,10 +67,6 @@ export default class SendDetails extends Component {
|
||||
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
|
||||
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
|
||||
|
||||
let fromAddress;
|
||||
if (props.navigation.state.params) fromAddress = props.navigation.state.params.fromAddress;
|
||||
let fromSecret;
|
||||
if (props.navigation.state.params) fromSecret = props.navigation.state.params.fromSecret;
|
||||
/** @type {LegacyWallet} */
|
||||
let fromWallet = null;
|
||||
if (props.navigation.state.params) fromWallet = props.navigation.state.params.fromWallet;
|
||||
@ -83,8 +79,6 @@ export default class SendDetails extends Component {
|
||||
} else {
|
||||
if (!fromWallet && wallets.length > 0) {
|
||||
fromWallet = wallets[0];
|
||||
fromAddress = fromWallet.getAddress();
|
||||
fromSecret = fromWallet.getSecret();
|
||||
}
|
||||
this.state = {
|
||||
isLoading: false,
|
||||
@ -93,9 +87,7 @@ export default class SendDetails extends Component {
|
||||
isAdvancedTransactionOptionsVisible: false,
|
||||
isTransactionReplaceable: fromWallet.type === HDSegwitBech32Wallet.type,
|
||||
recipientsScrollIndex: 0,
|
||||
fromAddress,
|
||||
fromWallet,
|
||||
fromSecret,
|
||||
addresses: [],
|
||||
memo: '',
|
||||
networkTransactionFees: new NetworkTransactionFee(1, 1, 1),
|
||||
@ -466,7 +458,7 @@ export default class SendDetails extends Component {
|
||||
|
||||
onWalletSelect = wallet => {
|
||||
const changeWallet = () => {
|
||||
this.setState({ fromAddress: wallet.getAddress(), fromSecret: wallet.getSecret(), fromWallet: wallet }, () => {
|
||||
this.setState({ fromWallet: wallet }, () => {
|
||||
this.renderNavigationHeader();
|
||||
this.props.navigation.pop();
|
||||
});
|
||||
@ -1012,9 +1004,7 @@ SendDetails.propTypes = {
|
||||
params: PropTypes.shape({
|
||||
amount: PropTypes.number,
|
||||
address: PropTypes.string,
|
||||
fromAddress: PropTypes.string,
|
||||
satoshiPerByte: PropTypes.string,
|
||||
fromSecret: PropTypes.fromSecret,
|
||||
fromWallet: PropTypes.fromWallet,
|
||||
memo: PropTypes.string,
|
||||
uri: PropTypes.string,
|
||||
|
@ -293,7 +293,9 @@ export default class PsbtWithHardwareWallet extends Component {
|
||||
<ScrollView centerContent contentContainerStyle={{ flexGrow: 1, justifyContent: 'space-between' }}>
|
||||
<View style={{ flexDirection: 'row', justifyContent: 'center', paddingTop: 16, paddingBottom: 16 }}>
|
||||
<BlueCard>
|
||||
<BlueText>This is partially signed bitcoin transaction (PSBT). Please finish signing it with your hardware wallet.</BlueText>
|
||||
<BlueText testID={'TextHelperForPSBT'}>
|
||||
This is partially signed bitcoin transaction (PSBT). Please finish signing it with your hardware wallet.
|
||||
</BlueText>
|
||||
<BlueSpacing20 />
|
||||
<QRCode
|
||||
value={this.state.isFirstPSBTAlreadyBase64 ? this.state.psbt : this.state.psbt.toBase64()}
|
||||
|
@ -428,7 +428,6 @@ export default class WalletTransactions extends Component {
|
||||
}
|
||||
this.props.navigation.navigate('SendDetails', {
|
||||
memo: loc.lnd.refill_lnd_balance,
|
||||
fromSecret: wallet.getSecret(),
|
||||
address: toAddress,
|
||||
fromWallet: wallet,
|
||||
});
|
||||
@ -446,8 +445,6 @@ export default class WalletTransactions extends Component {
|
||||
|
||||
navigateToSendScreen = () => {
|
||||
this.props.navigation.navigate('SendDetails', {
|
||||
fromAddress: this.state.wallet.getAddress(),
|
||||
fromSecret: this.state.wallet.getSecret(),
|
||||
fromWallet: this.state.wallet,
|
||||
});
|
||||
};
|
||||
@ -470,6 +467,7 @@ export default class WalletTransactions extends Component {
|
||||
this.setState({ isLoading: false });
|
||||
this.props.navigation.navigate(this.state.wallet.chain === Chain.ONCHAIN ? 'SendDetails' : 'ScanLndInvoice', {
|
||||
fromSecret: this.state.wallet.getSecret(),
|
||||
// ScanLndInvoice actrually uses `fromSecret` so keeping it for now
|
||||
uri: ret.data ? ret.data : ret,
|
||||
fromWallet: this.state.wallet,
|
||||
});
|
||||
|
@ -309,30 +309,14 @@ describe('BlueWallet UI Tests', () => {
|
||||
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
||||
return;
|
||||
}
|
||||
await yo('WalletsList');
|
||||
|
||||
// going to Import Wallet screen and importing mnemonic for existing BIP84 wallet with real balance
|
||||
await element(by.id('CreateAWallet')).tap();
|
||||
await element(by.id('ImportWallet')).tap();
|
||||
await element(by.id('MnemonicInput')).typeText(process.env.HD_MNEMONIC_BIP84);
|
||||
try {
|
||||
await element(by.id('DoImport')).tap();
|
||||
} catch (_) {}
|
||||
await sleep(60000);
|
||||
await sup('OK', 3 * 61000); // waiting for wallet import
|
||||
await element(by.text('OK')).tap();
|
||||
// ok, wallet imported
|
||||
|
||||
// lets go inside wallet
|
||||
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
||||
// label might change in the future; see HDSegwitBech32Wallet.typeReadable
|
||||
expect(element(by.id('WalletBalance'))).toHaveText('0.00105526 BTC');
|
||||
await helperImportWallet(process.env.HD_MNEMONIC_BIP84, 'Imported HD SegWit (BIP84 Bech32 Native)', '0.00105526 BTC');
|
||||
|
||||
// lets create real transaction:
|
||||
await element(by.id('SendButton')).tap();
|
||||
await element(by.id('AddressInput')).typeText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
||||
await element(by.id('BitcoinAmountInput')).typeText('0.0005\n');
|
||||
await sleep(5000);
|
||||
if (process.env.TRAVIS) await sleep(5000);
|
||||
try {
|
||||
await element(by.id('CreateTransactionButton')).tap();
|
||||
} catch (_) {}
|
||||
@ -370,11 +354,31 @@ describe('BlueWallet UI Tests', () => {
|
||||
}
|
||||
|
||||
let transaction = bitcoin.Transaction.fromHex(txhex);
|
||||
assert.strictEqual(transaction.ins.length, 2);
|
||||
assert.ok(transaction.ins.length === 1 || transaction.ins.length === 2); // depending on current fees gona use either 1 or 2 inputs
|
||||
assert.strictEqual(transaction.outs.length, 2);
|
||||
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[0].script), 'bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl'); // to address
|
||||
assert.strictEqual(transaction.outs[0].value, 50000);
|
||||
});
|
||||
|
||||
it('can import zpub as watch-only and create PSBT', async () => {
|
||||
await helperImportWallet(
|
||||
'zpub6r7jhKKm7BAVx3b3nSnuadY1WnshZYkhK8gKFoRLwK9rF3Mzv28BrGcCGA3ugGtawi1WLb2vyjQAX9ZTDGU5gNk2bLdTc3iEXr6tzR1ipNP',
|
||||
'Imported Watch-only',
|
||||
'0.002 BTC',
|
||||
);
|
||||
|
||||
await element(by.id('SendButton')).tap();
|
||||
await element(by.text('OK')).tap();
|
||||
|
||||
await element(by.id('AddressInput')).typeText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
||||
await element(by.id('BitcoinAmountInput')).typeText('0.0005\n');
|
||||
if (process.env.TRAVIS) await sleep(5000);
|
||||
try {
|
||||
await element(by.id('CreateTransactionButton')).tap();
|
||||
} catch (_) {}
|
||||
|
||||
await yo('TextHelperForPSBT');
|
||||
});
|
||||
});
|
||||
|
||||
async function sleep(ms) {
|
||||
@ -410,3 +414,24 @@ async function helperCreateWallet(walletName) {
|
||||
await expect(element(by.id('WalletsList'))).toBeVisible();
|
||||
await expect(element(by.id(walletName || 'cr34t3d'))).toBeVisible();
|
||||
}
|
||||
|
||||
async function helperImportWallet(importText, expectedWalletLabel, expectedBalance) {
|
||||
await yo('WalletsList');
|
||||
|
||||
// going to Import Wallet screen and importing mnemonic
|
||||
await element(by.id('CreateAWallet')).tap();
|
||||
await element(by.id('ImportWallet')).tap();
|
||||
await element(by.id('MnemonicInput')).typeText(importText);
|
||||
try {
|
||||
await element(by.id('DoImport')).tap();
|
||||
} catch (_) {}
|
||||
if (process.env.TRAVIS) await sleep(60000);
|
||||
await sup('OK', 3 * 61000); // waiting for wallet import
|
||||
await element(by.text('OK')).tap();
|
||||
// ok, wallet imported
|
||||
|
||||
// lets go inside wallet
|
||||
await element(by.text(expectedWalletLabel)).tap();
|
||||
// label might change in the future
|
||||
expect(element(by.id('WalletBalance'))).toHaveText(expectedBalance);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user