Skip to content

Commit 2daed26

Browse files
author
Developer
committed
add Nimiq support
1 parent bcd0c8f commit 2daed26

File tree

7 files changed

+193
-54
lines changed

7 files changed

+193
-54
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ npm install wallet-address-validator
7171
* NEO/NEO, `'NEO'` or `'NEO'`
7272
* NeoGas/GAS, `'neogas'` or `'GAS'`
7373

74+
* Nimiq/NIM, `'nimiq'` or `'NIM'`
75+
7476
* Peercoin/PPCoin/PPC, `'peercoin'` or `'PPC'`
7577
* Primecoin/XPM, `'primecoin'` or `'XPM'`
7678
* Protoshares/PTS, `'protoshares'` or `'PTS'`

dist/wallet-address-validator.js

Lines changed: 129 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(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){
1+
(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){
22
// base-x encoding
33
// Forked from https://github.com/cryptocoinjs/bs58
44
// Originally written by Mike Hearn for BitcoinJ
@@ -114,65 +114,97 @@ for (var i = 0, len = code.length; i < len; ++i) {
114114
revLookup['-'.charCodeAt(0)] = 62
115115
revLookup['_'.charCodeAt(0)] = 63
116116

117-
function placeHoldersCount (b64) {
117+
function getLens (b64) {
118118
var len = b64.length
119+
119120
if (len % 4 > 0) {
120121
throw new Error('Invalid string. Length must be a multiple of 4')
121122
}
122123

123-
// the number of equal signs (place holders)
124-
// if there are two placeholders, than the two characters before it
125-
// represent one byte
126-
// if there is only one, then the three characters before it represent 2 bytes
127-
// this is just a cheap hack to not do indexOf twice
128-
return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
124+
// Trim off extra bytes after placeholder bytes are found
125+
// See: https://github.com/beatgammit/base64-js/issues/42
126+
var validLen = b64.indexOf('=')
127+
if (validLen === -1) validLen = len
128+
129+
var placeHoldersLen = validLen === len
130+
? 0
131+
: 4 - (validLen % 4)
132+
133+
return [validLen, placeHoldersLen]
129134
}
130135

136+
// base64 is 4/3 + up to two characters of the original data
131137
function byteLength (b64) {
132-
// base64 is 4/3 + up to two characters of the original data
133-
return (b64.length * 3 / 4) - placeHoldersCount(b64)
138+
var lens = getLens(b64)
139+
var validLen = lens[0]
140+
var placeHoldersLen = lens[1]
141+
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
142+
}
143+
144+
function _byteLength (b64, validLen, placeHoldersLen) {
145+
return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
134146
}
135147

136148
function toByteArray (b64) {
137-
var i, l, tmp, placeHolders, arr
138-
var len = b64.length
139-
placeHolders = placeHoldersCount(b64)
149+
var tmp
150+
var lens = getLens(b64)
151+
var validLen = lens[0]
152+
var placeHoldersLen = lens[1]
140153

141-
arr = new Arr((len * 3 / 4) - placeHolders)
154+
var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))
155+
156+
var curByte = 0
142157

143158
// if there are placeholders, only get up to the last complete 4 chars
144-
l = placeHolders > 0 ? len - 4 : len
159+
var len = placeHoldersLen > 0
160+
? validLen - 4
161+
: validLen
145162

146-
var L = 0
163+
for (var i = 0; i < len; i += 4) {
164+
tmp =
165+
(revLookup[b64.charCodeAt(i)] << 18) |
166+
(revLookup[b64.charCodeAt(i + 1)] << 12) |
167+
(revLookup[b64.charCodeAt(i + 2)] << 6) |
168+
revLookup[b64.charCodeAt(i + 3)]
169+
arr[curByte++] = (tmp >> 16) & 0xFF
170+
arr[curByte++] = (tmp >> 8) & 0xFF
171+
arr[curByte++] = tmp & 0xFF
172+
}
147173

148-
for (i = 0; i < l; i += 4) {
149-
tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
150-
arr[L++] = (tmp >> 16) & 0xFF
151-
arr[L++] = (tmp >> 8) & 0xFF
152-
arr[L++] = tmp & 0xFF
174+
if (placeHoldersLen === 2) {
175+
tmp =
176+
(revLookup[b64.charCodeAt(i)] << 2) |
177+
(revLookup[b64.charCodeAt(i + 1)] >> 4)
178+
arr[curByte++] = tmp & 0xFF
153179
}
154180

155-
if (placeHolders === 2) {
156-
tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
157-
arr[L++] = tmp & 0xFF
158-
} else if (placeHolders === 1) {
159-
tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
160-
arr[L++] = (tmp >> 8) & 0xFF
161-
arr[L++] = tmp & 0xFF
181+
if (placeHoldersLen === 1) {
182+
tmp =
183+
(revLookup[b64.charCodeAt(i)] << 10) |
184+
(revLookup[b64.charCodeAt(i + 1)] << 4) |
185+
(revLookup[b64.charCodeAt(i + 2)] >> 2)
186+
arr[curByte++] = (tmp >> 8) & 0xFF
187+
arr[curByte++] = tmp & 0xFF
162188
}
163189

164190
return arr
165191
}
166192

167193
function tripletToBase64 (num) {
168-
return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
194+
return lookup[num >> 18 & 0x3F] +
195+
lookup[num >> 12 & 0x3F] +
196+
lookup[num >> 6 & 0x3F] +
197+
lookup[num & 0x3F]
169198
}
170199

171200
function encodeChunk (uint8, start, end) {
172201
var tmp
173202
var output = []
174203
for (var i = start; i < end; i += 3) {
175-
tmp = ((uint8[i] << 16) & 0xFF0000) + ((uint8[i + 1] << 8) & 0xFF00) + (uint8[i + 2] & 0xFF)
204+
tmp =
205+
((uint8[i] << 16) & 0xFF0000) +
206+
((uint8[i + 1] << 8) & 0xFF00) +
207+
(uint8[i + 2] & 0xFF)
176208
output.push(tripletToBase64(tmp))
177209
}
178210
return output.join('')
@@ -182,31 +214,34 @@ function fromByteArray (uint8) {
182214
var tmp
183215
var len = uint8.length
184216
var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
185-
var output = ''
186217
var parts = []
187218
var maxChunkLength = 16383 // must be multiple of 3
188219

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

194227
// pad the end with zeros, but make sure to not forget the extra bytes
195228
if (extraBytes === 1) {
196229
tmp = uint8[len - 1]
197-
output += lookup[tmp >> 2]
198-
output += lookup[(tmp << 4) & 0x3F]
199-
output += '=='
230+
parts.push(
231+
lookup[tmp >> 2] +
232+
lookup[(tmp << 4) & 0x3F] +
233+
'=='
234+
)
200235
} else if (extraBytes === 2) {
201-
tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
202-
output += lookup[tmp >> 10]
203-
output += lookup[(tmp >> 4) & 0x3F]
204-
output += lookup[(tmp << 2) & 0x3F]
205-
output += '='
236+
tmp = (uint8[len - 2] << 8) + uint8[len - 1]
237+
parts.push(
238+
lookup[tmp >> 10] +
239+
lookup[(tmp >> 4) & 0x3F] +
240+
lookup[(tmp << 2) & 0x3F] +
241+
'='
242+
)
206243
}
207244

208-
parts.push(output)
209-
210245
return parts.join('')
211246
}
212247

@@ -1951,7 +1986,7 @@ function numberIsNaN (obj) {
19511986
},{"base64-js":2,"ieee754":4}],4:[function(require,module,exports){
19521987
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
19531988
var e, m
1954-
var eLen = nBytes * 8 - mLen - 1
1989+
var eLen = (nBytes * 8) - mLen - 1
19551990
var eMax = (1 << eLen) - 1
19561991
var eBias = eMax >> 1
19571992
var nBits = -7
@@ -1964,12 +1999,12 @@ exports.read = function (buffer, offset, isLE, mLen, nBytes) {
19641999
e = s & ((1 << (-nBits)) - 1)
19652000
s >>= (-nBits)
19662001
nBits += eLen
1967-
for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
2002+
for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}
19682003

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

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

19852020
exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
19862021
var e, m, c
1987-
var eLen = nBytes * 8 - mLen - 1
2022+
var eLen = (nBytes * 8) - mLen - 1
19882023
var eMax = (1 << eLen) - 1
19892024
var eBias = eMax >> 1
19902025
var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
@@ -2017,7 +2052,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
20172052
m = 0
20182053
e = eMax
20192054
} else if (e + eBias >= 1) {
2020-
m = (value * c - 1) * Math.pow(2, mLen)
2055+
m = ((value * c) - 1) * Math.pow(2, mLen)
20212056
e = e + eBias
20222057
} else {
20232058
m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
@@ -5506,6 +5541,7 @@ var ETHValidator = require('./ethereum_validator');
55065541
var BTCValidator = require('./bitcoin_validator');
55075542
var XMRValidator = require('./monero_validator');
55085543
var NANOValidator = require('./nano_validator');
5544+
var IBANValidator = require('./iban_validator');
55095545

55105546
// defines P2PKH and P2SH address types for standard (prod) and testnet networks
55115547
var CURRENCIES = [{
@@ -5712,6 +5748,12 @@ var CURRENCIES = [{
57125748
name: 'raiblocks',
57135749
symbol: 'xrb',
57145750
validator: NANOValidator,
5751+
},{
5752+
name: 'nimiq',
5753+
symbol: 'nim',
5754+
countryCode: 'NQ',
5755+
length: 36,
5756+
validator: IBANValidator
57155757
}];
57165758

57175759

@@ -5728,7 +5770,7 @@ module.exports = {
57285770
}
57295771
};
57305772

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

57345776
module.exports = {
@@ -5765,6 +5807,40 @@ module.exports = {
57655807
};
57665808

57675809
},{"./crypto/utils":17}],20:[function(require,module,exports){
5810+
function ibanCheck(address) {
5811+
var num = address.split('').map(function(c) {
5812+
var code = c.toUpperCase().charCodeAt(0);
5813+
return code >= 48 && code <= 57 ? c : (code - 55).toString();
5814+
}).join('');
5815+
var tmp = '';
5816+
5817+
for (var i = 0; i < Math.ceil(num.length / 6); i++) {
5818+
tmp = (parseInt(tmp + num.substr(i * 6, 6)) % 97).toString();
5819+
}
5820+
5821+
return parseInt(tmp);
5822+
}
5823+
5824+
module.exports = {
5825+
isValidAddress: function (address, currency) {
5826+
currency = currency || {};
5827+
address = address.replace(/ /g, '');
5828+
5829+
if (address.substr(0, 2).toUpperCase() !== currency.countryCode) {
5830+
return false;
5831+
}
5832+
if (address.length !== currency.length) {
5833+
return false;
5834+
}
5835+
if (ibanCheck(address.substr(4) + address.substr(0, 4)) !== 1) {
5836+
return false;
5837+
}
5838+
5839+
return true;
5840+
}
5841+
};
5842+
5843+
},{}],21:[function(require,module,exports){
57685844
var cryptoUtils = require('./crypto/utils');
57695845
var cnBase58 = require('./crypto/cnBase58');
57705846

@@ -5826,7 +5902,7 @@ module.exports = {
58265902
}
58275903
};
58285904

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

@@ -5855,7 +5931,7 @@ module.exports = {
58555931
}
58565932
};
58575933

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

@@ -5885,7 +5961,7 @@ module.exports = {
58855961
}
58865962
};
58875963

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

58915967
var DEFAULT_CURRENCY_NAME = 'bitcoin';
@@ -5902,5 +5978,5 @@ module.exports = {
59025978
},
59035979
};
59045980

5905-
},{"./currencies":18}]},{},[23])(23)
5906-
});
5981+
},{"./currencies":18}]},{},[24])(24)
5982+
});

dist/wallet-address-validator.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"validator",
2727
"vertcoin",
2828
"nano",
29+
"nimiq",
2930
"raiblocks",
3031
"javascript",
3132
"browser",

src/currencies.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var ETHValidator = require('./ethereum_validator');
33
var BTCValidator = require('./bitcoin_validator');
44
var XMRValidator = require('./monero_validator');
55
var NANOValidator = require('./nano_validator');
6+
var IBANValidator = require('./iban_validator');
67

78
// defines P2PKH and P2SH address types for standard (prod) and testnet networks
89
var CURRENCIES = [{
@@ -209,6 +210,12 @@ var CURRENCIES = [{
209210
name: 'raiblocks',
210211
symbol: 'xrb',
211212
validator: NANOValidator,
213+
},{
214+
name: 'nimiq',
215+
symbol: 'nim',
216+
countryCode: 'NQ',
217+
length: 36,
218+
validator: IBANValidator
212219
}];
213220

214221

src/iban_validator.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
function ibanCheck(address) {
2+
var num = address.split('').map(function(c) {
3+
var code = c.toUpperCase().charCodeAt(0);
4+
return code >= 48 && code <= 57 ? c : (code - 55).toString();
5+
}).join('');
6+
var tmp = '';
7+
8+
for (var i = 0; i < Math.ceil(num.length / 6); i++) {
9+
tmp = (parseInt(tmp + num.substr(i * 6, 6)) % 97).toString();
10+
}
11+
12+
return parseInt(tmp);
13+
}
14+
15+
module.exports = {
16+
isValidAddress: function (address, currency) {
17+
currency = currency || {};
18+
address = address.replace(/ /g, '');
19+
20+
if (address.substr(0, 2).toUpperCase() !== currency.countryCode) {
21+
return false;
22+
}
23+
if (address.length !== currency.length) {
24+
return false;
25+
}
26+
if (ibanCheck(address.substr(4) + address.substr(0, 4)) !== 1) {
27+
return false;
28+
}
29+
30+
return true;
31+
}
32+
};

0 commit comments

Comments
 (0)