diff --git a/.eslintrc b/.eslintrc index 288d3d994..980ecf460 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,6 +9,7 @@ 'warn', { singleQuote: true, + printWidth: 140, trailingComma: 'all' } ] diff --git a/App.js b/App.js index a0a278da6..10c8ac339 100644 --- a/App.js +++ b/App.js @@ -23,14 +23,8 @@ const appjson = require('./app.json'); const CustomDrawerContentComponent = props => ( - - props.navigation.navigate('About')} - style={styles.heading} - > + + props.navigation.navigate('About')} style={styles.heading}> {' '} {pkg.name} v{pkg.version} (build {appjson.expo.ios.buildNumber}) diff --git a/App.test.js b/App.test.js index 2772b3743..bbd59738f 100644 --- a/App.test.js +++ b/App.test.js @@ -10,6 +10,7 @@ let assert = require('assert'); jest.mock('react-native-qrcode', () => 'Video'); const AsyncStorage = new MockStorage(); jest.setMock('AsyncStorage', AsyncStorage); +jest.useFakeTimers(); jest.mock('Picker', () => { // eslint-disable-next-line import/no-unresolved const React = require('React'); @@ -164,9 +165,7 @@ it('Appstorage - encryptStorage & load encrypted storage works', async () => { assert.equal(Storage2.wallets[1].getLabel(), 'testlabel2'); // next, adding new `fake` storage which should be unlocked with `fake` password - let createFakeStorageResult = await Storage2.createFakeStorage( - 'fakePassword', - ); + let createFakeStorageResult = await Storage2.createFakeStorage('fakePassword'); assert.ok(createFakeStorageResult); assert.equal(Storage2.wallets.length, 0); assert.equal(Storage2.cachedPassword, 'fakePassword'); @@ -190,46 +189,6 @@ it('Appstorage - encryptStorage & load encrypted storage works', async () => { assert.equal(Storage3.wallets[0].getLabel(), 'fakewallet'); }); -it('bip38 decodes', async () => { - const bip38 = require('./bip38'); - const wif = require('wif'); - - let encryptedKey = - '6PRVWUbkzq2VVjRuv58jpwVjTeN46MeNmzUHqUjQptBJUHGcBakduhrUNc'; - let decryptedKey = await bip38.decrypt( - encryptedKey, - 'TestingOneTwoThree', - () => {}, - { N: 1, r: 8, p: 8 }, // using non-default parameters to speed it up (not-bip38 compliant) - ); - - assert.equal( - wif.encode(0x80, decryptedKey.privateKey, decryptedKey.compressed), - '5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR', - ); -}); - -it('bip38 decodes slow', async () => { - if (process.env.USER === 'burn') { - // run only on circleCI - return; - } - jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000; - const bip38 = require('bip38'); - const wif = require('wif'); - - let encryptedKey = - '6PnU5voARjBBykwSddwCdcn6Eu9EcsK24Gs5zWxbJbPZYW7eiYQP8XgKbN'; - let decryptedKey = await bip38.decrypt(encryptedKey, 'qwerty', status => - process.stdout.write(parseInt(status.percent) + '%\r'), - ); - - assert.equal( - wif.encode(0x80, decryptedKey.privateKey, decryptedKey.compressed), - 'KxqRtpd9vFju297ACPKHrGkgXuberTveZPXbRDiQ3MXZycSQYtjc', - ); -}); - it('Wallet can fetch UTXO', async () => { jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000; let w = new SegwitP2SHWallet(); @@ -251,11 +210,20 @@ it('Wallet can fetch balance', async () => { assert.ok(w._lastBalanceFetch > 0); }); +it.skip('Wallet can fetch TXs', async () => { + let w = new LegacyWallet(); + w._address = '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG'; + await w.fetchTransactions(); + console.log('txs num:', w.getTransactions().length); + assert.equal(w.getTransactions().length, 2); +}); + describe('currency', () => { - it.only('fetches exchange rate and saves to AsyncStorage', async () => { + it('fetches exchange rate and saves to AsyncStorage', async () => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000; AsyncStorage.storageCache = {}; // cleanup from other tests let currency = require('./currency'); - await currency.startUpdater(true); + await currency.startUpdater(); let cur = AsyncStorage.storageCache[AppStorage.CURRENCY]; cur = JSON.parse(cur); assert.ok(Number.isInteger(cur[currency.STRUCT.LAST_UPDATED])); diff --git a/App2.test.js b/App2.test.js new file mode 100644 index 000000000..528cd67f4 --- /dev/null +++ b/App2.test.js @@ -0,0 +1,32 @@ +/* global it, jasmine */ +let assert = require('assert'); + +it('bip38 decodes', async () => { + const bip38 = require('./bip38'); + const wif = require('wif'); + + let encryptedKey = '6PRVWUbkzq2VVjRuv58jpwVjTeN46MeNmzUHqUjQptBJUHGcBakduhrUNc'; + let decryptedKey = await bip38.decrypt( + encryptedKey, + 'TestingOneTwoThree', + () => {}, + { N: 1, r: 8, p: 8 }, // using non-default parameters to speed it up (not-bip38 compliant) + ); + + assert.equal(wif.encode(0x80, decryptedKey.privateKey, decryptedKey.compressed), '5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR'); +}); + +it('bip38 decodes slow', async () => { + if (process.env.USER === 'burn' || process.env.USER === 'igor') { + // run only on circleCI + return; + } + jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000; + const bip38 = require('bip38'); + const wif = require('wif'); + + let encryptedKey = '6PnU5voARjBBykwSddwCdcn6Eu9EcsK24Gs5zWxbJbPZYW7eiYQP8XgKbN'; + let decryptedKey = await bip38.decrypt(encryptedKey, 'qwerty', status => process.stdout.write(parseInt(status.percent) + '%\r')); + + assert.equal(wif.encode(0x80, decryptedKey.privateKey, decryptedKey.compressed), 'KxqRtpd9vFju297ACPKHrGkgXuberTveZPXbRDiQ3MXZycSQYtjc'); +}); diff --git a/BlueApp.js b/BlueApp.js index 335fe639e..73f27572f 100644 --- a/BlueApp.js +++ b/BlueApp.js @@ -15,10 +15,7 @@ async function startAndDecrypt(retry) { let password = false; if (await BlueApp.storageIsEncrypted()) { do { - password = await prompt( - (retry && loc._.bad_password) || loc._.enter_password, - loc._.storage_is_encrypted, - ); + password = await prompt((retry && loc._.bad_password) || loc._.enter_password, loc._.storage_is_encrypted); } while (!password); } let success = await BlueApp.loadFromDisk(password); @@ -35,10 +32,7 @@ async function startAndDecrypt(retry) { console.log('time to refresh wallet #0'); let oldBalance = wallets[0].getBalance(); await wallets[0].fetchBalance(); - if ( - oldBalance !== wallets[0].getBalance() || - wallets[0].getUnconfirmedBalance() !== 0 - ) { + if (oldBalance !== wallets[0].getBalance() || wallets[0].getUnconfirmedBalance() !== 0) { // balance changed, thus txs too await wallets[0].fetchTransactions(); hadToRefresh = true; diff --git a/BlueComponents.js b/BlueComponents.js index fab79cdc4..32ca68d59 100644 --- a/BlueComponents.js +++ b/BlueComponents.js @@ -3,25 +3,8 @@ import React, { Component } from 'react'; import { SafeAreaView } from 'react-navigation'; import Ionicons from 'react-native-vector-icons/Ionicons'; import { LinearGradient } from 'expo'; -import { - Icon, - Button, - FormLabel, - FormInput, - Card, - Text, - Header, - List, - ListItem, -} from 'react-native-elements'; -import { - TouchableOpacity, - ActivityIndicator, - View, - StyleSheet, - Dimensions, - Image, -} from 'react-native'; +import { Icon, Button, FormLabel, FormInput, Card, Text, Header, List, ListItem } from 'react-native-elements'; +import { TouchableOpacity, ActivityIndicator, View, StyleSheet, Dimensions, Image } from 'react-native'; import Carousel from 'react-native-snap-carousel'; let loc = require('./loc/'); /** @type {AppStorage} */ @@ -91,12 +74,7 @@ export class BlueCard extends Component { export class BlueText extends Component { render() { - return ( - - ); + return ; } } @@ -123,12 +101,7 @@ export class BlueListItem extends Component { export class BlueFormLabel extends Component { render() { - return ( - - ); + return ; } } @@ -215,12 +188,7 @@ export class BlueHeaderDefaultSub extends Component { > - + @@ -264,12 +232,7 @@ export class BlueHeaderDefaultMain extends Component { > - + @@ -281,23 +244,13 @@ export class BlueHeaderDefaultMain extends Component { export class BlueSpacing extends Component { render() { - return ( - - ); + return ; } } export class BlueSpacing40 extends Component { render() { - return ( - - ); + return ; } } @@ -463,14 +416,7 @@ export class BlueTransactionIncommingIcon extends Component { - + @@ -505,14 +451,7 @@ export class BlueTransactionOutgoingIcon extends Component { - + @@ -556,14 +495,7 @@ export class BlueReceiveButtonIcon extends Component { transform: [{ rotate: '-45deg' }], }} > - + - + - + { - let address = SegwitP2SHWallet.witnessToAddress( - '035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8', - ); + let address = SegwitP2SHWallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8'); assert.equal(address, '34ZVGb3gT8xMLT6fpqC6dNVqJtJmvdjbD7'); - address = SegwitBech32Wallet.witnessToAddress( - '035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8', - ); + address = SegwitBech32Wallet.witnessToAddress('035c618df829af694cb99e664ce1b34f80ad2c3b49bcd0d9c0b1836c66b2d25fd8'); assert.equal(address, 'bc1quhnve8q4tk3unhmjts7ymxv8cd6w9xv8wy29uv'); }); -it('can create a BIP49', function() { +it('can create a Segwit HD (BIP49)', async function() { let bip39 = require('bip39'); let bitcoin = require('bitcoinjs-lib'); let mnemonic = @@ -35,10 +33,7 @@ it('can create a BIP49', function() { let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash); let addressBytes = bitcoin.crypto.hash160(scriptSig); let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes); - let address = bitcoin.address.fromOutputScript( - outputScript, - bitcoin.networks.bitcoin, - ); + let address = bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin); assert.equal(address, '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK'); @@ -54,24 +49,65 @@ it('can create a BIP49', function() { assert.equal(true, hd.validateMnemonic()); assert.equal(child.keyPair.toWIF(), hd._getExternalWIFByIndex(0)); + assert.equal( + 'ypub6WhHmKBmHNjcrUVNCa3sXduH9yxutMipDcwiKW31vWjcMbfhQHjXdyx4rqXbEtVgzdbhFJ5mZJWmfWwnP4Vjzx97admTUYKQt6b9D7jjSCp', + hd.getXpub(), + ); + + // checking that internal pointer and async address getter return the same address + let freeAddress = await hd.getAddressAsync(); + assert.equal(hd._getExternalAddressByIndex(hd.next_free_address_index), freeAddress); +}); + +it.only('can create a Legacy HD (BIP44)', async function() { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 30 * 1000; + let bip39 = require('bip39'); + let bitcoin = require('bitcoinjs-lib'); + let mnemonic = 'high relief amount witness try remember adult destroy puppy fox giant peace'; + assert.ok(bip39.validateMnemonic(mnemonic)); + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + + let path = "m/44'/0'/0'/0/0"; + let child = root.derivePath(path); + + let w = new LegacyWallet(); + w.setSecret(child.keyPair.toWIF()); + assert.equal('12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG', w.getAddress()); + + // testing our class + let hd = new HDLegacyP2PKHWallet(); + hd.setSecret(mnemonic); + assert.equal(hd.validateMnemonic(), true); + assert.equal(hd._getExternalAddressByIndex(0), '12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG'); + assert.equal(hd._getInternalAddressByIndex(0), '1KZjqYHm7a1DjhjcdcjfQvYfF2h6PqatjX'); + assert.equal( + hd.getXpub(), + 'xpub6CQdfC3v9gU86eaSn7AhUFcBVxiGhdtYxdC5Cw2vLmFkfth2KXCMmYcPpvZviA89X6DXDs4PJDk5QVL2G2xaVjv7SM4roWHr1gR4xB3Z7Ps', + ); + + assert.equal(hd._getExternalWIFByIndex(0), 'L1hqNoJ26YuCdujMBJfWBNfgf4Jo7AcKFvcNcKLoMtoJDdDtRq7Q'); + assert.equal(hd._getInternalWIFByIndex(0), 'Kx3QkrfemEEV49Mj5oWfb4bsWymboPdstta7eN3kAzop9apxYEFP'); + await hd.fetchBalance(); + assert.equal(hd.balance, 0); + await hd.fetchTransactions(); + assert.equal(hd.transactions.length, 4); + assert.equal(hd.next_free_address_index, 1); + assert.equal(hd.next_free_change_address_index, 1); + + // TODO: rewrite fetchTransactions on Frisbee and uncomment: + // let freeAddress = await hd.getAddressAsync(); + // assert.equal(hd._getExternalAddressByIndex(hd.next_free_address_index), freeAddress); }); it('HD breadwallet works', async function() { jasmine.DEFAULT_TIMEOUT_INTERVAL = 300 * 1000; let hdBread = new HDLegacyBreadwalletWallet(); - hdBread.setSecret( - 'high relief amount witness try remember adult destroy puppy fox giant peace', - ); + hdBread.setSecret('high relief amount witness try remember adult destroy puppy fox giant peace'); assert.equal(hdBread.validateMnemonic(), true); - assert.equal( - hdBread._getExternalAddressByIndex(0), - '1ARGkNMdsBE36fJhddSwf8PqBXG3s4d2KU', - ); - assert.equal( - hdBread._getInternalAddressByIndex(0), - '1JLvA5D7RpWgChb4A5sFcLNrfxYbyZdw3V', - ); + assert.equal(hdBread._getExternalAddressByIndex(0), '1ARGkNMdsBE36fJhddSwf8PqBXG3s4d2KU'); + assert.equal(hdBread._getInternalAddressByIndex(0), '1JLvA5D7RpWgChb4A5sFcLNrfxYbyZdw3V'); assert.equal( hdBread.getXpub(), diff --git a/MockStorage.js b/MockStorage.js index 33b9bbee6..cc461bf5f 100644 --- a/MockStorage.js +++ b/MockStorage.js @@ -14,17 +14,13 @@ export default class MockStorage { getItem = jest.fn(key => { return new Promise(resolve => { - return this.storageCache.hasOwnProperty(key) - ? resolve(this.storageCache[key]) - : resolve(null); + return this.storageCache.hasOwnProperty(key) ? resolve(this.storageCache[key]) : resolve(null); }); }); removeItem = jest.fn(key => { return new Promise((resolve, reject) => { - return this.storageCache.hasOwnProperty(key) - ? resolve(delete this.storageCache[key]) - : reject(new Error('No such key!')); + return this.storageCache.hasOwnProperty(key) ? resolve(delete this.storageCache[key]) : reject(new Error('No such key!')); }); }); @@ -33,8 +29,6 @@ export default class MockStorage { }); getAllKeys = jest.fn(key => { - return new Promise((resolve, reject) => - resolve(Object.keys(this.storageCache)), - ); + return new Promise((resolve, reject) => resolve(Object.keys(this.storageCache))); }); } diff --git a/README.md b/README.md index 90ce69edf..5ac89da19 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # BlueWallet - Bitcoin Wallet [![CircleCI](https://circleci.com/gh/Overtorment/BlueWallet.svg?style=svg)](https://circleci.com/gh/Overtorment/BlueWallet) +[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) Thin Bitcoin Wallet. Built with React Native, Expo and BlockCypher API. diff --git a/class/app-storage.js b/class/app-storage.js index 7071d0a1b..5559c4ea8 100644 --- a/class/app-storage.js +++ b/class/app-storage.js @@ -197,9 +197,7 @@ export class AppStorage { } else { // decrypted ok, this is our bucket // we serialize our object's data, encrypt it, and add it to buckets - newData.push( - encryption.encrypt(JSON.stringify(data), this.cachedPassword), - ); + newData.push(encryption.encrypt(JSON.stringify(data), this.cachedPassword)); await AsyncStorage.setItem(AppStorage.FLAG_ENCRYPTED, '1'); } } diff --git a/class/hd-legacy-breadwallet-wallet.js b/class/hd-legacy-breadwallet-wallet.js index ff4a7678d..1fc889356 100644 --- a/class/hd-legacy-breadwallet-wallet.js +++ b/class/hd-legacy-breadwallet-wallet.js @@ -4,7 +4,7 @@ const bip39 = require('bip39'); /** * HD Wallet (BIP39). - * In particular, BIP49 (P2SH Segwit) https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki + * In particular, Breadwallet-compatible (Legacy addresses) */ export class HDLegacyBreadwalletWallet extends HDSegwitP2SHWallet { constructor() { @@ -16,10 +16,6 @@ export class HDLegacyBreadwalletWallet extends HDSegwitP2SHWallet { return 'HD Legacy Breadwallet-compatible (P2PKH)'; } - getAddress() { - // TODO: derive from hierarchy, return next free address - } - /** * @see https://github.com/bitcoinjs/bitcoinjs-lib/issues/584 * @see https://github.com/bitcoinjs/bitcoinjs-lib/issues/914 @@ -59,4 +55,28 @@ export class HDLegacyBreadwalletWallet extends HDSegwitP2SHWallet { return child.getAddress(); } + + _getExternalWIFByIndex(index) { + index = index * 1; // cast to int + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + let path = "m/0'/1/" + index; + let child = root.derivePath(path); + return child.keyPair.toWIF(); + } + + _getInternalWIFByIndex(index) { + index = index * 1; // cast to int + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + let path = "m/0'/1/" + index; + let child = root.derivePath(path); + return child.keyPair.toWIF(); + } + + getAddressAsync() { + // TODO + } } diff --git a/class/hd-legacy-p2pkh-wallet.js b/class/hd-legacy-p2pkh-wallet.js new file mode 100644 index 000000000..84be646e9 --- /dev/null +++ b/class/hd-legacy-p2pkh-wallet.js @@ -0,0 +1,104 @@ +import { LegacyWallet, HDSegwitP2SHWallet } from './'; +const bitcoin = require('bitcoinjs-lib'); +const bip39 = require('bip39'); + +/** + * HD Wallet (BIP39). + * In particular, BIP44 (P2PKH legacy addressess) + * @see https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki + */ +export class HDLegacyP2PKHWallet extends HDSegwitP2SHWallet { + constructor() { + super(); + this.type = 'HDlegacyP2PKH'; + } + + getTypeReadable() { + return 'HD Legacy (BIP44 P2PKH)'; + } + + getXpub() { + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + + let path = "m/44'/0'/0'"; + let child = root.derivePath(path).neutered(); + return child.toBase58(); + } + + _getExternalWIFByIndex(index) { + index = index * 1; // cast to int + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + let path = "m/44'/0'/0'/0/" + index; + let child = root.derivePath(path); + return child.keyPair.toWIF(); + } + + _getInternalWIFByIndex(index) { + index = index * 1; // cast to int + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + let path = "m/44'/0'/0'/1/" + index; + let child = root.derivePath(path); + return child.keyPair.toWIF(); + } + + _getExternalAddressByIndex(index) { + index = index * 1; // cast to int + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + let path = "m/44'/0'/0'/0/" + index; + let child = root.derivePath(path); + + let w = new LegacyWallet(); + w.setSecret(child.keyPair.toWIF()); + return w.getAddress(); + } + + _getInternalAddressByIndex(index) { + index = index * 1; // cast to int + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + + let path = "m/44'/0'/0'/1/" + index; + let child = root.derivePath(path); + + let w = new LegacyWallet(); + w.setSecret(child.keyPair.toWIF()); + return w.getAddress(); + } + + /** + * @inheritDoc + */ + async getAddressAsync() { + // looking for free external address + let freeAddress = ''; + let c; + for (c = -1; c < 5; c++) { + let Legacy = new LegacyWallet(); + Legacy.setSecret(this._getExternalWIFByIndex(this.next_free_address_index + c)); + await Legacy.fetchTransactions(); + if (Legacy.transactions.length === 0) { + // found free address + freeAddress = Legacy.getAddress(); + this.next_free_address_index += c + 1; // now points to the one _after_ + break; + } + } + + if (!freeAddress) { + // could not find in cycle above, give up + freeAddress = this._getExternalAddressByIndex(this.next_free_address_index + c); // we didnt check this one, maybe its free + this.next_free_address_index += c + 1; // now points to the one _after_ + } + + return freeAddress; + } +} diff --git a/class/hd-segwit-p2sh-wallet.js b/class/hd-segwit-p2sh-wallet.js index 3e3b60940..2be31c550 100644 --- a/class/hd-segwit-p2sh-wallet.js +++ b/class/hd-segwit-p2sh-wallet.js @@ -3,10 +3,12 @@ import { SegwitP2SHWallet } from './segwit-p2sh-wallet'; import Frisbee from 'frisbee'; const bitcoin = require('bitcoinjs-lib'); const bip39 = require('bip39'); +const BigNumber = require('bignumber.js'); /** * HD Wallet (BIP39). - * In particular, BIP49 (P2SH Segwit) https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki + * In particular, BIP49 (P2SH Segwit) + * @see https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki */ export class HDSegwitP2SHWallet extends LegacyWallet { constructor() { @@ -18,18 +20,22 @@ export class HDSegwitP2SHWallet extends LegacyWallet { this.external_addresses_cache = {}; // index => address } + allowSend() { + return false; // TODO send from HD + } + validateMnemonic() { return bip39.validateMnemonic(this.secret); } getTypeReadable() { - return 'HD SegWit (P2SH)'; + return 'HD SegWit (BIP49 P2SH)'; } /** * Derives from hierarchy, returns next free address * (the one that has no transactions). Looks for several, - * gve ups if none found, and returns the used one + * gives up if none found, and returns the used one * * @return {Promise.} */ @@ -39,9 +45,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet { let c; for (c = -1; c < 5; c++) { let Segwit = new SegwitP2SHWallet(); - Segwit.setSecret( - this._getExternalWIFByIndex(this.next_free_address_index + c), - ); + Segwit.setSecret(this._getExternalWIFByIndex(this.next_free_address_index + c)); await Segwit.fetchTransactions(); if (Segwit.transactions.length === 0) { // found free address @@ -53,9 +57,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet { if (!freeAddress) { // could not find in cycle above, give up - freeAddress = this._getExternalAddressByIndex( - this.next_free_address_index + c, - ); // we didnt check this one, maybe its free + freeAddress = this._getExternalAddressByIndex(this.next_free_address_index + c); // we didnt check this one, maybe its free this.next_free_address_index += c + 1; // now points to the one _after_ } @@ -94,12 +96,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet { let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash); let addressBytes = bitcoin.crypto.hash160(scriptSig); let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes); - let address = bitcoin.address.fromOutputScript( - outputScript, - bitcoin.networks.bitcoin, - ); - - return address; + return bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin); } _getInternalAddressByIndex(index) { @@ -115,10 +112,17 @@ export class HDSegwitP2SHWallet extends LegacyWallet { let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash); let addressBytes = bitcoin.crypto.hash160(scriptSig); let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes); - return bitcoin.address.fromOutputScript( - outputScript, - bitcoin.networks.bitcoin, - ); + return bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin); + } + + getXpub() { + let mnemonic = this.secret; + let seed = bip39.mnemonicToSeed(mnemonic); + let root = bitcoin.HDNode.fromSeedBuffer(seed); + + let path = "m/49'/0'/0'"; + let child = root.derivePath(path).neutered(); + return child.toBase58(); } async fetchBalance() { @@ -135,15 +139,21 @@ export class HDSegwitP2SHWallet extends LegacyWallet { } } + /** + * Async function to fetch all transactions. Use getter to get actual txs. + * Also, sets internals: + * `this.internal_addresses_cache` + * `this.external_addresses_cache` + * + * @returns {Promise} + */ async fetchTransactions() { const api = new Frisbee({ baseURI: 'https://blockchain.info' }); this.transactions = []; let offset = 0; while (1) { - let response = await api.get( - '/multiaddr?active=' + this.getXpub() + '&n=100&offset=' + offset, - ); + let response = await api.get('/multiaddr?active=' + this.getXpub() + '&n=100&offset=' + offset); if (response && response.body) { if (response.body.txs && response.body.txs.length === 0) { @@ -165,18 +175,12 @@ export class HDSegwitP2SHWallet extends LegacyWallet { let path = input.prev_out.xpub.path.split('/'); if (path[path.length - 2] === '1') { // change address - this.next_free_change_address_index = Math.max( - path[path.length - 1] * 1 + 1, - this.next_free_change_address_index, - ); + this.next_free_change_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_change_address_index); // setting to point to last maximum known change address + 1 } if (path[path.length - 2] === '0') { // main (aka external) address - this.next_free_address_index = Math.max( - path[path.length - 1] * 1 + 1, - this.next_free_address_index, - ); + this.next_free_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_address_index); // setting to point to last maximum known main address + 1 } // done with cache @@ -193,25 +197,19 @@ export class HDSegwitP2SHWallet extends LegacyWallet { let path = output.xpub.path.split('/'); if (path[path.length - 2] === '1') { // change address - this.next_free_change_address_index = Math.max( - path[path.length - 1] * 1 + 1, - this.next_free_change_address_index, - ); + this.next_free_change_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_change_address_index); // setting to point to last maximum known change address + 1 } if (path[path.length - 2] === '0') { // main (aka external) address - this.next_free_address_index = Math.max( - path[path.length - 1] * 1 + 1, - this.next_free_address_index, - ); + this.next_free_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_address_index); // setting to point to last maximum known main address + 1 } // done with cache } } - tx.value = value / 100000000; + tx.value = new BigNumber(value).div(100000000).toString() * 1; this.transactions.push(tx); } @@ -219,7 +217,7 @@ export class HDSegwitP2SHWallet extends LegacyWallet { break; // error ? } } else { - throw new Error('Could not fetch balance from API'); // breaks here + throw new Error('Could not fetch transactions from API'); // breaks here } offset += 100; diff --git a/class/index.js b/class/index.js index efc5e3c01..9e6aa2f80 100644 --- a/class/index.js +++ b/class/index.js @@ -6,3 +6,4 @@ export * from './segwit-bech-wallet'; export * from './segwit-p2sh-wallet'; export * from './hd-segwit-p2sh-wallet'; export * from './hd-legacy-breadwallet-wallet'; +export * from './hd-legacy-p2pkh-wallet'; diff --git a/class/legacy-wallet.js b/class/legacy-wallet.js index bbfa8af7c..4ac54baff 100644 --- a/class/legacy-wallet.js +++ b/class/legacy-wallet.js @@ -83,25 +83,17 @@ export class LegacyWallet extends AbstractWallet { }); let response = await api.get( - this.getAddress() + - '/balance' + - ((useBlockcypherTokens && - '&token=' + this.getRandomBlockcypherToken()) || - ''), + this.getAddress() + '/balance' + ((useBlockcypherTokens && '&token=' + this.getRandomBlockcypherToken()) || ''), ); let json = response.body; - if ( - typeof json === 'undefined' || - typeof json.final_balance === 'undefined' - ) { + if (typeof json === 'undefined' || typeof json.final_balance === 'undefined') { throw new Error('Could not fetch UTXO from API' + response.err); } this.balance = new BigNumber(json.final_balance); this.balance = this.balance.div(100000000).toString() * 1; this.unconfirmed_balance = new BigNumber(json.unconfirmed_balance); - this.unconfirmed_balance = - this.unconfirmed_balance.div(100000000).toString() * 1; + this.unconfirmed_balance = this.unconfirmed_balance.div(100000000).toString() * 1; this._lastBalanceFetch = +new Date(); } catch (err) { console.warn(err); @@ -129,15 +121,10 @@ export class LegacyWallet extends AbstractWallet { this.getAddress() + '?limit=2000&after=' + maxHeight + - ((useBlockcypherTokens && - '&token=' + this.getRandomBlockcypherToken()) || - ''), + ((useBlockcypherTokens && '&token=' + this.getRandomBlockcypherToken()) || ''), ); json = response.body; - if ( - typeof json === 'undefined' || - typeof json.final_balance === 'undefined' - ) { + if (typeof json === 'undefined' || typeof json.final_balance === 'undefined') { throw new Error('Could not fetch UTXO from API' + response.err); } json.txrefs = json.txrefs || []; // case when source address is empty (or maxheight too high, no txs) @@ -169,19 +156,10 @@ export class LegacyWallet extends AbstractWallet { let url; if (useBlockcypherTokens) { response = await fetch( - (url = - 'https://api.blockcypher.com/v1/btc/main/addrs/' + - this.getAddress() + - '/full?token=' + - this.getRandomBlockcypherToken()), + (url = 'https://api.blockcypher.com/v1/btc/main/addrs/' + this.getAddress() + '/full?token=' + this.getRandomBlockcypherToken()), ); } else { - response = await fetch( - (url = - 'https://api.blockcypher.com/v1/btc/main/addrs/' + - this.getAddress() + - '/full'), - ); + response = await fetch((url = 'https://api.blockcypher.com/v1/btc/main/addrs/' + this.getAddress() + '/full')); } console.log(url); let json = await response.json(); @@ -369,25 +347,9 @@ export class LegacyWallet extends AbstractWallet { u.amount = u.amount.div(100000000); u.amount = u.amount.toString(10); } - console.log( - 'creating legacy tx ', - amount, - ' with fee ', - fee, - 'secret=', - this.getSecret(), - 'from address', - this.getAddress(), - ); + console.log('creating legacy tx ', amount, ' with fee ', fee, 'secret=', this.getSecret(), 'from address', this.getAddress()); let amountPlusFee = parseFloat(new BigNumber(amount).add(fee).toString(10)); - return signer.createTransaction( - utxos, - toAddress, - amountPlusFee, - fee, - this.getSecret(), - this.getAddress(), - ); + return signer.createTransaction(utxos, toAddress, amountPlusFee, fee, this.getSecret(), this.getAddress()); } getLatestTransactionTime() { diff --git a/class/segwit-bech-wallet.js b/class/segwit-bech-wallet.js index 008e64cda..da8d8a753 100644 --- a/class/segwit-bech-wallet.js +++ b/class/segwit-bech-wallet.js @@ -17,9 +17,7 @@ export class SegwitBech32Wallet extends LegacyWallet { try { let keyPair = bitcoin.ECPair.fromWIF(this.secret); let pubKey = keyPair.getPublicKeyBuffer(); - let scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode( - bitcoin.crypto.hash160(pubKey), - ); + let scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey)); address = bitcoin.address.fromOutputScript(scriptPubKey); } catch (err) { return false; @@ -32,12 +30,7 @@ export class SegwitBech32Wallet extends LegacyWallet { static witnessToAddress(witness) { const pubKey = Buffer.from(witness, 'hex'); const pubKeyHash = bitcoin.crypto.hash160(pubKey); - const scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode( - pubKeyHash, - ); - return bitcoin.address.fromOutputScript( - scriptPubKey, - bitcoin.networks.bitcoin, - ); + const scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash); + return bitcoin.address.fromOutputScript(scriptPubKey, bitcoin.networks.bitcoin); } } diff --git a/class/segwit-p2sh-wallet.js b/class/segwit-p2sh-wallet.js index 73eb5f863..dd8b49963 100644 --- a/class/segwit-p2sh-wallet.js +++ b/class/segwit-p2sh-wallet.js @@ -16,17 +16,10 @@ export class SegwitP2SHWallet extends LegacyWallet { static witnessToAddress(witness) { const pubKey = Buffer.from(witness, 'hex'); const pubKeyHash = bitcoin.crypto.hash160(pubKey); - const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode( - pubKeyHash, - ); + const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash); const redeemScriptHash = bitcoin.crypto.hash160(redeemScript); - const scriptPubkey = bitcoin.script.scriptHash.output.encode( - redeemScriptHash, - ); - return bitcoin.address.fromOutputScript( - scriptPubkey, - bitcoin.networks.bitcoin, - ); + const scriptPubkey = bitcoin.script.scriptHash.output.encode(redeemScriptHash); + return bitcoin.address.fromOutputScript(scriptPubkey, bitcoin.networks.bitcoin); } getAddress() { @@ -35,12 +28,8 @@ export class SegwitP2SHWallet extends LegacyWallet { try { let keyPair = bitcoin.ECPair.fromWIF(this.secret); let pubKey = keyPair.getPublicKeyBuffer(); - let witnessScript = bitcoin.script.witnessPubKeyHash.output.encode( - bitcoin.crypto.hash160(pubKey), - ); - let scriptPubKey = bitcoin.script.scriptHash.output.encode( - bitcoin.crypto.hash160(witnessScript), - ); + let witnessScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(pubKey)); + let scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(witnessScript)); address = bitcoin.address.fromOutputScript(scriptPubKey); } catch (err) { return false; @@ -76,26 +65,9 @@ export class SegwitP2SHWallet extends LegacyWallet { u.amount = u.amount.div(100000000); u.amount = u.amount.toString(10); } - console.log( - 'creating tx ', - amount, - ' with fee ', - fee, - 'secret=', - this.getSecret(), - 'from address', - this.getAddress(), - ); + console.log('creating tx ', amount, ' with fee ', fee, 'secret=', this.getSecret(), 'from address', this.getAddress()); let amountPlusFee = parseFloat(new BigNumber(amount).add(fee).toString(10)); // to compensate that module substracts fee from amount - return signer.createSegwitTransaction( - utxos, - address, - amountPlusFee, - fee, - this.getSecret(), - this.getAddress(), - sequence, - ); + return signer.createSegwitTransaction(utxos, address, amountPlusFee, fee, this.getSecret(), this.getAddress(), sequence); } } diff --git a/currency.js b/currency.js index 89a82dab0..b4b6d5cf7 100644 --- a/currency.js +++ b/currency.js @@ -37,7 +37,7 @@ async function updateExchangeRate() { console.log('updated currency exchange:', lang); } -async function startUpdater(doNotSetInterval) { +async function startUpdater() { lang = await AsyncStorage.getItem(AppStorage.CURRENCY); try { lang = JSON.parse(lang); @@ -52,9 +52,7 @@ async function startUpdater(doNotSetInterval) { lang[STRUCT.LAST_UPDATED] = lang[STRUCT.LAST_UPDATED] || 0; lang[STRUCT.BTC_USD] = lang[STRUCT.BTC_USD] || 6500; - if (!doNotSetInterval) { - setInterval(() => updateExchangeRate(), 2 * 60 * 100); - } + setInterval(() => updateExchangeRate(), 2 * 60 * 100); return updateExchangeRate(); } diff --git a/events.js b/events.js index a98811251..afc9f0767 100644 --- a/events.js +++ b/events.js @@ -1,11 +1,6 @@ function EV(eventName, arg) { if (Object.values(EV.enum).indexOf(eventName) === -1) { - return console.warn( - 'Unregistered event', - eventName, - 'registered events:', - EV.enum, - ); + return console.warn('Unregistered event', eventName, 'registered events:', EV.enum); } EV.callbacks = EV.callbacks || {}; // static variable EV.callbacks[eventName] = EV.callbacks[eventName] || []; @@ -27,8 +22,7 @@ function EV(eventName, arg) { EV.enum = { WALLETS_COUNT_CHANGED: 'WALLETS_COUNT_CHANGED', TRANSACTIONS_COUNT_CHANGED: 'TRANSACTIONS_COUNT_CHANGED', - CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS: - 'CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS', + CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS: 'CREATE_TRANSACTION_NEW_DESTINATION_ADDRESS', RECEIVE_ADDRESS_CHANGED: 'RECEIVE_ADDRESS_CHANGED', }; diff --git a/loc/en.js b/loc/en.js index f082e9646..fbb1b53db 100644 --- a/loc/en.js +++ b/loc/en.js @@ -1,7 +1,6 @@ module.exports = { _: { - storage_is_encrypted: - 'Your storage is encrypted. Password is required to decrypt it', + storage_is_encrypted: 'Your storage is encrypted. Password is required to decrypt it', enter_password: 'Enter password', bad_password: 'Bad pasword, try again', months_ago: 'months ago', @@ -14,9 +13,7 @@ module.exports = { tabBarLabel: 'Wallets', app_name: 'Blue Wallet', title: 'wallets', - header: - 'A wallet represents a pair of a secret (private key) and an address' + - 'you can share to receive coins.', + header: 'A wallet represents a pair of a secret (private key) and an address' + 'you can share to receive coins.', add: 'Add Wallet', create_a_wallet: 'Create a wallet', create_a_wallet1: "It's free and you can create", @@ -98,8 +95,7 @@ module.exports = { title: 'Create Transaction', error: 'Error creating transaction. Invalid address or send amount?', go_back: 'Go Back', - this_is_hex: - 'This is transaction hex, signed and ready to be broadcast to the network. Continue?', + this_is_hex: 'This is transaction hex, signed and ready to be broadcast to the network. Continue?', to: 'To', amount: 'Amount', fee: 'Fee', @@ -141,16 +137,12 @@ module.exports = { "BlueWallet, it will unlock new 'fake' storage. This will seem " + 'legit to a 3rd party, but will secretly keep your main storage ' + 'with coins safe.', - help2: - 'New storage will be fully functional, and you can store some ' + - 'minimum amounts there so it looks more believable.', + help2: 'New storage will be fully functional, and you can store some ' + 'minimum amounts there so it looks more believable.', create_fake_storage: 'Create fake encrypted storage', go_back: 'Go Back', create_password: 'Create a password', - create_password_explanation: - 'Password for fake storage should not match password for your main storage', - password_should_not_match: - 'Password for fake storage should not match password for your main storage', + create_password_explanation: 'Password for fake storage should not match password for your main storage', + password_should_not_match: 'Password for fake storage should not match password for your main storage', retype_password: 'Retype password', passwords_do_not_match: 'Passwords do not match, try again', success: 'Success', diff --git a/loc/es.js b/loc/es.js index f560e85ee..6686bc5a3 100644 --- a/loc/es.js +++ b/loc/es.js @@ -4,9 +4,7 @@ module.exports = { tabBarLabel: 'Monederos', app_name: 'Blue Wallet', title: 'Mi Monederos de Bitcoin', - header: - 'Un Monedero esta representado con secreto (clave privada) y una dirección' + - 'que puedes compartir para recibir monedas.', + header: 'Un Monedero esta representado con secreto (clave privada) y una dirección' + 'que puedes compartir para recibir monedas.', add: 'Añadir Monedero', }, add: { @@ -50,8 +48,7 @@ module.exports = { list: { tabBarLabel: 'Transacciónes', title: 'Mi Transacciónes', - description: - 'Una lista de las transacciones entrantes o salientes de sus monederos', + description: 'Una lista de las transacciones entrantes o salientes de sus monederos', conf: 'conf', }, details: { @@ -81,11 +78,9 @@ module.exports = { }, create: { title: 'Crear una Transaccion', - error: - 'Error al crear una transacción. ¿Dirección o cantidad estan invalidas?', + error: 'Error al crear una transacción. ¿Dirección o cantidad estan invalidas?', go_back: 'Regresar', - this_is_hex: - 'Este es representacion hex de transacción, firmado y listo para ser transmitido a la red. ¿Continuar?', + this_is_hex: 'Este es representacion hex de transacción, firmado y listo para ser transmitido a la red. ¿Continuar?', to: 'A', amount: 'Cantidad', fee: 'Tasa', @@ -110,8 +105,7 @@ module.exports = { plausible_deniability: 'Negación plausible...', storage_not_encrypted: 'Almacenamiento: no esta encriptado', password: 'Contraseña', - password_explain: - 'Crea la contraseña que usarás para descifrar el almacenamiento', + password_explain: 'Crea la contraseña que usarás para descifrar el almacenamiento', retype_password: 'Ingresa la contraseña de nuevo', passwords_do_not_match: 'Contraseñas deben ser iguales', encrypt_storage: 'Cifrar almacenamiento', diff --git a/loc/index.js b/loc/index.js index 1f4c43dda..cdaa321ca 100644 --- a/loc/index.js +++ b/loc/index.js @@ -21,13 +21,7 @@ let strings; locale = locale.split('-'); locale = locale[0]; console.log('current locale:', locale); - if ( - locale === 'en' || - locale === 'ru' || - locale === 'ua' || - locale === 'es' || - locale === 'pt' - ) { + if (locale === 'en' || locale === 'ru' || locale === 'ua' || locale === 'es' || locale === 'pt') { strings.setLanguage(locale); } else { strings.setLanguage('en'); diff --git a/loc/pt_BR.js b/loc/pt_BR.js index 380a3b052..bd601174f 100644 --- a/loc/pt_BR.js +++ b/loc/pt_BR.js @@ -1,7 +1,6 @@ module.exports = { _: { - storage_is_encrypted: - 'O armazenamento está encriptado. Uma password é necessaria para desencriptar', + storage_is_encrypted: 'O armazenamento está encriptado. Uma password é necessaria para desencriptar', enter_password: 'Inserir password', bad_password: 'pasword errada, tentar novamente', }, @@ -10,9 +9,7 @@ module.exports = { tabBarLabel: 'Wallets', app_name: 'Blue Wallet', title: 'Minhas Bitcoin Wallets', - header: - 'Uma wallet representa um par entre um segredo (chave privada) e um endereço' + - 'que pode partilhar para receber Bitcoin.', + header: 'Uma wallet representa um par entre um segredo (chave privada) e um endereço' + 'que pode partilhar para receber Bitcoin.', add: 'Adicionar Wallet', }, add: { @@ -56,8 +53,7 @@ module.exports = { list: { tabBarLabel: 'Transações', title: 'Minhas Transações', - description: - 'Uma lista de transações feitas ou recebidas nas suas wallets', + description: 'Uma lista de transações feitas ou recebidas nas suas wallets', conf: 'conf', }, details: { @@ -89,8 +85,7 @@ module.exports = { title: 'Criar Transacção', error: 'Erro ao criar transação. Endereço inválido ou quantia?', go_back: 'Voltar', - this_is_hex: - 'Este é o hex da transação, assinado e pronto para ser difundido para a network. Continuar?', + this_is_hex: 'Este é o hex da transação, assinado e pronto para ser difundido para a network. Continuar?', to: 'Para', amount: 'Quantia', fee: 'Taxa', @@ -132,16 +127,12 @@ module.exports = { 'BlueWallet, esta vai abrir um armazenamento "falso". Que vai parecer ' + 'legítimo a um terceiro, mas que secretamente vai manter o seu armazenamento principal ' + 'com as moedas em segurança.', - help2: - 'Este novo armazenamento é completamente funcional, e pode guardar ' + - 'um valor minímo para parecer mais real.', + help2: 'Este novo armazenamento é completamente funcional, e pode guardar ' + 'um valor minímo para parecer mais real.', create_fake_storage: 'Criar armazenamento encriptado FALSO', go_back: 'Voltar', create_password: 'Criar password', - create_password_explanation: - 'Password para armazenamento FALSO não deve coincidir com o principal', - password_should_not_match: - 'Password para armazenamento FALSO não deve coincidir com o principal', + create_password_explanation: 'Password para armazenamento FALSO não deve coincidir com o principal', + password_should_not_match: 'Password para armazenamento FALSO não deve coincidir com o principal', retype_password: 'Inserir password novamente', passwords_do_not_match: 'Passwords não coincidem, tente novamente', success: 'Sucesso', diff --git a/loc/pt_PT.js b/loc/pt_PT.js index aef320391..1faa01cf5 100644 --- a/loc/pt_PT.js +++ b/loc/pt_PT.js @@ -1,7 +1,6 @@ module.exports = { _: { - storage_is_encrypted: - 'O armazenamento está encriptado. Uma password é necessaria para desencriptar', + storage_is_encrypted: 'O armazenamento está encriptado. Uma password é necessaria para desencriptar', enter_password: 'Inserir password', bad_password: 'pasword errada, tente novamente', }, @@ -10,9 +9,7 @@ module.exports = { tabBarLabel: 'Wallets', app_name: 'Blue Wallet', title: 'Minhas Bitcoin Wallets', - header: - 'Uma wallet representa um par entre um segredo (chave privada) e um endereço' + - 'que pode partilhar para receber Bitcoin.', + header: 'Uma wallet representa um par entre um segredo (chave privada) e um endereço' + 'que pode partilhar para receber Bitcoin.', add: 'Adicionar Wallet', }, add: { @@ -56,8 +53,7 @@ module.exports = { list: { tabBarLabel: 'Transacções', title: 'Minhas Transacções', - description: - 'Uma lista de transações feitas ou recebidas nas suas wallets', + description: 'Uma lista de transações feitas ou recebidas nas suas wallets', conf: 'conf', }, details: { @@ -89,8 +85,7 @@ module.exports = { title: 'Criar Transacção', error: 'Erro ao criar transacção. Endereço inválido ou quantia?', go_back: 'Voltar', - this_is_hex: - 'Este é o hex da transacção, assinado e pronto para ser difundido para a network. Continuar?', + this_is_hex: 'Este é o hex da transacção, assinado e pronto para ser difundido para a network. Continuar?', to: 'Para', amount: 'Quantia', fee: 'Taxa', @@ -132,16 +127,12 @@ module.exports = { 'BlueWallet, esta vai abrir um armazenamento "falso". Que vai parecer ' + 'legítimo a um terceiro, mas que secretamente vai manter o seu armazenamento principal ' + 'com as moedas em segurança.', - help2: - 'Este novo armazenamento é completamente funcional, e pode guardar ' + - 'um valor minímo para parecer mais real.', + help2: 'Este novo armazenamento é completamente funcional, e pode guardar ' + 'um valor minímo para parecer mais real.', create_fake_storage: 'Criar armazenamento encriptado FALSO', go_back: 'Voltar', create_password: 'Criar password', - create_password_explanation: - 'Password para armazenamento FALSO não deve coincidir com o principal', - password_should_not_match: - 'Password para armazenamento FALSO não deve coincidir com o principal', + create_password_explanation: 'Password para armazenamento FALSO não deve coincidir com o principal', + password_should_not_match: 'Password para armazenamento FALSO não deve coincidir com o principal', retype_password: 'Inserir password novamente', passwords_do_not_match: 'Passwords não coincidem, tente novamente', success: 'Sucesso', diff --git a/loc/ru.js b/loc/ru.js index f0a9fdf7d..b4b52131f 100644 --- a/loc/ru.js +++ b/loc/ru.js @@ -1,7 +1,6 @@ module.exports = { _: { - storage_is_encrypted: - 'Ваше хранилище зашифровано. Введите пароль для расшифровки', + storage_is_encrypted: 'Ваше хранилище зашифровано. Введите пароль для расшифровки', enter_password: 'Введите пароль', bad_password: 'Неверный пароль, попробуйте еще раз', months_ago: 'месяцев назад', @@ -14,8 +13,7 @@ module.exports = { tabBarLabel: 'Кошельки', app_name: 'BlueWallet', title: 'Мои Кошельки', - header: - 'Кошелек это секретный (приватный) ключ, и соответствующий ему адрес на который можно получать биткоины', + header: 'Кошелек это секретный (приватный) ключ, и соответствующий ему адрес на который можно получать биткоины', add: 'Добавить Кошелек', create_a_wallet: 'Создать кошелек', create_a_wallet1: 'Это бесплатно и вы можете создать', @@ -95,11 +93,9 @@ module.exports = { }, create: { title: 'Создать Транзакцию', - error: - 'Ошибка при создании транзакции. Неправильный адрес назначения или недостаточно средств?', + error: 'Ошибка при создании транзакции. Неправильный адрес назначения или недостаточно средств?', go_back: 'Назад', - this_is_hex: - 'Это данные транзакции. Транзакция подписана и готова быть транслирована в сеть. Продолжить?', + this_is_hex: 'Это данные транзакции. Транзакция подписана и готова быть транслирована в сеть. Продолжить?', to: 'Куда', amount: 'Сколько', fee: 'Комиссия', @@ -147,10 +143,8 @@ module.exports = { create_fake_storage: 'Создать фальшивое хранилище', go_back: 'Назад', create_password: 'Придумайте пароль', - create_password_explanation: - 'Пароль для фальшивого хранилища не должен быть таким же как основной пароль', - password_should_not_match: - 'Пароль для фальшивого хранилища не должен быть таким же как основной пароль', + create_password_explanation: 'Пароль для фальшивого хранилища не должен быть таким же как основной пароль', + password_should_not_match: 'Пароль для фальшивого хранилища не должен быть таким же как основной пароль', retype_password: 'Наберите пароль повторно', passwords_do_not_match: 'Пароли не совпадают, попробуйте еще раз', success: 'Операция успешна', diff --git a/loc/ua.js b/loc/ua.js index b9b0ffc47..7c55bf7c2 100644 --- a/loc/ua.js +++ b/loc/ua.js @@ -1,7 +1,6 @@ module.exports = { _: { - storage_is_encrypted: - 'Ваше сховище зашифроване. Введіть пароль для розшифровки', + storage_is_encrypted: 'Ваше сховище зашифроване. Введіть пароль для розшифровки', enter_password: 'Введіть пароль', bad_password: 'Невірний пароль, спробуйте ще раз', }, @@ -10,8 +9,7 @@ module.exports = { tabBarLabel: 'Гаманці', app_name: 'BlueWallet', title: 'Мої Біткоїн Гаманці', - header: - 'Гаманець це секретний (приватний) ключ, і відповідна йому адреса на яку можна отримувати біткоїни', + header: 'Гаманець це секретний (приватний) ключ, і відповідна йому адреса на яку можна отримувати біткоїни', add: 'Додати Гаманець', }, add: { @@ -85,11 +83,9 @@ module.exports = { }, create: { title: 'Створити Транзакцію', - error: - 'Помилка при створенні транзакції. Невiрна адреса призначення або недостатньо коштiв?', + error: 'Помилка при створенні транзакції. Невiрна адреса призначення або недостатньо коштiв?', go_back: 'Назад', - this_is_hex: - 'Це дані транзакції. Транзакція підписана і готова бути трансльована в мережу. Продовжити?', + this_is_hex: 'Це дані транзакції. Транзакція підписана і готова бути трансльована в мережу. Продовжити?', to: 'Куди', amount: 'Скільки', fee: 'Комісія', @@ -137,10 +133,8 @@ module.exports = { create_fake_storage: 'Створити фальшиве сховище', go_back: 'Назад', create_password: 'Придумайте пароль', - create_password_explanation: - 'Пароль для фальшивого сховіща не має буті таким же як основній пароль', - password_should_not_match: - 'Пароль для фальшивого сховища не має бути таким же як основний пароль', + create_password_explanation: 'Пароль для фальшивого сховіща не має буті таким же як основній пароль', + password_should_not_match: 'Пароль для фальшивого сховища не має бути таким же як основний пароль', retype_password: 'Наберіть пароль ще раз', passwords_do_not_match: 'Паролі не збігаються, спробуйте ще раз', success: 'Операція успішна', diff --git a/models/signer.js b/models/signer.js index 6bedd7506..21f47a17d 100644 --- a/models/signer.js +++ b/models/signer.js @@ -9,15 +9,7 @@ let bitcoinjs = require('bitcoinjs-lib'); const toSatoshi = num => parseInt((num * 100000000).toFixed(0)); -exports.createSegwitTransaction = function( - utxos, - toAddress, - amount, - fixedFee, - WIF, - changeAddress, - sequence, -) { +exports.createSegwitTransaction = function(utxos, toAddress, amount, fixedFee, WIF, changeAddress, sequence) { changeAddress = changeAddress || exports.WIF2segwitAddress(WIF); if (sequence === undefined) { sequence = bitcoinjs.Transaction.DEFAULT_SEQUENCE; @@ -27,9 +19,7 @@ exports.createSegwitTransaction = function( let keyPair = bitcoinjs.ECPair.fromWIF(WIF); let pubKey = keyPair.getPublicKeyBuffer(); let pubKeyHash = bitcoinjs.crypto.hash160(pubKey); - let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode( - pubKeyHash, - ); + let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode(pubKeyHash); let txb = new bitcoinjs.TransactionBuilder(); let unspentAmount = 0; @@ -45,33 +35,18 @@ exports.createSegwitTransaction = function( txb.addOutput(toAddress, amountToOutput); if (amountToOutput + feeInSatoshis < unspentAmount) { // sending less than we have, so the rest should go back - txb.addOutput( - changeAddress, - unspentAmount - amountToOutput - feeInSatoshis, - ); + txb.addOutput(changeAddress, unspentAmount - amountToOutput - feeInSatoshis); } for (let c = 0; c < utxos.length; c++) { - txb.sign( - c, - keyPair, - redeemScript, - null, - parseInt((utxos[c].amount * 100000000).toFixed(0)), - ); + txb.sign(c, keyPair, redeemScript, null, parseInt((utxos[c].amount * 100000000).toFixed(0))); } let tx = txb.build(); return tx.toHex(); }; -exports.createRBFSegwitTransaction = function( - txhex, - addressReplaceMap, - feeDelta, - WIF, - utxodata, -) { +exports.createRBFSegwitTransaction = function(txhex, addressReplaceMap, feeDelta, WIF, utxodata) { if (feeDelta < 0) { throw Error('replace-by-fee requires increased fee, not decreased'); } @@ -89,11 +64,7 @@ exports.createRBFSegwitTransaction = function( // creating TX let txb = new bitcoinjs.TransactionBuilder(); for (let unspent of tx.ins) { - txb.addInput( - unspent.hash.reverse().toString('hex'), - unspent.index, - highestSequence + 1, - ); + txb.addInput(unspent.hash.reverse().toString('hex'), unspent.index, highestSequence + 1); } for (let o of tx.outs) { @@ -113,9 +84,7 @@ exports.createRBFSegwitTransaction = function( let keyPair = bitcoinjs.ECPair.fromWIF(WIF); let pubKey = keyPair.getPublicKeyBuffer(); let pubKeyHash = bitcoinjs.crypto.hash160(pubKey); - let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode( - pubKeyHash, - ); + let redeemScript = bitcoinjs.script.witnessPubKeyHash.output.encode(pubKeyHash); for (let c = 0; c < tx.ins.length; c++) { let txid = tx.ins[c].hash.reverse().toString('hex'); let index = tx.ins[c].index; @@ -131,12 +100,8 @@ exports.generateNewSegwitAddress = function() { let keyPair = bitcoinjs.ECPair.makeRandom(); let pubKey = keyPair.getPublicKeyBuffer(); - let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode( - bitcoinjs.crypto.hash160(pubKey), - ); - let scriptPubKey = bitcoinjs.script.scriptHash.output.encode( - bitcoinjs.crypto.hash160(witnessScript), - ); + let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode(bitcoinjs.crypto.hash160(pubKey)); + let scriptPubKey = bitcoinjs.script.scriptHash.output.encode(bitcoinjs.crypto.hash160(witnessScript)); let address = bitcoinjs.address.fromOutputScript(scriptPubKey); return { @@ -163,23 +128,12 @@ exports.URI = function(paymentInfo) { exports.WIF2segwitAddress = function(WIF) { let keyPair = bitcoinjs.ECPair.fromWIF(WIF); let pubKey = keyPair.getPublicKeyBuffer(); - let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode( - bitcoinjs.crypto.hash160(pubKey), - ); - let scriptPubKey = bitcoinjs.script.scriptHash.output.encode( - bitcoinjs.crypto.hash160(witnessScript), - ); + let witnessScript = bitcoinjs.script.witnessPubKeyHash.output.encode(bitcoinjs.crypto.hash160(pubKey)); + let scriptPubKey = bitcoinjs.script.scriptHash.output.encode(bitcoinjs.crypto.hash160(witnessScript)); return bitcoinjs.address.fromOutputScript(scriptPubKey); }; -exports.createTransaction = function( - utxos, - toAddress, - _amount, - _fixedFee, - WIF, - fromAddress, -) { +exports.createTransaction = function(utxos, toAddress, _amount, _fixedFee, WIF, fromAddress) { let fixedFee = toSatoshi(_fixedFee); let amountToOutput = toSatoshi(_amount - _fixedFee); let pk = bitcoinjs.ECPair.fromWIF(WIF); // eslint-disable-line new-cap diff --git a/screen/about.js b/screen/about.js index 1ba997a7e..99e2d3e4b 100644 --- a/screen/about.js +++ b/screen/about.js @@ -1,14 +1,6 @@ import React, { Component } from 'react'; import { ScrollView, Linking, Dimensions } from 'react-native'; -import { - BlueLoading, - BlueSpacing20, - BlueButton, - SafeBlueArea, - BlueCard, - BlueText, - BlueHeaderDefaultSub, -} from '../BlueComponents'; +import { BlueLoading, BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueHeaderDefaultSub } from '../BlueComponents'; import PropTypes from 'prop-types'; /** @type {AppStorage} */ let BlueApp = require('../BlueApp'); @@ -39,16 +31,11 @@ export default class About extends Component { return ( - this.props.navigation.goBack()} - /> + this.props.navigation.goBack()} /> - - BlueWallet is free and opensource Bitcoin wallet. Licensed MIT. - + BlueWallet is free and opensource Bitcoin wallet. Licensed MIT. { - Linking.openURL( - 'https://itunes.apple.com/us/app/bluewallet-bitcoin-wallet/id1376878040?l=ru&ls=1&mt=8', - ); + Linking.openURL('https://itunes.apple.com/us/app/bluewallet-bitcoin-wallet/id1376878040?l=ru&ls=1&mt=8'); }} title="Leave us a review on Appstore" /> diff --git a/screen/plausibledeniability.js b/screen/plausibledeniability.js index 583e31943..84e12469c 100644 --- a/screen/plausibledeniability.js +++ b/screen/plausibledeniability.js @@ -2,14 +2,7 @@ import React, { Component } from 'react'; import { ScrollView } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; -import { - BlueLoading, - BlueButton, - SafeBlueArea, - BlueCard, - BlueText, - BlueHeader, -} from '../BlueComponents'; +import { BlueLoading, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueHeader } from '../BlueComponents'; import PropTypes from 'prop-types'; /** @type {AppStorage} */ let BlueApp = require('../BlueApp'); @@ -21,11 +14,7 @@ export default class PlausibleDeniability extends Component { static navigationOptions = { tabBarLabel: loc.plausibledeniability.title, tabBarIcon: ({ tintColor, focused }) => ( - + ), }; @@ -73,14 +62,9 @@ export default class PlausibleDeniability extends Component { }} title={loc.plausibledeniability.create_fake_storage} onPress={async () => { - let p1 = await prompt( - loc.plausibledeniability.create_password, - loc.plausibledeniability.create_password_explanation, - ); + let p1 = await prompt(loc.plausibledeniability.create_password, loc.plausibledeniability.create_password_explanation); if (p1 === BlueApp.cachedPassword) { - return alert( - loc.plausibledeniability.password_should_not_match, - ); + return alert(loc.plausibledeniability.password_should_not_match); } if (!p1) { diff --git a/screen/receive/details.js b/screen/receive/details.js index 82db02250..0d5c5c029 100644 --- a/screen/receive/details.js +++ b/screen/receive/details.js @@ -70,10 +70,7 @@ export default class ReceiveDetails extends Component { return ; } })()} - this.props.navigation.goBack()} - /> + this.props.navigation.goBack()} /> ( - + ), }; diff --git a/screen/selftest.js b/screen/selftest.js index fa7b823b3..d82d2e62c 100644 --- a/screen/selftest.js +++ b/screen/selftest.js @@ -1,15 +1,7 @@ import React, { Component } from 'react'; import { ScrollView, View } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; -import { - BlueLoading, - BlueSpacing20, - SafeBlueArea, - BlueCard, - BlueText, - BlueButton, - BlueHeader, -} from '../BlueComponents'; +import { BlueLoading, BlueSpacing20, SafeBlueArea, BlueCard, BlueText, BlueButton, BlueHeader } from '../BlueComponents'; import PropTypes from 'prop-types'; import { SegwitP2SHWallet, LegacyWallet } from '../class'; let BlueApp = require('../BlueApp'); @@ -20,11 +12,7 @@ export default class Selftest extends Component { static navigationOptions = { tabBarLabel: 'Self test', tabBarIcon: ({ tintColor, focused }) => ( - + ), }; @@ -65,8 +53,7 @@ export default class Selftest extends Component { // utxos as received from blockcypher let utxos = [ { - tx_hash: - '2f445cf016fa2772db7d473bff97515355b4e6148e1c980ce351d47cf54c517f', + tx_hash: '2f445cf016fa2772db7d473bff97515355b4e6148e1c980ce351d47cf54c517f', block_height: 523186, tx_input_n: -1, tx_output_n: 1, @@ -101,12 +88,10 @@ export default class Selftest extends Component { double_spend: false, ref_balance: 300000, spent: false, - tx_hash: - 'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef', + tx_hash: 'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef', tx_input_n: -1, tx_output_n: 0, - txid: - 'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef', + txid: 'dc3605040a03724bc584ed43bc22a559f5d32a1b0708ca05b20b9018fdd523ef', value: 200000, vout: 0, }, @@ -118,12 +103,10 @@ export default class Selftest extends Component { double_spend: false, ref_balance: 100000, spent: false, - tx_hash: - 'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017', + tx_hash: 'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017', tx_input_n: -1, tx_output_n: 0, - txid: - 'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017', + txid: 'c473c104febfe6621804976d1082a1468c1198d0339e35f30a8ba1515d9eb017', value: 100000, vout: 0, }, @@ -160,8 +143,7 @@ export default class Selftest extends Component { // utxos as received from blockcypher let utxo = [ { - tx_hash: - '0f5eea78fb19e72b55bd119252ff29fc16c503d0e956a9c1b5b2ab0e95e0c323', + tx_hash: '0f5eea78fb19e72b55bd119252ff29fc16c503d0e956a9c1b5b2ab0e95e0c323', block_height: 514991, tx_input_n: -1, tx_output_n: 2, @@ -174,20 +156,12 @@ export default class Selftest extends Component { }, ]; - let tx = l.createTx( - utxo, - 0.001, - 0.0001, - '1QHf8Gp3wfmFiSdEX4FtrssCGR68diN1cj', - ); + let tx = l.createTx(utxo, 0.001, 0.0001, '1QHf8Gp3wfmFiSdEX4FtrssCGR68diN1cj'); let bitcoin = require('bitcoinjs-lib'); let txDecoded = bitcoin.Transaction.fromHex(tx); let txid = txDecoded.getId(); - if ( - txid !== - '110f51d28d585e922adbf701cba802e549b8fe3a53fa5d62426ab42549c9b6de' - ) { + if (txid !== '110f51d28d585e922adbf701cba802e549b8fe3a53fa5d62426ab42549c9b6de') { errorMessage += 'created txid doesnt match; '; isOk = false; } @@ -234,10 +208,7 @@ export default class Selftest extends Component { let scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash); let addressBytes = bitcoin.crypto.hash160(scriptSig); let outputScript = bitcoin.script.scriptHash.output.encode(addressBytes); - let address = bitcoin.address.fromOutputScript( - outputScript, - bitcoin.networks.bitcoin, - ); + let address = bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.bitcoin); if (address !== '3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK') { errorMessage += 'bip49 is not ok; '; diff --git a/screen/send/create.js b/screen/send/create.js index 2c51217dd..8f0b982b7 100644 --- a/screen/send/create.js +++ b/screen/send/create.js @@ -1,15 +1,7 @@ import React, { Component } from 'react'; import { TextInput } from 'react-native'; import { Text, FormValidationMessage } from 'react-native-elements'; -import { - BlueLoading, - BlueSpacing20, - BlueButton, - SafeBlueArea, - BlueCard, - BlueText, - BlueSpacing, -} from '../../BlueComponents'; +import { BlueLoading, BlueSpacing20, BlueButton, SafeBlueArea, BlueCard, BlueText, BlueSpacing } from '../../BlueComponents'; import PropTypes from 'prop-types'; let BigNumber = require('bignumber.js'); let BlueApp = require('../../BlueApp'); @@ -56,13 +48,7 @@ export default class SendCreate extends Component { utxo = this.state.fromWallet.utxo; let startTime = Date.now(); - tx = this.state.fromWallet.createTx( - utxo, - this.state.amount, - this.state.fee, - this.state.address, - this.state.memo, - ); + tx = this.state.fromWallet.createTx(utxo, this.state.amount, this.state.fee, this.state.address, this.state.memo); let endTime = Date.now(); console.log('create tx ', (endTime - startTime) / 1000, 'sec'); @@ -113,8 +99,7 @@ export default class SendCreate extends Component { } else { this.setState({ broadcastErrorMessage: '' }); this.setState({ - broadcastSuccessMessage: - 'Success! TXID: ' + JSON.stringify(result.result), + broadcastSuccessMessage: 'Success! TXID: ' + JSON.stringify(result.result), }); } } @@ -124,19 +109,11 @@ export default class SendCreate extends Component { return ( - + {loc.send.create.error} - - {this.state.errorMessage} - + {this.state.errorMessage} - this.props.navigation.goBack()} - title={loc.send.create.go_back} - /> + this.props.navigation.goBack()} title={loc.send.create.go_back} /> ); } @@ -148,10 +125,7 @@ export default class SendCreate extends Component { return ( - + {loc.send.create.this_is_hex} - {loc.send.create.satoshi_per_byte}: {this.state.satoshiPerByte}{' '} - Sat/B + {loc.send.create.satoshi_per_byte}: {this.state.satoshiPerByte} Sat/B {loc.send.create.memo}: {this.state.memo} @@ -210,12 +183,8 @@ export default class SendCreate extends Component { title={loc.send.create.go_back} /> - - {this.state.broadcastErrorMessage} - - - {this.state.broadcastSuccessMessage} - + {this.state.broadcastErrorMessage} + {this.state.broadcastSuccessMessage} ); } diff --git a/screen/send/details.js b/screen/send/details.js index 21778345c..771e661d0 100644 --- a/screen/send/details.js +++ b/screen/send/details.js @@ -38,11 +38,9 @@ export default class SendDetails extends Component { super(props); let startTime = Date.now(); let address; - if (props.navigation.state.params) - address = props.navigation.state.params.address; + if (props.navigation.state.params) address = props.navigation.state.params.address; let fromAddress; - if (props.navigation.state.params) - fromAddress = props.navigation.state.params.fromAddress; + if (props.navigation.state.params) fromAddress = props.navigation.state.params.fromAddress; let fromWallet = {}; let startTime2 = Date.now(); @@ -164,9 +162,7 @@ export default class SendDetails extends Component { if (!this.state.fromWallet.getAddress) { return ( - - System error: Source wallet not found (this should never happen) - + System error: Source wallet not found (this should never happen) ); } @@ -180,10 +176,7 @@ export default class SendDetails extends Component { return ; } })()} - + this.setState({ address: text })} @@ -192,18 +185,14 @@ export default class SendDetails extends Component { /> - this.setState({ amount: text.replace(',', '.') }) - } + onChangeText={text => this.setState({ amount: text.replace(',', '.') })} keyboardType={'numeric'} placeholder={loc.send.details.amount_placeholder} value={this.state.amount + ''} /> - this.setState({ fee: text.replace(',', '.') }) - } + onChangeText={text => this.setState({ fee: text.replace(',', '.') })} keyboardType={'numeric'} placeholder={loc.send.details.fee_placeholder} value={this.state.fee + ''} @@ -218,12 +207,7 @@ export default class SendDetails extends Component { {loc.send.details.remaining_balance}:{' '} - {this.recalculateAvailableBalance( - this.state.fromWallet.getBalance(), - this.state.amount, - this.state.fee, - )}{' '} - BTC + {this.recalculateAvailableBalance(this.state.fromWallet.getBalance(), this.state.amount, this.state.fee)} BTC @@ -231,10 +215,7 @@ export default class SendDetails extends Component { - this.props.navigation.goBack()} - title={loc.send.details.cancel} - /> + this.props.navigation.goBack()} title={loc.send.details.cancel} /> - this.createTransaction()} - title={loc.send.details.create} - /> + this.createTransaction()} title={loc.send.details.create} /> diff --git a/screen/send/list.js b/screen/send/list.js index 75cd6faee..2ce875924 100644 --- a/screen/send/list.js +++ b/screen/send/list.js @@ -1,12 +1,7 @@ import React, { Component } from 'react'; import { Dimensions, ActivityIndicator, View, ListView } from 'react-native'; import Ionicons from 'react-native-vector-icons/Ionicons'; -import { - SafeBlueArea, - BlueCard, - BlueListItem, - BlueHeader, -} from '../../BlueComponents'; +import { SafeBlueArea, BlueCard, BlueListItem, BlueHeader } from '../../BlueComponents'; import PropTypes from 'prop-types'; let EV = require('../../events'); /** @type {AppStorage} */ @@ -19,11 +14,7 @@ export default class SendList extends Component { static navigationOptions = { tabBarLabel: loc.send.list.tabBarLabel, tabBarIcon: ({ tintColor, focused }) => ( - + ), }; diff --git a/screen/send/scanQrAddress.js b/screen/send/scanQrAddress.js index 93cbe57fc..f8b76bf11 100644 --- a/screen/send/scanQrAddress.js +++ b/screen/send/scanQrAddress.js @@ -1,12 +1,6 @@ /* global alert */ import React from 'react'; -import { - Text, - ActivityIndicator, - Button, - View, - TouchableOpacity, -} from 'react-native'; +import { Text, ActivityIndicator, Button, View, TouchableOpacity } from 'react-native'; import { Camera, Permissions } from 'expo'; import PropTypes from 'prop-types'; let EV = require('../../events'); @@ -61,11 +55,7 @@ export default class CameraExample extends React.Component { } else { return ( - this.onBarCodeRead(ret)} - > + this.onBarCodeRead(ret)}> { this.setState({ - type: - this.state.type === Camera.Constants.Type.back - ? Camera.Constants.Type.front - : Camera.Constants.Type.back, + type: this.state.type === Camera.Constants.Type.back ? Camera.Constants.Type.front : Camera.Constants.Type.back, }); }} > -