blocktrail /
blocktrail-sdk-nodejs
| 1 | var util = require('util'); |
||
| 2 | var assert = require('assert'); |
||
| 3 | var CryptoJS = require('crypto-js'); |
||
| 4 | var bip39 = require('bip39'); |
||
| 5 | |||
| 6 | var blocktrail = { |
||
| 7 | COIN: 100000000, |
||
| 8 | PRECISION: 8, |
||
| 9 | DUST: 2730, |
||
| 10 | BASE_FEE: 10000, |
||
| 11 | LOCK_TIME_TIMESTAMP_THRESHOLD: 5000000 |
||
| 12 | }; |
||
| 13 | |||
| 14 | var convert = function(s, from, to) { |
||
| 15 | return (new Buffer(s, from)).toString(to); |
||
|
0 ignored issues
–
show
|
|||
| 16 | }; |
||
| 17 | |||
| 18 | var aesDecryptMnemonic = function(mnemonic, passphrase) { |
||
| 19 | var hex = bip39.mnemonicToEntropy(mnemonic); |
||
| 20 | var base64 = convert(hex, 'hex', 'base64'); |
||
| 21 | var decrypted = CryptoJS.AES.decrypt(base64, passphrase).toString(CryptoJS.enc.Utf8); |
||
| 22 | |||
| 23 | if (!decrypted.length) { |
||
| 24 | throw new blocktrail.WalletDecryptError(); |
||
| 25 | } |
||
| 26 | |||
| 27 | return decrypted; |
||
| 28 | }; |
||
| 29 | |||
| 30 | var aesDecryptMnemonicToSeed = function(mnemonic, passphrase) { |
||
| 31 | return aesDecryptMnemonic(mnemonic, passphrase).toString(CryptoJS.enc.Utf8); |
||
| 32 | }; |
||
| 33 | |||
| 34 | var aesDecryptMnemonicToSeedHex = function(mnemonic, passphrase) { |
||
| 35 | return convert(aesDecryptMnemonicToSeed(mnemonic, passphrase), 'base64', 'hex'); |
||
| 36 | }; |
||
| 37 | |||
| 38 | var aesDecryptMnemonicToSeedBuffer = function(mnemonic, passphrase) { |
||
| 39 | return new Buffer(aesDecryptMnemonicToSeedHex(mnemonic, passphrase), 'hex'); |
||
|
0 ignored issues
–
show
The variable
Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN. Loading history...
|
|||
| 40 | }; |
||
| 41 | |||
| 42 | var aesEncryptSeedToMnemonic = function(seed, passphrase) { |
||
| 43 | var base64 = CryptoJS.AES.encrypt(seed, passphrase).toString(CryptoJS.format.OpenSSL); |
||
| 44 | var hex = convert(base64, 'base64', 'hex'); |
||
| 45 | var mnemonic = bip39.entropyToMnemonic(hex); |
||
| 46 | |||
| 47 | return mnemonic; |
||
| 48 | }; |
||
| 49 | |||
| 50 | var aesEncryptSeedHexToMnemonic = function(seedHex, passphrase) { |
||
| 51 | return aesEncryptSeedToMnemonic(convert(seedHex, 'hex', 'base64'), passphrase); |
||
| 52 | }; |
||
| 53 | |||
| 54 | var aesEncryptSeedBufferToMnemonic = function(seedBuffer, passphrase) { |
||
| 55 | return aesEncryptSeedToMnemonic(seedBuffer.toString('base64'), passphrase); |
||
| 56 | }; |
||
| 57 | |||
| 58 | blocktrail.convert = convert; |
||
| 59 | blocktrail.aesDecryptMnemonicToSeed = aesDecryptMnemonicToSeed; |
||
| 60 | blocktrail.aesDecryptMnemonicToSeedBuffer = aesDecryptMnemonicToSeedBuffer; |
||
| 61 | blocktrail.aesDecryptMnemonicToSeedHex = aesDecryptMnemonicToSeedHex; |
||
| 62 | blocktrail.aesEncryptSeedToMnemonic = aesEncryptSeedToMnemonic; |
||
| 63 | blocktrail.aesEncryptSeedHexToMnemonic = aesEncryptSeedHexToMnemonic; |
||
| 64 | blocktrail.aesEncryptSeedBufferToMnemonic = aesEncryptSeedBufferToMnemonic; |
||
| 65 | |||
| 66 | blocktrail.V3Crypt = { |
||
| 67 | KeyDerivation: require('./keyderivation'), |
||
| 68 | Encryption: require('./encryption'), |
||
| 69 | EncryptionMnemonic: require('./encryption_mnemonic') |
||
| 70 | }; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * convert a BTC value to Satoshi |
||
| 74 | * |
||
| 75 | * @param btc float BTC value |
||
| 76 | * @returns int Satoshi value (int) |
||
| 77 | */ |
||
| 78 | blocktrail.toSatoshi = function(btc) { |
||
| 79 | return parseInt((btc * blocktrail.COIN).toFixed(0), 10); |
||
| 80 | }; |
||
| 81 | |||
| 82 | /** |
||
| 83 | * convert a Satoshi value to BTC |
||
| 84 | * |
||
| 85 | * @param satoshi int Satoshi value |
||
| 86 | * @returns {string} BTC value (float) |
||
| 87 | */ |
||
| 88 | blocktrail.toBTC = function(satoshi) { |
||
| 89 | return (satoshi / blocktrail.COIN).toFixed(blocktrail.PRECISION); |
||
| 90 | }; |
||
| 91 | |||
| 92 | /** |
||
| 93 | * patch the Q module to add spreadNodeify method to promises |
||
| 94 | * so that we can support multi parameter callbacks |
||
| 95 | * |
||
| 96 | * @param q |
||
| 97 | */ |
||
| 98 | blocktrail.patchQ = function(q) { |
||
| 99 | /* jshint -W003 */ |
||
| 100 | |||
| 101 | if (q.spreadNodeify && q.spreadDone) { |
||
| 102 | return; |
||
| 103 | } |
||
| 104 | |||
| 105 | q.spreadDone = spreadDone; |
||
| 106 | function spreadDone(value, fulfilled, rejected) { |
||
| 107 | return q(value).spreadDone(fulfilled, rejected); |
||
| 108 | } |
||
| 109 | |||
| 110 | q.makePromise.prototype.spreadDone = function(fulfilled, rejected) { |
||
| 111 | return this.all().done(function(array) { |
||
| 112 | return fulfilled.apply(void 0, array); |
||
|
0 ignored issues
–
show
|
|||
| 113 | }, rejected); |
||
| 114 | }; |
||
| 115 | |||
| 116 | q.spreadNodeify = spreadNodeify; |
||
| 117 | function spreadNodeify(object, nodeback) { |
||
| 118 | return q(object).spreadNodeify(nodeback); |
||
| 119 | } |
||
| 120 | |||
| 121 | q.makePromise.prototype.spreadNodeify = function(nodeback) { |
||
| 122 | if (nodeback) { |
||
| 123 | this.then(function(value) { |
||
| 124 | q.nextTick(function() { |
||
| 125 | nodeback.apply(void 0, [null].concat(value)); |
||
|
0 ignored issues
–
show
|
|||
| 126 | }); |
||
| 127 | }, function(error) { |
||
| 128 | q.nextTick(function() { |
||
| 129 | nodeback(error); |
||
| 130 | }); |
||
| 131 | }); |
||
|
0 ignored issues
–
show
|
|||
| 132 | } else { |
||
| 133 | return this; |
||
| 134 | } |
||
| 135 | }; |
||
| 136 | }; |
||
| 137 | |||
| 138 | |||
| 139 | /** |
||
| 140 | * Add extend() method to Error type |
||
| 141 | * |
||
| 142 | * @param subTypeName |
||
| 143 | * @param errorCode [optional] |
||
| 144 | * @returns {SubType} |
||
| 145 | */ |
||
| 146 | Error.extend = function(subTypeName, errorCode /*optional*/) { |
||
|
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
|
|||
| 147 | assert(subTypeName, 'subTypeName is required'); |
||
| 148 | //define new error type |
||
| 149 | var SubType = function(message) { |
||
| 150 | |||
| 151 | //handle constructor call without 'new' |
||
| 152 | if (!(this instanceof SubType)) { |
||
| 153 | return new SubType(message); |
||
| 154 | } |
||
| 155 | |||
| 156 | //populate error details |
||
| 157 | this.name = subTypeName; |
||
| 158 | this.code = errorCode; |
||
| 159 | this.message = message ? (message.message || message || '') : ''; |
||
| 160 | |||
| 161 | //include stack trace in error object (only supported in v8 browsers) |
||
| 162 | if (Error.captureStackTrace) { |
||
|
0 ignored issues
–
show
There is no return statement if
Error.captureStackTrace is false. Are you sure this is correct? If so, consider adding return; explicitly.
This check looks for functions where a Consider this little piece of code function isBig(a) {
if (a > 5000) {
return "yes";
}
}
console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined
The function This behaviour may not be what you had intended. In any case, you can add a
Loading history...
|
|||
| 163 | Error.captureStackTrace(this, this.constructor); |
||
|
0 ignored issues
–
show
|
|||
| 164 | } |
||
| 165 | }; |
||
| 166 | |||
| 167 | //inherit the base prototype chain |
||
| 168 | util.inherits(SubType, this); |
||
| 169 | |||
| 170 | //override the toString method to error type name and inspected message (to expand objects) |
||
| 171 | SubType.prototype.toString = function() { |
||
| 172 | return this.name + ': ' + util.inspect(this.message); |
||
| 173 | }; |
||
| 174 | |||
| 175 | //attach extend() to the SubType to make it extendable further |
||
| 176 | SubType.extend = this.extend; |
||
| 177 | return SubType; |
||
| 178 | }; |
||
| 179 | |||
| 180 | if (typeof Uint8Array.prototype.reverse !== 'function') { |
||
| 181 | Buffer.prototype.reverse = function reverse() { |
||
|
0 ignored issues
–
show
The variable
Buffer seems to be never declared. If this is a global, consider adding a /** global: Buffer */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN. Loading history...
|
|||
| 182 | var c; |
||
| 183 | for (var i = 0, j = this.length - 1; i <= j; ++i, --j) { |
||
| 184 | c = this[i]; |
||
| 185 | this[i] = this[j]; |
||
| 186 | this[j] = c; |
||
| 187 | } |
||
| 188 | |||
| 189 | return this; |
||
| 190 | }; |
||
| 191 | } |
||
| 192 | |||
| 193 | //Wallet Errors |
||
| 194 | blocktrail.WalletInitError = Error.extend("WalletInitError", 400); |
||
| 195 | blocktrail.WalletCreateError = Error.extend("WalletCreateError", 400); |
||
| 196 | blocktrail.WalletUpgradeError = Error.extend("WalletUpgradeError", 400); |
||
| 197 | blocktrail.WalletChecksumError = Error.extend("WalletChecksumError", 400); |
||
| 198 | blocktrail.WalletDeleteError = Error.extend("WalletDeleteError", 400); |
||
| 199 | blocktrail.WalletDecryptError = Error.extend("WalletDecryptError", 400); |
||
| 200 | blocktrail.WalletAddressError = Error.extend("WalletAddressError", 500); |
||
| 201 | blocktrail.WalletSendError = Error.extend("WalletSendError", 400); |
||
| 202 | blocktrail.WalletLockedError = Error.extend("WalletLockedError", 500); |
||
| 203 | blocktrail.WalletFeeError = Error.extend("WalletFeeError", 500); |
||
| 204 | blocktrail.WalletInvalid2FAError = Error.extend("WalletInvalid2FAError", 401); |
||
| 205 | blocktrail.WalletMissing2FAError = Error.extend("WalletMissing2FAError", 401); |
||
| 206 | blocktrail.TransactionSignError = Error.extend("TransactionSignError", 500); |
||
| 207 | blocktrail.TransactionInputError = Error.extend("TransactionInputError", 400); |
||
| 208 | blocktrail.TransactionOutputError = Error.extend("TransactionOutputError", 400); |
||
| 209 | |||
| 210 | blocktrail.KeyPathError = Error.extend("KeyPathError", 400); |
||
| 211 | |||
| 212 | blocktrail.InvalidAddressError = Error.extend("InvalidAddressError", 400); |
||
| 213 | |||
| 214 | //Other Errors |
||
| 215 | blocktrail.Error = Error.extend("Error", 500); |
||
| 216 | |||
| 217 | blocktrail.FEE_STRATEGY_FORCE_FEE = 'force_fee'; |
||
| 218 | blocktrail.FEE_STRATEGY_BASE_FEE = 'base_fee'; |
||
| 219 | blocktrail.FEE_STRATEGY_HIGH_PRIORITY = 'high_priority'; |
||
| 220 | blocktrail.FEE_STRATEGY_OPTIMAL = 'optimal'; |
||
| 221 | blocktrail.FEE_STRATEGY_LOW_PRIORITY = 'low_priority'; |
||
| 222 | blocktrail.FEE_STRATEGY_MIN_RELAY_FEE = 'min_relay_fee'; |
||
| 223 | |||
| 224 | // apply patch to Q to add spreadNodeify for all dependants of this module |
||
| 225 | blocktrail.patchQ(require('q')); |
||
| 226 | |||
| 227 | module.exports = blocktrail; |
||
| 228 |
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.
To learn more about declaring variables in Javascript, see the MDN.