commit
0dadfb2c2f
|
@ -18,9 +18,24 @@ var BASE_URL = 'http://localhost:3001/copay/api';
|
|||
var WALLET_CRITICAL_DATA = ['xPrivKey', 'm', 'publicKeyRing'];
|
||||
|
||||
function _createProposalOpts(opts, signingKey) {
|
||||
var hash = WalletUtils.getProposalHash(opts.toAddress, opts.amount, opts.message);
|
||||
opts.proposalSignature = WalletUtils.signMessage(hash, signingKey);
|
||||
return opts;
|
||||
var args = {
|
||||
toAddress: opts.toAddress,
|
||||
amount: opts.amount,
|
||||
message: _encryptProposalMessage(opts.message, signingKey),
|
||||
};
|
||||
var hash = WalletUtils.getProposalHash(args.toAddress, args.amount, args.message);
|
||||
args.proposalSignature = WalletUtils.signMessage(hash, signingKey);
|
||||
return args;
|
||||
};
|
||||
|
||||
function _encryptProposalMessage(message, encryptingKey) {
|
||||
if (!message) return null;
|
||||
return WalletUtils.encryptMessage(message, encryptingKey);
|
||||
};
|
||||
|
||||
function _decryptProposalMessage(message, encryptingKey) {
|
||||
if (!message) return '';
|
||||
return WalletUtils.decryptMessage(message, encryptingKey);
|
||||
};
|
||||
|
||||
function _parseError(body) {
|
||||
|
@ -392,7 +407,14 @@ API.prototype.getTxProposals = function(opts, cb) {
|
|||
this._loadAndCheck(function(err, data) {
|
||||
if (err) return cb(err);
|
||||
var url = '/v1/txproposals/';
|
||||
self._doGetRequest(url, data, cb);
|
||||
self._doGetRequest(url, data, function(err, txps) {
|
||||
if (err) return cb(err);
|
||||
|
||||
_.each(txps, function(txp) {
|
||||
txp.message = self._decryptProposalMessage(txp.message, data.signingPrivKey);
|
||||
});
|
||||
return cb(null, txps);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ var PrivateKey = Bitcore.PrivateKey;
|
|||
var PublicKey = Bitcore.PublicKey;
|
||||
var crypto = Bitcore.crypto;
|
||||
var HDPath = require('./hdpath');
|
||||
var sjcl = require('sjcl');
|
||||
|
||||
function WalletUtils() {};
|
||||
|
||||
|
@ -80,6 +81,21 @@ WalletUtils.fromSecret = function(secret) {
|
|||
};
|
||||
|
||||
|
||||
WalletUtils.encryptMessage = function(message, privKey) {
|
||||
var hash = sjcl.hash.sha256.hash(privKey);
|
||||
var key = sjcl.codec.utf8String.toBits(hash);
|
||||
key = sjcl.bitArray.clamp(key, 128);
|
||||
return sjcl.encrypt(key, message, {
|
||||
ks: 128,
|
||||
iter: 1
|
||||
});
|
||||
};
|
||||
|
||||
WalletUtils.decryptMessage = function(cyphertextJson, privKey) {
|
||||
var hash = sjcl.hash.sha256.hash(privKey);
|
||||
var key = sjcl.codec.utf8String.toBits(hash);
|
||||
key = sjcl.bitArray.clamp(key, 128);
|
||||
return sjcl.decrypt(key, cyphertextJson);
|
||||
};
|
||||
|
||||
module.exports = WalletUtils;
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
"morgan": "*",
|
||||
"npmlog": "^0.1.1",
|
||||
"preconditions": "^1.0.7",
|
||||
"request": "^2.53.0",
|
||||
"qr-image": "*",
|
||||
"request": "^2.53.0",
|
||||
"sjcl": "^1.0.2",
|
||||
"uuid": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -8,6 +8,7 @@ var Client = require('../../lib/client');
|
|||
var API = Client.API;
|
||||
var Bitcore = require('bitcore');
|
||||
var TestData = require('./clienttestdata');
|
||||
var WalletUtils = require('../../lib/walletutils');
|
||||
|
||||
describe('client API ', function() {
|
||||
var client;
|
||||
|
@ -172,6 +173,31 @@ describe('client API ', function() {
|
|||
it.skip('Should recreate a wallet acording stored data', function(done) {});
|
||||
});
|
||||
|
||||
describe('#sendTxProposal ', function() {
|
||||
it('should send tx proposal with encrypted message', function(done) {
|
||||
var response = {};
|
||||
var request = sinon.mock().yields(null, {
|
||||
statusCode: 200
|
||||
}, response);
|
||||
client.request = request;
|
||||
|
||||
var args = {
|
||||
toAddress: '2N3fA6wDtnebzywPkGuNK9KkFaEzgbPRRTq',
|
||||
amount: 100000,
|
||||
message: 'some message',
|
||||
};
|
||||
client.sendTxProposal(args, function(err) {
|
||||
var callArgs = request.getCall(0).args[0].body;
|
||||
callArgs.toAddress.should.equal(args.toAddress);
|
||||
callArgs.amount.should.equal(args.amount);
|
||||
callArgs.message.should.not.equal(args.message);
|
||||
var decryptedMsg = WalletUtils.decryptMessage(callArgs.message, '42798f82c4ed9ace4d66335165071edf180e70bc0fc08dacb3e35185a2141d5b');
|
||||
decryptedMsg.should.equal(args.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#signTxProposal ', function() {
|
||||
it.skip('should sign tx proposal', function(done) {});
|
||||
|
||||
|
|
|
@ -65,4 +65,13 @@ describe('WalletUtils', function() {
|
|||
WalletUtils.verifyMessage(aLongerText, sig, aPubKey).should.equal(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#encryptMessage #decryptMessage round trip', function() {
|
||||
it('should encrypt and decrypt', function() {
|
||||
var pwd = '0dea92f1df6675085b5cdd965487bb862f84f2755bcb56fa45dbf5b387a6c4a0';
|
||||
var ct = WalletUtils.encryptMessage('hello world', pwd);
|
||||
var msg = WalletUtils.decryptMessage(ct, pwd);
|
||||
msg.should.equal('hello world');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue