multichain-address-validator 0.8.0 → 0.8.2
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/README.md +0 -1
- package/dist/cjs/chain-validators.js +2 -0
- package/dist/esm/chain-validators.js +2 -0
- package/package.json +17 -12
- package/.editorconfig +0 -10
- package/.travis.yml +0 -11
- package/.vscode/launch.json +0 -23
- package/index.html +0 -12
- package/package-lock.json +0 -1705
- package/src/chain-validators.ts +0 -183
- package/src/crypto/base32.ts +0 -66
- package/src/crypto/base58.ts +0 -46
- package/src/crypto/bech32.js +0 -132
- package/src/crypto/biginteger.js +0 -1426
- package/src/crypto/blake256.js +0 -188
- package/src/crypto/blake2b.js +0 -276
- package/src/crypto/cnBase58.js +0 -226
- package/src/crypto/segwit_addr.js +0 -118
- package/src/crypto/utils.ts +0 -133
- package/src/helpers.ts +0 -13
- package/src/index.ts +0 -28
- package/src/types.ts +0 -19
- package/src/validators/algorand_validator.ts +0 -28
- package/src/validators/base58_validator.ts +0 -32
- package/src/validators/bch_validator.ts +0 -66
- package/src/validators/bip173_validator.ts +0 -19
- package/src/validators/bitcoin_validator.ts +0 -93
- package/src/validators/bittensor_validator.ts +0 -8
- package/src/validators/cardano_validator.ts +0 -50
- package/src/validators/eos_validator.ts +0 -13
- package/src/validators/ethereum_validator.ts +0 -37
- package/src/validators/hedera_validator.ts +0 -10
- package/src/validators/index.ts +0 -20
- package/src/validators/monero_validator.ts +0 -72
- package/src/validators/move_validator.ts +0 -11
- package/src/validators/nano_validator.ts +0 -32
- package/src/validators/nem_validator.ts +0 -18
- package/src/validators/polkadot_validator.ts +0 -7
- package/src/validators/ripple_validator.ts +0 -44
- package/src/validators/sia_validator.ts +0 -33
- package/src/validators/solana_validator.ts +0 -21
- package/src/validators/ss58_validator.ts +0 -80
- package/src/validators/tezos_validator.ts +0 -36
- package/src/validators/tron_validator.ts +0 -59
- package/src/validators/xlm_validator.ts +0 -54
- package/src/validators/zcash_validator.ts +0 -57
- package/test/addresses/addresses.ts +0 -63
- package/test/addresses/algorand.json +0 -6
- package/test/addresses/aptos.json +0 -6
- package/test/addresses/bch-testnet.json +0 -4
- package/test/addresses/bch.json +0 -7
- package/test/addresses/bittensor.json +0 -27
- package/test/addresses/btc-testnet.json +0 -14
- package/test/addresses/btc.json +0 -18
- package/test/addresses/cardano.json +0 -8
- package/test/addresses/doge-testnet.json +0 -3
- package/test/addresses/doge.json +0 -7
- package/test/addresses/eos.json +0 -6
- package/test/addresses/evm.json +0 -20
- package/test/addresses/hbar.json +0 -11
- package/test/addresses/ltc-testnet.json +0 -10
- package/test/addresses/ltc.json +0 -9
- package/test/addresses/monero-testnet.json +0 -5
- package/test/addresses/monero.json +0 -7
- package/test/addresses/nano.json +0 -12
- package/test/addresses/nem.json +0 -4
- package/test/addresses/polkadot.json +0 -8
- package/test/addresses/ripple.json +0 -20
- package/test/addresses/sia.json +0 -5
- package/test/addresses/solana.json +0 -12
- package/test/addresses/sui.json +0 -6
- package/test/addresses/tezos.json +0 -9
- package/test/addresses/tron.json +0 -6
- package/test/addresses/xlm.json +0 -21
- package/test/addresses/zcash.json +0 -8
- package/test/multichain-address-validator.test.ts +0 -242
- package/tsconfig.cjs.json +0 -7
- package/tsconfig.esm.json +0 -7
- package/tsconfig.json +0 -24
package/src/validators/index.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export {default as AlgorandValidator} from "./algorand_validator.js"
|
|
2
|
-
export {default as BCHValidator} from "./bch_validator.js"
|
|
3
|
-
export {default as BittensorValidator} from "./bittensor_validator.js"
|
|
4
|
-
export {default as BTCValidator} from "./bitcoin_validator.js"
|
|
5
|
-
export {default as CardanoValidator} from "./cardano_validator.js"
|
|
6
|
-
export {default as EOSValidator} from "./eos_validator.js"
|
|
7
|
-
export {default as ETHValidator} from "./ethereum_validator.js"
|
|
8
|
-
export {default as HederaValidator} from "./hedera_validator.js"
|
|
9
|
-
export {default as MoneroValidator} from "./monero_validator.js"
|
|
10
|
-
export {default as MoveValidator} from "./move_validator.js"
|
|
11
|
-
export {default as NemValidator} from "./nem_validator.js"
|
|
12
|
-
export {default as NanoValidator} from "./nano_validator.js"
|
|
13
|
-
export {default as PolkadotValidator} from "./polkadot_validator.js"
|
|
14
|
-
export {default as RippleValidator} from "./ripple_validator.js"
|
|
15
|
-
export {default as SiaValidator} from "./sia_validator.js"
|
|
16
|
-
export {default as SolanaValidator} from "./solana_validator.js"
|
|
17
|
-
export {default as TezosValidator} from "./tezos_validator.js"
|
|
18
|
-
export {default as TronValidator} from "./tron_validator.js"
|
|
19
|
-
export {default as XLMValidator} from "./xlm_validator.js"
|
|
20
|
-
export {default as ZcashValidator} from "./zcash_validator.js"
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
2
|
-
import {Address, NetworkType} from '../types.js'
|
|
3
|
-
import {getAddress} from '../helpers.js'
|
|
4
|
-
import cnBase58 from '../crypto/cnBase58.js'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const addressRegTest = new RegExp(
|
|
8
|
-
'^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{95}$'
|
|
9
|
-
)
|
|
10
|
-
const integratedAddressRegTest = new RegExp(
|
|
11
|
-
'^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{106}$'
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
const types = {
|
|
15
|
-
addressTypes: {mainnet: ['18', '42'], testnet: ['53', '63'], stagenet: ['24']},
|
|
16
|
-
iAddressTypes: {mainnet: ['19'], testnet: ['54'], stagenet: ['25']},
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function validateNetwork(decoded: string, networkType: NetworkType, addressType: 'standard' | 'integrated') {
|
|
20
|
-
const addressTypes = addressType === 'integrated'
|
|
21
|
-
? types.iAddressTypes[networkType]
|
|
22
|
-
: types.addressTypes[networkType]
|
|
23
|
-
|
|
24
|
-
const at = parseInt(decoded.substr(0, 2), 16).toString()
|
|
25
|
-
|
|
26
|
-
switch (networkType) {
|
|
27
|
-
case 'mainnet':
|
|
28
|
-
return addressTypes.indexOf(at) >= 0
|
|
29
|
-
case 'testnet':
|
|
30
|
-
return addressTypes.indexOf(at) >= 0
|
|
31
|
-
// case 'stagenet':
|
|
32
|
-
// return network.stagenet.indexOf(at) >= 0
|
|
33
|
-
// case 'both':
|
|
34
|
-
// return network.prod.indexOf(at) >= 0 || network.testnet.indexOf(at) >= 0 || network.stagenet.indexOf(at) >= 0
|
|
35
|
-
default:
|
|
36
|
-
return false
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function hextobin(hex: string) {
|
|
41
|
-
if (hex.length % 2 !== 0) return null
|
|
42
|
-
const res = new Uint8Array(hex.length / 2)
|
|
43
|
-
for (let i = 0; i < hex.length / 2; ++i) {
|
|
44
|
-
res[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16)
|
|
45
|
-
}
|
|
46
|
-
return res
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
export default (networkType: NetworkType) => ({
|
|
51
|
-
isValidAddress(address: Address) {
|
|
52
|
-
const addr = getAddress(address)
|
|
53
|
-
let addressType: 'standard' | 'integrated' = 'standard'
|
|
54
|
-
if (!addressRegTest.test(addr)) {
|
|
55
|
-
if (integratedAddressRegTest.test(addr)) {
|
|
56
|
-
addressType = 'integrated'
|
|
57
|
-
} else {
|
|
58
|
-
return false
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const decodedAddrStr = cnBase58.decode(addr)
|
|
63
|
-
if (!decodedAddrStr) return false
|
|
64
|
-
|
|
65
|
-
if (!validateNetwork(decodedAddrStr, networkType, addressType)) return false
|
|
66
|
-
|
|
67
|
-
const addrChecksum = decodedAddrStr.slice(-8)
|
|
68
|
-
const hashChecksum = cryptoUtils.keccak256Checksum(hextobin(decodedAddrStr.slice(0, -8)))
|
|
69
|
-
|
|
70
|
-
return addrChecksum === hashChecksum
|
|
71
|
-
}
|
|
72
|
-
})
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Address} from '../types.js'
|
|
2
|
-
import {getAddress} from '../helpers.js'
|
|
3
|
-
|
|
4
|
-
const regexp = new RegExp('^0x[0-9a-fA-F]{64}$');
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
isValidAddress(address: Address) {
|
|
8
|
-
const addr = getAddress(address)
|
|
9
|
-
return regexp.test(addr)
|
|
10
|
-
},
|
|
11
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import baseX from 'base-x'
|
|
2
|
-
|
|
3
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
4
|
-
import {Address} from '../types.js'
|
|
5
|
-
import {getAddress} from '../helpers.js'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const ALLOWED_CHARS = '13456789abcdefghijkmnopqrstuwxyz';
|
|
9
|
-
|
|
10
|
-
const codec = baseX(ALLOWED_CHARS);
|
|
11
|
-
// https://github.com/nanocurrency/raiblocks/wiki/Accounts,-Keys,-Seeds,-and-Wallet-Identifiers
|
|
12
|
-
const regexp = new RegExp('^(xrb|nano)_([' + ALLOWED_CHARS + ']{60})$');
|
|
13
|
-
|
|
14
|
-
export default {
|
|
15
|
-
isValidAddress(address: Address) {
|
|
16
|
-
const addr = getAddress(address)
|
|
17
|
-
if (regexp.test(addr)) {
|
|
18
|
-
return this.verifyChecksum(addr);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return false;
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
verifyChecksum: function (address: string) {
|
|
25
|
-
const bytes = codec.decode(regexp.exec(address)[2]).slice(-37);
|
|
26
|
-
// https://github.com/nanocurrency/raiblocks/blob/master/rai/lib/numbers.cpp#L73
|
|
27
|
-
const computedChecksum = cryptoUtils.blake2b(cryptoUtils.toHex(bytes.slice(0, -5)), 5);
|
|
28
|
-
const checksum = cryptoUtils.toHex(bytes.slice(-5).reverse());
|
|
29
|
-
|
|
30
|
-
return computedChecksum === checksum
|
|
31
|
-
}
|
|
32
|
-
};
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import {Buffer} from 'buffer'
|
|
2
|
-
|
|
3
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
4
|
-
import {Address} from '../types.js'
|
|
5
|
-
import {getAddress} from '../helpers.js'
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
isValidAddress(address: Address) {
|
|
9
|
-
const addr = getAddress(address).toString().toUpperCase().replace(/-/g, '');
|
|
10
|
-
if (!address || addr.length !== 40) {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
const decoded = cryptoUtils.toHex(cryptoUtils.base32.b32decode(addr));
|
|
14
|
-
const stepThreeChecksum = cryptoUtils.keccak256Checksum(Buffer.from(decoded.slice(0, 42), 'hex'));
|
|
15
|
-
|
|
16
|
-
return stepThreeChecksum === decoded.slice(42);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import createSS58Validator from './ss58_validator.js'
|
|
2
|
-
|
|
3
|
-
// Polkadot uses SS58 address format (Substrate-based)
|
|
4
|
-
// SS58 Registry: https://github.com/paritytech/ss58-registry
|
|
5
|
-
// Accepts any valid SS58 address (no network prefix restriction)
|
|
6
|
-
|
|
7
|
-
export default createSS58Validator()
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import baseX from 'base-x'
|
|
2
|
-
|
|
3
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
4
|
-
import {Address} from '../types.js'
|
|
5
|
-
import {getAddress, getMemo} from '../helpers.js'
|
|
6
|
-
|
|
7
|
-
const ALLOWED_CHARS = 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz';
|
|
8
|
-
|
|
9
|
-
const codec = baseX(ALLOWED_CHARS);
|
|
10
|
-
const regexp = new RegExp('^r[' + ALLOWED_CHARS + ']{27,35}$');
|
|
11
|
-
|
|
12
|
-
export default {
|
|
13
|
-
/**
|
|
14
|
-
* ripple address validation
|
|
15
|
-
*/
|
|
16
|
-
isValidAddress: function (address: Address) {
|
|
17
|
-
const addr = getAddress(address)
|
|
18
|
-
const memo = getMemo(address)
|
|
19
|
-
|
|
20
|
-
const validAddress = regexp.test(addr) && this.verifyChecksum(addr);
|
|
21
|
-
|
|
22
|
-
return validAddress && this.verifyMemo(memo)
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
isValidMemo(memo: string): boolean {
|
|
26
|
-
return this.verifyMemo(memo)
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
verifyMemo(memo?: string): boolean {
|
|
30
|
-
if (!memo) return true; // Optional
|
|
31
|
-
|
|
32
|
-
const memoNumber = Number(memo);
|
|
33
|
-
// A memo is a 32-bit unsigned integer.
|
|
34
|
-
return /^[0-9]+$/.test(memo) && memoNumber >= 0 && memoNumber <= 4294967295;
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
verifyChecksum(address: string): boolean {
|
|
38
|
-
const bytes = codec.decode(address);
|
|
39
|
-
const computedChecksum = cryptoUtils.sha256Checksum(cryptoUtils.toHex(bytes.slice(0, -4)));
|
|
40
|
-
const checksum = cryptoUtils.toHex(bytes.slice(-4));
|
|
41
|
-
|
|
42
|
-
return computedChecksum === checksum
|
|
43
|
-
}
|
|
44
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import isEqual from 'lodash.isequal'
|
|
2
|
-
|
|
3
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
4
|
-
import {Address} from '../types.js'
|
|
5
|
-
import {getAddress} from '../helpers.js'
|
|
6
|
-
|
|
7
|
-
function hexToBytes(hex: string) {
|
|
8
|
-
const bytes = []
|
|
9
|
-
for (let c = 0; c < hex.length; c += 2) {
|
|
10
|
-
bytes.push(parseInt(hex.substr(c, 2), 16))
|
|
11
|
-
}
|
|
12
|
-
return bytes
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function verifyChecksum(address: string) {
|
|
16
|
-
const checksumBytes = address.slice(0, 32 * 2)
|
|
17
|
-
const check = address.slice(32 * 2, 38 * 2)
|
|
18
|
-
const blakeHash = cryptoUtils.blake2b(checksumBytes, 32).slice(0, 6 * 2)
|
|
19
|
-
return !!isEqual(blakeHash, check)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default {
|
|
23
|
-
isValidAddress: function (address: Address) {
|
|
24
|
-
const addr = getAddress(address)
|
|
25
|
-
if (addr.length !== 76) {
|
|
26
|
-
// Check if it has the basic requirements of an address
|
|
27
|
-
return false
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Otherwise check each case
|
|
31
|
-
return verifyChecksum(addr)
|
|
32
|
-
},
|
|
33
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import base58Validator from './base58_validator.js';
|
|
2
|
-
import {Address} from '../types.js'
|
|
3
|
-
import {getAddress} from '../helpers.js'
|
|
4
|
-
import {Buffer} from 'buffer'
|
|
5
|
-
import base58 from '../crypto/base58.js'
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
isValidAddress: function (address: Address) {
|
|
9
|
-
const validBase58 = base58Validator.isValidAddress(getAddress(address), {
|
|
10
|
-
maxLength: 44,
|
|
11
|
-
minLength: 43,
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
if (!validBase58) {
|
|
15
|
-
return false
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// solana address must be 32 bytes
|
|
19
|
-
return base58.decode(getAddress(address)).length === 32
|
|
20
|
-
}
|
|
21
|
-
};
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
2
|
-
import {Address, Validator} from '../types.js'
|
|
3
|
-
import {getAddress} from '../helpers.js'
|
|
4
|
-
|
|
5
|
-
// SS58 address format (Substrate-based)
|
|
6
|
-
// SS58 Registry: https://github.com/paritytech/ss58-registry
|
|
7
|
-
const addressFormats = [
|
|
8
|
-
{addressLength: 3, accountIndexLength: 1, checkSumLength: 1},
|
|
9
|
-
{addressLength: 4, accountIndexLength: 2, checkSumLength: 1},
|
|
10
|
-
{addressLength: 5, accountIndexLength: 2, checkSumLength: 2},
|
|
11
|
-
{addressLength: 6, accountIndexLength: 4, checkSumLength: 1},
|
|
12
|
-
{addressLength: 7, accountIndexLength: 4, checkSumLength: 2},
|
|
13
|
-
{addressLength: 8, accountIndexLength: 4, checkSumLength: 3},
|
|
14
|
-
{addressLength: 9, accountIndexLength: 4, checkSumLength: 4},
|
|
15
|
-
{addressLength: 10, accountIndexLength: 8, checkSumLength: 1},
|
|
16
|
-
{addressLength: 11, accountIndexLength: 8, checkSumLength: 2},
|
|
17
|
-
{addressLength: 12, accountIndexLength: 8, checkSumLength: 3},
|
|
18
|
-
{addressLength: 13, accountIndexLength: 8, checkSumLength: 4},
|
|
19
|
-
{addressLength: 14, accountIndexLength: 8, checkSumLength: 5},
|
|
20
|
-
{addressLength: 15, accountIndexLength: 8, checkSumLength: 6},
|
|
21
|
-
{addressLength: 16, accountIndexLength: 8, checkSumLength: 7},
|
|
22
|
-
{addressLength: 17, accountIndexLength: 8, checkSumLength: 8},
|
|
23
|
-
{addressLength: 34, accountIndexLength: 32, checkSumLength: 2},
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
interface SS58ValidatorOptions {
|
|
27
|
-
// Network prefix to validate (in decimal). If provided, only addresses with this prefix are valid.
|
|
28
|
-
// Examples: 0 = Polkadot, 2 = Kusama, 42 = Substrate/Bittensor
|
|
29
|
-
networkPrefix?: number;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Creates an SS58 validator with optional network prefix filtering
|
|
34
|
-
* @param options Configuration options including optional network prefix
|
|
35
|
-
* @returns Validator instance for SS58 addresses
|
|
36
|
-
*/
|
|
37
|
-
export default function createSS58Validator(options: SS58ValidatorOptions = {}): Validator {
|
|
38
|
-
function verifyChecksum(address: string): boolean {
|
|
39
|
-
try {
|
|
40
|
-
const preImage = '53533538505245'
|
|
41
|
-
const decoded = cryptoUtils.base58(address);
|
|
42
|
-
const addressType = cryptoUtils.byteArray2hexStr(decoded.slice(0, 1));
|
|
43
|
-
|
|
44
|
-
// If a specific network prefix is required, validate it
|
|
45
|
-
if (options.networkPrefix !== undefined) {
|
|
46
|
-
const expectedPrefix = options.networkPrefix.toString(16).padStart(2, '0').toUpperCase();
|
|
47
|
-
if (addressType.toUpperCase() !== expectedPrefix) {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const addressAndChecksum = decoded.slice(1)
|
|
53
|
-
|
|
54
|
-
// get the address format
|
|
55
|
-
const addressFormat = addressFormats.find(af => af.addressLength === addressAndChecksum.length);
|
|
56
|
-
|
|
57
|
-
if (!addressFormat) {
|
|
58
|
-
throw new Error('Invalid address length');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const decodedAddress = cryptoUtils.byteArray2hexStr(addressAndChecksum.slice(0, addressFormat.accountIndexLength));
|
|
62
|
-
const checksum = cryptoUtils.byteArray2hexStr(addressAndChecksum.slice(-addressFormat.checkSumLength));
|
|
63
|
-
|
|
64
|
-
const calculatedHash = cryptoUtils
|
|
65
|
-
.blake2b(preImage + addressType + decodedAddress, 64)
|
|
66
|
-
.substr(0, addressFormat.checkSumLength * 2)
|
|
67
|
-
.toUpperCase();
|
|
68
|
-
|
|
69
|
-
return calculatedHash == checksum;
|
|
70
|
-
} catch (err) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
isValidAddress(address: Address) {
|
|
77
|
-
return verifyChecksum(getAddress(address))
|
|
78
|
-
},
|
|
79
|
-
}
|
|
80
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import base58 from '../crypto/base58.js'
|
|
2
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
3
|
-
import {Address} from '../types.js'
|
|
4
|
-
import {getAddress} from '../helpers.js'
|
|
5
|
-
|
|
6
|
-
const prefix = new Uint8Array([6, 161, 159]);
|
|
7
|
-
|
|
8
|
-
function decodeRaw(buffer: any) {
|
|
9
|
-
let payload = buffer.slice(0, -4);
|
|
10
|
-
let checksum = buffer.slice(-4);
|
|
11
|
-
let newChecksum = cryptoUtils.hexStr2byteArray(
|
|
12
|
-
cryptoUtils.sha256x2(cryptoUtils.byteArray2hexStr(payload))
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
if (checksum[0] ^ newChecksum[0] |
|
|
16
|
-
checksum[1] ^ newChecksum[1] |
|
|
17
|
-
checksum[2] ^ newChecksum[2] |
|
|
18
|
-
checksum[3] ^ newChecksum[3])
|
|
19
|
-
return;
|
|
20
|
-
return payload;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export default {
|
|
24
|
-
isValidAddress(address: Address) {
|
|
25
|
-
try {
|
|
26
|
-
let buffer = base58.decode(getAddress(address));
|
|
27
|
-
let payload = decodeRaw(buffer);
|
|
28
|
-
if (!payload)
|
|
29
|
-
return false;
|
|
30
|
-
payload.slice(prefix.length);
|
|
31
|
-
return true;
|
|
32
|
-
} catch (e) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import {Address} from '../types.js'
|
|
2
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
3
|
-
import {getAddress} from '../helpers.js'
|
|
4
|
-
|
|
5
|
-
function decodeBase58Address(base58String: string) {
|
|
6
|
-
if (typeof (base58String) !== 'string') {
|
|
7
|
-
return false;
|
|
8
|
-
}
|
|
9
|
-
if (base58String.length !== 34) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
let address: number[]
|
|
14
|
-
try {
|
|
15
|
-
address = cryptoUtils.base58(base58String);
|
|
16
|
-
} catch (e) {
|
|
17
|
-
return false
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const len = address.length;
|
|
21
|
-
const offset = len - 4;
|
|
22
|
-
const checkSum = address.slice(offset);
|
|
23
|
-
address = address.slice(0, offset);
|
|
24
|
-
const hash0 = cryptoUtils.sha256(cryptoUtils.byteArray2hexStr(address));
|
|
25
|
-
const hash1 = cryptoUtils.hexStr2byteArray(cryptoUtils.sha256(hash0));
|
|
26
|
-
const checkSum1 = hash1.slice(0, 4);
|
|
27
|
-
if (checkSum[0] === checkSum1[0] && checkSum[1] === checkSum1[1] && checkSum[2]
|
|
28
|
-
=== checkSum1[2] && checkSum[3] === checkSum1[3]
|
|
29
|
-
) {
|
|
30
|
-
return address;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface TronValidatorOpts {
|
|
37
|
-
addressTypes: string[],
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const DefaultTronValidatorOpts: TronValidatorOpts = {
|
|
41
|
-
addressTypes: ['65']
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export default (opts?: TronValidatorOpts) => ({
|
|
45
|
-
isValidAddress: function (address: Address) {
|
|
46
|
-
const _opts = {...DefaultTronValidatorOpts, ...opts}
|
|
47
|
-
const addr = decodeBase58Address(getAddress(address));
|
|
48
|
-
|
|
49
|
-
if (!addr) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (addr.length !== 21) {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return _opts.addressTypes.includes(addr[0].toString());
|
|
58
|
-
}
|
|
59
|
-
});
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import baseX from 'base-x'
|
|
2
|
-
import crc from 'crc'
|
|
3
|
-
|
|
4
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
5
|
-
import {Address} from '../types.js'
|
|
6
|
-
import {getAddress, getMemo} from '../helpers.js'
|
|
7
|
-
|
|
8
|
-
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
|
9
|
-
|
|
10
|
-
const base32 = baseX(ALPHABET);
|
|
11
|
-
const regexp = new RegExp('^[' + ALPHABET + ']{56}$');
|
|
12
|
-
const ed25519PublicKeyVersionByte = (6 << 3);
|
|
13
|
-
|
|
14
|
-
function swap16(number: number) {
|
|
15
|
-
const lower = number & 0xFF;
|
|
16
|
-
const upper = (number >> 8) & 0xFF;
|
|
17
|
-
return (lower << 8) | upper;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export default {
|
|
21
|
-
isValidAddress: function (address: Address) {
|
|
22
|
-
const addr = getAddress(address)
|
|
23
|
-
const memo = getMemo(address)
|
|
24
|
-
|
|
25
|
-
const validAddress = regexp.test(addr) && this.verifyChecksum(addr);
|
|
26
|
-
|
|
27
|
-
return validAddress && this.verifyMemo(memo)
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
isValidMemo(memo: string): boolean {
|
|
31
|
-
return this.verifyMemo(memo)
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
verifyMemo(memo?: string): boolean {
|
|
35
|
-
if (!memo) return true; // Optional
|
|
36
|
-
|
|
37
|
-
// Ensure it's a valid UTF-8 string and does not exceed 28 bytes
|
|
38
|
-
const encoder = new TextEncoder();
|
|
39
|
-
return encoder.encode(memo).length <= 28;
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
verifyChecksum: function (address: string) {
|
|
43
|
-
// based on https://github.com/stellar/js-stellar-base/blob/master/src/strkey.js#L126
|
|
44
|
-
var bytes = base32.decode(address);
|
|
45
|
-
if (bytes[0] !== ed25519PublicKeyVersionByte) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const computedChecksum = cryptoUtils.numberToHex(swap16(crc.crc16xmodem(bytes.slice(0, -2))), 4);
|
|
50
|
-
const checksum = cryptoUtils.toHex(bytes.slice(-2));
|
|
51
|
-
|
|
52
|
-
return computedChecksum === checksum
|
|
53
|
-
}
|
|
54
|
-
};
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import base58 from '../crypto/base58.js'
|
|
2
|
-
import cryptoUtils from '../crypto/utils.js'
|
|
3
|
-
import {Address, NetworkType} from '../types.js'
|
|
4
|
-
import {getAddress} from '../helpers.js'
|
|
5
|
-
|
|
6
|
-
function getDecoded(address: string) {
|
|
7
|
-
try {
|
|
8
|
-
return base58.decode(address);
|
|
9
|
-
} catch (e) {
|
|
10
|
-
// if decoding fails, assume invalid address
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function getChecksum(payload: any) {
|
|
16
|
-
return cryptoUtils.sha256Checksum(payload);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function isValidTransparentAddress(address: string, networkType: NetworkType) {
|
|
20
|
-
// Zcash transparent addresses use 2-byte version prefixes
|
|
21
|
-
// Expected length: 26 bytes (2 bytes version + 20 bytes payload + 4 bytes checksum)
|
|
22
|
-
const expectedLength = 26;
|
|
23
|
-
const decoded = getDecoded(address);
|
|
24
|
-
|
|
25
|
-
if (!decoded || decoded.length !== expectedLength) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const checksum = cryptoUtils.toHex(decoded.slice(expectedLength - 4, expectedLength));
|
|
30
|
-
const body = cryptoUtils.toHex(decoded.slice(0, expectedLength - 4));
|
|
31
|
-
const goodChecksum = getChecksum(body);
|
|
32
|
-
|
|
33
|
-
if (checksum !== goodChecksum) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Get the 2-byte version prefix
|
|
38
|
-
const versionPrefix = cryptoUtils.toHex(decoded.slice(0, 2));
|
|
39
|
-
|
|
40
|
-
// Define valid version prefixes for each network
|
|
41
|
-
// Only supporting transparent addresses (t1/t3 for mainnet, tm/t2 for testnet)
|
|
42
|
-
const validPrefixes = networkType === NetworkType.MainNet
|
|
43
|
-
? ['1cb8', '1cbd'] // t1 (P2PKH) and t3 (P2SH) for mainnet
|
|
44
|
-
: ['1d25', '1cba']; // tm (P2PKH) and t2 (P2SH) for testnet
|
|
45
|
-
|
|
46
|
-
return validPrefixes.includes(versionPrefix);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export default (networkType: NetworkType) => ({
|
|
50
|
-
isValidAddress(address: Address): boolean {
|
|
51
|
-
const addr = getAddress(address);
|
|
52
|
-
|
|
53
|
-
// Only validate transparent addresses (t1/t3 for mainnet, tm/t2 for testnet)
|
|
54
|
-
// Sapling (zs) and Unified (u) addresses are NOT supported
|
|
55
|
-
return isValidTransparentAddress(addr, networkType);
|
|
56
|
-
}
|
|
57
|
-
})
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import algorand from './algorand.json'
|
|
2
|
-
import aptos from './aptos.json'
|
|
3
|
-
import bch from './bch.json'
|
|
4
|
-
import bchTestnet from './bch-testnet.json'
|
|
5
|
-
import bittensor from './bittensor.json'
|
|
6
|
-
import btc from './btc.json'
|
|
7
|
-
import btcTestnet from './btc-testnet.json'
|
|
8
|
-
import cardano from './cardano.json'
|
|
9
|
-
import doge from './doge.json'
|
|
10
|
-
import dogeTestnet from './doge-testnet.json'
|
|
11
|
-
import eos from './eos.json'
|
|
12
|
-
import evm from './evm.json'
|
|
13
|
-
import hbar from './hbar.json'
|
|
14
|
-
import ltc from './ltc.json'
|
|
15
|
-
import ltcTestnet from './ltc-testnet.json'
|
|
16
|
-
import monero from './monero.json'
|
|
17
|
-
import moneroTestnet from './monero-testnet.json'
|
|
18
|
-
import nem from './nem.json'
|
|
19
|
-
import nano from './nano.json'
|
|
20
|
-
import polkadot from './polkadot.json'
|
|
21
|
-
import ripple from './ripple.json'
|
|
22
|
-
import sia from './sia.json'
|
|
23
|
-
import solana from './solana.json'
|
|
24
|
-
import sui from './sui.json'
|
|
25
|
-
import tezos from './tezos.json'
|
|
26
|
-
import tron from './tron.json'
|
|
27
|
-
import xlm from './xlm.json'
|
|
28
|
-
import zcash from './zcash.json'
|
|
29
|
-
|
|
30
|
-
export type TestAddress = string | { address: string, memo?: string } & { invalid?: boolean, invalidMemo?: boolean }
|
|
31
|
-
|
|
32
|
-
const testAddresses: Record<string, TestAddress[]> = {
|
|
33
|
-
aptos,
|
|
34
|
-
algorand,
|
|
35
|
-
bch,
|
|
36
|
-
'bch-testnet': bchTestnet,
|
|
37
|
-
bittensor,
|
|
38
|
-
btc,
|
|
39
|
-
'btc-testnet': btcTestnet,
|
|
40
|
-
cardano,
|
|
41
|
-
doge,
|
|
42
|
-
'doge-testnet': dogeTestnet,
|
|
43
|
-
eos,
|
|
44
|
-
evm,
|
|
45
|
-
hbar,
|
|
46
|
-
ltc,
|
|
47
|
-
'ltc-testnet': ltcTestnet,
|
|
48
|
-
monero,
|
|
49
|
-
'monero-testnet': moneroTestnet,
|
|
50
|
-
nem,
|
|
51
|
-
nano,
|
|
52
|
-
polkadot,
|
|
53
|
-
ripple,
|
|
54
|
-
sia,
|
|
55
|
-
sui,
|
|
56
|
-
solana,
|
|
57
|
-
tezos,
|
|
58
|
-
tron,
|
|
59
|
-
xlm,
|
|
60
|
-
zcash,
|
|
61
|
-
} as const;
|
|
62
|
-
|
|
63
|
-
export default testAddresses
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
"0xaabf25b0c115130a4ad88bfa08627c5a103b7851e90869c23fadaf0512dd5133",
|
|
3
|
-
"0xdce6ab89a1d26c99491a70fd4a2536d065925114deee916a1ae7d35007f4dedf",
|
|
4
|
-
"0xd05448f15a03f25b2816c4538b72bd54752ba7522d4831a4c9ea5a613becb47a",
|
|
5
|
-
"0x39f521d22f611a4dec2f790fef2e4f8d1f96550509e85beccf8acec52c1a7219"
|
|
6
|
-
]
|