Skip to content

Commit

Permalink
add Nimiq support
Browse files Browse the repository at this point in the history
  • Loading branch information
Developer committed Aug 1, 2019
1 parent bcd0c8f commit 2daed26
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 54 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ npm install wallet-address-validator
* NEO/NEO, `'NEO'` or `'NEO'`
* NeoGas/GAS, `'neogas'` or `'GAS'`

* Nimiq/NIM, `'nimiq'` or `'NIM'`

* Peercoin/PPCoin/PPC, `'peercoin'` or `'PPC'`
* Primecoin/XPM, `'primecoin'` or `'XPM'`
* Protoshares/PTS, `'protoshares'` or `'PTS'`
Expand Down
182 changes: 129 additions & 53 deletions dist/wallet-address-validator.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WAValidator = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WAValidator = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
// base-x encoding
// Forked from https://github.com/cryptocoinjs/bs58
// Originally written by Mike Hearn for BitcoinJ
Expand Down Expand Up @@ -114,65 +114,97 @@ for (var i = 0, len = code.length; i < len; ++i) {
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63

function placeHoldersCount (b64) {
function getLens (b64) {
var len = b64.length

if (len % 4 > 0) {
throw new Error('Invalid string. Length must be a multiple of 4')
}

// the number of equal signs (place holders)
// if there are two placeholders, than the two characters before it
// represent one byte
// if there is only one, then the three characters before it represent 2 bytes
// this is just a cheap hack to not do indexOf twice
return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
// Trim off extra bytes after placeholder bytes are found
// See: https://github.com/beatgammit/base64-js/issues/42
var validLen = b64.indexOf('=')
if (validLen === -1) validLen = len

var placeHoldersLen = validLen === len
? 0
: 4 - (validLen % 4)

return [validLen, placeHoldersLen]
}

// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
// base64 is 4/3 + up to two characters of the original data
return (b64.length * 3 / 4) - placeHoldersCount(b64)
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function _byteLength (b64, validLen, placeHoldersLen) {
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function toByteArray (b64) {
var i, l, tmp, placeHolders, arr
var len = b64.length
placeHolders = placeHoldersCount(b64)
var tmp
var lens = getLens(b64)
var validLen = lens[0]
var placeHoldersLen = lens[1]

arr = new Arr((len * 3 / 4) - placeHolders)
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))

var curByte = 0

// if there are placeholders, only get up to the last complete 4 chars
l = placeHolders > 0 ? len - 4 : len
var len = placeHoldersLen > 0
? validLen - 4
: validLen

var L = 0
for (var i = 0; i < len; i += 4) {
tmp =
(revLookup[b64.charCodeAt(i)] << 18) |
(revLookup[b64.charCodeAt(i + 1)] << 12) |
(revLookup[b64.charCodeAt(i + 2)] << 6) |
revLookup[b64.charCodeAt(i + 3)]
arr[curByte++] = (tmp >> 16) & 0xFF
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}

for (i = 0; i < l; i += 4) {
tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
arr[L++] = (tmp >> 16) & 0xFF
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
if (placeHoldersLen === 2) {
tmp =
(revLookup[b64.charCodeAt(i)] << 2) |
(revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[curByte++] = tmp & 0xFF
}

if (placeHolders === 2) {
tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
arr[L++] = tmp & 0xFF
} else if (placeHolders === 1) {
tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[L++] = (tmp >> 8) & 0xFF
arr[L++] = tmp & 0xFF
if (placeHoldersLen === 1) {
tmp =
(revLookup[b64.charCodeAt(i)] << 10) |
(revLookup[b64.charCodeAt(i + 1)] << 4) |
(revLookup[b64.charCodeAt(i + 2)] >> 2)
arr[curByte++] = (tmp >> 8) & 0xFF
arr[curByte++] = tmp & 0xFF
}

return arr
}

function tripletToBase64 (num) {
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
return lookup[num >> 18 & 0x3F] +
lookup[num >> 12 & 0x3F] +
lookup[num >> 6 & 0x3F] +
lookup[num & 0x3F]
}

function encodeChunk (uint8, start, end) {
var tmp
var output = []
for (var i = start; i < end; i += 3) {
tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF)
tmp =
((uint8[i] << 16) & 0xFF0000) +
((uint8[i + 1] << 8) & 0xFF00) +
(uint8[i + 2] & 0xFF)
output.push(tripletToBase64(tmp))
}
return output.join('')
Expand All @@ -182,31 +214,34 @@ function fromByteArray (uint8) {
var tmp
var len = uint8.length
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
var output = ''
var parts = []
var maxChunkLength = 16383 // must be multiple of 3

// go through the array every three bytes, we'll deal with trailing stuff later
for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
parts.push(encodeChunk(
uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
))
}

// pad the end with zeros, but make sure to not forget the extra bytes
if (extraBytes === 1) {
tmp = uint8[len - 1]
output += lookup[tmp >> 2]
output += lookup[(tmp << 4) & 0x3F]
output += '=='
parts.push(
lookup[tmp >> 2] +
lookup[(tmp << 4) & 0x3F] +
'=='
)
} else if (extraBytes === 2) {
tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
output += lookup[tmp >> 10]
output += lookup[(tmp >> 4) & 0x3F]
output += lookup[(tmp << 2) & 0x3F]
output += '='
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
parts.push(
lookup[tmp >> 10] +
lookup[(tmp >> 4) & 0x3F] +
lookup[(tmp << 2) & 0x3F] +
'='
)
}

parts.push(output)

return parts.join('')
}

Expand Down Expand Up @@ -1951,7 +1986,7 @@ function numberIsNaN (obj) {
},{"base64-js":2,"ieee754":4}],4:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
var e, m
var eLen = nBytes * 8 - mLen - 1
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var nBits = -7
Expand All @@ -1964,12 +1999,12 @@ exports.read = function (buffer, offset, isLE, mLen, nBytes) {
e = s & ((1 << (-nBits)) - 1)
s >>= (-nBits)
nBits += eLen
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}

m = e & ((1 << (-nBits)) - 1)
e >>= (-nBits)
nBits += mLen
for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}

if (e === 0) {
e = 1 - eBias
Expand All @@ -1984,7 +2019,7 @@ exports.read = function (buffer, offset, isLE, mLen, nBytes) {

exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
var e, m, c
var eLen = nBytes * 8 - mLen - 1
var eLen = (nBytes * 8) - mLen - 1
var eMax = (1 << eLen) - 1
var eBias = eMax >> 1
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
Expand Down Expand Up @@ -2017,7 +2052,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
m = 0
e = eMax
} else if (e + eBias >= 1) {
m = (value * c - 1) * Math.pow(2, mLen)
m = ((value * c) - 1) * Math.pow(2, mLen)
e = e + eBias
} else {
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
Expand Down Expand Up @@ -5506,6 +5541,7 @@ var ETHValidator = require('./ethereum_validator');
var BTCValidator = require('./bitcoin_validator');
var XMRValidator = require('./monero_validator');
var NANOValidator = require('./nano_validator');
var IBANValidator = require('./iban_validator');

// defines P2PKH and P2SH address types for standard (prod) and testnet networks
var CURRENCIES = [{
Expand Down Expand Up @@ -5712,6 +5748,12 @@ var CURRENCIES = [{
name: 'raiblocks',
symbol: 'xrb',
validator: NANOValidator,
},{
name: 'nimiq',
symbol: 'nim',
countryCode: 'NQ',
length: 36,
validator: IBANValidator
}];


Expand All @@ -5728,7 +5770,7 @@ module.exports = {
}
};

},{"./bitcoin_validator":8,"./ethereum_validator":19,"./monero_validator":20,"./nano_validator":21,"./ripple_validator":22}],19:[function(require,module,exports){
},{"./bitcoin_validator":8,"./ethereum_validator":19,"./iban_validator":20,"./monero_validator":21,"./nano_validator":22,"./ripple_validator":23}],19:[function(require,module,exports){
var cryptoUtils = require('./crypto/utils');

module.exports = {
Expand Down Expand Up @@ -5765,6 +5807,40 @@ module.exports = {
};

},{"./crypto/utils":17}],20:[function(require,module,exports){
function ibanCheck(address) {
var num = address.split('').map(function(c) {
var code = c.toUpperCase().charCodeAt(0);
return code >= 48 && code <= 57 ? c : (code - 55).toString();
}).join('');
var tmp = '';

for (var i = 0; i < Math.ceil(num.length / 6); i++) {
tmp = (parseInt(tmp + num.substr(i * 6, 6)) % 97).toString();
}

return parseInt(tmp);
}

module.exports = {
isValidAddress: function (address, currency) {
currency = currency || {};
address = address.replace(/ /g, '');

if (address.substr(0, 2).toUpperCase() !== currency.countryCode) {
return false;
}
if (address.length !== currency.length) {
return false;
}
if (ibanCheck(address.substr(4) + address.substr(0, 4)) !== 1) {
return false;
}

return true;
}
};

},{}],21:[function(require,module,exports){
var cryptoUtils = require('./crypto/utils');
var cnBase58 = require('./crypto/cnBase58');

Expand Down Expand Up @@ -5826,7 +5902,7 @@ module.exports = {
}
};

},{"./crypto/cnBase58":14,"./crypto/utils":17}],21:[function(require,module,exports){
},{"./crypto/cnBase58":14,"./crypto/utils":17}],22:[function(require,module,exports){
var cryptoUtils = require('./crypto/utils');
var baseX = require('base-x');

Expand Down Expand Up @@ -5855,7 +5931,7 @@ module.exports = {
}
};

},{"./crypto/utils":17,"base-x":1}],22:[function(require,module,exports){
},{"./crypto/utils":17,"base-x":1}],23:[function(require,module,exports){
var cryptoUtils = require('./crypto/utils');
var baseX = require('base-x');

Expand Down Expand Up @@ -5885,7 +5961,7 @@ module.exports = {
}
};

},{"./crypto/utils":17,"base-x":1}],23:[function(require,module,exports){
},{"./crypto/utils":17,"base-x":1}],24:[function(require,module,exports){
var currencies = require('./currencies');

var DEFAULT_CURRENCY_NAME = 'bitcoin';
Expand All @@ -5902,5 +5978,5 @@ module.exports = {
},
};

},{"./currencies":18}]},{},[23])(23)
});
},{"./currencies":18}]},{},[24])(24)
});
2 changes: 1 addition & 1 deletion dist/wallet-address-validator.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"validator",
"vertcoin",
"nano",
"nimiq",
"raiblocks",
"javascript",
"browser",
Expand Down
7 changes: 7 additions & 0 deletions src/currencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var ETHValidator = require('./ethereum_validator');
var BTCValidator = require('./bitcoin_validator');
var XMRValidator = require('./monero_validator');
var NANOValidator = require('./nano_validator');
var IBANValidator = require('./iban_validator');

// defines P2PKH and P2SH address types for standard (prod) and testnet networks
var CURRENCIES = [{
Expand Down Expand Up @@ -209,6 +210,12 @@ var CURRENCIES = [{
name: 'raiblocks',
symbol: 'xrb',
validator: NANOValidator,
},{
name: 'nimiq',
symbol: 'nim',
countryCode: 'NQ',
length: 36,
validator: IBANValidator
}];


Expand Down
32 changes: 32 additions & 0 deletions src/iban_validator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
function ibanCheck(address) {
var num = address.split('').map(function(c) {
var code = c.toUpperCase().charCodeAt(0);
return code >= 48 && code <= 57 ? c : (code - 55).toString();
}).join('');
var tmp = '';

for (var i = 0; i < Math.ceil(num.length / 6); i++) {
tmp = (parseInt(tmp + num.substr(i * 6, 6)) % 97).toString();
}

return parseInt(tmp);
}

module.exports = {
isValidAddress: function (address, currency) {
currency = currency || {};
address = address.replace(/ /g, '');

if (address.substr(0, 2).toUpperCase() !== currency.countryCode) {
return false;
}
if (address.length !== currency.length) {
return false;
}
if (ibanCheck(address.substr(4) + address.substr(0, 4)) !== 1) {
return false;
}

return true;
}
};
Loading

0 comments on commit 2daed26

Please sign in to comment.