-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
100 lines (80 loc) · 2.23 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const Emitter = require('tiny-emitter');
const ONE_SECOND = 1000;
const keyFormats = {
wif: require('./key-formats/wif'),
bip39: require('./key-formats/bip39'),
xpub: require('./key-formats/xpub')
};
const addressFormats = {
p2pkh: require('./address-formats/p2pkh'),
'p2wpkh-p2sh': require('./address-formats/p2wpkh-p2sh'),
p2wpkh: require('./address-formats/p2wpkh')
};
class Vain extends Emitter {
constructor(options = {}) {
super();
this.options = {
keyFormat: 'wif',
addressFormat: 'p2pkh',
...options
};
this.generating = false;
this.generateKey = keyFormats[this.options.keyFormat];
this.addressFormat = addressFormats[this.options.addressFormat];
if (typeof this.options.prefix !== 'string' || this.options.prefix.length === 0) {
throw new Error('Prefix must be set');
}
this.options.prefix.split('').forEach(char => {
if (!this.addressFormat.charset.includes(char)) {
throw new Error(`Invalid characters for address format "${this.options.prefix.addressFormat}"`);
}
});
this.prefix = `${this.addressFormat.prefix}${this.options.prefix}`;
}
generate() {
this.generating = true;
const startTime = Date.now();
const {generateKey, addressFormat, options} = this;
let found;
let attempts = 0;
let keyData;
let address;
let lastUpdate = Date.now();
while (!found) {
if (!this.generating) {
return {stopped: true};
}
attempts++;
keyData = generateKey({addressFormat, options, attempts});
address = addressFormat.derive(keyData.publicKey);
if (address.startsWith(this.prefix)) {
found = true;
this.generating = false;
}
const now = Date.now();
if ((now - lastUpdate) > ONE_SECOND) {
const duration = now - startTime;
const addressesPerSecond = Math.floor(attempts / (duration / ONE_SECOND));
this.emit('update', {
duration,
attempts,
addressesPerSecond
});
lastUpdate = now;
}
}
const endTime = Date.now();
const duration = endTime - startTime;
const addressesPerSecond = Math.floor(attempts / (duration / ONE_SECOND));
const result = {
duration,
attempts,
addressesPerSecond,
address,
...keyData.format()
};
this.emit('found', result);
return result;
}
}
module.exports = Vain;