Skip to content

Commit

Permalink
chore(address-validator): move trezor-address-validator package into …
Browse files Browse the repository at this point in the history
…monorepo
  • Loading branch information
mroz22 committed Jul 1, 2024
1 parent 682362e commit 72b8c49
Show file tree
Hide file tree
Showing 54 changed files with 8,684 additions and 76 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module.exports = {
'**/public/*',
'packages/suite-data/files/*',
'packages/protobuf/scripts/protobuf-patches/*',
'packages/address-validator',
'packages/connect-examples',
'ci/',
],
Expand Down
3 changes: 3 additions & 0 deletions packages/address-validator/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 1.0.0

- package created
11 changes: 11 additions & 0 deletions packages/address-validator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# @trezor/address-validator

Moved from https://github.com/trezor/trezor-address-validator

which is a fork of

https://github.com/christsim/multicoin-address-validator

which is a fork of

https://github.com/ryanralph/altcoin-address
25 changes: 25 additions & 0 deletions packages/address-validator/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@trezor/address-validator",
"version": "1.0.0",
"license": "See LICENSE.md in repo root",
"sideEffects": false,
"private": true,
"main": "src/index",
"scripts": {
"test:unit": "yarn g:jest -c ../../jest.config.base.js"
},
"dependencies": {
"base-x": "^3.0.7",
"bech32": "^2.0.0",
"browserify-bignum": "^1.3.0-2",
"cbor-js": "^0.1.0",
"crc": "^3.8.0",
"groestl-hash-js": "1.0.0",
"jssha": "2.3.1",
"lodash": "^4.17.15"
},
"devDependencies": {
"jest-environment-jsdom": "29.7.0",
"rimraf": "^5.0.5"
}
}
74 changes: 74 additions & 0 deletions packages/address-validator/src/ada_validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const { addressType } = require('./crypto/utils');
var cbor = require('cbor-js');
var CRC = require('crc');
var base58 = require('./crypto/base58');
var { bech32 } = require('bech32');

var DEFAULT_NETWORK_TYPE = 'prod';

function getDecoded(address) {
try {
var decoded = base58.decode(address);
return cbor.decode(new Uint8Array(decoded).buffer);
} catch (e) {
// if decoding fails, assume invalid address
return null;
}
}

function isValidLegacyAddress(address) {
var decoded = getDecoded(address);

if (!decoded || (!Array.isArray(decoded) && decoded.length != 2)) {
return false;
}

var tagged = decoded[0];
var validCrc = decoded[1];
if (typeof validCrc != 'number') {
return false;
}

// get crc of the payload
var crc = CRC.crc32(tagged);

return crc == validCrc;
}

// it is not possible to use bitcoin ./crypto/segwit_addr library, the cardano address is too long for that
function isValidBech32Address(address, currency, networkType) {
if (!currency.segwitHrp) {
return false;
}
var hrp = currency.segwitHrp[networkType];
if (!hrp) {
return false;
}

try {
var dec = bech32.decode(address, networkType === 'prod' ? 103 : 108);
} catch (err) {
return false;
}

if (dec === null || dec.prefix !== hrp || dec.words.length < 1 || dec.words[0] > 16) {
return false;
}

return true;
}

module.exports = {
isValidAddress: function (address, currency, networkType) {
networkType = networkType || DEFAULT_NETWORK_TYPE;
return (
isValidLegacyAddress(address) || isValidBech32Address(address, currency, networkType)
);
},
getAddressType: function (address, currency, networkType) {
if (this.isValidAddress(address, currency, networkType)) {
return addressType.ADDRESS;
}
return undefined;
},
};
30 changes: 30 additions & 0 deletions packages/address-validator/src/ae_validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const { addressType } = require('./crypto/utils');
var base58 = require('./crypto/base58');

const ALLOWED_CHARS = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';

var regexp = new RegExp('^(ak_)([' + ALLOWED_CHARS + ']+)$'); // Begins with ak_ followed by

module.exports = {
isValidAddress: function (address, currency, networkType) {
let match = regexp.exec(address);
if (match !== null) {
return this.verifyChecksum(match[2]);
} else {
return false;
}
},

verifyChecksum: function (address) {
var decoded = base58.decode(address);
decoded.splice(-4, 4); // remove last 4 elements. Why is base 58 adding them?
return decoded.length === 32;
},

getAddressType: function (address, currency, networkType) {
if (this.isValidAddress(address, currency, networkType)) {
return addressType.ADDRESS;
}
return undefined;
},
};
19 changes: 19 additions & 0 deletions packages/address-validator/src/ardr_validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const { addressType } = require('./crypto/utils');
const ardorRegex = new RegExp('^ARDOR(-[A-Z0-9]{4}){3}(-[A-Z0-9]{5})$');

module.exports = {
isValidAddress: function (address, currency, networkType) {
if (!ardorRegex.test(address)) {
return false;
}

return true;
},

getAddressType: function (address, currency, networkType) {
if (this.isValidAddress(address, currency, networkType)) {
return addressType.ADDRESS;
}
return undefined;
},
};
24 changes: 24 additions & 0 deletions packages/address-validator/src/atom_validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const { addressType } = require('./crypto/utils');
const { bech32 } = require('bech32');

const ALLOWED_CHARS = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';

var regexp = new RegExp('^(cosmos)1([' + ALLOWED_CHARS + ']+)$'); // cosmos + bech32 separated by '1'

module.exports = {
isValidAddress: function (address, currency, networkType) {
return regexp.exec(address) !== null;
},

verifyChecksum: function (address) {
const decoded = bech32.decode(address);
return decoded && decoded.words.length === 32;
},

getAddressType: function (address, currency, networkType) {
if (this.isValidAddress(address)) {
return addressType.ADDRESS;
}
return undefined;
},
};
95 changes: 95 additions & 0 deletions packages/address-validator/src/bch_validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
const { addressType } = require('./crypto/utils');
var cryptoUtils = require('./crypto/utils');
var BTCValidator = require('./bitcoin_validator');

var GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];

function polymod(values) {
var chk = 1;
for (var p = 0; p < values.length; ++p) {
var top = chk >> 25;
chk = ((chk & 0x1ffffff) << 5) ^ values[p];
for (var i = 0; i < 5; ++i) {
if ((top >> i) & 1) {
chk ^= GENERATOR[i];
}
}
}
return chk;
}

function hrpExpand(hrp) {
var ret = [];
var p;
for (p = 0; p < hrp.length; ++p) {
ret.push(hrp.charCodeAt(p) >> 5);
}
ret.push(0);
for (p = 0; p < hrp.length; ++p) {
ret.push(hrp.charCodeAt(p) & 31);
}
return ret;
}

function verifyChecksum(hrp, data) {
return polymod(hrpExpand(hrp).concat(data)) === 1;
}

function validateAddress(address, currency, networkType) {
var prefix = 'bitcoincash';
var regexp = new RegExp(currency.regexp);
var raw_address;

var res = address.split(':');
if (res.length > 2) {
return false;
}
if (res.length === 1) {
raw_address = address;
} else {
if (res[0] !== 'bitcoincash') {
return false;
}
raw_address = res[1];
}

if (!regexp.test(raw_address)) {
return false;
}

if (raw_address.toLowerCase() != raw_address && raw_address.toUpperCase() != raw_address) {
return false;
}

var decoded = cryptoUtils.base32.b32decode(raw_address);
if (networkType === 'testnet') {
prefix = 'bchtest';
}

try {
if (verifyChecksum(prefix, decoded)) {
return false;
}
} catch (e) {
return false;
}

return true;
}

module.exports = {
isValidAddress: function (address, currency, networkType) {
return (
validateAddress(address, currency, networkType) ||
(currency.symbol !== 'bch' &&
BTCValidator.isValidAddress(address, currency, networkType))
);
},
getAddressType: function (address, currency, networkType) {
networkType = networkType || DEFAULT_NETWORK_TYPE;
if (this.isValidAddress(address, currency, networkType)) {
return addressType.ADDRESS;
}
return undefined;
},
};
17 changes: 17 additions & 0 deletions packages/address-validator/src/binance_validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const { addressType } = require('./crypto/utils');
module.exports = {
isValidAddress: function (address) {
var binanceAddress = address.slice(address.indexOf('bnb'));
if (binanceAddress.length !== 42) {
return false;
}
return true;
},

getAddressType: function (address, currency, networkType) {
if (this.isValidAddress(address, currency, networkType)) {
return addressType.ADDRESS;
}
return undefined;
},
};
Loading

0 comments on commit 72b8c49

Please sign in to comment.