mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-02-23 15:20:55 +01:00
Merge pull request #913 from BlueWallet/electrum-tls
ADD: support for Electrum Personal Server (SSL connection)
This commit is contained in:
commit
7b5db85c9b
13 changed files with 190 additions and 83 deletions
|
@ -6,7 +6,7 @@ let reverse = require('buffer-reverse');
|
|||
let BigNumber = require('bignumber.js');
|
||||
|
||||
const storageKey = 'ELECTRUM_PEERS';
|
||||
const defaultPeer = { host: 'electrum1.bluewallet.io', tcp: '50001' };
|
||||
const defaultPeer = { host: 'electrum1.bluewallet.io', ssl: '443' };
|
||||
const hardcodedPeers = [
|
||||
// { host: 'noveltybobble.coinjoined.com', tcp: '50001' }, // down
|
||||
// { host: 'electrum.be', tcp: '50001' },
|
||||
|
@ -16,27 +16,27 @@ const hardcodedPeers = [
|
|||
// { host: 'Bitkoins.nl', tcp: '50001' }, // down
|
||||
// { host: 'fullnode.coinkite.com', tcp: '50001' },
|
||||
// { host: 'preperfect.eleCTruMioUS.com', tcp: '50001' }, // down
|
||||
{ host: 'electrum1.bluewallet.io', tcp: '50001' },
|
||||
{ host: 'electrum1.bluewallet.io', tcp: '50001' }, // 2x weight
|
||||
{ host: 'electrum2.bluewallet.io', tcp: '50001' },
|
||||
{ host: 'electrum3.bluewallet.io', tcp: '50001' },
|
||||
{ host: 'electrum3.bluewallet.io', tcp: '50001' }, // 2x weight
|
||||
{ host: 'electrum1.bluewallet.io', ssl: '443' },
|
||||
{ host: 'electrum1.bluewallet.io', ssl: '443' }, // 2x weight
|
||||
{ host: 'electrum2.bluewallet.io', ssl: '443' },
|
||||
{ host: 'electrum3.bluewallet.io', ssl: '443' },
|
||||
{ host: 'electrum3.bluewallet.io', ssl: '443' }, // 2x weight
|
||||
];
|
||||
|
||||
let mainClient = false;
|
||||
let mainClient: ElectrumClient = false;
|
||||
let mainConnected = false;
|
||||
let wasConnectedAtLeastOnce = false;
|
||||
|
||||
async function connectMain() {
|
||||
let usingPeer = await getRandomHardcodedPeer();
|
||||
let savedPeer = await getSavedPeer();
|
||||
if (savedPeer && savedPeer.host && savedPeer.tcp) {
|
||||
if (savedPeer && savedPeer.host && (savedPeer.tcp || savedPeer.ssl)) {
|
||||
usingPeer = savedPeer;
|
||||
}
|
||||
|
||||
try {
|
||||
console.log('begin connection:', JSON.stringify(usingPeer));
|
||||
mainClient = new ElectrumClient(usingPeer.tcp, usingPeer.host, 'tcp');
|
||||
mainClient = new ElectrumClient(usingPeer.ssl || usingPeer.tcp, usingPeer.host, usingPeer.ssl ? 'tls' : 'tcp');
|
||||
mainClient.onError = function(e) {
|
||||
console.log('ElectrumClient error: ' + e);
|
||||
mainConnected = false;
|
||||
|
@ -78,7 +78,8 @@ async function getRandomHardcodedPeer() {
|
|||
async function getSavedPeer() {
|
||||
let host = await AsyncStorage.getItem(AppStorage.ELECTRUM_HOST);
|
||||
let port = await AsyncStorage.getItem(AppStorage.ELECTRUM_TCP_PORT);
|
||||
return { host, tcp: port };
|
||||
let sslPort = await AsyncStorage.getItem(AppStorage.ELECTRUM_SSL_PORT);
|
||||
return { host, tcp: port, ssl: sslPort };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -391,17 +392,15 @@ module.exports.broadcastV2 = async function(hex) {
|
|||
*
|
||||
* @param host
|
||||
* @param tcpPort
|
||||
* @param sslPort
|
||||
* @returns {Promise<boolean>} Whether provided host:port is a valid electrum server
|
||||
*/
|
||||
module.exports.testConnection = async function(host, tcpPort) {
|
||||
let client = new ElectrumClient(tcpPort, host, 'tcp');
|
||||
module.exports.testConnection = async function(host, tcpPort, sslPort) {
|
||||
let client = new ElectrumClient(sslPort || tcpPort, host, sslPort ? 'tls' : 'tcp');
|
||||
try {
|
||||
await client.connect();
|
||||
await client.server_version('2.7.11', '1.4');
|
||||
await client.server_ping();
|
||||
|
||||
client.keepAlive = () => {}; // dirty hack to make it stop reconnecting
|
||||
client.reconnect = () => {}; // dirty hack to make it stop reconnecting
|
||||
client.close();
|
||||
return true;
|
||||
} catch (_) {
|
||||
|
@ -410,8 +409,6 @@ module.exports.testConnection = async function(host, tcpPort) {
|
|||
};
|
||||
|
||||
module.exports.forceDisconnect = () => {
|
||||
mainClient.keepAlive = () => {}; // dirty hack to make it stop reconnecting
|
||||
mainClient.reconnect = () => {}; // dirty hack to make it stop reconnecting
|
||||
mainClient.close();
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ export class AppStorage {
|
|||
static LNDHUB = 'lndhub';
|
||||
static ELECTRUM_HOST = 'electrum_host';
|
||||
static ELECTRUM_TCP_PORT = 'electrum_tcp_port';
|
||||
static ELECTRUM_SSL_PORT = 'electrum_ssl_port';
|
||||
static PREFERRED_CURRENCY = 'preferredCurrency';
|
||||
static ADVANCED_MODE_ENABLED = 'advancedmodeenabled';
|
||||
static DELETE_WALLET_AFTER_UNINSTALL = 'deleteWalletAfterUninstall';
|
||||
|
|
95
package-lock.json
generated
95
package-lock.json
generated
|
@ -6767,9 +6767,9 @@
|
|||
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA=="
|
||||
},
|
||||
"ip-regex": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz",
|
||||
"integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0="
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-T8wDtjy+Qf2TAPDQmBp0eGKJ8GavlWlUnamr3wRn6vvdZlKVuJXXMlSncYFRYgVHOM3If5NR1H4+OvVQU9Idvg=="
|
||||
},
|
||||
"is": {
|
||||
"version": "0.2.7",
|
||||
|
@ -11697,33 +11697,86 @@
|
|||
}
|
||||
},
|
||||
"react-native-tcp": {
|
||||
"version": "git+https://github.com/aprock/react-native-tcp.git#6a3b1bc702bf1d40287274ac32698335a8fba61a",
|
||||
"from": "git+https://github.com/aprock/react-native-tcp.git",
|
||||
"version": "git+https://github.com/BlueWallet/react-native-tcp.git#113433d505063d58a17317e925f03f65e7fc5c3d",
|
||||
"from": "git+https://github.com/BlueWallet/react-native-tcp.git",
|
||||
"requires": {
|
||||
"base64-js": "0.0.8",
|
||||
"buffer": "^5.0.0",
|
||||
"events": "^1.0.2",
|
||||
"ip-regex": "^1.0.3",
|
||||
"process": "^0.11.9",
|
||||
"util": "^0.10.3"
|
||||
"base64-js": "1.3.0",
|
||||
"buffer": "5.2.1",
|
||||
"events": "3.0.0",
|
||||
"ip-regex": "3.0.0",
|
||||
"process": "0.11.10",
|
||||
"stream-browserify": "2.0.1",
|
||||
"util": "0.11.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"base64-js": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
|
||||
"integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg="
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
|
||||
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
"buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
|
||||
"integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"stream-browserify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
|
||||
"integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
|
||||
"requires": {
|
||||
"inherits": "~2.0.1",
|
||||
"readable-stream": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"util": {
|
||||
"version": "0.10.4",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
|
||||
"integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
|
||||
"integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
|
||||
"requires": {
|
||||
"inherits": "2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
"react-native-snap-carousel": "3.8.4",
|
||||
"react-native-sortable-list": "0.0.23",
|
||||
"react-native-svg": "9.13.6",
|
||||
"react-native-tcp": "git+https://github.com/aprock/react-native-tcp.git",
|
||||
"react-native-tcp": "git+https://github.com/BlueWallet/react-native-tcp.git",
|
||||
"react-native-tooltip": "git+https://github.com/marcosrdz/react-native-tooltip.git",
|
||||
"react-native-vector-icons": "6.6.0",
|
||||
"react-native-watch-connectivity": "0.4.2",
|
||||
|
|
|
@ -25,11 +25,13 @@ export default class ElectrumSettings extends Component {
|
|||
async componentDidMount() {
|
||||
let host = await AsyncStorage.getItem(AppStorage.ELECTRUM_HOST);
|
||||
let port = await AsyncStorage.getItem(AppStorage.ELECTRUM_TCP_PORT);
|
||||
let sslPort = await AsyncStorage.getItem(AppStorage.ELECTRUM_SSL_PORT);
|
||||
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
host,
|
||||
port,
|
||||
sslPort,
|
||||
});
|
||||
|
||||
await this.setState({
|
||||
|
@ -41,16 +43,19 @@ export default class ElectrumSettings extends Component {
|
|||
this.setState({ isLoading: true }, async () => {
|
||||
this.state.host = this.state.host ? this.state.host : '';
|
||||
this.state.port = this.state.port ? this.state.port : '';
|
||||
this.state.sslPort = this.state.sslPort ? this.state.sslPort : '';
|
||||
try {
|
||||
if (!this.state.host && !this.state.port) {
|
||||
if (!this.state.host && !this.state.port && !this.state.sslPort) {
|
||||
await AsyncStorage.setItem(AppStorage.ELECTRUM_HOST, '');
|
||||
await AsyncStorage.setItem(AppStorage.ELECTRUM_TCP_PORT, '');
|
||||
await AsyncStorage.setItem(AppStorage.ELECTRUM_SSL_PORT, '');
|
||||
alert('Your changes have been saved successfully. Restart may be required for changes to take effect.');
|
||||
} else if (!(await BlueElectrum.testConnection(this.state.host, this.state.port))) {
|
||||
} else if (!(await BlueElectrum.testConnection(this.state.host, this.state.port, this.state.sslPort))) {
|
||||
alert("Can't connect to provided Electrum server");
|
||||
} else {
|
||||
await AsyncStorage.setItem(AppStorage.ELECTRUM_HOST, this.state.host);
|
||||
await AsyncStorage.setItem(AppStorage.ELECTRUM_TCP_PORT, this.state.port);
|
||||
await AsyncStorage.setItem(AppStorage.ELECTRUM_SSL_PORT, this.state.sslPort);
|
||||
alert('Your changes have been saved successfully. Restart may be required for changes to take effect.');
|
||||
}
|
||||
} catch (_) {}
|
||||
|
@ -99,6 +104,7 @@ export default class ElectrumSettings extends Component {
|
|||
borderBottomWidth: 0.5,
|
||||
backgroundColor: '#f5f5f5',
|
||||
minHeight: 44,
|
||||
width: 200,
|
||||
height: 44,
|
||||
alignItems: 'center',
|
||||
borderRadius: 4,
|
||||
|
@ -114,6 +120,32 @@ export default class ElectrumSettings extends Component {
|
|||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</View>
|
||||
<BlueSpacing20 />
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
borderColor: '#d2d2d2',
|
||||
borderBottomColor: '#d2d2d2',
|
||||
borderWidth: 1.0,
|
||||
borderBottomWidth: 0.5,
|
||||
backgroundColor: '#f5f5f5',
|
||||
minHeight: 44,
|
||||
height: 44,
|
||||
width: 200,
|
||||
alignItems: 'center',
|
||||
borderRadius: 4,
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
placeholder={'SSL port, usually 50002'}
|
||||
value={this.state.sslPort}
|
||||
onChangeText={text => this.setState({ sslPort: text })}
|
||||
numberOfLines={1}
|
||||
style={{ flex: 1, marginHorizontal: 8, minHeight: 36, height: 36 }}
|
||||
editable={!this.state.isLoading}
|
||||
underlineColorAndroid="transparent"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<BlueSpacing20 />
|
||||
{this.state.isLoading ? <BlueLoading /> : <BlueButton onPress={this.save} title={loc.settings.save} />}
|
||||
|
|
4
shim.js
4
shim.js
|
@ -1,6 +1,5 @@
|
|||
/* global __DEV__, localStorage */
|
||||
if (typeof Buffer === 'undefined') global.Buffer = require('buffer').Buffer;
|
||||
global.net = require('react-native-tcp');
|
||||
if (typeof __dirname === 'undefined') global.__dirname = '/';
|
||||
if (typeof __filename === 'undefined') global.__filename = '';
|
||||
if (typeof process === 'undefined') {
|
||||
|
@ -16,6 +15,9 @@ if (typeof process === 'undefined') {
|
|||
|
||||
process.browser = false;
|
||||
|
||||
global.net = require('react-native-tcp');
|
||||
global.tls = require('react-native-tcp/tls');
|
||||
|
||||
// global.location = global.location || { port: 80 }
|
||||
const isDev = typeof __DEV__ === 'boolean' && __DEV__;
|
||||
process.env['NODE_ENV'] = isDev ? 'development' : 'production';
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* global it, describe, afterAll, beforeAll, jasmine */
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
global.net = require('net');
|
||||
global.tls = require('tls');
|
||||
let BlueElectrum = require('../../BlueElectrum');
|
||||
let assert = require('assert');
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 150 * 1000;
|
||||
|
@ -8,7 +8,6 @@ jasmine.DEFAULT_TIMEOUT_INTERVAL = 150 * 1000;
|
|||
afterAll(() => {
|
||||
// after all tests we close socket so the test suite can actually terminate
|
||||
BlueElectrum.forceDisconnect();
|
||||
return new Promise(resolve => setTimeout(resolve, 10000)); // simple sleep to wait for all timeouts termination
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
|
@ -22,53 +21,16 @@ beforeAll(async () => {
|
|||
}
|
||||
});
|
||||
|
||||
describe('Electrum', () => {
|
||||
describe('BlueElectrum', () => {
|
||||
it('ElectrumClient can test connection', async () => {
|
||||
assert.ok(await BlueElectrum.testConnection('electrum1.bluewallet.io', '50001'));
|
||||
assert.ok(await BlueElectrum.testConnection('electrum1.bluewallet.io', false, 443));
|
||||
});
|
||||
|
||||
it('ElectrumClient can estimate fees', async () => {
|
||||
assert.ok((await BlueElectrum.estimateFee(1)) > 1);
|
||||
});
|
||||
|
||||
it('ElectrumClient can connect and query', async () => {
|
||||
const ElectrumClient = require('electrum-client');
|
||||
|
||||
for (let peer of BlueElectrum.hardcodedPeers) {
|
||||
let mainClient = new ElectrumClient(peer.tcp, peer.host, 'tcp');
|
||||
|
||||
try {
|
||||
await mainClient.connect();
|
||||
await mainClient.server_version('2.7.11', '1.4');
|
||||
} catch (e) {
|
||||
mainClient.reconnect = mainClient.keepAlive = () => {}; // dirty hack to make it stop reconnecting
|
||||
mainClient.close();
|
||||
throw new Error('bad connection: ' + JSON.stringify(peer) + ' ' + e.message);
|
||||
}
|
||||
|
||||
let addr4elect = 'bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej';
|
||||
let script = bitcoin.address.toOutputScript(addr4elect);
|
||||
let hash = bitcoin.crypto.sha256(script);
|
||||
let reversedHash = Buffer.from(hash.reverse());
|
||||
let start = +new Date();
|
||||
let balance = await mainClient.blockchainScripthash_getBalance(reversedHash.toString('hex'));
|
||||
let end = +new Date();
|
||||
console.warn(peer.host, 'took', (end - start) / 1000, 'seconds to fetch balance');
|
||||
assert.ok(balance.confirmed > 0);
|
||||
|
||||
addr4elect = '3GCvDBAktgQQtsbN6x5DYiQCMmgZ9Yk8BK';
|
||||
script = bitcoin.address.toOutputScript(addr4elect);
|
||||
hash = bitcoin.crypto.sha256(script);
|
||||
reversedHash = Buffer.from(hash.reverse());
|
||||
balance = await mainClient.blockchainScripthash_getBalance(reversedHash.toString('hex'));
|
||||
|
||||
// let peers = await mainClient.serverPeers_subscribe();
|
||||
// console.log(peers);
|
||||
mainClient.reconnect = mainClient.keepAlive = () => {}; // dirty hack to make it stop reconnecting
|
||||
mainClient.close();
|
||||
}
|
||||
});
|
||||
|
||||
it('BlueElectrum can do getBalanceByAddress()', async function() {
|
||||
let address = '3GCvDBAktgQQtsbN6x5DYiQCMmgZ9Yk8BK';
|
||||
let balance = await BlueElectrum.getBalanceByAddress(address);
|
55
tests/integration/ElectrumClient.test.js
Normal file
55
tests/integration/ElectrumClient.test.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* global it, describe, jasmine */
|
||||
const bitcoin = require('bitcoinjs-lib');
|
||||
global.net = require('net');
|
||||
global.tls = require('tls');
|
||||
|
||||
let assert = require('assert');
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 150 * 1000;
|
||||
|
||||
const hardcodedPeers = [
|
||||
{ host: 'electrum1.bluewallet.io', ssl: '443' },
|
||||
{ host: 'electrum2.bluewallet.io', ssl: '443' },
|
||||
{ host: 'electrum3.bluewallet.io', ssl: '443' },
|
||||
{ host: 'electrum1.bluewallet.io', tcp: '50001' },
|
||||
{ host: 'electrum2.bluewallet.io', tcp: '50001' },
|
||||
{ host: 'electrum3.bluewallet.io', tcp: '50001' },
|
||||
];
|
||||
|
||||
describe('ElectrumClient', () => {
|
||||
it('can connect and query', async () => {
|
||||
const ElectrumClient = require('electrum-client');
|
||||
|
||||
for (let peer of hardcodedPeers) {
|
||||
let mainClient = new ElectrumClient(peer.ssl || peer.tcp, peer.host, peer.ssl ? 'tls' : 'tcp');
|
||||
|
||||
try {
|
||||
await mainClient.connect();
|
||||
await mainClient.server_version('2.7.11', '1.4');
|
||||
} catch (e) {
|
||||
mainClient.reconnect = mainClient.keepAlive = () => {}; // dirty hack to make it stop reconnecting
|
||||
mainClient.close();
|
||||
throw new Error('bad connection: ' + JSON.stringify(peer) + ' ' + e.message);
|
||||
}
|
||||
|
||||
let addr4elect = 'bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej';
|
||||
let script = bitcoin.address.toOutputScript(addr4elect);
|
||||
let hash = bitcoin.crypto.sha256(script);
|
||||
let reversedHash = Buffer.from(hash.reverse());
|
||||
let start = +new Date();
|
||||
let balance = await mainClient.blockchainScripthash_getBalance(reversedHash.toString('hex'));
|
||||
let end = +new Date();
|
||||
end - start > 1000 && console.warn(peer.host, 'took', (end - start) / 1000, 'seconds to fetch balance');
|
||||
assert.ok(balance.confirmed > 0);
|
||||
|
||||
addr4elect = '3GCvDBAktgQQtsbN6x5DYiQCMmgZ9Yk8BK';
|
||||
script = bitcoin.address.toOutputScript(addr4elect);
|
||||
hash = bitcoin.crypto.sha256(script);
|
||||
reversedHash = Buffer.from(hash.reverse());
|
||||
balance = await mainClient.blockchainScripthash_getBalance(reversedHash.toString('hex'));
|
||||
|
||||
// let peers = await mainClient.serverPeers_subscribe();
|
||||
// console.log(peers);
|
||||
mainClient.close();
|
||||
}
|
||||
});
|
||||
});
|
|
@ -12,6 +12,7 @@ const bitcoin = require('bitcoinjs-lib');
|
|||
global.crypto = require('crypto'); // shall be used by tests under nodejs CLI, but not in RN environment
|
||||
let assert = require('assert');
|
||||
global.net = require('net'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
global.tls = require('tls'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
let BlueElectrum = require('../../BlueElectrum'); // so it connects ASAP
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 300 * 1000;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { LegacyWallet, SegwitP2SHWallet, SegwitBech32Wallet } from '../../class';
|
||||
let assert = require('assert');
|
||||
global.net = require('net'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
global.tls = require('tls'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
let BlueElectrum = require('../../BlueElectrum'); // so it connects ASAP
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { WatchOnlyWallet } from '../../class';
|
||||
let assert = require('assert');
|
||||
global.net = require('net'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
global.tls = require('tls'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
let BlueElectrum = require('../../BlueElectrum'); // so it connects ASAP
|
||||
|
||||
afterAll(async () => {
|
||||
|
|
|
@ -4,6 +4,7 @@ const bitcoin = require('bitcoinjs-lib');
|
|||
global.crypto = require('crypto'); // shall be used by tests under nodejs CLI, but not in RN environment
|
||||
let assert = require('assert');
|
||||
global.net = require('net'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
global.tls = require('tls'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
let BlueElectrum = require('../../BlueElectrum');
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 150 * 1000;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { HDSegwitBech32Wallet } from '../../class';
|
|||
global.crypto = require('crypto'); // shall be used by tests under nodejs CLI, but not in RN environment
|
||||
let assert = require('assert');
|
||||
global.net = require('net'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
global.tls = require('tls'); // needed by Electrum client. For RN it is proviced in shim.js
|
||||
let BlueElectrum = require('../../BlueElectrum'); // so it connects ASAP
|
||||
|
||||
afterAll(async () => {
|
||||
|
|
Loading…
Add table
Reference in a new issue