Skip to content
This repository has been archived by the owner on Mar 7, 2023. It is now read-only.

Commit

Permalink
* refactor(Cream): move blockchain specific stuff to its own class (#256
Browse files Browse the repository at this point in the history
)

* refactor(Cream): move blockchain specific stuff out of Coinify classes

* fix(BuySell): stop if 2nd password is enabled

* test(Coinify): repaired and added some ExchangeDelegate tests

* test(ExchangeDelegate): more tests
  • Loading branch information
Sjors authored Sep 1, 2016
1 parent 1ff1310 commit da2f5a2
Show file tree
Hide file tree
Showing 12 changed files with 534 additions and 259 deletions.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ module.exports = {
Address: require('./src/address'),
Metadata: require('./src/metadata'),
Bitcoin: require('bitcoinjs-lib'),
External: require('./src/external')
External: require('./src/external'),
BuySell: require('./src/buy-sell')
};
3 changes: 2 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ module.exports = function (config) {
'tests/wallet_signup_spec.js.coffee',
'tests/blockchain_settings_api_spec.js.coffee',
'tests/account_info_spec.js.coffee',
'tests/metadata_spec.js.coffee'
'tests/metadata_spec.js.coffee',
'tests/exchange_delegate_spec.js.coffee'
]
};

Expand Down
2 changes: 1 addition & 1 deletion src/blockchain-wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ Wallet.prototype.loadExternal = function () {
if (this.isDoubleEncrypted === true || !this.isUpgradedToHD) {
return Promise.resolve();
} else {
this._external = new External();
this._external = new External(this);
return this._external.fetchOrCreate();
}
};
25 changes: 25 additions & 0 deletions src/buy-sell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

module.exports = BuySell;

// var buySell = new Blockchain.BuySell(Blockchain.MyWallet.wallet);
function BuySell (wallet) {
this._wallet = wallet;

// Stop if 2nd password is enabled
if (wallet.external === null) return;

// Add Coinify if not already added:
if (!this._wallet.external.coinify) this._wallet.external.addCoinify();
}

Object.defineProperties(BuySell.prototype, {
'exchanges': {
configurable: false,
get: function () {
if (this._wallet.external === null) return;
return {
coinify: this._wallet.external.coinify
};
}
}
});
108 changes: 72 additions & 36 deletions src/coinify/coinify.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,55 @@
'use strict';

/* To use this class, three things are needed:
1 - a delegate object with functions that provide the following:
email() -> String : the users email address
isEmailVerified() -> Boolean : whether the users email is verified
getEmailToken() -> stringify : JSON web token {email: '[email protected]'}
monitorAddress(address, callback) : callback(amount) if btc received
checkAddress(address) : look for existing transaction at address
getReceiveAddress(trade) : return the trades receive address
reserveReceiveAddress()
commitReceiveAddress()
releaseReceiveAddress()
serializeExtraFields(obj, trade) : e.g. obj.account_index = ...
deserializeExtraFields(obj, trade)
2 - a Coinify parner identifier
3 - a parent object with a save() method, e.g.:
var parent = {
save: function () { return JSON.stringify(this._coinify); }
}
var object = {user: 1, offline_token: 'token'};
var coinify = new Coinify(object, parent, delegate);
coinify.partnerId = ...;
parent._coinify = coinify;
coinify.save()
// "{"user":1,"offline_token":"token"}"
*/

var CoinifyProfile = require('./profile');
var CoinifyTrade = require('./trade');
var CoinifyKYC = require('./kyc');
var PaymentMethod = require('./payment-method');
var ExchangeRate = require('./exchange-rate');

var MyWallet = require('../wallet');
var Helpers = require('../helpers');
var API = require('../api');

var assert = require('assert');

var isBoolean = function (value) {
return typeof (value) === 'boolean';
};

var isString = function (str) {
return typeof str === 'string' || str instanceof String;
};

module.exports = Coinify;

function Coinify (object, parent) {
function Coinify (object, parent, delegate) {
var obj = object || {};
this._parent = parent; // parent this of external (for save)
this._delegate = delegate; // ExchangeDelegate
this._partner_id = null;
this._user = obj.user;
this._offline_token = obj.offline_token;
Expand All @@ -41,6 +74,13 @@ function Coinify (object, parent) {
}

Object.defineProperties(Coinify.prototype, {
'delegate': {
configurable: false,
get: function () { return this._delegate; },
set: function (value) {
this._delegate = value;
}
},
'user': {
configurable: false,
get: function () { return this._user; }
Expand All @@ -50,7 +90,7 @@ Object.defineProperties(Coinify.prototype, {
get: function () { return this._auto_login; },
set: function (value) {
assert(
Helpers.isBoolean(value),
isBoolean(value),
'Boolean'
);
this._auto_login = value;
Expand Down Expand Up @@ -119,29 +159,33 @@ Coinify.prototype.save = function () {
};
// Country and default currency must be set
// Email must be set and verified
Coinify.prototype.signup = function (countryCode) {
Coinify.prototype.signup = function (countryCode, currencyCode) {
var self = this;
var runChecks = function () {
assert(!this.user, 'Already signed up');
assert(!self.user, 'Already signed up');

assert(self.delegate, 'ExchangeDelegate required');

assert(
countryCode &&
Helpers.isString(countryCode) &&
isString(countryCode) &&
countryCode.length === 2 &&
countryCode.match(/[a-zA-Z]{2}/),
'ISO 3166-1 alpha-2'
);

assert(MyWallet.wallet.accountInfo.email, 'email required');
assert(MyWallet.wallet.accountInfo.isEmailVerified, 'email must be verified');
assert(MyWallet.wallet.accountInfo.currency, 'default currency required');
assert(currencyCode, 'currency required');

assert(self.delegate.email(), 'email required');
assert(self.delegate.isEmailVerified(), 'email must be verified');
};

var doSignup = function (emailToken) {
assert(emailToken, 'email token missing');
return this.POST('signup/trader', {
email: MyWallet.wallet.accountInfo.email,
partnerId: this.partnerId,
defaultCurrency: MyWallet.wallet.accountInfo.currency, // ISO 4217
email: self.delegate.email(),
partnerId: self.partnerId,
defaultCurrency: currencyCode, // ISO 4217
profile: {
address: {
country: countryCode.toUpperCase()
Expand All @@ -159,28 +203,11 @@ Coinify.prototype.signup = function (countryCode) {
};

return Promise.resolve().then(runChecks.bind(this))
.then(this.getEmailToken.bind(this))
.then(this.delegate.getEmailToken.bind(this.delegate))
.then(doSignup.bind(this))
.then(saveMetadata.bind(this));
};

Coinify.prototype.getEmailToken = function () {
return API.request(
'GET',
'wallet/signed-email-token',
{
guid: MyWallet.wallet.guid,
sharedKey: MyWallet.wallet.sharedKey
}
).then(function (res) {
if (res.success) {
return res.token;
} else {
throw new Error('Unable to obtain email verification proof');
}
});
};

Coinify.prototype.login = function () {
var parentThis = this;

Expand Down Expand Up @@ -400,8 +427,17 @@ Coinify.prototype.request = function (method, endpoint, data) {
options.headers['Authorization'] = 'Bearer ' + this._access_token;
}

// encodeFormData :: Object -> url encoded params
var encodeFormData = function (data) {
if (!data) return '';
var encoded = Object.keys(data).map(function (k) {
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
}).join('&');
return encoded;
};

if (method === 'GET') {
url += '?' + API.encodeFormData(data);
url += '?' + encodeFormData(data);
} else {
options.body = JSON.stringify(data);
}
Expand All @@ -427,10 +463,10 @@ Coinify.prototype.request = function (method, endpoint, data) {
.then(checkStatus);
};

Coinify.new = function (parent) {
Coinify.new = function (parent, delegate) {
var object = {
auto_login: true
};
var coinify = new Coinify(object, parent);
var coinify = new Coinify(object, parent, delegate);
return coinify;
};
Empty file added src/coinify/helpers.js
Empty file.
Loading

0 comments on commit da2f5a2

Please sign in to comment.