diff --git a/js/models/network/Async.js b/js/models/network/Async.js
index e63b2ecfc..e774d2eea 100644
--- a/js/models/network/Async.js
+++ b/js/models/network/Async.js
@@ -167,6 +167,7 @@ Network.prototype.iterateNonce = function() {
var noncep2uint = this.networkNonce.slice(4, 8).readUInt32BE(0);
var noncep2 = this.networkNonce.slice(4, 8);
noncep2.writeUInt32BE(noncep2uint + 1, 0);
+ this.networkNonce = Buffer.concat([noncep1, noncep2], 8);
return this.networkNonce;
};
diff --git a/js/models/storage/File.js b/js/models/storage/File.js
deleted file mode 100644
index ec0880145..000000000
--- a/js/models/storage/File.js
+++ /dev/null
@@ -1,149 +0,0 @@
-'use strict';
-var fs = require('fs');
-var CryptoJS = require('node-cryptojs-aes').CryptoJS;
-
-var passwords = [];
-
-function Storage(opts) {
- opts = opts || {};
-
- this.data = {};
- passwords[0] = opts.password;
-}
-
-Storage.prototype._encrypt = function(string) {
- var encrypted = CryptoJS.AES.encrypt(string, passwords[0]);
- var encryptedBase64 = encrypted.toString();
- return encryptedBase64;
-};
-
-Storage.prototype._encryptObj = function(obj) {
- var string = JSON.stringify(obj);
- return this._encrypt(string);
-};
-
-Storage.prototype._decrypt = function(base64) {
- var decrypted = CryptoJS.AES.decrypt(base64, passwords[0]);
- var decryptedStr = decrypted.toString(CryptoJS.enc.Utf8);
- return decryptedStr;
-};
-
-Storage.prototype._decryptObj = function(base64) {
- var decryptedStr = this._decrypt(base64);
- return JSON.parse(decryptedStr);
-};
-
-Storage.prototype.load = function(walletId, callback) {
- var self = this;
- fs.readFile(walletId, function(err, base64) {
- if (typeof base64 !== 'string')
- base64 = base64.toString();
- var data = self._decryptObj(base64);
-
- if (err) return callback(err);
-
- try {
- this.data[walletId] = JSON.parse(data);
- } catch (err) {
- if (callback)
- return callback(err);
- }
-
- if (callback)
- return callback(null);
- });
-};
-
-Storage.prototype.save = function(walletId, callback) {
- var obj = this.data[walletId];
- var encryptedBase64 = this._encryptObj(obj);
-
- //TODO: update to use a queue to ensure that saves are made sequentially
- fs.writeFile(walletId, encryptedBase64, function(err) {
- if (callback)
- return callback(err);
- });
-};
-
-Storage.prototype._read = function(k) {
- var split = k.split('::');
- var walletId = split[0];
- var key = split[1];
- return this.data[walletId][key];
-};
-
-Storage.prototype._write = function(k, v, callback) {
- var split = k.split('::');
- var walletId = split[0];
- var key = split[1];
- if (!this.data[walletId])
- this.data[walletId] = {};
- this.data[walletId][key] = v;
- this.save(walletId, callback);
-};
-
-// get value by key
-Storage.prototype.getGlobal = function(k) {
- return this._read(k);
-};
-
-// set value for key
-Storage.prototype.setGlobal = function(k, v, callback) {
- this._write(k, v, callback);
-};
-
-// remove value for key
-Storage.prototype.removeGlobal = function(k, callback) {
- var split = k.split('::');
- var walletId = split[0];
- var key = split[1];
- delete this.data[walletId][key];
- this.save(walletId, callback);
-};
-
-Storage.prototype._key = function(walletId, k) {
- return walletId + '::' + k;
-};
-
-// get value by key
-Storage.prototype.get = function(walletId, k) {
- return this.getGlobal(this._key(walletId, k));
-};
-
-// set value for key
-Storage.prototype.set = function(walletId, k, v, callback) {
- this.setGlobal(this._key(walletId, k), v, callback);
-};
-
-// remove value for key
-Storage.prototype.remove = function(walletId, k, callback) {
- this.removeGlobal(this._key(walletId, k), callback);
-};
-
-Storage.prototype.getWalletIds = function() {
- return [];
-};
-
-Storage.prototype.setFromObj = function(walletId, obj, callback) {
- this.data[walletId] = obj;
- this.save(walletId, callback);
-};
-
-Storage.prototype.setFromEncryptedObj = function(walletId, base64, callback) {
- var obj = this._decryptObj(base64);
- this.setFromObj(walletId, obj, callback);
-};
-
-Storage.prototype.getEncryptedObj = function(walletId) {
- var encryptedBase64 = this._encryptObj(this.data[walletId]);
-
- return encryptedBase64;
-};
-
-// remove all values
-Storage.prototype.clearAll = function(callback) {
- this.data = {};
- this.save(callback);
-};
-
-module.exports = Storage;
diff --git a/karma.conf.js b/karma.conf.js
index ab1abaf1f..79314df62 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -59,7 +59,10 @@ module.exports = function(config) {
'test/mocha.conf.js',
//test files
- 'test/unit/**/*.js'
+ 'test/test.*.js',
+
+ 'test/unit/**/*.js',
+
],
@@ -99,7 +102,7 @@ module.exports = function(config) {
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
- browsers: ['Chrome'],
+ browsers: ['Chrome', 'Firefox'],
// Continuous Integration mode
diff --git a/package.json b/package.json
index 26dcad40e..55572279e 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
"setup-shell": "node shell/scripts/download-atom-shell.js",
"start": "node server.js",
"coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --reporter spec test",
- "test": "node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && ./node_modules/karma/bin/karma start --browsers Firefox --single-run",
+ "test": "sh test/run.sh",
"dist": "node shell/scripts/dist.js",
"sign": "gpg -u 1112CFA1 --output browser-extensions/firefox/copay.xpi.sig --detach-sig browser-extensions/firefox/copay.xpi; gpg -u 1112CFA1 --output browser-extensions/chrome/copay-chrome-extension.zip.sig --detach-sig browser-extensions/chrome/copay-chrome-extension.zip",
"verify": "gpg --verify browser-extensions/firefox/copay.xpi.sig browser-extensions/firefox/copay.xpi; gpg --verify browser-extensions/chrome/copay-chrome-extension.zip.sig browser-extensions/chrome/copay-chrome-extension.zip"
diff --git a/test/index.html b/test/index.html
deleted file mode 100644
index e5aa76a6c..000000000
--- a/test/index.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- Mocha
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/run.sh b/test/run.sh
new file mode 100644
index 000000000..c13caa84d
--- /dev/null
+++ b/test/run.sh
@@ -0,0 +1,5 @@
+#! /bin/bash
+
+node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && \
+ cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && \
+ ./node_modules/karma/bin/karma start --browsers Firefox --single-run
diff --git a/test/test.PayPro.js b/test/test.PayPro.js
index 4f22917e2..0528864f3 100644
--- a/test/test.PayPro.js
+++ b/test/test.PayPro.js
@@ -3,14 +3,12 @@
var chai = chai || require('chai');
var should = chai.should();
var sinon = require('sinon');
-var is_browser = typeof process == 'undefined'
- || typeof process.versions === 'undefined';
+var is_browser = typeof process == 'undefined' || typeof process.versions === 'undefined';
if (is_browser) {
var copay = require('copay'); //browser
} else {
var copay = require('../copay'); //node
}
-var copayConfig = require('../config');
var Wallet = copay.Wallet;
var PrivateKey = copay.PrivateKey;
var Storage = require('./mocks/FakeStorage');
@@ -26,7 +24,7 @@ var startServer = copay.FakePayProServer; // TODO should be require('./mocks/Fak
var server;
-var config = {
+var walletConfig = {
requiredCopayers: 1,
totalCopayers: 1,
spendUnconfirmed: true,
@@ -36,861 +34,861 @@ var config = {
var getNewEpk = function() {
return new PrivateKey({
- networkName: config.networkName,
- })
- .deriveBIP45Branch()
- .extendedPublicKeyString();
+ networkName: walletConfig.networkName,
+ })
+ .deriveBIP45Branch()
+ .extendedPublicKeyString();
};
describe('PayPro (in Wallet) model', function() {
- var createW = function(N, conf) {
- var c = JSON.parse(JSON.stringify(conf || config));
- if (!N) N = c.totalCopayers;
+ if (!is_browser) {
+ var createW = function(N, conf) {
+ var c = JSON.parse(JSON.stringify(conf || walletConfig));
+ if (!N) N = c.totalCopayers;
- var mainPrivateKey = new copay.PrivateKey({
- networkName: config.networkName
- });
- var mainCopayerEPK = mainPrivateKey.deriveBIP45Branch().extendedPublicKeyString();
- c.privateKey = mainPrivateKey;
+ var mainPrivateKey = new copay.PrivateKey({
+ networkName: walletConfig.networkName
+ });
+ var mainCopayerEPK = mainPrivateKey.deriveBIP45Branch().extendedPublicKeyString();
+ c.privateKey = mainPrivateKey;
- c.publicKeyRing = new copay.PublicKeyRing({
- networkName: c.networkName,
- requiredCopayers: Math.min(N, c.requiredCopayers),
- totalCopayers: N,
- });
- c.publicKeyRing.addCopayer(mainCopayerEPK);
+ c.publicKeyRing = new copay.PublicKeyRing({
+ networkName: c.networkName,
+ requiredCopayers: Math.min(N, c.requiredCopayers),
+ totalCopayers: N,
+ });
+ c.publicKeyRing.addCopayer(mainCopayerEPK);
- c.txProposals = new copay.TxProposals({
- networkName: c.networkName,
- });
+ c.txProposals = new copay.TxProposals({
+ networkName: c.networkName,
+ });
- var storage = new Storage(config.storage);
- var network = new Network(config.network);
- var blockchain = new Blockchain(config.blockchain);
- c.storage = storage;
- c.network = network;
- c.blockchain = blockchain;
+ var storage = new Storage(walletConfig.storage);
+ var network = new Network(walletConfig.network);
+ var blockchain = new Blockchain(walletConfig.blockchain);
+ c.storage = storage;
+ c.network = network;
+ c.blockchain = blockchain;
- c.addressBook = {
- '2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': {
- label: 'John',
- copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03',
- createdTs: 1403102115,
- hidden: false
- },
- '2MtP8WyiwG7ZdVWM96CVsk2M1N8zyfiVQsY': {
- label: 'Jennifer',
- copayerId: '032991f836543a492bd6d0bb112552bfc7c5f3b7d5388fcbcbf2fbb893b44770d7',
- createdTs: 1403103115,
- hidden: false
- }
- };
-
- c.networkName = config.networkName;
- c.verbose = config.verbose;
- c.version = '0.0.1';
-
- return new Wallet(c);
- }
-
- var unspentTest = [{
- "address": "dummy",
- "scriptPubKey": "dummy",
- "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
- "vout": 1,
- "amount": 10,
- "confirmations": 7
- }];
-
- var createW2 = function(privateKeys, N, conf) {
- if (!N) N = 3;
- var w = createW(N, conf);
- should.exist(w);
-
- var pkr = w.publicKeyRing;
-
- for (var i = 0; i < N - 1; i++) {
- if (privateKeys) {
- var k = privateKeys[i];
- pkr.addCopayer(k ? k.deriveBIP45Branch().extendedPublicKeyString() : getNewEpk());
- } else {
- pkr.addCopayer(getNewEpk());
- }
- }
-
- return w;
- };
-
- var cachedW2 = null;
- var cachedW2obj = null;
- var cachedCreateW2 = function() {
- if (!cachedW2) {
- cachedW2 = createW2();
- cachedW2obj = cachedW2.toObj();
- cachedW2obj.opts.reconnectDelay = 100;
- }
- var w = Wallet.fromObj(cachedW2obj, cachedW2.storage, cachedW2.network, cachedW2.blockchain);
- return w;
- };
-
- var createWallet = function() {
- var w = cachedCreateW2();
- unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
- unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
- w.getUnspent = function(cb) {
- return setTimeout(function() {
- return cb(null, unspentTest, unspentTest);
- }, 1);
- };
- return w;
- };
-
- it('#start the example server', function(done) {
- startServer(function(err, s) {
- if (err) return done(err);
- server = s;
- server.uri = 'https://localhost:8080/-';
- done();
- });
- });
-
- var pr;
- var ppw;
-
- ppw = createWallet();
-
- it('#retrieve a payment request message via http', function(done) {
- var w = ppw;
- should.exist(w);
-
- var req = {
- headers: {
- 'Host': 'localhost:8080',
- 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
- + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
- 'Content-Type': 'application/octet-stream',
- 'Content-Length': '0'
- },
- socket: {
- remoteAddress: 'localhost',
- remotePort: 8080
- },
- body: {}
- };
-
- Object.keys(req.headers).forEach(function(key) {
- req.headers[key.toLowerCase()] = req.headers[key];
- });
-
- server.GET['/-/request'](req, function(err, res, body) {
- var data = PayPro.PaymentRequest.decode(body);
- pr = new PayPro();
- pr = pr.makePaymentRequest(data);
- done();
- });
- });
-
- it('#send a payment message via http', function(done) {
- var w = ppw;
- should.exist(w);
-
- var ver = pr.get('payment_details_version');
- var pki_type = pr.get('pki_type');
- var pki_data = pr.get('pki_data');
- var details = pr.get('serialized_payment_details');
- var sig = pr.get('signature');
-
- var certs = PayPro.X509Certificates.decode(pki_data);
- certs = certs.certificate;
-
- var verified = pr.verify();
-
- if (!verified) {
- return done(new Error('Server sent a bad signature.'));
- }
-
- details = PayPro.PaymentDetails.decode(details);
- var pd = new PayPro();
- pd = pd.makePaymentDetails(details);
-
- var network = pd.get('network');
- var outputs = pd.get('outputs');
- var time = pd.get('time');
- var expires = pd.get('expires');
- var memo = pd.get('memo');
- var payment_url = pd.get('payment_url');
- var merchant_data = pd.get('merchant_data');
-
- var priv = w.privateKey;
- var pkr = w.publicKeyRing;
-
- var opts = {
- remainderOut: {
- address: w._doGenerateAddress(true).toString()
- }
- };
-
- var outs = [];
- outputs.forEach(function(output) {
- var amount = output.get('amount');
- var script = {
- offset: output.get('script').offset,
- limit: output.get('script').limit,
- buffer: new Buffer(new Uint8Array(
- output.get('script').buffer))
+ c.addressBook = {
+ '2NFR2kzH9NUdp8vsXTB4wWQtTtzhpKxsyoJ': {
+ label: 'John',
+ copayerId: '026a55261b7c898fff760ebe14fd22a71892295f3b49e0ca66727bc0a0d7f94d03',
+ createdTs: 1403102115,
+ hidden: false
+ },
+ '2MtP8WyiwG7ZdVWM96CVsk2M1N8zyfiVQsY': {
+ label: 'Jennifer',
+ copayerId: '032991f836543a492bd6d0bb112552bfc7c5f3b7d5388fcbcbf2fbb893b44770d7',
+ createdTs: 1403103115,
+ hidden: false
+ }
};
- // big endian
- var v = new Buffer(8);
- v[0] = (amount.high >> 24) & 0xff;
- v[1] = (amount.high >> 16) & 0xff;
- v[2] = (amount.high >> 8) & 0xff;
- v[3] = (amount.high >> 0) & 0xff;
- v[4] = (amount.low >> 24) & 0xff;
- v[5] = (amount.low >> 16) & 0xff;
- v[6] = (amount.low >> 8) & 0xff;
- v[7] = (amount.low >> 0) & 0xff;
+ c.networkName = walletConfig.networkName;
+ c.verbose = walletConfig.verbose;
+ c.version = '0.0.1';
- var s = script.buffer.slice(script.offset, script.limit);
- var net = network === 'main' ? 'livenet' : 'testnet';
- var addr = bitcore.Address.fromScriptPubKey(new bitcore.Script(s), net);
+ return new Wallet(c);
+ }
- outs.push({
- address: addr[0].toString(),
- amountSatStr: bitcore.Bignum.fromBuffer(v, {
- // XXX for some reason, endian is ALWAYS 'big'
- // in node (in the browser it behaves correctly)
- endian: 'big',
- size: 1
- }).toString(10)
+ var unspentTest = [{
+ "address": "dummy",
+ "scriptPubKey": "dummy",
+ "txid": "2ac165fa7a3a2b535d106a0041c7568d03b531e58aeccdd3199d7289ab12cfc1",
+ "vout": 1,
+ "amount": 10,
+ "confirmations": 7
+ }];
+
+ var createW2 = function(privateKeys, N, conf) {
+ if (!N) N = 3;
+ var w = createW(N, conf);
+ should.exist(w);
+
+ var pkr = w.publicKeyRing;
+
+ for (var i = 0; i < N - 1; i++) {
+ if (privateKeys) {
+ var k = privateKeys[i];
+ pkr.addCopayer(k ? k.deriveBIP45Branch().extendedPublicKeyString() : getNewEpk());
+ } else {
+ pkr.addCopayer(getNewEpk());
+ }
+ }
+
+ return w;
+ };
+
+ var cachedW2 = null;
+ var cachedW2obj = null;
+ var cachedCreateW2 = function() {
+ if (!cachedW2) {
+ cachedW2 = createW2();
+ cachedW2obj = cachedW2.toObj();
+ cachedW2obj.opts.reconnectDelay = 100;
+ }
+ var w = Wallet.fromObj(cachedW2obj, cachedW2.storage, cachedW2.network, cachedW2.blockchain);
+ return w;
+ };
+
+ var createWallet = function() {
+ var w = cachedCreateW2();
+ unspentTest[0].address = w.publicKeyRing.getAddress(1, true, w.publicKey).toString();
+ unspentTest[0].scriptPubKey = w.publicKeyRing.getScriptPubKeyHex(1, true, w.publicKey);
+ w.getUnspent = function(cb) {
+ return setTimeout(function() {
+ return cb(null, unspentTest, unspentTest);
+ }, 1);
+ };
+ return w;
+ };
+
+ it('#start the example server', function(done) {
+ startServer(function(err, s) {
+ if (err) return done(err);
+ server = s;
+ server.uri = 'https://localhost:8080/-';
+ done();
});
});
- var b = new bitcore.TransactionBuilder(opts)
- .setUnspent(unspentTest)
- .setOutputs(outs);
+ var pr;
+ var ppw;
- outputs.forEach(function(output, i) {
- var script = {
- offset: output.get('script').offset,
- limit: output.get('script').limit,
- buffer: new Buffer(new Uint8Array(
- output.get('script').buffer))
- };
- var s = script.buffer.slice(script.offset, script.limit);
- b.tx.outs[i].s = s;
- });
+ ppw = createWallet();
- var selectedUtxos = b.getSelectedUnspent();
- var inputChainPaths = selectedUtxos.map(function(utxo) {
- return pkr.pathForAddress(utxo.address);
- });
+ it('#retrieve a payment request message via http', function(done) {
+ var w = ppw;
+ should.exist(w);
- b = b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
-
- if (priv) {
- var keys = priv.getForPaths(inputChainPaths);
- var signed = b.sign(keys);
- }
-
- var tx = b.build();
-
- var refund_outputs = [];
-
- var refund_to = w.publicKeyRing.getPubKeys(0, false, w.getMyCopayerId())[0];
-
- var total = outputs.reduce(function(total, _, i) {
- // XXX reverse endianness to work around bignum bug:
- var txv = tx.outs[i].v;
- var v = new Buffer(8);
- for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
- return total.add(bignum.fromBuffer(v, {
- endian: 'big',
- size: 1
- }));
- }, bitcore.Bignum('0', 10));
-
- var rpo = new PayPro();
- rpo = rpo.makeOutput();
-
- rpo.set('amount', +total.toString(10));
-
- rpo.set('script',
- Buffer.concat([
- new Buffer([
- 118, // OP_DUP
- 169, // OP_HASH160
- 76, // OP_PUSHDATA1
- 20, // number of bytes
- ]),
- // needs to be ripesha'd
- bitcore.util.sha256ripe160(refund_to),
- new Buffer([
- 136, // OP_EQUALVERIFY
- 172 // OP_CHECKSIG
- ])
- ])
- );
-
- refund_outputs.push(rpo.message);
-
- var pay = new PayPro();
- pay = pay.makePayment();
- pay.set('merchant_data', new Buffer([0, 1]));
- pay.set('transactions', [tx.serialize()]);
- pay.set('refund_to', refund_outputs);
- pay.set('memo', 'Hi server, I would like to give you some money.');
-
- pay = pay.serialize();
-
- var req = {
- headers: {
- 'Host': 'localhost:8080',
- 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
- + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
- 'Content-Type': PayPro.PAYMENT_CONTENT_TYPE,
- 'Content-Length': pay.length + ''
- },
- socket: {
- remoteAddress: 'localhost',
- remotePort: 8080
- },
- body: pay,
- data: pay
- };
-
- Object.keys(req.headers).forEach(function(key) {
- req.headers[key.toLowerCase()] = req.headers[key];
- });
-
- server.POST['/-/pay'](req, function(err, res, body) {
- if (err) return done(err);
-
- var data = PayPro.PaymentACK.decode(body);
- var ack = new PayPro();
- ack = ack.makePaymentACK(data);
-
- var payment = ack.get('payment');
- var memo = ack.get('memo');
-
- payment = PayPro.Payment.decode(payment);
- var pay = new PayPro();
- payment = pay.makePayment(payment);
-
- var tx = payment.message.transactions[0];
-
- if (!tx) {
- return done(new Error('No tx in payment ACK.'));
- }
-
- if (tx.buffer) {
- tx.buffer = new Buffer(new Uint8Array(tx.buffer));
- tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
- var ptx = new bitcore.Transaction();
- ptx.parse(tx.buffer);
- tx = ptx;
- }
-
- var ackTotal = outputs.reduce(function(total, _, i) {
- // XXX reverse endianness to work around bignum bug:
- var txv = tx.outs[i].v;
- var v = new Buffer(8);
- for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
- return total.add(bignum.fromBuffer(v, {
- endian: 'big',
- size: 1
- }));
- }, bitcore.Bignum('0', 10));
-
- ackTotal.toString(10).should.equal(total.toString(10));
-
- done();
- });
- });
-
- it('#retrieve a payment request message via http', function(done) {
- var w = ppw;
- should.exist(w);
-
- var req = {
- headers: {
- 'Host': 'localhost:8080',
- 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
- + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
- 'Content-Type': 'application/octet-stream',
- 'Content-Length': '0'
- },
- socket: {
- remoteAddress: 'localhost',
- remotePort: 8080
- },
- body: {}
- };
-
- Object.keys(req.headers).forEach(function(key) {
- req.headers[key.toLowerCase()] = req.headers[key];
- });
-
- server.GET['/-/request'](req, function(err, res, body) {
- var data = PayPro.PaymentRequest.decode(body);
- pr = new PayPro();
- pr = pr.makePaymentRequest(data);
- done();
- });
- });
-
- it('#send a payment message via http', function(done) {
- var w = ppw;
- should.exist(w);
-
- var ver = pr.get('payment_details_version');
- var pki_type = pr.get('pki_type');
- var pki_data = pr.get('pki_data');
- var details = pr.get('serialized_payment_details');
- var sig = pr.get('signature');
-
- var certs = PayPro.X509Certificates.decode(pki_data);
- certs = certs.certificate;
-
- var verified = pr.verify();
-
- if (!verified) {
- return done(new Error('Server sent a bad signature.'));
- }
-
- details = PayPro.PaymentDetails.decode(details);
- var pd = new PayPro();
- pd = pd.makePaymentDetails(details);
-
- var network = pd.get('network');
- var outputs = pd.get('outputs');
- var time = pd.get('time');
- var expires = pd.get('expires');
- var memo = pd.get('memo');
- var payment_url = pd.get('payment_url');
- var merchant_data = pd.get('merchant_data');
-
- var priv = w.privateKey;
- var pkr = w.publicKeyRing;
-
- var opts = {
- remainderOut: {
- address: w._doGenerateAddress(true).toString()
- }
- };
-
- var outs = [];
- outputs.forEach(function(output) {
- var amount = output.get('amount');
- var script = {
- offset: output.get('script').offset,
- limit: output.get('script').limit,
- buffer: new Buffer(new Uint8Array(
- output.get('script').buffer))
+ var req = {
+ headers: {
+ 'Host': 'localhost:8080',
+ 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
+ 'Content-Type': 'application/octet-stream',
+ 'Content-Length': '0'
+ },
+ socket: {
+ remoteAddress: 'localhost',
+ remotePort: 8080
+ },
+ body: {}
};
- // big endian
- var v = new Buffer(8);
- v[0] = (amount.high >> 24) & 0xff;
- v[1] = (amount.high >> 16) & 0xff;
- v[2] = (amount.high >> 8) & 0xff;
- v[3] = (amount.high >> 0) & 0xff;
- v[4] = (amount.low >> 24) & 0xff;
- v[5] = (amount.low >> 16) & 0xff;
- v[6] = (amount.low >> 8) & 0xff;
- v[7] = (amount.low >> 0) & 0xff;
+ Object.keys(req.headers).forEach(function(key) {
+ req.headers[key.toLowerCase()] = req.headers[key];
+ });
- var s = script.buffer.slice(script.offset, script.limit);
- var net = network === 'main' ? 'livenet' : 'testnet';
- var addr = bitcore.Address.fromScriptPubKey(new bitcore.Script(s), net);
-
- outs.push({
- address: addr[0].toString(),
- amountSatStr: bitcore.Bignum.fromBuffer(v, {
- // XXX for some reason, endian is ALWAYS 'big'
- // in node (in the browser it behaves correctly)
- endian: 'big',
- size: 1
- }).toString(10)
+ server.GET['/-/request'](req, function(err, res, body) {
+ var data = PayPro.PaymentRequest.decode(body);
+ pr = new PayPro();
+ pr = pr.makePaymentRequest(data);
+ done();
});
});
- var b = new bitcore.TransactionBuilder(opts)
- .setUnspent(unspentTest)
- .setOutputs(outs);
+ it('#send a payment message via http', function(done) {
+ var w = ppw;
+ should.exist(w);
- outputs.forEach(function(output, i) {
- var script = {
- offset: output.get('script').offset,
- limit: output.get('script').limit,
- buffer: new Buffer(new Uint8Array(
- output.get('script').buffer))
- };
- var s = script.buffer.slice(script.offset, script.limit);
- b.tx.outs[i].s = s;
- });
-
- var selectedUtxos = b.getSelectedUnspent();
- var inputChainPaths = selectedUtxos.map(function(utxo) {
- return pkr.pathForAddress(utxo.address);
- });
-
- b = b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
-
- if (priv) {
- var keys = priv.getForPaths(inputChainPaths);
- var signed = b.sign(keys);
- }
-
- var tx = b.build();
-
- var refund_outputs = [];
-
- var refund_to = w.publicKeyRing.getPubKeys(0, false, w.getMyCopayerId())[0];
-
- var total = outputs.reduce(function(total, _, i) {
- // XXX reverse endianness to work around bignum bug:
- var txv = tx.outs[i].v;
- var v = new Buffer(8);
- for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
- return total.add(bignum.fromBuffer(v, {
- endian: 'big',
- size: 1
- }));
- }, bitcore.Bignum('0', 10));
-
- var rpo = new PayPro();
- rpo = rpo.makeOutput();
-
- rpo.set('amount', +total.toString(10));
-
- rpo.set('script',
- Buffer.concat([
- new Buffer([
- 118, // OP_DUP
- 169, // OP_HASH160
- 76, // OP_PUSHDATA1
- 20, // number of bytes
- ]),
- // needs to be ripesha'd
- bitcore.util.sha256ripe160(refund_to),
- new Buffer([
- 136, // OP_EQUALVERIFY
- 172 // OP_CHECKSIG
- ])
- ])
- );
-
- refund_outputs.push(rpo.message);
-
- var pay = new PayPro();
- pay = pay.makePayment();
- pay.set('merchant_data', new Buffer([0, 1]));
- pay.set('transactions', [tx.serialize()]);
- pay.set('refund_to', refund_outputs);
- pay.set('memo', 'Hi server, I would like to give you some money.');
-
- pay = pay.serialize();
-
- var req = {
- headers: {
- 'Host': 'localhost:8080',
- 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
- + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
- 'Content-Type': PayPro.PAYMENT_CONTENT_TYPE,
- 'Content-Length': pay.length + ''
- },
- socket: {
- remoteAddress: 'localhost',
- remotePort: 8080
- },
- body: pay,
- data: pay
- };
-
- Object.keys(req.headers).forEach(function(key) {
- req.headers[key.toLowerCase()] = req.headers[key];
- });
-
- server.POST['/-/pay'](req, function(err, res, body) {
- if (err) return done(err);
-
- var data = PayPro.PaymentACK.decode(body);
- var ack = new PayPro();
- ack = ack.makePaymentACK(data);
-
- var payment = ack.get('payment');
- var memo = ack.get('memo');
-
- payment = PayPro.Payment.decode(payment);
- var pay = new PayPro();
- payment = pay.makePayment(payment);
-
- var tx = payment.message.transactions[0];
-
- if (!tx) {
- return done(new Error('No tx in payment ACK.'));
- }
-
- if (tx.buffer) {
- tx.buffer = new Buffer(new Uint8Array(tx.buffer));
- tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
- var ptx = new bitcore.Transaction();
- ptx.parse(tx.buffer);
- tx = ptx;
- }
-
- var ackTotal = outputs.reduce(function(total, _, i) {
- // XXX reverse endianness to work around bignum bug:
- var txv = tx.outs[i].v;
- var v = new Buffer(8);
- for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
- return total.add(bignum.fromBuffer(v, {
- endian: 'big',
- size: 1
- }));
- }, bitcore.Bignum('0', 10));
-
- ackTotal.toString(10).should.equal(total.toString(10));
-
- should.exist(ack);
- memo.should.equal('Thank you for your payment!');
-
- done();
- });
- });
-
- ppw = createWallet();
-
- it('#retrieve a payment request message via model', function(done) {
- var w = ppw;
- should.exist(w);
- // Caches Payment Request but does not add TX proposal
- w.fetchPaymentTx({
- uri: 'https://localhost:8080/-/request'
- }, function(err, merchantData) {
- if (err) return done(err);
- merchantData.pr.pd.payment_url.should.equal('https://localhost:8080/-/pay');
- return done();
- });
- });
-
- it('#add tx proposal based on payment message via model', function(done) {
- var w = ppw;
- should.exist(w);
- var options = {
- uri: 'https://localhost:8080/-/request'
- };
- var req = w.paymentRequests[options.uri];
- should.exist(req);
- delete w.paymentRequests[options.uri];
- w.receivePaymentRequest(options, req.pr, function(ntxid, merchantData) {
- should.exist(ntxid);
- should.exist(merchantData);
- w._ntxid = ntxid;
- merchantData.pr.pd.payment_url.should.equal('https://localhost:8080/-/pay');
- return done();
- });
- });
-
- it('#add tx proposal based on payment message via model', function(done) {
- var w = ppw;
- should.exist(w);
- w.sendPaymentTx(w._ntxid, function(txid, merchantData) {
- should.exist(txid);
- should.exist(merchantData);
- should.exist(merchantData.ack);
- merchantData.ack.memo.should.equal('Thank you for your payment!');
- return done();
- });
- });
-
- it('#send a payment request using payment api', function(done) {
- var w = createWallet();
- should.exist(w);
- var uri = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
- var memo = 'Hello, server. I\'d like to make a payment.';
- w.createPaymentTx({
- uri: uri,
- memo: memo
- }, function(ntxid, merchantData) {
- should.exist(ntxid);
- should.exist(merchantData);
- if (w.isShared()) {
- return done();
- } else {
- w.sendPaymentTx(ntxid, { memo: memo }, function(txid, merchantData) {
- should.exist(txid);
- should.exist(merchantData);
- return done();
- });
- }
- });
- });
-
- it('#send a payment request with merchant prefix', function(done) {
- var w = createWallet();
- should.exist(w);
- var address = 'Merchant: ' + server.uri + '/request\nMemo: foo';
- var commentText = 'Hello, server. I\'d like to make a payment.';
- var uri;
-
- // Replicates code in controllers/send.js:
- if (address.indexOf('bitcoin:') === 0) {
- uri = new bitcore.BIP21(address).data;
- } else if (address.indexOf('Merchant: ') === 0) {
- uri = address.split(/\s+/)[1];
- }
-
- w.createTx(uri, commentText, function(ntxid, merchantData) {
- if (w.isShared()) {
- should.exist(ntxid);
- should.exist(merchantData);
- return done();
- } else {
- should.exist(merchantData);
- w.sendTx(ntxid, function(txid, merchantData) {
- should.exist(txid);
- should.exist(merchantData);
- return done();
- });
- }
- });
- });
-
- it('#send a payment request with bitcoin uri', function(done) {
- var w = createWallet();
- should.exist(w);
- var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
- var commentText = 'Hello, server. I\'d like to make a payment.';
- w.createTx(address, commentText, function(ntxid, merchantData) {
- if (w.isShared()) {
- should.exist(ntxid);
- should.exist(merchantData);
- return done();
- } else {
- w.sendTx(ntxid, function(txid, merchantData) {
- should.exist(txid);
- should.exist(merchantData);
- return done();
- });
- }
- });
- });
-
- it('#try to sign a tampered payment request (raw)', function(done) {
- var w = createWallet();
- should.exist(w);
- var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
- var commentText = 'Hello, server. I\'d like to make a payment.';
- w.createTx(address, commentText, function(ntxid, merchantData) {
- should.exist(ntxid);
- should.exist(merchantData);
-
- // Tamper with payment request in its raw form:
- var data = new Buffer(merchantData.raw, 'hex');
- data = PayPro.PaymentRequest.decode(data);
- var pr = new PayPro();
- pr = pr.makePaymentRequest(data);
+ var ver = pr.get('payment_details_version');
+ var pki_type = pr.get('pki_type');
+ var pki_data = pr.get('pki_data');
var details = pr.get('serialized_payment_details');
+ var sig = pr.get('signature');
+
+ var certs = PayPro.X509Certificates.decode(pki_data);
+ certs = certs.certificate;
+
+ var verified = pr.verify();
+
+ if (!verified) {
+ return done(new Error('Server sent a bad signature.'));
+ }
+
details = PayPro.PaymentDetails.decode(details);
var pd = new PayPro();
pd = pd.makePaymentDetails(details);
+
+ var network = pd.get('network');
var outputs = pd.get('outputs');
- outputs[outputs.length - 1].set('amount', 1000000000);
- pd.set('outputs', outputs);
- pr.set('serialized_payment_details', pd.serialize());
- merchantData.raw = pr.serialize().toString('hex');
+ var time = pd.get('time');
+ var expires = pd.get('expires');
+ var memo = pd.get('memo');
+ var payment_url = pd.get('payment_url');
+ var merchant_data = pd.get('merchant_data');
- var myId = w.getMyCopayerId();
- var txp = w.txProposals.get(ntxid);
- should.exist(txp);
- should.exist(txp.signedBy[myId]);
- should.not.exist(txp.rejectedBy[myId]);
+ var priv = w.privateKey;
+ var pkr = w.publicKeyRing;
- w.verifyPaymentRequest(ntxid).should.equal(false);
+ var opts = {
+ remainderOut: {
+ address: w._doGenerateAddress(true).toString()
+ }
+ };
- return done();
+ var outs = [];
+ outputs.forEach(function(output) {
+ var amount = output.get('amount');
+ var script = {
+ offset: output.get('script').offset,
+ limit: output.get('script').limit,
+ buffer: new Buffer(new Uint8Array(
+ output.get('script').buffer))
+ };
+
+ // big endian
+ var v = new Buffer(8);
+ v[0] = (amount.high >> 24) & 0xff;
+ v[1] = (amount.high >> 16) & 0xff;
+ v[2] = (amount.high >> 8) & 0xff;
+ v[3] = (amount.high >> 0) & 0xff;
+ v[4] = (amount.low >> 24) & 0xff;
+ v[5] = (amount.low >> 16) & 0xff;
+ v[6] = (amount.low >> 8) & 0xff;
+ v[7] = (amount.low >> 0) & 0xff;
+
+ var s = script.buffer.slice(script.offset, script.limit);
+ var net = network === 'main' ? 'livenet' : 'testnet';
+ var addr = bitcore.Address.fromScriptPubKey(new bitcore.Script(s), net);
+
+ outs.push({
+ address: addr[0].toString(),
+ amountSatStr: bitcore.Bignum.fromBuffer(v, {
+ // XXX for some reason, endian is ALWAYS 'big'
+ // in node (in the browser it behaves correctly)
+ endian: 'big',
+ size: 1
+ }).toString(10)
+ });
+ });
+
+ var b = new bitcore.TransactionBuilder(opts)
+ .setUnspent(unspentTest)
+ .setOutputs(outs);
+
+ outputs.forEach(function(output, i) {
+ var script = {
+ offset: output.get('script').offset,
+ limit: output.get('script').limit,
+ buffer: new Buffer(new Uint8Array(
+ output.get('script').buffer))
+ };
+ var s = script.buffer.slice(script.offset, script.limit);
+ b.tx.outs[i].s = s;
+ });
+
+ var selectedUtxos = b.getSelectedUnspent();
+ var inputChainPaths = selectedUtxos.map(function(utxo) {
+ return pkr.pathForAddress(utxo.address);
+ });
+
+ b = b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
+
+ if (priv) {
+ var keys = priv.getForPaths(inputChainPaths);
+ var signed = b.sign(keys);
+ }
+
+ var tx = b.build();
+
+ var refund_outputs = [];
+
+ var refund_to = w.publicKeyRing.getPubKeys(0, false, w.getMyCopayerId())[0];
+
+ var total = outputs.reduce(function(total, _, i) {
+ // XXX reverse endianness to work around bignum bug:
+ var txv = tx.outs[i].v;
+ var v = new Buffer(8);
+ for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
+ return total.add(bignum.fromBuffer(v, {
+ endian: 'big',
+ size: 1
+ }));
+ }, bitcore.Bignum('0', 10));
+
+ var rpo = new PayPro();
+ rpo = rpo.makeOutput();
+
+ rpo.set('amount', +total.toString(10));
+
+ rpo.set('script',
+ Buffer.concat([
+ new Buffer([
+ 118, // OP_DUP
+ 169, // OP_HASH160
+ 76, // OP_PUSHDATA1
+ 20, // number of bytes
+ ]),
+ // needs to be ripesha'd
+ bitcore.util.sha256ripe160(refund_to),
+ new Buffer([
+ 136, // OP_EQUALVERIFY
+ 172 // OP_CHECKSIG
+ ])
+ ])
+ );
+
+ refund_outputs.push(rpo.message);
+
+ var pay = new PayPro();
+ pay = pay.makePayment();
+ pay.set('merchant_data', new Buffer([0, 1]));
+ pay.set('transactions', [tx.serialize()]);
+ pay.set('refund_to', refund_outputs);
+ pay.set('memo', 'Hi server, I would like to give you some money.');
+
+ pay = pay.serialize();
+
+ var req = {
+ headers: {
+ 'Host': 'localhost:8080',
+ 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
+ 'Content-Type': PayPro.PAYMENT_CONTENT_TYPE,
+ 'Content-Length': pay.length + ''
+ },
+ socket: {
+ remoteAddress: 'localhost',
+ remotePort: 8080
+ },
+ body: pay,
+ data: pay
+ };
+
+ Object.keys(req.headers).forEach(function(key) {
+ req.headers[key.toLowerCase()] = req.headers[key];
+ });
+
+ server.POST['/-/pay'](req, function(err, res, body) {
+ if (err) return done(err);
+
+ var data = PayPro.PaymentACK.decode(body);
+ var ack = new PayPro();
+ ack = ack.makePaymentACK(data);
+
+ var payment = ack.get('payment');
+ var memo = ack.get('memo');
+
+ payment = PayPro.Payment.decode(payment);
+ var pay = new PayPro();
+ payment = pay.makePayment(payment);
+
+ var tx = payment.message.transactions[0];
+
+ if (!tx) {
+ return done(new Error('No tx in payment ACK.'));
+ }
+
+ if (tx.buffer) {
+ tx.buffer = new Buffer(new Uint8Array(tx.buffer));
+ tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
+ var ptx = new bitcore.Transaction();
+ ptx.parse(tx.buffer);
+ tx = ptx;
+ }
+
+ var ackTotal = outputs.reduce(function(total, _, i) {
+ // XXX reverse endianness to work around bignum bug:
+ var txv = tx.outs[i].v;
+ var v = new Buffer(8);
+ for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
+ return total.add(bignum.fromBuffer(v, {
+ endian: 'big',
+ size: 1
+ }));
+ }, bitcore.Bignum('0', 10));
+
+ ackTotal.toString(10).should.equal(total.toString(10));
+
+ done();
+ });
});
- });
- it('#try to sign a tampered payment request (abstract)', function(done) {
- var w = createWallet();
- should.exist(w);
- var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
- var commentText = 'Hello, server. I\'d like to make a payment.';
- w.createTx(address, commentText, function(ntxid, merchantData) {
- should.exist(ntxid);
- should.exist(merchantData);
+ it('#retrieve a payment request message via http', function(done) {
+ var w = ppw;
+ should.exist(w);
- // Tamper with payment request in its abstract form:
- var outputs = merchantData.pr.pd.outputs;
- var output = outputs[outputs.length - 1];
- var amount = output.amount;
- amount.low = 2;
+ var req = {
+ headers: {
+ 'Host': 'localhost:8080',
+ 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
+ 'Content-Type': 'application/octet-stream',
+ 'Content-Length': '0'
+ },
+ socket: {
+ remoteAddress: 'localhost',
+ remotePort: 8080
+ },
+ body: {}
+ };
- var myId = w.getMyCopayerId();
- var txp = w.txProposals.get(ntxid);
- should.exist(txp);
- should.exist(txp.signedBy[myId]);
- should.not.exist(txp.rejectedBy[myId]);
+ Object.keys(req.headers).forEach(function(key) {
+ req.headers[key.toLowerCase()] = req.headers[key];
+ });
- w.verifyPaymentRequest(ntxid).should.equal(false);
-
- return done();
+ server.GET['/-/request'](req, function(err, res, body) {
+ var data = PayPro.PaymentRequest.decode(body);
+ pr = new PayPro();
+ pr = pr.makePaymentRequest(data);
+ done();
+ });
});
- });
- it('#try to sign a tampered txp tx (abstract)', function(done) {
- var w = createWallet();
- should.exist(w);
- var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
- var commentText = 'Hello, server. I\'d like to make a payment.';
- w.createTx(address, commentText, function(ntxid, merchantData) {
- should.exist(ntxid);
- should.exist(merchantData);
+ it('#send a payment message via http', function(done) {
+ var w = ppw;
+ should.exist(w);
- // Tamper with payment request in its abstract form:
- var txp = w.txProposals.get(ntxid);
- var tx = txp.builder.tx || txp.builder.build();
- tx.outs[0].v = new Buffer([2, 0, 0, 0, 0, 0, 0, 0]);
+ var ver = pr.get('payment_details_version');
+ var pki_type = pr.get('pki_type');
+ var pki_data = pr.get('pki_data');
+ var details = pr.get('serialized_payment_details');
+ var sig = pr.get('signature');
- var myId = w.getMyCopayerId();
- var txp = w.txProposals.get(ntxid);
- should.exist(txp);
- should.exist(txp.signedBy[myId]);
- should.not.exist(txp.rejectedBy[myId]);
+ var certs = PayPro.X509Certificates.decode(pki_data);
+ certs = certs.certificate;
- w.verifyPaymentRequest(ntxid).should.equal(false);
+ var verified = pr.verify();
- return done();
+ if (!verified) {
+ return done(new Error('Server sent a bad signature.'));
+ }
+
+ details = PayPro.PaymentDetails.decode(details);
+ var pd = new PayPro();
+ pd = pd.makePaymentDetails(details);
+
+ var network = pd.get('network');
+ var outputs = pd.get('outputs');
+ var time = pd.get('time');
+ var expires = pd.get('expires');
+ var memo = pd.get('memo');
+ var payment_url = pd.get('payment_url');
+ var merchant_data = pd.get('merchant_data');
+
+ var priv = w.privateKey;
+ var pkr = w.publicKeyRing;
+
+ var opts = {
+ remainderOut: {
+ address: w._doGenerateAddress(true).toString()
+ }
+ };
+
+ var outs = [];
+ outputs.forEach(function(output) {
+ var amount = output.get('amount');
+ var script = {
+ offset: output.get('script').offset,
+ limit: output.get('script').limit,
+ buffer: new Buffer(new Uint8Array(
+ output.get('script').buffer))
+ };
+
+ // big endian
+ var v = new Buffer(8);
+ v[0] = (amount.high >> 24) & 0xff;
+ v[1] = (amount.high >> 16) & 0xff;
+ v[2] = (amount.high >> 8) & 0xff;
+ v[3] = (amount.high >> 0) & 0xff;
+ v[4] = (amount.low >> 24) & 0xff;
+ v[5] = (amount.low >> 16) & 0xff;
+ v[6] = (amount.low >> 8) & 0xff;
+ v[7] = (amount.low >> 0) & 0xff;
+
+ var s = script.buffer.slice(script.offset, script.limit);
+ var net = network === 'main' ? 'livenet' : 'testnet';
+ var addr = bitcore.Address.fromScriptPubKey(new bitcore.Script(s), net);
+
+ outs.push({
+ address: addr[0].toString(),
+ amountSatStr: bitcore.Bignum.fromBuffer(v, {
+ // XXX for some reason, endian is ALWAYS 'big'
+ // in node (in the browser it behaves correctly)
+ endian: 'big',
+ size: 1
+ }).toString(10)
+ });
+ });
+
+ var b = new bitcore.TransactionBuilder(opts)
+ .setUnspent(unspentTest)
+ .setOutputs(outs);
+
+ outputs.forEach(function(output, i) {
+ var script = {
+ offset: output.get('script').offset,
+ limit: output.get('script').limit,
+ buffer: new Buffer(new Uint8Array(
+ output.get('script').buffer))
+ };
+ var s = script.buffer.slice(script.offset, script.limit);
+ b.tx.outs[i].s = s;
+ });
+
+ var selectedUtxos = b.getSelectedUnspent();
+ var inputChainPaths = selectedUtxos.map(function(utxo) {
+ return pkr.pathForAddress(utxo.address);
+ });
+
+ b = b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
+
+ if (priv) {
+ var keys = priv.getForPaths(inputChainPaths);
+ var signed = b.sign(keys);
+ }
+
+ var tx = b.build();
+
+ var refund_outputs = [];
+
+ var refund_to = w.publicKeyRing.getPubKeys(0, false, w.getMyCopayerId())[0];
+
+ var total = outputs.reduce(function(total, _, i) {
+ // XXX reverse endianness to work around bignum bug:
+ var txv = tx.outs[i].v;
+ var v = new Buffer(8);
+ for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
+ return total.add(bignum.fromBuffer(v, {
+ endian: 'big',
+ size: 1
+ }));
+ }, bitcore.Bignum('0', 10));
+
+ var rpo = new PayPro();
+ rpo = rpo.makeOutput();
+
+ rpo.set('amount', +total.toString(10));
+
+ rpo.set('script',
+ Buffer.concat([
+ new Buffer([
+ 118, // OP_DUP
+ 169, // OP_HASH160
+ 76, // OP_PUSHDATA1
+ 20, // number of bytes
+ ]),
+ // needs to be ripesha'd
+ bitcore.util.sha256ripe160(refund_to),
+ new Buffer([
+ 136, // OP_EQUALVERIFY
+ 172 // OP_CHECKSIG
+ ])
+ ])
+ );
+
+ refund_outputs.push(rpo.message);
+
+ var pay = new PayPro();
+ pay = pay.makePayment();
+ pay.set('merchant_data', new Buffer([0, 1]));
+ pay.set('transactions', [tx.serialize()]);
+ pay.set('refund_to', refund_outputs);
+ pay.set('memo', 'Hi server, I would like to give you some money.');
+
+ pay = pay.serialize();
+
+ var req = {
+ headers: {
+ 'Host': 'localhost:8080',
+ 'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE + ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
+ 'Content-Type': PayPro.PAYMENT_CONTENT_TYPE,
+ 'Content-Length': pay.length + ''
+ },
+ socket: {
+ remoteAddress: 'localhost',
+ remotePort: 8080
+ },
+ body: pay,
+ data: pay
+ };
+
+ Object.keys(req.headers).forEach(function(key) {
+ req.headers[key.toLowerCase()] = req.headers[key];
+ });
+
+ server.POST['/-/pay'](req, function(err, res, body) {
+ if (err) return done(err);
+
+ var data = PayPro.PaymentACK.decode(body);
+ var ack = new PayPro();
+ ack = ack.makePaymentACK(data);
+
+ var payment = ack.get('payment');
+ var memo = ack.get('memo');
+
+ payment = PayPro.Payment.decode(payment);
+ var pay = new PayPro();
+ payment = pay.makePayment(payment);
+
+ var tx = payment.message.transactions[0];
+
+ if (!tx) {
+ return done(new Error('No tx in payment ACK.'));
+ }
+
+ if (tx.buffer) {
+ tx.buffer = new Buffer(new Uint8Array(tx.buffer));
+ tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
+ var ptx = new bitcore.Transaction();
+ ptx.parse(tx.buffer);
+ tx = ptx;
+ }
+
+ var ackTotal = outputs.reduce(function(total, _, i) {
+ // XXX reverse endianness to work around bignum bug:
+ var txv = tx.outs[i].v;
+ var v = new Buffer(8);
+ for (var j = 0; j < 8; j++) v[j] = txv[7 - j];
+ return total.add(bignum.fromBuffer(v, {
+ endian: 'big',
+ size: 1
+ }));
+ }, bitcore.Bignum('0', 10));
+
+ ackTotal.toString(10).should.equal(total.toString(10));
+
+ should.exist(ack);
+ memo.should.equal('Thank you for your payment!');
+
+ done();
+ });
});
- });
- it('#sign an untampered payment request', function(done) {
- var w = createWallet();
- should.exist(w);
- var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
- var commentText = 'Hello, server. I\'d like to make a payment.';
- w.createTx(address, commentText, function(ntxid, merchantData) {
- should.exist(ntxid);
- should.exist(merchantData);
+ ppw = createWallet();
- var myId = w.getMyCopayerId();
- var txp = w.txProposals.get(ntxid);
- should.exist(txp);
- should.exist(txp.signedBy[myId]);
- should.not.exist(txp.rejectedBy[myId]);
-
- w.verifyPaymentRequest(ntxid).should.equal(true);
-
- return done();
+ it('#retrieve a payment request message via model', function(done) {
+ var w = ppw;
+ should.exist(w);
+ // Caches Payment Request but does not add TX proposal
+ w.fetchPaymentTx({
+ uri: 'https://localhost:8080/-/request'
+ }, function(err, merchantData) {
+ if (err) return done(err);
+ merchantData.pr.pd.payment_url.should.equal('https://localhost:8080/-/pay');
+ return done();
+ });
});
- });
- it('#close payment server', function(done) {
- server.close(function() {
- return done();
+ it('#add tx proposal based on payment message via model', function(done) {
+ var w = ppw;
+ should.exist(w);
+ var options = {
+ uri: 'https://localhost:8080/-/request'
+ };
+ var req = w.paymentRequests[options.uri];
+ should.exist(req);
+ delete w.paymentRequests[options.uri];
+ w.receivePaymentRequest(options, req.pr, function(ntxid, merchantData) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+ w._ntxid = ntxid;
+ merchantData.pr.pd.payment_url.should.equal('https://localhost:8080/-/pay');
+ return done();
+ });
});
- });
+
+ it('#add tx proposal based on payment message via model', function(done) {
+ var w = ppw;
+ should.exist(w);
+ w.sendPaymentTx(w._ntxid, function(txid, merchantData) {
+ should.exist(txid);
+ should.exist(merchantData);
+ should.exist(merchantData.ack);
+ merchantData.ack.memo.should.equal('Thank you for your payment!');
+ return done();
+ });
+ });
+
+ it('#send a payment request using payment api', function(done) {
+ var w = createWallet();
+ should.exist(w);
+ var uri = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
+ var memo = 'Hello, server. I\'d like to make a payment.';
+ w.createPaymentTx({
+ uri: uri,
+ memo: memo
+ }, function(ntxid, merchantData) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+ if (w.isShared()) {
+ return done();
+ } else {
+ w.sendPaymentTx(ntxid, {
+ memo: memo
+ }, function(txid, merchantData) {
+ should.exist(txid);
+ should.exist(merchantData);
+ return done();
+ });
+ }
+ });
+ });
+
+ it('#send a payment request with merchant prefix', function(done) {
+ var w = createWallet();
+ should.exist(w);
+ var address = 'Merchant: ' + server.uri + '/request\nMemo: foo';
+ var commentText = 'Hello, server. I\'d like to make a payment.';
+ var uri;
+
+ // Replicates code in controllers/send.js:
+ if (address.indexOf('bitcoin:') === 0) {
+ uri = new bitcore.BIP21(address).data;
+ } else if (address.indexOf('Merchant: ') === 0) {
+ uri = address.split(/\s+/)[1];
+ }
+
+ w.createTx(uri, commentText, function(ntxid, merchantData) {
+ if (w.isShared()) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+ return done();
+ } else {
+ should.exist(merchantData);
+ w.sendTx(ntxid, function(txid, merchantData) {
+ should.exist(txid);
+ should.exist(merchantData);
+ return done();
+ });
+ }
+ });
+ });
+
+ it('#send a payment request with bitcoin uri', function(done) {
+ var w = createWallet();
+ should.exist(w);
+ var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
+ var commentText = 'Hello, server. I\'d like to make a payment.';
+ w.createTx(address, commentText, function(ntxid, merchantData) {
+ if (w.isShared()) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+ return done();
+ } else {
+ w.sendTx(ntxid, function(txid, merchantData) {
+ should.exist(txid);
+ should.exist(merchantData);
+ return done();
+ });
+ }
+ });
+ });
+
+ it('#try to sign a tampered payment request (raw)', function(done) {
+ var w = createWallet();
+ should.exist(w);
+ var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
+ var commentText = 'Hello, server. I\'d like to make a payment.';
+ w.createTx(address, commentText, function(ntxid, merchantData) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+
+ // Tamper with payment request in its raw form:
+ var data = new Buffer(merchantData.raw, 'hex');
+ data = PayPro.PaymentRequest.decode(data);
+ var pr = new PayPro();
+ pr = pr.makePaymentRequest(data);
+ var details = pr.get('serialized_payment_details');
+ details = PayPro.PaymentDetails.decode(details);
+ var pd = new PayPro();
+ pd = pd.makePaymentDetails(details);
+ var outputs = pd.get('outputs');
+ outputs[outputs.length - 1].set('amount', 1000000000);
+ pd.set('outputs', outputs);
+ pr.set('serialized_payment_details', pd.serialize());
+ merchantData.raw = pr.serialize().toString('hex');
+
+ var myId = w.getMyCopayerId();
+ var txp = w.txProposals.get(ntxid);
+ should.exist(txp);
+ should.exist(txp.signedBy[myId]);
+ should.not.exist(txp.rejectedBy[myId]);
+
+ w.verifyPaymentRequest(ntxid).should.equal(false);
+
+ return done();
+ });
+ });
+
+ it('#try to sign a tampered payment request (abstract)', function(done) {
+ var w = createWallet();
+ should.exist(w);
+ var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
+ var commentText = 'Hello, server. I\'d like to make a payment.';
+ w.createTx(address, commentText, function(ntxid, merchantData) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+
+ // Tamper with payment request in its abstract form:
+ var outputs = merchantData.pr.pd.outputs;
+ var output = outputs[outputs.length - 1];
+ var amount = output.amount;
+ amount.low = 2;
+
+ var myId = w.getMyCopayerId();
+ var txp = w.txProposals.get(ntxid);
+ should.exist(txp);
+ should.exist(txp.signedBy[myId]);
+ should.not.exist(txp.rejectedBy[myId]);
+
+ w.verifyPaymentRequest(ntxid).should.equal(false);
+
+ return done();
+ });
+ });
+
+ it('#try to sign a tampered txp tx (abstract)', function(done) {
+ var w = createWallet();
+ should.exist(w);
+ var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
+ var commentText = 'Hello, server. I\'d like to make a payment.';
+ w.createTx(address, commentText, function(ntxid, merchantData) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+
+ // Tamper with payment request in its abstract form:
+ var txp = w.txProposals.get(ntxid);
+ var tx = txp.builder.tx || txp.builder.build();
+ tx.outs[0].v = new Buffer([2, 0, 0, 0, 0, 0, 0, 0]);
+
+ var myId = w.getMyCopayerId();
+ var txp = w.txProposals.get(ntxid);
+ should.exist(txp);
+ should.exist(txp.signedBy[myId]);
+ should.not.exist(txp.rejectedBy[myId]);
+
+ w.verifyPaymentRequest(ntxid).should.equal(false);
+
+ return done();
+ });
+ });
+
+ it('#sign an untampered payment request', function(done) {
+ var w = createWallet();
+ should.exist(w);
+ var address = 'bitcoin:2NBzZdFBoQymDgfzH2Pmnthser1E71MmU47?amount=0.00003&r=' + server.uri + '/request';
+ var commentText = 'Hello, server. I\'d like to make a payment.';
+ w.createTx(address, commentText, function(ntxid, merchantData) {
+ should.exist(ntxid);
+ should.exist(merchantData);
+
+ var myId = w.getMyCopayerId();
+ var txp = w.txProposals.get(ntxid);
+ should.exist(txp);
+ should.exist(txp.signedBy[myId]);
+ should.not.exist(txp.rejectedBy[myId]);
+
+ w.verifyPaymentRequest(ntxid).should.equal(true);
+
+ return done();
+ });
+ });
+
+ it('#close payment server', function(done) {
+ server.close(function() {
+ return done();
+ });
+ });
+ }
});
diff --git a/test/test.PrivateKey.js b/test/test.PrivateKey.js
index 60ca71664..69753234e 100644
--- a/test/test.PrivateKey.js
+++ b/test/test.PrivateKey.js
@@ -18,21 +18,21 @@ try {
}
var PrivateKey = copay.PrivateKey || require('../js/models/core/PrivateKey');
-var config = {
+var pkConfig = {
networkName: 'livenet',
};
describe('PrivateKey model', function() {
it('should create an instance', function() {
- var w = new PrivateKey(config);
+ var w = new PrivateKey(pkConfig);
should.exist(w);
should.exist(w.bip);
should.exist(w.bip.derive);
});
it('should derive priv keys', function() {
- var pk = new PrivateKey(config);
+ var pk = new PrivateKey(pkConfig);
for (var j = false; !j; j=true) {
for (var i = 0; i < 3; i++) {
var wk = pk.get(i, j);
@@ -51,7 +51,7 @@ describe('PrivateKey model', function() {
}
});
it('should derive priv keys array', function() {
- var w = new PrivateKey(config);
+ var w = new PrivateKey(pkConfig);
var wks = w.getAll(2, 3);
wks.length.should.equal(5);
for (var j = 0; j < wks.length; j++) {
@@ -71,7 +71,7 @@ describe('PrivateKey model', function() {
});
it('fromObj toObj roundtrip', function() {
- var w1 = new PrivateKey(config);
+ var w1 = new PrivateKey(pkConfig);
var o = JSON.parse(JSON.stringify(w1.toObj()))
var w2 = PrivateKey.fromObj(o);
@@ -86,7 +86,7 @@ describe('PrivateKey model', function() {
describe('#getId', function() {
it('should calculate the copayerId', function() {
- var w1 = new PrivateKey(config);
+ var w1 = new PrivateKey(pkConfig);
should.exist(w1.getId());
w1.getId().length.should.equal(33 * 2);
});
@@ -94,7 +94,7 @@ describe('PrivateKey model', function() {
describe('#getIdPriv', function() {
it('should calculate .id', function() {
- var w1 = new PrivateKey(config);
+ var w1 = new PrivateKey(pkConfig);
should.exist(w1.getIdPriv());
w1.getIdPriv().length.should.equal(32 * 2);
});
@@ -102,7 +102,7 @@ describe('PrivateKey model', function() {
describe('#cacheId', function() {
it('should set .id and .idpriv', function() {
- var w1 = new PrivateKey(config);
+ var w1 = new PrivateKey(pkConfig);
w1.cacheId();
var pub = w1.id;
var priv = w1.idpriv;
@@ -111,7 +111,7 @@ describe('PrivateKey model', function() {
});
it('should set the id equal to the public key of the idpriv private key', function() {
- var w1 = new PrivateKey(config);
+ var w1 = new PrivateKey(pkConfig);
w1.cacheId();
var pub = w1.id;
var priv = w1.idpriv;
diff --git a/test/test.Wallet.js b/test/test.Wallet.js
index 3406cf42c..df588df86 100644
--- a/test/test.Wallet.js
+++ b/test/test.Wallet.js
@@ -20,7 +20,7 @@ var TransactionBuilder = bitcore.TransactionBuilder;
var Transaction = bitcore.Transaction;
var Address = bitcore.Address;
-var config = {
+var walletConfig = {
requiredCopayers: 3,
totalCopayers: 5,
spendUnconfirmed: true,
@@ -30,7 +30,7 @@ var config = {
var getNewEpk = function() {
return new PrivateKey({
- networkName: config.networkName,
+ networkName: walletConfig.networkName,
})
.deriveBIP45Branch()
.extendedPublicKeyString();
@@ -46,7 +46,7 @@ describe('Wallet model', function() {
it('should fail to create an instance', function() {
(function() {
- new Wallet(config)
+ new Wallet(walletConfig)
}).should.
throw();
});
@@ -58,11 +58,11 @@ describe('Wallet model', function() {
var createW = function(N, conf) {
- var c = JSON.parse(JSON.stringify(conf || config));
+ var c = JSON.parse(JSON.stringify(conf || walletConfig));
if (!N) N = c.totalCopayers;
var mainPrivateKey = new copay.PrivateKey({
- networkName: config.networkName
+ networkName: walletConfig.networkName
});
var mainCopayerEPK = mainPrivateKey.deriveBIP45Branch().extendedPublicKeyString();
c.privateKey = mainPrivateKey;
@@ -78,9 +78,9 @@ describe('Wallet model', function() {
networkName: c.networkName,
});
- var storage = new Storage(config.storage);
- var network = new Network(config.network);
- var blockchain = new Blockchain(config.blockchain);
+ var storage = new Storage(walletConfig.storage);
+ var network = new Network(walletConfig.network);
+ var blockchain = new Blockchain(walletConfig.blockchain);
c.storage = storage;
c.network = network;
c.blockchain = blockchain;
@@ -100,8 +100,8 @@ describe('Wallet model', function() {
}
};
- c.networkName = config.networkName;
- c.verbose = config.verbose;
+ c.networkName = walletConfig.networkName;
+ c.verbose = walletConfig.verbose;
c.version = '0.0.1';
return new Wallet(c);
@@ -322,9 +322,9 @@ describe('Wallet model', function() {
o.opts.reconnectDelay = 100;
var w2 = Wallet.fromObj(o,
- new Storage(config.storage),
- new Network(config.network),
- new Blockchain(config.blockchain));
+ new Storage(walletConfig.storage),
+ new Network(walletConfig.network),
+ new Blockchain(walletConfig.blockchain));
should.exist(w2);
w2.publicKeyRing.requiredCopayers.should.equal(w.publicKeyRing.requiredCopayers);
should.exist(w2.publicKeyRing.getCopayerId);
@@ -580,7 +580,7 @@ describe('Wallet model', function() {
});
it('#getUnspent should honor spendUnconfirmed = false', function(done) {
- var conf = JSON.parse(JSON.stringify(config));
+ var conf = JSON.parse(JSON.stringify(walletConfig));
conf.spendUnconfirmed = false;
var w = createW2(null, null, conf);
w.getBalance(function(err, balance, balanceByAddr, safeBalance) {
@@ -592,7 +592,7 @@ describe('Wallet model', function() {
});
it('#getUnspent and spendUnconfirmed should count transactions with 1 confirmations', function(done) {
- var conf = JSON.parse(JSON.stringify(config));
+ var conf = JSON.parse(JSON.stringify(walletConfig));
conf.spendUnconfirmed = false;
var w = cachedCreateW2(null, null, conf);
w.blockchain.getUnspent = w.blockchain.getUnspent2;
@@ -684,7 +684,7 @@ describe('Wallet model', function() {
it('should create & sign transaction from received funds', function(done) {
var k2 = new PrivateKey({
- networkName: config.networkName
+ networkName: walletConfig.networkName
});
var w = createW2([k2]);
@@ -1093,7 +1093,7 @@ describe('Wallet model', function() {
it('should throw if network is different', function() {
var backup = copayConfig.forceNetwork;
copayConfig.forceNetwork = true;
- config.networkName = 'livenet';
+ walletConfig.networkName = 'livenet';
createW2.should.throw(Error);
copayConfig.forceNetwork = backup;
});
diff --git a/test/test.storage.File.js b/test/test.storage.File.js
deleted file mode 100644
index ae1c516a2..000000000
--- a/test/test.storage.File.js
+++ /dev/null
@@ -1,204 +0,0 @@
-'use strict';
-
-var chai = chai || require('chai');
-var should = chai.should();
-var Storage = require('../js/models/storage/File');
-var sinon = require('sinon');
-var CryptoJS = require('node-cryptojs-aes').CryptoJS;
-
-var mock = require('mock-fs');
-
-describe('Storage/File', function() {
- it('should exist', function() {
- should.exist(Storage);
- });
-
- var mockFS = function() {
- var obj = {
- "test": "test"
- };
- var encryptedStr = CryptoJS.AES.encrypt(JSON.stringify(obj), 'password').toString();
- mock({
- 'myfilename': encryptedStr
- });
- };
-
- describe('#load', function(done) {
- it('should call fs.readFile', function(done) {
- mockFS();
- var storage = new Storage({
- password: 'password'
- });
- storage.load('myfilename', function(err) {
- mock.restore();
- done();
- });
- });
- });
-
- describe('#save', function(done) {
- it('should call fs.writeFile', function(done) {
- mockFS();
- var storage = new Storage({
- password: 'password'
- });
- storage.save('myfilename', function(err) {
- mock.restore();
- done();
- });
- });
- });
-
- describe('#_read', function() {
- it('should return the value of a key', function() {
- var storage = new Storage();
- storage.data = {
- 'walletId': {
- 'test': 'data'
- }
- };
- storage._read('walletId::test').should.equal('data');
- });
- });
-
- describe('#_write', function() {
- it('should save the value of a key and then run save', function(done) {
- var storage = new Storage();
- storage.save = function(walletId, callback) {
- storage.data[walletId]['key'].should.equal('value');
- callback();
- };
- storage._write('walletId::key', 'value', function() {
- done();
- });
- });
- });
-
- describe('#getGlobal', function() {
- it('should call storage._read', function() {
- var storage = new Storage();
- storage.data = {
- 'walletId': {
- 'test': 'test'
- }
- };
- storage._read = sinon.spy();
- storage.getGlobal('walletId::test');
- storage._read.calledOnce.should.equal(true);
- });
- });
-
- describe('#setGlobal', function() {
- it('should store a global key', function(done) {
- var storage = new Storage();
- storage.save = function(walletId, callback) {
- storage.data[walletId]['key'].should.equal('value');
- callback();
- };
- storage.setGlobal('walletId::key', 'value', function() {
- done();
- });
- });
- });
-
- describe('#removeGlobal', function() {
- it('should remove a global key', function(done) {
- var storage = new Storage();
- storage.data = {
- 'walletId': {
- 'key': 'value'
- }
- };
- storage.save = function(walletId, callback) {
- should.not.exist(storage.data[walletId]['key']);
- callback();
- };
- storage.removeGlobal('walletId::key', function() {
- done();
- });
- });
- });
-
- describe('#_key', function() {
- it('should merge the wallet id and item key', function() {
- var storage = new Storage();
- storage._key('wallet', 'key').should.equal('wallet::key');
- });
- });
-
- describe('#get', function() {
- it('should call getGlobal with the correct key', function() {
- var storage = new Storage();
- storage.getGlobal = sinon.spy();
- storage.get('wallet', 'key');
- storage.getGlobal.calledOnce.should.equal(true);
- storage.getGlobal.calledWith('wallet::key').should.equal(true);
- });
- });
-
- describe('#set', function() {
- it('should call setGlobal with the correct key', function() {
- var storage = new Storage();
- storage.setGlobal = sinon.spy();
- storage.set('wallet', 'key');
- storage.setGlobal.calledOnce.should.equal(true);
- storage.setGlobal.calledWith('wallet::key').should.equal(true);
- });
- });
-
- describe('#remove', function() {
- it('should call removeGlobal with the correct key', function() {
- var storage = new Storage();
- storage.removeGlobal = sinon.spy();
- storage.remove('wallet', 'key');
- storage.removeGlobal.calledOnce.should.equal(true);
- storage.removeGlobal.calledWith('wallet::key').should.equal(true);
- });
- });
-
- describe('#setFromObj', function() {
- it('should set this object for a wallet', function(done) {
- var obj = {
- test: 'testval'
- };
- var storage = new Storage();
- storage.save = function(walletId, callback) {
- callback();
- };
- storage.setFromObj('walletId', obj, function() {
- storage.data.walletId.test.should.equal('testval');
- done();
- });
- });
- });
-
- describe('#getEncryptedObj', function() {
- it('should give an encrypted object', function() {
- var obj = {
- test: 'testval'
- };
- var data = JSON.stringify(obj);
- var encrypted = CryptoJS.AES.encrypt(data, 'password');
- var base64 = encrypted.toString();
-
- var storage = new Storage({
- password: 'password'
- });
- storage.data['walletId'] = obj;
-
- var enc = storage.getEncryptedObj('walletId');
- //enc.length.should.equal(96);
- enc.length.should.be.greaterThan(10);
- enc.slice(0, 10).should.equal(base64.slice(0, 10));
- //enc.slice(0,6).should.equal("53616c");
- });
- });
-
- describe('#clearAll', function() {
- it('should set data to {}', function() {
-
- });
- });
-
-});
-
diff --git a/util/build.js b/util/build.js
index 5495a04a2..db14b847d 100644
--- a/util/build.js
+++ b/util/build.js
@@ -59,9 +59,6 @@ var createBundle = function(opts) {
b.require('./js/models/core/HDPath', {
expose: '../js/models/core/HDPath'
});
- b.require('./js/models/storage/File', {
- expose: '../js/models/storage/File'
- });
b.require('./config', {
expose: '../config'
});