mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2024-11-19 09:50:15 +01:00
550 lines
24 KiB
JavaScript
550 lines
24 KiB
JavaScript
import assert from 'assert';
|
|
import * as bitcoin from 'bitcoinjs-lib';
|
|
|
|
import { extractTextFromElementById, hashIt, helperImportWallet, sleep, sup, yo } from './helperz';
|
|
|
|
/**
|
|
* in this suite each test requires that there is one specific wallet present, thus, we import it
|
|
* before anything else.
|
|
* we dont clean it up as we expect other test suites to do clean install of the app
|
|
*/
|
|
|
|
beforeAll(async () => {
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
// reinstalling the app just for any case to clean up app's storage
|
|
await device.launchApp({ delete: true });
|
|
|
|
console.log('before all - importing bip48...');
|
|
await helperImportWallet(process.env.HD_MNEMONIC_BIP84, 'HDsegwitBech32', 'Imported HD SegWit (BIP84 Bech32 Native)', '0.00105526');
|
|
console.log('...imported!');
|
|
await device.pressBack();
|
|
await sleep(15000);
|
|
}, 1200_000);
|
|
|
|
describe('BlueWallet UI Tests - import BIP84 wallet', () => {
|
|
it('can create a transaction; can scanQR with bip21; can switch units', async () => {
|
|
const lockFile = '/tmp/travislock.' + hashIt('t21');
|
|
if (process.env.TRAVIS) {
|
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t21'), 'as it previously passed on Travis');
|
|
}
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
await device.launchApp({ newInstance: true });
|
|
|
|
// go inside the wallet
|
|
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
|
|
|
// lets create real transaction:
|
|
await element(by.id('SendButton')).tap();
|
|
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
|
await element(by.id('BitcoinAmountInput')).typeText('0.0001\n');
|
|
|
|
// setting fee rate:
|
|
const feeRate = 2;
|
|
await element(by.id('chooseFee')).tap();
|
|
await element(by.id('feeCustom')).tap();
|
|
await element(by.type('android.widget.EditText')).typeText(feeRate + '');
|
|
await element(by.text('OK')).tap();
|
|
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
|
|
// created. verifying:
|
|
await yo('TransactionValue');
|
|
await expect(element(by.id('TransactionValue'))).toHaveText('0.0001');
|
|
const transactionFee = await extractTextFromElementById('TransactionFee');
|
|
assert.ok(transactionFee.startsWith('Fee: 0.00000292 BTC'), 'Unexpected tx fee: ' + transactionFee);
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
|
|
let txhex = await extractTextFromElementById('TxhexInput');
|
|
|
|
let transaction = bitcoin.Transaction.fromHex(txhex);
|
|
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, 10000);
|
|
|
|
// checking fee rate:
|
|
const totalIns = 69909; // we hardcode it since we know it in advance
|
|
const totalOuts = transaction.outs.map(el => el.value).reduce((a, b) => a + b, 0);
|
|
const tx = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(Math.round((totalIns - totalOuts) / tx.virtualSize()), feeRate);
|
|
assert.strictEqual(transactionFee.split(' ')[1] * 100000000, totalIns - totalOuts);
|
|
|
|
if (device.getPlatform() === 'ios') {
|
|
console.warn('rest of the test is Android only, skipped');
|
|
return;
|
|
}
|
|
|
|
// now, testing scanQR with bip21:
|
|
|
|
await device.pressBack();
|
|
await device.pressBack();
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to SATS
|
|
await element(by.id('BlueAddressInputScanQrButton')).tap();
|
|
|
|
// tapping 5 times invisible button is a backdoor:
|
|
for (let c = 0; c <= 5; c++) {
|
|
await element(by.id('ScanQrBackdoorButton')).tap();
|
|
await sleep(1000);
|
|
}
|
|
|
|
const bip21 = 'bitcoin:bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7?amount=0.00015&pj=https://btc.donate.kukks.org/BTC/pj';
|
|
await element(by.id('scanQrBackdoorInput')).replaceText(bip21);
|
|
await element(by.id('scanQrBackdoorOkButton')).tap();
|
|
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
// created. verifying:
|
|
await yo('TransactionValue');
|
|
await yo('PayjoinSwitch');
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
txhex = await extractTextFromElementById('TxhexInput');
|
|
transaction = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[0].script), 'bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
|
assert.strictEqual(transaction.outs[0].value, 15000);
|
|
|
|
// now, testing scanQR with just address after amount set to 1.1 USD. Denomination should not change after qrcode scan
|
|
|
|
await device.pressBack();
|
|
await device.pressBack();
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to SATS
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to FIAT
|
|
await element(by.id('BitcoinAmountInput')).replaceText('1.1');
|
|
await element(by.id('BlueAddressInputScanQrButton')).tap();
|
|
|
|
// tapping 5 times invisible button is a backdoor:
|
|
for (let c = 0; c <= 5; c++) {
|
|
await element(by.id('ScanQrBackdoorButton')).tap();
|
|
await sleep(1000);
|
|
}
|
|
|
|
await element(by.id('scanQrBackdoorInput')).replaceText('bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
|
await element(by.id('scanQrBackdoorOkButton')).tap();
|
|
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
// created. verifying:
|
|
await yo('TransactionValue');
|
|
await yo('PayjoinSwitch');
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
txhex = await extractTextFromElementById('TxhexInput');
|
|
transaction = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[0].script), 'bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
|
assert.notEqual(transaction.outs[0].value, 110000000); // check that it is 1.1 USD, not 1 BTC
|
|
assert.ok(transaction.outs[0].value < 10000); // 1.1 USD ~ 0,00001964 sats in march 2021
|
|
|
|
// now, testing units switching, and then creating tx with SATS:
|
|
|
|
await device.pressBack();
|
|
await device.pressBack();
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to BTC
|
|
await element(by.id('BitcoinAmountInput')).replaceText('0.00015');
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to sats
|
|
assert.strictEqual(await extractTextFromElementById('BitcoinAmountInput'), '15000');
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to FIAT
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to BTC
|
|
assert.strictEqual(await extractTextFromElementById('BitcoinAmountInput'), '0.00015');
|
|
await element(by.id('changeAmountUnitButton')).tap(); // switched to sats
|
|
await element(by.id('BitcoinAmountInput')).replaceText('50000');
|
|
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
// created. verifying:
|
|
await yo('TransactionValue');
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
txhex = await extractTextFromElementById('TxhexInput');
|
|
transaction = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(transaction.outs.length, 2);
|
|
assert.strictEqual(transaction.outs[0].value, 50000);
|
|
|
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
|
});
|
|
|
|
it('can batch send', async () => {
|
|
const lockFile = '/tmp/travislock.' + hashIt('t_batch_send');
|
|
if (process.env.TRAVIS) {
|
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping as it previously passed on Travis');
|
|
}
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
await device.launchApp({ newInstance: true });
|
|
|
|
// go inside the wallet
|
|
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
|
await element(by.id('SendButton')).tap();
|
|
|
|
// lets create real transaction:
|
|
await element(by.id('AddressInput')).replaceText('bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
|
await element(by.id('BitcoinAmountInput')).replaceText('0.0001\n');
|
|
|
|
// setting fee rate:
|
|
const feeRate = 2;
|
|
await element(by.id('chooseFee')).tap();
|
|
await element(by.id('feeCustom')).tap();
|
|
await element(by.type('android.widget.EditText')).replaceText(feeRate + '');
|
|
await element(by.text('OK')).tap();
|
|
|
|
// lest add another two outputs
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('AddRecipient')).tap();
|
|
await yo('Transaction1'); // adding a recipient autoscrolls it to the last one
|
|
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
|
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).replaceText('0.0002\n');
|
|
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('AddRecipient')).tap();
|
|
await yo('Transaction2'); // adding a recipient autoscrolls it to the last one
|
|
|
|
// remove last output, check if second output is shown
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('RemoveRecipient')).tap();
|
|
await yo('Transaction1');
|
|
|
|
// adding it again
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('AddRecipient')).tap();
|
|
await yo('Transaction2'); // adding a recipient autoscrolls it to the last one
|
|
await element(by.id('AddressInput').withAncestor(by.id('Transaction2'))).replaceText('bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7');
|
|
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction2'))).replaceText('0.0003\n');
|
|
|
|
// remove second output
|
|
await element(by.id('Transaction2')).swipe('right', 'fast', NaN, 0.2);
|
|
await sleep(5000);
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('RemoveRecipient')).tap();
|
|
|
|
// creating and verifying. tx should have 3 outputs
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
const txhex = await extractTextFromElementById('TxhexInput');
|
|
const transaction = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(transaction.outs.length, 3);
|
|
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[0].script), 'bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
|
assert.strictEqual(transaction.outs[0].value, 10000);
|
|
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[1].script), 'bc1qh6tf004ty7z7un2v5ntu4mkf630545gvhs45u7');
|
|
assert.strictEqual(transaction.outs[1].value, 30000, `got txhex ${txhex}`);
|
|
|
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
|
});
|
|
|
|
it('can sendMAX', async () => {
|
|
const lockFile = '/tmp/travislock.' + hashIt('t_sendMAX');
|
|
if (process.env.TRAVIS) {
|
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping as it previously passed on Travis');
|
|
}
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
await device.launchApp({ newInstance: true });
|
|
|
|
// go inside the wallet
|
|
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
|
|
|
await element(by.id('SendButton')).tap();
|
|
|
|
// set fee rate
|
|
const feeRate = 2;
|
|
await element(by.id('chooseFee')).tap();
|
|
await element(by.id('feeCustom')).tap();
|
|
await element(by.type('android.widget.EditText')).typeText(feeRate + '');
|
|
await element(by.text('OK')).tap();
|
|
|
|
// first send MAX output
|
|
await element(by.id('AddressInput')).replaceText('bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
|
await element(by.id('BitcoinAmountInput')).typeText('0.0001\n');
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('sendMaxButton')).tap();
|
|
await element(by.text('OK')).tap();
|
|
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
// created. verifying:
|
|
await yo('TransactionDetailsButton');
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
let txhex = await extractTextFromElementById('TxhexInput');
|
|
let transaction = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(transaction.outs.length, 1, 'should be single output, no change');
|
|
assert.ok(transaction.outs[0].value > 100000);
|
|
|
|
// add second output with amount
|
|
await device.pressBack();
|
|
await device.pressBack();
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('AddRecipient')).tap();
|
|
await yo('Transaction1');
|
|
await element(by.id('AddressInput').withAncestor(by.id('Transaction1'))).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
|
await element(by.id('BitcoinAmountInput').withAncestor(by.id('Transaction1'))).typeText('0.0001\n');
|
|
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
// created. verifying:
|
|
await yo('TransactionDetailsButton');
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
txhex = await extractTextFromElementById('TxhexInput');
|
|
transaction = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(transaction.outs.length, 2, 'should be single output, no change');
|
|
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[0].script), 'bc1qnapskphjnwzw2w3dk4anpxntunc77v6qrua0f7');
|
|
assert.ok(transaction.outs[0].value > 50000);
|
|
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[1].script), 'bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
|
assert.strictEqual(transaction.outs[1].value, 10000);
|
|
|
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
|
});
|
|
|
|
it('can cosign psbt', async () => {
|
|
const lockFile = '/tmp/travislock.' + hashIt('t_cosign');
|
|
if (process.env.TRAVIS) {
|
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping as it previously passed on Travis');
|
|
}
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
await device.launchApp({ newInstance: true });
|
|
|
|
// go inside the wallet
|
|
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
|
await element(by.id('SendButton')).tap();
|
|
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('PsbtSign')).tap();
|
|
|
|
// tapping 5 times invisible button is a backdoor:
|
|
for (let c = 0; c <= 5; c++) {
|
|
await element(by.id('ScanQrBackdoorButton')).tap();
|
|
await sleep(1000);
|
|
}
|
|
// 1 input, 2 outputs. wallet can fully sign this tx
|
|
const psbt =
|
|
'cHNidP8BAFICAAAAAXYa7FEQBAQ2X0B48aHHKKgzkVuHfQ2yCOi3v9RR0IqlAQAAAAAAAACAAegDAAAAAAAAFgAUSnH40G+jiJfreeRb36cs641KFm8AAAAAAAEBH5YVAAAAAAAAFgAUTKHjDm4OJQSbvy9uzyLYi5i5XIoiBgMQcGrP5TIMrdvb73yB4WnZvkPzKr1EzJXJYBHWmlPJZRgAAAAAVAAAgAAAAIAAAACAAQAAAD4AAAAAAA==';
|
|
await element(by.id('scanQrBackdoorInput')).replaceText(psbt);
|
|
await element(by.id('scanQrBackdoorOkButton')).tap();
|
|
|
|
// this is fully-signed tx, "this is tx hex" help text should appear
|
|
await yo('DynamicCode');
|
|
|
|
const txhex = await extractTextFromElementById('TxhexInput');
|
|
console.warn(txhex);
|
|
const transaction = bitcoin.Transaction.fromHex(txhex);
|
|
assert.strictEqual(transaction.ins.length, 1);
|
|
assert.strictEqual(transaction.outs.length, 1);
|
|
assert.strictEqual(bitcoin.address.fromOutputScript(transaction.outs[0].script), 'bc1qffcl35r05wyf06meu3dalfevawx559n0ufrxcw'); // to address
|
|
assert.strictEqual(transaction.outs[0].value, 1000);
|
|
|
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
|
});
|
|
|
|
it('can do basic wallet-details operations', async () => {
|
|
const lockFile = '/tmp/travislock.' + hashIt('t_walletdetails');
|
|
if (process.env.TRAVIS) {
|
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping as it previously passed on Travis');
|
|
}
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
await device.launchApp({ newInstance: true });
|
|
|
|
// go inside the wallet
|
|
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
|
|
|
// let's test wallet details screens
|
|
await element(by.id('WalletDetails')).tap();
|
|
|
|
// rename test
|
|
await element(by.id('WalletNameInput')).replaceText('testname\n');
|
|
await element(by.id('Save')).tap();
|
|
await sup('OK');
|
|
await element(by.text('OK')).tap();
|
|
await expect(element(by.id('WalletLabel'))).toHaveText('testname');
|
|
await element(by.id('WalletDetails')).tap();
|
|
|
|
// rename back
|
|
await element(by.id('WalletNameInput')).replaceText('Imported HD SegWit (BIP84 Bech32 Native)\n');
|
|
await element(by.id('Save')).tap();
|
|
await sup('OK');
|
|
await element(by.text('OK')).tap();
|
|
await expect(element(by.id('WalletLabel'))).toHaveText('Imported HD SegWit (BIP84 Bech32 Native)');
|
|
await element(by.id('WalletDetails')).tap();
|
|
|
|
// wallet export
|
|
await element(by.id('WalletDetailsScroll')).swipe('up', 'fast', 1);
|
|
await element(by.id('WalletExport')).tap();
|
|
await element(by.id('WalletExportScroll')).swipe('up', 'fast', 1);
|
|
await expect(element(by.id('Secret'))).toHaveText(process.env.HD_MNEMONIC_BIP84);
|
|
await device.pressBack();
|
|
|
|
// XPUB
|
|
await element(by.id('WalletDetailsScroll')).swipe('up', 'fast', 1);
|
|
await element(by.id('XPub')).tap();
|
|
await expect(element(by.id('CopyTextToClipboard'))).toBeVisible();
|
|
await device.pressBack();
|
|
|
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
|
});
|
|
|
|
it('should handle URL successfully', async () => {
|
|
const lockFile = '/tmp/travislock.' + hashIt('t22');
|
|
if (process.env.TRAVIS) {
|
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t22'), 'as it previously passed on Travis');
|
|
}
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
await device.launchApp({ newInstance: true });
|
|
|
|
await device.launchApp({
|
|
newInstance: true,
|
|
url: 'bitcoin:BC1QH6TF004TY7Z7UN2V5NTU4MKF630545GVHS45U7?amount=0.0001&label=Yo',
|
|
});
|
|
|
|
// setting fee rate:
|
|
const feeRate = 2;
|
|
await element(by.id('chooseFee')).tap();
|
|
await element(by.id('feeCustom')).tap();
|
|
await element(by.type('android.widget.EditText')).typeText(feeRate + '');
|
|
await element(by.text('OK')).tap();
|
|
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
try {
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
} catch (_) {}
|
|
|
|
// created. verifying:
|
|
await yo('TransactionValue');
|
|
await expect(element(by.id('TransactionValue'))).toHaveText('0.0001');
|
|
await expect(element(by.id('TransactionAddress'))).toHaveText('BC1QH6TF004TY7Z7UN2V5NTU4MKF630545GVHS45U7');
|
|
|
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
|
});
|
|
|
|
it('can manage UTXO', async () => {
|
|
const lockFile = '/tmp/travislock.' + hashIt('t23');
|
|
if (process.env.TRAVIS) {
|
|
if (require('fs').existsSync(lockFile)) return console.warn('skipping', JSON.stringify('t23'), 'as it previously passed on Travis');
|
|
}
|
|
if (!process.env.HD_MNEMONIC_BIP84) {
|
|
console.error('process.env.HD_MNEMONIC_BIP84 not set, skipped');
|
|
return;
|
|
}
|
|
await device.launchApp({ newInstance: true });
|
|
// go inside the wallet
|
|
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
|
|
|
await waitFor(element(by.id('NoTxBuyBitcoin')))
|
|
.not.toExist()
|
|
.withTimeout(300 * 1000);
|
|
|
|
// change note of 0.00069909 tx output
|
|
await element(by.text('0.00069909')).atIndex(0).tap();
|
|
await element(by.text('Details')).tap();
|
|
await expect(element(by.text('8b0ab2c7196312e021e0d3dc73f801693826428782970763df6134457bd2ec20'))).toBeVisible();
|
|
await element(by.type('android.widget.EditText')).typeText('test1');
|
|
await element(by.text('Save')).tap();
|
|
await element(by.text('OK')).tap();
|
|
|
|
// Terminate and reopen the app to confirm the note is persisted
|
|
await device.launchApp({ newInstance: true });
|
|
await yo('WalletsList');
|
|
await element(by.text('Imported HD SegWit (BIP84 Bech32 Native)')).tap();
|
|
await element(by.id('SendButton')).tap();
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('CoinControl')).tap();
|
|
await waitFor(element(by.id('Loading'))) // wait for outputs to be loaded
|
|
.not.toExist()
|
|
.withTimeout(300 * 1000);
|
|
await expect(element(by.text('test1')).atIndex(0)).toBeVisible();
|
|
|
|
// change output note and freeze it
|
|
await element(by.text('test1')).atIndex(0).tap();
|
|
await element(by.id('OutputMemo')).replaceText('test2');
|
|
await element(by.type('android.widget.CompoundButton')).tap(); // freeze switch
|
|
await device.pressBack(); // closing modal
|
|
await expect(element(by.text('test2')).atIndex(0)).toBeVisible();
|
|
await expect(element(by.text('Freeze')).atIndex(0)).toBeVisible();
|
|
|
|
// use frozen output to create tx using "Use coin" feature
|
|
await element(by.text('test2')).atIndex(0).tap();
|
|
await element(by.id('UseCoin')).tap();
|
|
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('sendMaxButton')).tap();
|
|
await element(by.text('OK')).tap();
|
|
// setting fee rate:
|
|
await element(by.id('chooseFee')).tap();
|
|
await element(by.id('feeCustom')).tap();
|
|
await element(by.type('android.widget.EditText')).typeText('1');
|
|
await element(by.text('OK')).tap();
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
|
|
const txhex1 = await extractTextFromElementById('TxhexInput');
|
|
const tx1 = bitcoin.Transaction.fromHex(txhex1);
|
|
assert.strictEqual(tx1.outs.length, 1);
|
|
assert.strictEqual(tx1.outs[0].script.toString('hex'), '00147ea385f352be696ab0f6e94a0ee0e3c6d4b14a53');
|
|
assert.strictEqual(tx1.outs[0].value, 69797);
|
|
assert.strictEqual(tx1.ins.length, 1);
|
|
assert.strictEqual(tx1.ins[0].hash.toString('hex'), '20ecd27b453461df63079782874226386901f873dcd3e021e0126319c7b20a8b');
|
|
assert.strictEqual(tx1.ins[0].index, 0);
|
|
|
|
// back to wallet screen
|
|
await device.pressBack();
|
|
await device.pressBack();
|
|
await device.pressBack();
|
|
|
|
// create tx with unfrozen input
|
|
await element(by.id('SendButton')).tap();
|
|
await element(by.id('AddressInput')).replaceText('bc1q063ctu6jhe5k4v8ka99qac8rcm2tzjjnuktyrl');
|
|
await element(by.id('advancedOptionsMenuButton')).tap();
|
|
await element(by.id('sendMaxButton')).tap();
|
|
await element(by.text('OK')).tap();
|
|
// setting fee rate:
|
|
await element(by.id('chooseFee')).tap();
|
|
await element(by.id('feeCustom')).tap();
|
|
await element(by.type('android.widget.EditText')).typeText('1');
|
|
await element(by.text('OK')).tap();
|
|
if (process.env.TRAVIS) await sleep(5000);
|
|
await element(by.id('CreateTransactionButton')).tap();
|
|
await element(by.id('TransactionDetailsButton')).tap();
|
|
|
|
const txhex2 = await extractTextFromElementById('TxhexInput');
|
|
const tx2 = bitcoin.Transaction.fromHex(txhex2);
|
|
|
|
assert.strictEqual(tx2.outs.length, 1);
|
|
assert.strictEqual(tx2.outs[0].script.toString('hex'), '00147ea385f352be696ab0f6e94a0ee0e3c6d4b14a53');
|
|
assert.strictEqual(tx2.outs[0].value, 35369);
|
|
assert.strictEqual(tx2.ins.length, 3);
|
|
assert.strictEqual(tx2.ins[0].hash.toString('hex'), 'd479264875a0f7c4a84e47141be005404531a8655f2388ae21e89a9701f14c10');
|
|
assert.strictEqual(tx2.ins[0].index, 0);
|
|
|
|
process.env.TRAVIS && require('fs').writeFileSync(lockFile, '1');
|
|
});
|
|
});
|