diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index d2c1ad13..2cf302f4 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -18,16 +18,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.1.0.tgz" }, - "hash.js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - } - } - }, "https-proxy-agent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", @@ -94,6 +84,16 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz", "dependencies": { + "hash.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, "x-address-codec": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz", @@ -191,6 +191,16 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } + }, + "hash.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.0.3.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } } } }, diff --git a/package.json b/package.json index 89d3fc9d..475e4ce8 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "dependencies": { "babel-runtime": "^5.5.4", "bignumber.js": "^2.0.3", - "hash.js": "^1.0.3", "https-proxy-agent": "^1.0.0", "is-my-json-valid": "^2.12.2", "lodash": "^3.1.0", diff --git a/src/common/index.js b/src/common/index.js index 7c65dfb6..aa77581a 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -14,7 +14,6 @@ module.exports = { generateAddress: utils.generateAddress, generateAddressAPI: utils.generateAddressAPI, removeUndefined: utils.removeUndefined, - convertExceptions: utils.convertExceptions, convertKeysFromSnakeCaseToCamelCase: utils.convertKeysFromSnakeCaseToCamelCase, rippleToUnixTimestamp: utils.rippleToUnixTimestamp, diff --git a/src/common/schema-validator.js b/src/common/schema-validator.js index 3df2f89c..95942fb2 100644 --- a/src/common/schema-validator.js +++ b/src/common/schema-validator.js @@ -112,6 +112,5 @@ function schemaValidate(schemaName: string, object: any): void { SCHEMAS = loadSchemas(); module.exports = { - schemaValidate: schemaValidate, - SCHEMAS: SCHEMAS + schemaValidate }; diff --git a/src/common/validate.js b/src/common/validate.js index 2613d126..fc9ac1f6 100644 --- a/src/common/validate.js +++ b/src/common/validate.js @@ -18,19 +18,6 @@ function isValidSecret(secret) { } } -function validateAddressAndSecret(obj: {address: string, secret: string} -): void { - const address = obj.address; - const secret = obj.secret; - schemaValidate('address', address); - if (!secret) { - throw error('Parameter missing: secret'); - } - if (!isValidSecret(secret)) { - throw error('Invalid parameter: secret'); - } -} - function validateSecret(secret: string): void { if (!secret) { throw error('Parameter missing: secret'); @@ -57,7 +44,6 @@ function validateOptions(schema, options) { module.exports = { address: _.partial(schemaValidate, 'address'), - addressAndSecret: validateAddressAndSecret, secret: validateSecret, currency: _.partial(schemaValidate, 'currency'), identifier: _.partial(schemaValidate, 'hash256'), diff --git a/src/index.js b/src/index.js index 59c6cb32..7eceb23b 100644 --- a/src/index.js +++ b/src/index.js @@ -64,6 +64,9 @@ class RippleAPI extends EventEmitter { this.connection.on('ledgerClosed', message => { this.emit('ledgerClosed', server.formatLedgerClose(message)); }); + this.connection.on('error', (type, info) => { + this.emit('error', type, info); + }); } else { throw new errors.RippleError('Multi-server not implemented'); } diff --git a/src/ledger/utils.js b/src/ledger/utils.js index 5ef678cb..a8062ff8 100644 --- a/src/ledger/utils.js +++ b/src/ledger/utils.js @@ -126,7 +126,6 @@ module.exports = { getXRPBalance, ensureLedgerVersion, compareTransactions, - renameCounterpartyToIssuer, renameCounterpartyToIssuerInOrder, getRecursive, hasCompleteLedgerRange, diff --git a/src/transaction/sign.js b/src/transaction/sign.js index 7053d28d..82832eaa 100644 --- a/src/transaction/sign.js +++ b/src/transaction/sign.js @@ -3,34 +3,9 @@ const utils = require('./utils'); const keypairs = require('ripple-keypairs'); const binary = require('ripple-binary-codec'); -const sha512 = require('hash.js').sha512; +const {computeBinaryTransactionHash} = require('ripple-hashes'); const validate = utils.common.validate; -/** - * These prefixes are inserted before the source material used to - * generate various hashes. This is done to put each hash in its own - * "space." This way, two different types of objects with the - * same binary data will produce different hashes. - * - * Each prefix is a 4-byte value with the last byte set to zero - * and the first three bytes formed from the ASCII equivalent of - * some arbitrary string. For example "TXN". - */ -const HASH_TX_ID = 0x54584E00; // 'TXN' - -// For a hash function, rippled uses SHA-512 and then truncates the result -// to the first 256 bytes. This algorithm, informally called SHA-512Half, -// provides an output that has comparable security to SHA-256, but runs -// faster on 64-bit processors. -function sha512half(buffer) { - return sha512().update(buffer).digest('hex').toUpperCase().slice(0, 64); -} - -function hashSerialization(serialized, prefix) { - const hexPrefix = prefix.toString(16).toUpperCase(); - return sha512half(new Buffer(hexPrefix + serialized, 'hex')); -} - function computeSignature(txJSON, privateKey) { const signingData = binary.encodeForSigning(txJSON); return keypairs.sign(signingData, privateKey); @@ -40,6 +15,8 @@ function sign(txJSON: string, secret: string ): {signedTransaction: string; id: string} { const tx = JSON.parse(txJSON); validate.txJSON(tx); + // we can't validate that the secret matches the account because + // the secret could correspond to the regular key validate.secret(secret); const keypair = keypairs.deriveKeypair(secret); @@ -50,7 +27,7 @@ function sign(txJSON: string, secret: string const serialized = binary.encode(tx); return { signedTransaction: serialized, - id: hashSerialization(serialized, HASH_TX_ID) + id: computeBinaryTransactionHash(serialized) }; } diff --git a/test/api-test.js b/test/api-test.js index 3e3d0e5c..b5093014 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -15,7 +15,6 @@ const validate = common.validate; const utils = RippleAPI._PRIVATE.ledgerUtils; const ledgerClosed = require('./fixtures/api/rippled/ledger-close-newer'); const schemaValidator = RippleAPI._PRIVATE.schemaValidator; -const ledgerHashSchema = require('./fixtures/schemas/ledgerhash.json'); const orderbook = { base: { @@ -752,12 +751,6 @@ describe('RippleAPI', function() { assert.strictEqual(utils.compareTransactions(first, second), 1); }); - it('ledger utils - renameCounterpartyToIssuer', function() { - assert.strictEqual(utils.renameCounterpartyToIssuer(undefined), undefined); - const amountArg = {issuer: '1'}; - assert.deepEqual(utils.renameCounterpartyToIssuer(amountArg), amountArg); - }); - it('ledger utils - getRecursive', function() { function getter(marker, limit) { return new Promise((resolve, reject) => { @@ -776,26 +769,22 @@ describe('RippleAPI', function() { }); describe('schema-validator', function() { - beforeEach(function() { - schemaValidator.SCHEMAS.ledgerhash = ledgerHashSchema; - }); - it('valid', function() { assert.doesNotThrow(function() { - schemaValidator.schemaValidate('ledgerhash', + schemaValidator.schemaValidate('hash256', '0F7ED9F40742D8A513AE86029462B7A6768325583DF8EE21B7EC663019DD6A0F'); }); }); it('invalid', function() { assert.throws(function() { - schemaValidator.schemaValidate('ledgerhash', 'invalid'); + schemaValidator.schemaValidate('hash256', 'invalid'); }, this.api.errors.ValidationError); }); it('invalid - empty value', function() { assert.throws(function() { - schemaValidator.schemaValidate('ledgerhash', ''); + schemaValidator.schemaValidate('hash256', ''); }, this.api.errors.ValidationError); }); @@ -820,21 +809,6 @@ describe('RippleAPI', function() { /minLedgerVersion must not be greater than maxLedgerVersion/); }); - it('addressAndSecret', function() { - const noSecret = {address: address}; - assert.throws(_.partial(validate.addressAndSecret, noSecret), - this.api.errors.ValidationError); - assert.throws(_.partial(validate.addressAndSecret, noSecret), - /Parameter missing/); - const badSecret = {address: address, secret: 'sbad'}; - assert.throws(_.partial(validate.addressAndSecret, badSecret), - this.api.errors.ValidationError); - const goodWallet = {address: 'rpZMK8hwyrBvLorFNWHRCGt88nCJWbixur', - secret: 'shzjfakiK79YQdMjy4h8cGGfQSV6u' - }; - assert.doesNotThrow(_.partial(validate.addressAndSecret, goodWallet)); - }); - it('secret', function() { assert.doesNotThrow(_.partial(validate.secret, 'shzjfakiK79YQdMjy4h8cGGfQSV6u')); diff --git a/test/integration/integration-test.js b/test/integration/integration-test.js index e8c1ed83..8a0aca68 100644 --- a/test/integration/integration-test.js +++ b/test/integration/integration-test.js @@ -292,7 +292,8 @@ describe('integration tests', function() { it('generateWallet', function() { const newWallet = this.api.generateAddress(); assert(newWallet && newWallet.address && newWallet.secret); - validate.addressAndSecret(newWallet); + validate.address(newWallet.address); + validate.secret(newWallet.secret); }); });