multichain-address-validator 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +10 -0
- package/.travis.yml +11 -0
- package/.vscode/launch.json +23 -0
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/config/esbuild.inject.js +1 -0
- package/config/esbuild.ts +14 -0
- package/dist/chain-validators.d.ts +2 -0
- package/dist/chain-validators.js +98 -0
- package/dist/crypto/base32.d.ts +5 -0
- package/dist/crypto/base32.js +64 -0
- package/dist/crypto/base58.d.ts +4 -0
- package/dist/crypto/base58.js +42 -0
- package/dist/crypto/bech32.d.ts +17 -0
- package/dist/crypto/bech32.js +124 -0
- package/dist/crypto/biginteger.d.ts +57 -0
- package/dist/crypto/biginteger.js +1311 -0
- package/dist/crypto/blake256.d.ts +22 -0
- package/dist/crypto/blake256.js +169 -0
- package/dist/crypto/blake2b.d.ts +13 -0
- package/dist/crypto/blake2b.js +242 -0
- package/dist/crypto/cnBase58.d.ts +7 -0
- package/dist/crypto/cnBase58.js +209 -0
- package/dist/crypto/segwit_addr.d.ts +12 -0
- package/dist/crypto/segwit_addr.js +102 -0
- package/dist/crypto/utils.d.ts +26 -0
- package/dist/crypto/utils.js +123 -0
- package/dist/helpers.d.ts +2 -0
- package/dist/helpers.js +5 -0
- package/dist/multichain-address-validator.bundle.min.js +17 -0
- package/dist/multichain-address-validator.d.ts +2 -0
- package/dist/multichain-address-validator.js +8 -0
- package/dist/types.d.ts +15 -0
- package/dist/types.js +5 -0
- package/dist/validators/algorand_validator.d.ts +5 -0
- package/dist/validators/algorand_validator.js +23 -0
- package/dist/validators/base58_validator.d.ts +4 -0
- package/dist/validators/base58_validator.js +31 -0
- package/dist/validators/bch_validator.d.ts +13 -0
- package/dist/validators/bch_validator.js +50 -0
- package/dist/validators/bip173_validator.d.ts +7 -0
- package/dist/validators/bip173_validator.js +12 -0
- package/dist/validators/bitcoin_validator.d.ts +12 -0
- package/dist/validators/bitcoin_validator.js +68 -0
- package/dist/validators/cardano_validator.d.ts +5 -0
- package/dist/validators/cardano_validator.js +41 -0
- package/dist/validators/eos_validator.d.ts +5 -0
- package/dist/validators/eos_validator.js +10 -0
- package/dist/validators/ethereum_validator.d.ts +6 -0
- package/dist/validators/ethereum_validator.js +30 -0
- package/dist/validators/index.d.ts +16 -0
- package/dist/validators/index.js +16 -0
- package/dist/validators/monero_validator.d.ts +5 -0
- package/dist/validators/monero_validator.js +58 -0
- package/dist/validators/nano_validator.d.ts +6 -0
- package/dist/validators/nano_validator.js +23 -0
- package/dist/validators/nem_validator.d.ts +5 -0
- package/dist/validators/nem_validator.js +14 -0
- package/dist/validators/polkadot_validator.d.ts +5 -0
- package/dist/validators/polkadot_validator.js +49 -0
- package/dist/validators/ripple_validator.d.ts +10 -0
- package/dist/validators/ripple_validator.js +26 -0
- package/dist/validators/sia_validator.d.ts +5 -0
- package/dist/validators/sia_validator.js +27 -0
- package/dist/validators/solana_validator.d.ts +5 -0
- package/dist/validators/solana_validator.js +10 -0
- package/dist/validators/tezos_validator.d.ts +5 -0
- package/dist/validators/tezos_validator.js +30 -0
- package/dist/validators/tron_validator.d.ts +8 -0
- package/dist/validators/tron_validator.js +45 -0
- package/dist/validators/xlm_validator.d.ts +6 -0
- package/dist/validators/xlm_validator.js +32 -0
- package/index.html +12 -0
- package/package.json +353 -0
- package/src/chain-validators.ts +131 -0
- package/src/crypto/base32.ts +66 -0
- package/src/crypto/base58.ts +46 -0
- package/src/crypto/bech32.js +132 -0
- package/src/crypto/biginteger.js +1426 -0
- package/src/crypto/blake256.js +186 -0
- package/src/crypto/blake2b.js +276 -0
- package/src/crypto/cnBase58.js +226 -0
- package/src/crypto/segwit_addr.js +112 -0
- package/src/crypto/utils.ts +133 -0
- package/src/helpers.ts +7 -0
- package/src/multichain-address-validator.ts +11 -0
- package/src/types.ts +18 -0
- package/src/validators/algorand_validator.ts +28 -0
- package/src/validators/base58_validator.ts +32 -0
- package/src/validators/bch_validator.ts +66 -0
- package/src/validators/bip173_validator.ts +19 -0
- package/src/validators/bitcoin_validator.ts +94 -0
- package/src/validators/cardano_validator.ts +50 -0
- package/src/validators/eos_validator.ts +13 -0
- package/src/validators/ethereum_validator.ts +37 -0
- package/src/validators/index.ts +16 -0
- package/src/validators/monero_validator.ts +72 -0
- package/src/validators/nano_validator.ts +32 -0
- package/src/validators/nem_validator.ts +18 -0
- package/src/validators/polkadot_validator.ts +57 -0
- package/src/validators/ripple_validator.ts +36 -0
- package/src/validators/sia_validator.ts +33 -0
- package/src/validators/solana_validator.ts +12 -0
- package/src/validators/tezos_validator.ts +36 -0
- package/src/validators/tron_validator.ts +59 -0
- package/src/validators/xlm_validator.ts +42 -0
- package/test/addresses/addresses.ts +45 -0
- package/test/addresses/algorand.json +6 -0
- package/test/addresses/bch-testnet.json +4 -0
- package/test/addresses/bch.json +12 -0
- package/test/addresses/btc-testnet.json +6 -0
- package/test/addresses/btc.json +14 -0
- package/test/addresses/cardano.json +8 -0
- package/test/addresses/doge.json +7 -0
- package/test/addresses/eos.json +6 -0
- package/test/addresses/evm.json +21 -0
- package/test/addresses/invalid.json +15 -0
- package/test/addresses/ltc-testnet.json +7 -0
- package/test/addresses/ltc.json +9 -0
- package/test/addresses/monero.json +7 -0
- package/test/addresses/nano.json +12 -0
- package/test/addresses/nem.json +4 -0
- package/test/addresses/polkadot.json +8 -0
- package/test/addresses/ripple.json +11 -0
- package/test/addresses/sia.json +6 -0
- package/test/addresses/solana.json +8 -0
- package/test/addresses/tezos.json +9 -0
- package/test/addresses/tron.json +6 -0
- package/test/addresses/xlm.json +12 -0
- package/test/multichain-address-validator.test.ts +1589 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
2
|
+
import { getAddress } from '../helpers.js';
|
|
3
|
+
const ALGORAND_CHECKSUM_BYTE_LENGTH = 4;
|
|
4
|
+
const ALGORAND_ADDRESS_LENGTH = 58;
|
|
5
|
+
function verifyChecksum(address) {
|
|
6
|
+
if (address.length !== ALGORAND_ADDRESS_LENGTH) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
// Decode base32 Address
|
|
11
|
+
const decoded = cryptoUtils.base32.b32decode(address);
|
|
12
|
+
const addr = decoded.slice(0, decoded.length - ALGORAND_CHECKSUM_BYTE_LENGTH);
|
|
13
|
+
const checksum = cryptoUtils.byteArray2hexStr(decoded.slice(-4));
|
|
14
|
+
// Hash Address - Checksum
|
|
15
|
+
const code = cryptoUtils.sha512_256(cryptoUtils.byteArray2hexStr(addr)).substr(-ALGORAND_CHECKSUM_BYTE_LENGTH * 2);
|
|
16
|
+
return code.toUpperCase() === checksum;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export default {
|
|
20
|
+
isValidAddress: function (address) {
|
|
21
|
+
return verifyChecksum(getAddress(address));
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import base58 from '../crypto/base58.js';
|
|
2
|
+
// simple base58 validator. Just checks if it can be decoded.
|
|
3
|
+
export default {
|
|
4
|
+
isValidAddress: function (address, opts) {
|
|
5
|
+
try {
|
|
6
|
+
if (!address || address.length == 0) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
if (opts.minLength && (address.length < opts.minLength)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
if (opts.maxLength && (address.length > opts.maxLength)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const decoded = base58.decode(address);
|
|
17
|
+
if (!decoded || !decoded.length) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
// if decoding fails, assume invalid address
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Address, NetworkType } from '../types.js';
|
|
2
|
+
interface BCHValidatorOpts {
|
|
3
|
+
addressTypes: string[];
|
|
4
|
+
expectedLength?: number;
|
|
5
|
+
bech32Hrp?: [string];
|
|
6
|
+
hashFunction?: 'blake256' | 'blake256keccak256' | 'keccak256' | 'sha256';
|
|
7
|
+
regexp?: RegExp;
|
|
8
|
+
networkType: NetworkType;
|
|
9
|
+
}
|
|
10
|
+
declare const _default: (opts: BCHValidatorOpts) => {
|
|
11
|
+
isValidAddress: (address: Address) => boolean;
|
|
12
|
+
};
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
2
|
+
import bech32 from '../crypto/bech32.js';
|
|
3
|
+
import { NetworkType } from '../types.js';
|
|
4
|
+
import BTCValidator from './bitcoin_validator.js';
|
|
5
|
+
import { getAddress } from '../helpers.js';
|
|
6
|
+
function validateAddress(address, opts) {
|
|
7
|
+
const regexp = new RegExp(opts.regexp);
|
|
8
|
+
let raw_address;
|
|
9
|
+
const res = address.split(':');
|
|
10
|
+
if (res.length === 1) {
|
|
11
|
+
raw_address = address;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
if (res[0] !== 'bitcoincash') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
raw_address = res[1];
|
|
18
|
+
}
|
|
19
|
+
if (!regexp.test(raw_address)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
if (raw_address.toLowerCase() != raw_address && raw_address.toUpperCase() != raw_address) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const decoded = cryptoUtils.base32.b32decode(raw_address);
|
|
26
|
+
const prefix = opts.networkType === NetworkType.MainNet
|
|
27
|
+
? 'bitcoincash'
|
|
28
|
+
: 'bchtest';
|
|
29
|
+
try {
|
|
30
|
+
if (bech32.verifyChecksum(prefix, decoded, bech32.encodings.BECH32)) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
const DefaultBCHValidatorOpts = {
|
|
40
|
+
// addressTypes: {mainnet: ['00', '05'], testnet: ['6f', 'c4', '3c', '26']},
|
|
41
|
+
// bech32Hrp: {mainnet: ['bc'], testnet: ['tb']},
|
|
42
|
+
regexp: /^[qQpP][0-9a-zA-Z]{41}$/,
|
|
43
|
+
};
|
|
44
|
+
export default (opts) => ({
|
|
45
|
+
isValidAddress: function (address) {
|
|
46
|
+
const addr = getAddress(address);
|
|
47
|
+
const _opts = { ...DefaultBCHValidatorOpts, ...opts };
|
|
48
|
+
return validateAddress(addr, _opts) || BTCValidator(opts).isValidAddress(address);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import bech32 from '../crypto/bech32.js';
|
|
2
|
+
// bip 173 bech 32 addresses (https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)
|
|
3
|
+
export default {
|
|
4
|
+
isValidAddress: function (address, opts) {
|
|
5
|
+
const decoded = bech32.decode(address, bech32.encodings.BECH32);
|
|
6
|
+
if (!decoded) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const bech32Hrp = decoded.hrp;
|
|
10
|
+
return opts.bech32Hrp.indexOf(bech32Hrp) !== -1;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Address } from '../types.js';
|
|
2
|
+
interface BTCValidatorOpts {
|
|
3
|
+
addressTypes: string[];
|
|
4
|
+
expectedLength?: number;
|
|
5
|
+
bech32Hrp?: [string];
|
|
6
|
+
hashFunction?: 'blake256' | 'blake256keccak256' | 'keccak256' | 'sha256';
|
|
7
|
+
regex?: RegExp;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: (opts: BTCValidatorOpts) => {
|
|
10
|
+
isValidAddress(address: Address): boolean;
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import base58 from '../crypto/base58.js';
|
|
2
|
+
import segwit from '../crypto/segwit_addr.js';
|
|
3
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
4
|
+
import { getAddress } from '../helpers.js';
|
|
5
|
+
import { Buffer } from 'buffer';
|
|
6
|
+
function getDecoded(address) {
|
|
7
|
+
try {
|
|
8
|
+
return base58.decode(address);
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
// if decoding fails, assume invalid address
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function getChecksum(hashFunction, payload) {
|
|
16
|
+
// Each currency may implement different hashing algorithm
|
|
17
|
+
switch (hashFunction) {
|
|
18
|
+
// blake then keccak hash chain
|
|
19
|
+
case 'blake256keccak256':
|
|
20
|
+
const blake = cryptoUtils.blake2b256(payload);
|
|
21
|
+
return cryptoUtils.keccak256Checksum(Buffer.from(blake, 'hex'));
|
|
22
|
+
case 'blake256':
|
|
23
|
+
return cryptoUtils.blake256Checksum(payload);
|
|
24
|
+
case 'keccak256':
|
|
25
|
+
return cryptoUtils.keccak256Checksum(payload);
|
|
26
|
+
case 'sha256':
|
|
27
|
+
default:
|
|
28
|
+
return cryptoUtils.sha256Checksum(payload);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function getAddressType(address, opts) {
|
|
32
|
+
// should be 25 bytes per btc address spec and 26 decred
|
|
33
|
+
const expectedLength = opts.expectedLength || 25;
|
|
34
|
+
const hashFunction = opts.hashFunction || 'sha256';
|
|
35
|
+
const decoded = getDecoded(address);
|
|
36
|
+
if (decoded) {
|
|
37
|
+
const length = decoded.length;
|
|
38
|
+
if (length !== expectedLength) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
if (opts.regex) {
|
|
42
|
+
if (!opts.regex.test(address)) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const checksum = cryptoUtils.toHex(decoded.slice(length - 4, length)), body = cryptoUtils.toHex(decoded.slice(0, length - 4)), goodChecksum = getChecksum(hashFunction, body);
|
|
47
|
+
return checksum === goodChecksum ? cryptoUtils.toHex(decoded.slice(0, expectedLength - 24)) : null;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
function isValidP2PKHandP2SHAddress(address, opts) {
|
|
52
|
+
const addressType = getAddressType(address, opts);
|
|
53
|
+
if (addressType) {
|
|
54
|
+
return opts.addressTypes.indexOf(addressType) >= 0;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
// const DefaultBTCValidatorOpts: BTCValidatorOpts = {
|
|
59
|
+
// addressTypes: {mainnet: ['00', '05'], testnet: ['6f', 'c4', '3c', '26']},
|
|
60
|
+
// bech32Hrp: {mainnet: ['bc'], testnet: ['tb']},
|
|
61
|
+
// }
|
|
62
|
+
export default (opts) => ({
|
|
63
|
+
isValidAddress(address) {
|
|
64
|
+
const addr = getAddress(address);
|
|
65
|
+
// const _opts = {...DefaultBTCValidatorOpts, ...opts}
|
|
66
|
+
return isValidP2PKHandP2SHAddress(addr, opts) || segwit.isValidAddress(addr, opts);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import cbor from 'cbor-js';
|
|
2
|
+
import CRC from 'crc';
|
|
3
|
+
import base58 from '../crypto/base58.js';
|
|
4
|
+
import BIP173Validator from './bip173_validator.js';
|
|
5
|
+
import { getAddress } from '../helpers.js';
|
|
6
|
+
function getDecoded(address) {
|
|
7
|
+
try {
|
|
8
|
+
const decoded = base58.decode(address);
|
|
9
|
+
return cbor.decode(new Uint8Array(decoded).buffer);
|
|
10
|
+
}
|
|
11
|
+
catch (e) {
|
|
12
|
+
// if decoding fails, assume invalid address
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function isValidAddressV1(address) {
|
|
17
|
+
const decoded = getDecoded(address);
|
|
18
|
+
if (!decoded || (!Array.isArray(decoded) && decoded.length != 2)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const tagged = decoded[0];
|
|
22
|
+
const validCrc = decoded[1];
|
|
23
|
+
if (typeof (validCrc) != 'number') {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
// get crc of the payload
|
|
27
|
+
const crc = CRC.crc32(tagged);
|
|
28
|
+
return crc == validCrc;
|
|
29
|
+
}
|
|
30
|
+
function isValidAddressShelley(address, opts) {
|
|
31
|
+
// shelley address are just bip 173 - bech32 addresses (https://cips.cardano.org/cips/cip4/)
|
|
32
|
+
return BIP173Validator.isValidAddress(address, opts);
|
|
33
|
+
}
|
|
34
|
+
export default {
|
|
35
|
+
isValidAddress(address) {
|
|
36
|
+
const addr = getAddress(address);
|
|
37
|
+
return isValidAddressV1(getAddress(addr)) || isValidAddressShelley(addr, {
|
|
38
|
+
bech32Hrp: ['addr']
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getAddress } from '../helpers.js';
|
|
2
|
+
function isValidEOSAddress(address) {
|
|
3
|
+
const regex = /^[a-z0-9.]+$/g; // Must be numbers, lowercase letters and decimal points only
|
|
4
|
+
return address.search(regex) !== -1 && address.length === 12;
|
|
5
|
+
}
|
|
6
|
+
export default {
|
|
7
|
+
isValidAddress: function (address) {
|
|
8
|
+
return isValidEOSAddress(getAddress(address));
|
|
9
|
+
}
|
|
10
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
2
|
+
import { getAddress } from '../helpers.js';
|
|
3
|
+
export default {
|
|
4
|
+
isValidAddress: function (address) {
|
|
5
|
+
const addr = getAddress(address);
|
|
6
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(addr)) {
|
|
7
|
+
// Check if it has the basic requirements of an address
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if (/^0x[0-9a-f]{40}$/.test(addr) || /^0x?[0-9A-F]{40}$/.test(addr)) {
|
|
11
|
+
// If it's all small caps or all caps, return true
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
// Otherwise check each case
|
|
15
|
+
return this.verifyChecksum(addr);
|
|
16
|
+
},
|
|
17
|
+
verifyChecksum: function (address) {
|
|
18
|
+
// Check each case
|
|
19
|
+
address = address.replace('0x', '');
|
|
20
|
+
const addressHash = cryptoUtils.keccak256(address.toLowerCase());
|
|
21
|
+
for (let i = 0; i < 40; i++) {
|
|
22
|
+
// The nth letter should be uppercase if the nth digit of casemap is 1
|
|
23
|
+
if ((parseInt(addressHash[i], 16) > 7 && address[i].toUpperCase() !== address[i]) ||
|
|
24
|
+
(parseInt(addressHash[i], 16) <= 7 && address[i].toLowerCase() !== address[i])) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { default as AlgorandValidator } from "./algorand_validator.js";
|
|
2
|
+
export { default as BCHValidator } from "./bch_validator.js";
|
|
3
|
+
export { default as BTCValidator } from "./bitcoin_validator.js";
|
|
4
|
+
export { default as CardanoValidator } from "./cardano_validator.js";
|
|
5
|
+
export { default as EOSValidator } from "./eos_validator.js";
|
|
6
|
+
export { default as ETHValidator } from "./ethereum_validator.js";
|
|
7
|
+
export { default as MoneroValidator } from "./monero_validator.js";
|
|
8
|
+
export { default as NemValidator } from "./nem_validator.js";
|
|
9
|
+
export { default as NanoValidator } from "./nano_validator.js";
|
|
10
|
+
export { default as PolkadotValidator } from "./polkadot_validator.js";
|
|
11
|
+
export { default as RippleValidator } from "./ripple_validator.js";
|
|
12
|
+
export { default as SiaValidator } from "./sia_validator.js";
|
|
13
|
+
export { default as SolanaValidator } from "./solana_validator.js";
|
|
14
|
+
export { default as TezosValidator } from "./tezos_validator.js";
|
|
15
|
+
export { default as TronValidator } from "./tron_validator.js";
|
|
16
|
+
export { default as XLMValidator } from "./xlm_validator.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { default as AlgorandValidator } from "./algorand_validator.js";
|
|
2
|
+
export { default as BCHValidator } from "./bch_validator.js";
|
|
3
|
+
export { default as BTCValidator } from "./bitcoin_validator.js";
|
|
4
|
+
export { default as CardanoValidator } from "./cardano_validator.js";
|
|
5
|
+
export { default as EOSValidator } from "./eos_validator.js";
|
|
6
|
+
export { default as ETHValidator } from "./ethereum_validator.js";
|
|
7
|
+
export { default as MoneroValidator } from "./monero_validator.js";
|
|
8
|
+
export { default as NemValidator } from "./nem_validator.js";
|
|
9
|
+
export { default as NanoValidator } from "./nano_validator.js";
|
|
10
|
+
export { default as PolkadotValidator } from "./polkadot_validator.js";
|
|
11
|
+
export { default as RippleValidator } from "./ripple_validator.js";
|
|
12
|
+
export { default as SiaValidator } from "./sia_validator.js";
|
|
13
|
+
export { default as SolanaValidator } from "./solana_validator.js";
|
|
14
|
+
export { default as TezosValidator } from "./tezos_validator.js";
|
|
15
|
+
export { default as TronValidator } from "./tron_validator.js";
|
|
16
|
+
export { default as XLMValidator } from "./xlm_validator.js";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
2
|
+
import { getAddress } from '../helpers.js';
|
|
3
|
+
import cnBase58 from '../crypto/cnBase58.js';
|
|
4
|
+
const addressRegTest = new RegExp('^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{95}$');
|
|
5
|
+
const integratedAddressRegTest = new RegExp('^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{106}$');
|
|
6
|
+
const types = {
|
|
7
|
+
addressTypes: { mainnet: ['18', '42'], testnet: ['53', '63'], stagenet: ['24'] },
|
|
8
|
+
iAddressTypes: { mainnet: ['19'], testnet: ['54'], stagenet: ['25'] },
|
|
9
|
+
};
|
|
10
|
+
function validateNetwork(decoded, networkType, addressType) {
|
|
11
|
+
const addressTypes = addressType === 'integrated'
|
|
12
|
+
? types.iAddressTypes[networkType]
|
|
13
|
+
: types.addressTypes[networkType];
|
|
14
|
+
const at = parseInt(decoded.substr(0, 2), 16).toString();
|
|
15
|
+
switch (networkType) {
|
|
16
|
+
case 'mainnet':
|
|
17
|
+
return addressTypes.indexOf(at) >= 0;
|
|
18
|
+
case 'testnet':
|
|
19
|
+
return addressTypes.indexOf(at) >= 0;
|
|
20
|
+
// case 'stagenet':
|
|
21
|
+
// return network.stagenet.indexOf(at) >= 0
|
|
22
|
+
// case 'both':
|
|
23
|
+
// return network.prod.indexOf(at) >= 0 || network.testnet.indexOf(at) >= 0 || network.stagenet.indexOf(at) >= 0
|
|
24
|
+
default:
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function hextobin(hex) {
|
|
29
|
+
if (hex.length % 2 !== 0)
|
|
30
|
+
return null;
|
|
31
|
+
const res = new Uint8Array(hex.length / 2);
|
|
32
|
+
for (let i = 0; i < hex.length / 2; ++i) {
|
|
33
|
+
res[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
34
|
+
}
|
|
35
|
+
return res;
|
|
36
|
+
}
|
|
37
|
+
export default (networkType) => ({
|
|
38
|
+
isValidAddress(address) {
|
|
39
|
+
const addr = getAddress(address);
|
|
40
|
+
let addressType = 'standard';
|
|
41
|
+
if (!addressRegTest.test(addr)) {
|
|
42
|
+
if (integratedAddressRegTest.test(addr)) {
|
|
43
|
+
addressType = 'integrated';
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const decodedAddrStr = cnBase58.decode(addr);
|
|
50
|
+
if (!decodedAddrStr)
|
|
51
|
+
return false;
|
|
52
|
+
if (!validateNetwork(decodedAddrStr, networkType, addressType))
|
|
53
|
+
return false;
|
|
54
|
+
const addrChecksum = decodedAddrStr.slice(-8);
|
|
55
|
+
const hashChecksum = cryptoUtils.keccak256Checksum(hextobin(decodedAddrStr.slice(0, -8)));
|
|
56
|
+
return addrChecksum === hashChecksum;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import baseX from 'base-x';
|
|
2
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
3
|
+
import { getAddress } from '../helpers.js';
|
|
4
|
+
const ALLOWED_CHARS = '13456789abcdefghijkmnopqrstuwxyz';
|
|
5
|
+
const codec = baseX(ALLOWED_CHARS);
|
|
6
|
+
// https://github.com/nanocurrency/raiblocks/wiki/Accounts,-Keys,-Seeds,-and-Wallet-Identifiers
|
|
7
|
+
const regexp = new RegExp('^(xrb|nano)_([' + ALLOWED_CHARS + ']{60})$');
|
|
8
|
+
export default {
|
|
9
|
+
isValidAddress(address) {
|
|
10
|
+
const addr = getAddress(address);
|
|
11
|
+
if (regexp.test(addr)) {
|
|
12
|
+
return this.verifyChecksum(addr);
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
},
|
|
16
|
+
verifyChecksum: function (address) {
|
|
17
|
+
const bytes = codec.decode(regexp.exec(address)[2]).slice(-37);
|
|
18
|
+
// https://github.com/nanocurrency/raiblocks/blob/master/rai/lib/numbers.cpp#L73
|
|
19
|
+
const computedChecksum = cryptoUtils.blake2b(cryptoUtils.toHex(bytes.slice(0, -5)), 5);
|
|
20
|
+
const checksum = cryptoUtils.toHex(bytes.slice(-5).reverse());
|
|
21
|
+
return computedChecksum === checksum;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
3
|
+
import { getAddress } from '../helpers.js';
|
|
4
|
+
export default {
|
|
5
|
+
isValidAddress(address) {
|
|
6
|
+
const addr = getAddress(address).toString().toUpperCase().replace(/-/g, '');
|
|
7
|
+
if (!address || addr.length !== 40) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
const decoded = cryptoUtils.toHex(cryptoUtils.base32.b32decode(addr));
|
|
11
|
+
const stepThreeChecksum = cryptoUtils.keccak256Checksum(Buffer.from(decoded.slice(0, 42), 'hex'));
|
|
12
|
+
return stepThreeChecksum === decoded.slice(42);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
2
|
+
import { getAddress } from '../helpers.js';
|
|
3
|
+
// from https://github.com/paritytech/substrate/wiki/External-Address-Format-(SS58)
|
|
4
|
+
const addressFormats = [
|
|
5
|
+
{ addressLength: 3, accountIndexLength: 1, checkSumLength: 1 },
|
|
6
|
+
{ addressLength: 4, accountIndexLength: 2, checkSumLength: 1 },
|
|
7
|
+
{ addressLength: 5, accountIndexLength: 2, checkSumLength: 2 },
|
|
8
|
+
{ addressLength: 6, accountIndexLength: 4, checkSumLength: 1 },
|
|
9
|
+
{ addressLength: 7, accountIndexLength: 4, checkSumLength: 2 },
|
|
10
|
+
{ addressLength: 8, accountIndexLength: 4, checkSumLength: 3 },
|
|
11
|
+
{ addressLength: 9, accountIndexLength: 4, checkSumLength: 4 },
|
|
12
|
+
{ addressLength: 10, accountIndexLength: 8, checkSumLength: 1 },
|
|
13
|
+
{ addressLength: 11, accountIndexLength: 8, checkSumLength: 2 },
|
|
14
|
+
{ addressLength: 12, accountIndexLength: 8, checkSumLength: 3 },
|
|
15
|
+
{ addressLength: 13, accountIndexLength: 8, checkSumLength: 4 },
|
|
16
|
+
{ addressLength: 14, accountIndexLength: 8, checkSumLength: 5 },
|
|
17
|
+
{ addressLength: 15, accountIndexLength: 8, checkSumLength: 6 },
|
|
18
|
+
{ addressLength: 16, accountIndexLength: 8, checkSumLength: 7 },
|
|
19
|
+
{ addressLength: 17, accountIndexLength: 8, checkSumLength: 8 },
|
|
20
|
+
{ addressLength: 34, accountIndexLength: 32, checkSumLength: 2 },
|
|
21
|
+
];
|
|
22
|
+
function verifyChecksum(address) {
|
|
23
|
+
try {
|
|
24
|
+
const preImage = '53533538505245';
|
|
25
|
+
const decoded = cryptoUtils.base58(address);
|
|
26
|
+
const addressType = cryptoUtils.byteArray2hexStr(decoded.slice(0, 1));
|
|
27
|
+
const addressAndChecksum = decoded.slice(1);
|
|
28
|
+
// get the address format
|
|
29
|
+
const addressFormat = addressFormats.find(af => af.addressLength === addressAndChecksum.length);
|
|
30
|
+
if (!addressFormat) {
|
|
31
|
+
throw new Error('Invalid address length');
|
|
32
|
+
}
|
|
33
|
+
const decodedAddress = cryptoUtils.byteArray2hexStr(addressAndChecksum.slice(0, addressFormat.accountIndexLength));
|
|
34
|
+
const checksum = cryptoUtils.byteArray2hexStr(addressAndChecksum.slice(-addressFormat.checkSumLength));
|
|
35
|
+
const calculatedHash = cryptoUtils
|
|
36
|
+
.blake2b(preImage + addressType + decodedAddress, 64)
|
|
37
|
+
.substr(0, addressFormat.checkSumLength * 2)
|
|
38
|
+
.toUpperCase();
|
|
39
|
+
return calculatedHash == checksum;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export default {
|
|
46
|
+
isValidAddress(address) {
|
|
47
|
+
return verifyChecksum(getAddress(address));
|
|
48
|
+
},
|
|
49
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Address } from '../types.js';
|
|
2
|
+
declare const _default: {
|
|
3
|
+
/**
|
|
4
|
+
* ripple address validation
|
|
5
|
+
*/
|
|
6
|
+
isValidAddress: (address: Address) => any;
|
|
7
|
+
verifyMemo(destinationTag: string | null): boolean;
|
|
8
|
+
verifyChecksum: (address: string) => boolean;
|
|
9
|
+
};
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import baseX from 'base-x';
|
|
2
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
3
|
+
import { getAddress } from '../helpers.js';
|
|
4
|
+
const ALLOWED_CHARS = 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz';
|
|
5
|
+
const codec = baseX(ALLOWED_CHARS);
|
|
6
|
+
const regexp = new RegExp('^r[' + ALLOWED_CHARS + ']{27,35}$');
|
|
7
|
+
export default {
|
|
8
|
+
/**
|
|
9
|
+
* ripple address validation
|
|
10
|
+
*/
|
|
11
|
+
isValidAddress: function (address) {
|
|
12
|
+
const addr = getAddress(address);
|
|
13
|
+
const destinationTag = address.destinationTag;
|
|
14
|
+
const validAddress = regexp.test(addr) && this.verifyChecksum(addr);
|
|
15
|
+
return validAddress && this.verifyMemo(destinationTag);
|
|
16
|
+
},
|
|
17
|
+
verifyMemo(destinationTag) {
|
|
18
|
+
return !destinationTag || /[0-9]+/.test(destinationTag);
|
|
19
|
+
},
|
|
20
|
+
verifyChecksum: function (address) {
|
|
21
|
+
const bytes = codec.decode(address);
|
|
22
|
+
const computedChecksum = cryptoUtils.sha256Checksum(cryptoUtils.toHex(bytes.slice(0, -4)));
|
|
23
|
+
const checksum = cryptoUtils.toHex(bytes.slice(-4));
|
|
24
|
+
return computedChecksum === checksum;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import isEqual from 'lodash.isequal';
|
|
2
|
+
import cryptoUtils from '../crypto/utils.js';
|
|
3
|
+
import { getAddress } from '../helpers.js';
|
|
4
|
+
function hexToBytes(hex) {
|
|
5
|
+
const bytes = [];
|
|
6
|
+
for (let c = 0; c < hex.length; c += 2) {
|
|
7
|
+
bytes.push(parseInt(hex.substr(c, 2), 16));
|
|
8
|
+
}
|
|
9
|
+
return bytes;
|
|
10
|
+
}
|
|
11
|
+
function verifyChecksum(address) {
|
|
12
|
+
const checksumBytes = address.slice(0, 32 * 2);
|
|
13
|
+
const check = address.slice(32 * 2, 38 * 2);
|
|
14
|
+
const blakeHash = cryptoUtils.blake2b(checksumBytes, 32).slice(0, 6 * 2);
|
|
15
|
+
return !!isEqual(blakeHash, check);
|
|
16
|
+
}
|
|
17
|
+
export default {
|
|
18
|
+
isValidAddress: function (address) {
|
|
19
|
+
const addr = getAddress(address);
|
|
20
|
+
if (addr.length !== 76) {
|
|
21
|
+
// Check if it has the basic requirements of an address
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
// Otherwise check each case
|
|
25
|
+
return verifyChecksum(addr);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import base58Validator from './base58_validator.js';
|
|
2
|
+
import { getAddress } from '../helpers.js';
|
|
3
|
+
export default {
|
|
4
|
+
isValidAddress: function (address) {
|
|
5
|
+
return base58Validator.isValidAddress(getAddress(address), {
|
|
6
|
+
maxLength: 44,
|
|
7
|
+
minLength: 43,
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
};
|