forked from ryanralph/altcoin-address
-
Notifications
You must be signed in to change notification settings - Fork 129
Expand file tree
/
Copy pathbitcoin_validator.js
More file actions
75 lines (60 loc) · 2.22 KB
/
bitcoin_validator.js
File metadata and controls
75 lines (60 loc) · 2.22 KB
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
var base58 = require('./crypto/base58');
var segwit = require('./crypto/segwit_addr');
var cryptoUtils = require('./crypto/utils');
var DEFAULT_NETWORK_TYPE = 'prod';
function getDecoded(address) {
try {
return base58.decode(address);
} catch (e) {
// if decoding fails, assume invalid address
return null;
}
}
function getChecksum(hashFunction, payload) {
// Each currency may implement different hashing algorithm
switch (hashFunction) {
case 'blake256':
return cryptoUtils.blake256Checksum(payload);
break;
case 'sha256':
default:
return cryptoUtils.sha256Checksum(payload);
}
}
function getAddressType(address, currency) {
currency = currency || {};
// should be 25 bytes per btc address spec and 26 decred
var expectedLength = currency.expectedLength || 25;
var hashFunction = currency.hashFunction || 'sha256';
var decoded = getDecoded(address);
if (decoded) {
var length = decoded.length;
if (length !== expectedLength) {
return null;
}
var checksum = cryptoUtils.toHex(decoded.slice(length - 4, length)),
body = cryptoUtils.toHex(decoded.slice(0, length - 4)),
goodChecksum = getChecksum(hashFunction, body);
return checksum === goodChecksum ? cryptoUtils.toHex(decoded.slice(0, expectedLength - 24)) : null;
}
return null;
}
function isValidP2PKHandP2SHAddress(address, currency, networkType) {
networkType = networkType || DEFAULT_NETWORK_TYPE;
var correctAddressTypes;
var addressType = getAddressType(address, currency);
if (addressType) {
if (networkType === 'prod' || networkType === 'testnet') {
correctAddressTypes = currency.addressTypes[networkType]
} else {
correctAddressTypes = currency.addressTypes.prod.concat(currency.addressTypes.testnet);
}
return correctAddressTypes.indexOf(addressType) >= 0;
}
return false;
}
module.exports = {
isValidAddress: function (address, currency, networkType) {
return isValidP2PKHandP2SHAddress(address, currency, networkType) || segwit.isValidAddress(address, currency.segwitHrp);
}
};