").append(x.parseHTML(e)).find(r):e)}).complete(n&&function(e,t){s.each(n,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Xt,type:"GET",isLocal:Qt.test(_t[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":on,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?ln(ln(e,x.ajaxSettings),t):ln(x.ajaxSettings,e)},ajaxPrefilter:an(nn),ajaxTransport:an(rn),ajax:function(e,t){"object"==typeof e&&(t=e,e=undefined),t=t||{};var n,r,i,o,s,a,u,l,c=x.ajaxSetup({},t),f=c.context||c,p=c.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),d=x.Callbacks("once memory"),g=c.statusCode||{},m={},y={},v=0,b="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(2===v){if(!o){o={};while(t=Jt.exec(i))o[t[1].toLowerCase()]=t[2]}t=o[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===v?i:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return v||(e=y[n]=y[n]||e,m[e]=t),this},overrideMimeType:function(e){return v||(c.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>v)for(t in e)g[t]=[g[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||b;return n&&n.abort(t),k(0,t),this}};if(h.promise(T).complete=d.add,T.success=T.done,T.error=T.fail,c.url=((e||c.url||Xt)+"").replace(Vt,"").replace(Zt,_t[1]+"//"),c.type=t.method||t.type||c.method||c.type,c.dataTypes=x.trim(c.dataType||"*").toLowerCase().match(w)||[""],null==c.crossDomain&&(a=en.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===_t[1]&&a[2]===_t[2]&&(a[3]||("http:"===a[1]?"80":"443"))===(_t[3]||("http:"===_t[1]?"80":"443")))),c.data&&c.processData&&"string"!=typeof c.data&&(c.data=x.param(c.data,c.traditional)),un(nn,c,t,T),2===v)return T;u=c.global,u&&0===x.active++&&x.event.trigger("ajaxStart"),c.type=c.type.toUpperCase(),c.hasContent=!Kt.test(c.type),r=c.url,c.hasContent||(c.data&&(r=c.url+=(Yt.test(r)?"&":"?")+c.data,delete c.data),c.cache===!1&&(c.url=Gt.test(r)?r.replace(Gt,"$1_="+Ut++):r+(Yt.test(r)?"&":"?")+"_="+Ut++)),c.ifModified&&(x.lastModified[r]&&T.setRequestHeader("If-Modified-Since",x.lastModified[r]),x.etag[r]&&T.setRequestHeader("If-None-Match",x.etag[r])),(c.data&&c.hasContent&&c.contentType!==!1||t.contentType)&&T.setRequestHeader("Content-Type",c.contentType),T.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+("*"!==c.dataTypes[0]?", "+on+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)T.setRequestHeader(l,c.headers[l]);if(c.beforeSend&&(c.beforeSend.call(f,T,c)===!1||2===v))return T.abort();b="abort";for(l in{success:1,error:1,complete:1})T[l](c[l]);if(n=un(rn,c,t,T)){T.readyState=1,u&&p.trigger("ajaxSend",[T,c]),c.async&&c.timeout>0&&(s=setTimeout(function(){T.abort("timeout")},c.timeout));try{v=1,n.send(m,k)}catch(C){if(!(2>v))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,t,o,a){var l,m,y,b,w,C=t;2!==v&&(v=2,s&&clearTimeout(s),n=undefined,i=a||"",T.readyState=e>0?4:0,l=e>=200&&300>e||304===e,o&&(b=cn(c,T,o)),b=fn(c,b,T,l),l?(c.ifModified&&(w=T.getResponseHeader("Last-Modified"),w&&(x.lastModified[r]=w),w=T.getResponseHeader("etag"),w&&(x.etag[r]=w)),204===e?C="nocontent":304===e?C="notmodified":(C=b.state,m=b.data,y=b.error,l=!y)):(y=C,(e||!C)&&(C="error",0>e&&(e=0))),T.status=e,T.statusText=(t||C)+"",l?h.resolveWith(f,[m,C,T]):h.rejectWith(f,[T,C,y]),T.statusCode(g),g=undefined,u&&p.trigger(l?"ajaxSuccess":"ajaxError",[T,c,l?m:y]),d.fireWith(f,[T,C]),u&&(p.trigger("ajaxComplete",[T,c]),--x.active||x.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,t){return x.get(e,undefined,t,"script")}}),x.each(["get","post"],function(e,t){x[t]=function(e,n,r,i){return x.isFunction(n)&&(i=i||r,r=n,n=undefined),x.ajax({url:e,type:t,dataType:i,data:n,success:r})}});function cn(e,t,n){var r,i,o,s,a=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),r===undefined&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}s||(s=i)}o=o||s}return o?(o!==u[0]&&u.unshift(o),n[o]):undefined}function fn(e,t,n,r){var i,o,s,a,u,l={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)l[s.toLowerCase()]=e.converters[s];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(s=l[u+" "+o]||l["* "+o],!s)for(i in l)if(a=i.split(" "),a[1]===o&&(s=l[u+" "+a[0]]||l["* "+a[0]])){s===!0?s=l[i]:l[i]!==!0&&(o=a[0],c.unshift(a[1]));break}if(s!==!0)if(s&&e["throws"])t=s(t);else try{t=s(t)}catch(f){return{state:"parsererror",error:s?f:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===undefined&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),x.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(r,i){t=x("
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Class: userAirdropDetailCache
-
-
-
-
-
- userAirdropDetailCache
-
-
-
-
-
-
-
-
-
-
-
-
- new userAirdropDetailCache(params)
-
-
-
-
-
-
-
-
-
-
-
-
-
- Parameters:
-
-
-
-
-
-
- Name
-
-
- Type
-
-
-
-
-
- Description
-
-
-
-
-
-
-
-
- params
-
-
-
-
-
-Object
-
-
-
-
-
-
-
-
-
-
- cache key generation & expiry related params
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Extends
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Methods
-
-
-
-
-
- fetchDataFromSource()
-
-
-
-
-
-
-
- fetch data from source
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Overrides:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns:
-
-
-
-
-
-
- Type
-
-
-
-Result
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- getCacheKey(address)
-
-
-
-
-
-
-
- Get cache keys
-
-
-
-
-
-
-
-
-
- Parameters:
-
-
-
-
-
-
- Name
-
-
- Type
-
-
-
-
-
- Description
-
-
-
-
-
-
-
-
- address
-
-
-
-
-
-string
-
-
-
-
-
-
-
-
-
-
- address
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Overrides:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns:
-
-
-
-
-
-
- Type
-
-
-
-string
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setCacheExpiry()
-
-
-
-
-
-
-
- set cache expiry in oThis.cacheExpiry and return it
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Overrides:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns:
-
-
-
-
-
-
- Type
-
-
-
-Number
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- setCacheKeys()
-
-
-
-
-
-
-
- set cache key
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Overrides:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Returns:
-
-
-
-
-
-
- Type
-
-
-
-Object
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/helpers/custom_console_logger.js b/helpers/custom_console_logger.js
index a8a1de0..ef4cb05 100644
--- a/helpers/custom_console_logger.js
+++ b/helpers/custom_console_logger.js
@@ -1,92 +1,16 @@
"use strict";
/*
- * Custom Console log methods. Apply different colors for different log levels/severity.
+ * Custom Console log methods.
*
*/
-//
-const CONSOLE_RESET = "\x1b[0m";
-const ERR_PRE = "\x1b[31m"; //Error. (RED)
-const INFO_PRE = "\x1b[33m "; //Info (YELLOW)
-const WIN_PRE = "\x1b[32m"; //Success (GREEN)
-const WARN_PRE = "\x1b[43m";
-const STEP_PRE = "\n\x1b[34m"; //Step Description (BLUE)
+const OSTBase = require('@openstfoundation/openst-base')
+ , Logger = OSTBase.Logger
+;
const rootPrefix = '..'
, coreConstants = require(rootPrefix + '/config/core_constants')
+ , loggerLevel = coreConstants.DEBUG_ENABLED == 1 ? Logger.LOG_LEVELS.TRACE : Logger.LOG_LEVELS.INFO
;
-module.exports = {
- "STEP_PRE": STEP_PRE,
-
- "WARN_PRE": WARN_PRE,
-
- "WIN_PRE": WIN_PRE,
-
- "INFO_PRE": INFO_PRE,
-
- "ERR_PRE": ERR_PRE,
-
- "CONSOLE_RESET": CONSOLE_RESET,
-
- step: function () {
- var args = [this.STEP_PRE];
- args = args.concat(Array.prototype.slice.call(arguments));
- args.push(this.CONSOLE_RESET);
- console.log.apply(console, args);
- },
-
- //Method to Log Information
- info: function () {
- var args = [this.INFO_PRE];
- args = args.concat(Array.prototype.slice.call(arguments));
- args.push(this.CONSOLE_RESET);
- console.log.apply(console, args);
- },
-
- //Method to Log Error.
- error: function () {
- var args = [this.ERR_PRE];
- args = args.concat(Array.prototype.slice.call(arguments));
- args.push(this.CONSOLE_RESET);
- console.log.apply(console, args);
- },
-
- warn: function () {
- var args = [this.WARN_PRE];
- args = args.concat(Array.prototype.slice.call(arguments));
- args.push(this.CONSOLE_RESET);
- console.log.apply(console, args);
- },
-
- debug: function () {
- if (coreConstants.DEBUG_ENABLED == 1) {
- var args = [this.INFO_PRE];
- args = args.concat(Array.prototype.slice.call(arguments));
- args.push(this.CONSOLE_RESET);
- console.log.apply(console, args);
- }
- },
-
- //Method to Log Success/Win.
- win: function () {
- var args = [this.WIN_PRE];
- args = args.concat(Array.prototype.slice.call(arguments));
- args.push(this.CONSOLE_RESET);
- console.log.apply(console, args);
- },
-
- log: function () {
- console.log.apply(console, arguments);
- },
-
- /**
- * Notify error - including the method so that code starts working.
- */
- notify: function () {
- var args = [this.ERR_PRE];
- args = args.concat(Array.prototype.slice.call(arguments));
- args.push(this.CONSOLE_RESET);
- console.log.apply(console, args);
- }
-};
\ No newline at end of file
+module.exports = new Logger("openst-payments", loggerLevel);
diff --git a/index.js b/index.js
index 9f0ac20..5a28327 100644
--- a/index.js
+++ b/index.js
@@ -1,27 +1,20 @@
+"use strict";
+
/**
* Index File of "@openstfoundation/openst-payments" node module
*/
-"use strict";
-
const rootPrefix = "."
, version = require(rootPrefix + '/package.json').version
- , deployer = require(rootPrefix + '/lib/deployer')
- , workers = require(rootPrefix + '/lib/contract_interact/workers')
- , airdrop = require(rootPrefix + '/lib/contract_interact/airdrop')
- , opsManaged = require(rootPrefix + "/lib/contract_interact/ops_managed_contract")
- , airdropManager = require(rootPrefix + "/lib/airdrop_management/base")
+ , serviceManifest = require(rootPrefix + '/services/manifest')
;
const OSTPayment = function () {
const oThis = this;
oThis.version = version;
- oThis.deployer = deployer;
- oThis.opsManaged = opsManaged;
- oThis.workers = workers;
- oThis.airdrop = airdrop;
- oThis.airdropManager = airdropManager;
+
+ oThis.services = serviceManifest;
};
module.exports = new OSTPayment();
\ No newline at end of file
diff --git a/lib/airdrop_management/adjust_airdrop_amount.js b/lib/airdrop_management/adjust_airdrop_amount.js
index 60abf33..bf467c8 100644
--- a/lib/airdrop_management/adjust_airdrop_amount.js
+++ b/lib/airdrop_management/adjust_airdrop_amount.js
@@ -1,19 +1,28 @@
+"use strict";
+
/**
*
* This class would be used for calculating user airdrop balance.
*
- * @module lib/airdrop_management/user_balance
+ * @module lib/airdrop_management/adjust_airdrop_amount
*
*/
const rootPrefix = '../..'
, responseHelper = require(rootPrefix + '/lib/formatter/response')
- , airdropKlass = require(rootPrefix + '/app/models/airdrop')
+ , AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
, userAirdropDetailKlass = require(rootPrefix + '/app/models/user_airdrop_detail')
, BigNumber = require('bignumber.js')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
/**
* Constructor to create object of userBalance
*
@@ -27,8 +36,8 @@ const rootPrefix = '../..'
*
*/
const AdjustAirdropAmountKlass = function(params) {
- logger.info("=======AdjustAirdropAmountKlass.params=======");
- logger.info(params);
+ logger.debug("=======AdjustAirdropAmountKlass.params=======");
+ logger.debug(params);
const oThis = this;
oThis.airdropContractAddress = params.airdropContractAddress;
oThis.userAddress = params.userAddress;
@@ -48,28 +57,52 @@ AdjustAirdropAmountKlass.prototype = {
return new Promise(async function (onResolve, onReject) {
var amountAdjustedLog = {};
try {
- const airdropModel = new airdropKlass();
- const airdropModelResult = await airdropModel.getByContractAddress(oThis.airdropContractAddress);
- const airdropRecord = airdropModelResult[0];
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ , airdropRecord = airdropModelCacheResponse.data[oThis.airdropContractAddress]
+ ;
var totalRemainingAmountToAdjust = new BigNumber(oThis.airdropAmountUsed);
// Zero airdrop amount is possible
if (totalRemainingAmountToAdjust.equals(0)) {
return onResolve(responseHelper.successWithData({}));
}
if (totalRemainingAmountToAdjust.lt(0)) {
- return onResolve(responseHelper.error('l_am_aaa_daua_1', 'negative airdropAmountUsed not allowed'));
+
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_daua_1',
+ api_error_identifier: 'amount_invalid',
+ error_config: errorConfig,
+ params_error_identifiers: ['negative_airdrop_amount'],
+ debug_options: {}
+ };
+
+ return onResolve(responseHelper.paramValidationError(errorParams));
}
if (!oThis.userAddress) {
- return onResolve(responseHelper.error('l_am_aaa_daua_2', 'Invalid User Address'));
+
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_daua_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_user_address'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
}
var userAirdropDetailModel = new userAirdropDetailKlass();
const userAirdropDetailResults = await userAirdropDetailModel.select("id, airdrop_id, user_address, CONVERT(airdrop_amount, char) as airdrop_amount, CONVERT(airdrop_used_amount, char) as airdrop_used_amount").
where({airdrop_id: airdropRecord.id, user_address: oThis.userAddress}).
where(["airdrop_amount > airdrop_used_amount"]).fire();
- logger.info("\n======debitAirdropUsedAmount.userAirdropDetailResults=========", userAirdropDetailResults);
+ logger.debug("\n======debitAirdropUsedAmount.userAirdropDetailResults=========", userAirdropDetailResults);
// Return error if no record found. Means airdrop_used_amount is not updated correctly in previous adjustments
if (!userAirdropDetailResults[0]) {
- return onResolve(responseHelper.error('l_am_aaa_daua_3', 'no airdrop record available for adjusting: '));
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_daua_3',
+ api_error_identifier: 'record_not_found',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
}
for (var uadIndex in userAirdropDetailResults) {
const uad = userAirdropDetailResults[uadIndex];
@@ -82,13 +115,13 @@ AdjustAirdropAmountKlass.prototype = {
userAirdropDetailModel = new userAirdropDetailKlass();
const updateResult = await userAirdropDetailModel.update(["airdrop_used_amount=airdrop_used_amount+?", amountToAdjustWithCurrentRecord.toString(10)]).
where(["id = ? AND ((airdrop_used_amount+?) <= airdrop_amount)", uad.id, amountToAdjustWithCurrentRecord.toString(10)]).fire();
- logger.info("\ndebitAirdropUsedAmount.updateResult: ", updateResult);
+ logger.debug("\ndebitAirdropUsedAmount.updateResult: ", updateResult);
if (updateResult.affectedRows < 1) {
continue; // Don't subtract totalRemainingAmountToAdjust if update is failed
} else{
amountAdjustedLog[uad.id] = amountToAdjustWithCurrentRecord.toString(10);
totalRemainingAmountToAdjust = totalRemainingAmountToAdjust.minus(amountToAdjustWithCurrentRecord);
- logger.info("\n=====debitAirdropUsedAmount.updateSuccess=======", "\ntotalRemainingAmountToAdjust: ",totalRemainingAmountToAdjust.toString(10));
+ logger.debug("\n=====debitAirdropUsedAmount.updateSuccess=======", "\ntotalRemainingAmountToAdjust: ",totalRemainingAmountToAdjust.toString(10));
}
}
} catch (err) {
@@ -97,7 +130,14 @@ AdjustAirdropAmountKlass.prototype = {
if (Object.keys(amountAdjustedLog).length > 0){
await oThis.rollbackDebitAirdropAdjustedAmount(amountAdjustedLog);
}
- return onResolve(responseHelper.errorWithData({amountAdjustedLog: amountAdjustedLog}, 'l_am_aaa_daua_4', 'Error in debitAirdropUsedAmount: ' + err));
+
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_daua_4',
+ api_error_identifier: 'amount_update_failed',
+ error_config: errorConfig,
+ debug_options: { amountAdjustedLog: amountAdjustedLog, err: err }
+ };
+ return onResolve(responseHelper.error(errorParams));
}
// In case totalRemainingAmountToAdjust > 0 means no record available for adjusting or parallel requests issue
if (totalRemainingAmountToAdjust.gt(0)) {
@@ -105,7 +145,13 @@ AdjustAirdropAmountKlass.prototype = {
if (Object.keys(amountAdjustedLog).length > 0){
await oThis.rollbackDebitAirdropAdjustedAmount(amountAdjustedLog);
}
- return onResolve(responseHelper.errorWithData({amountAdjustedLog: amountAdjustedLog}, 'l_am_aaa_daua_5', 'Airdrop used Amount not adjusted. This could be because of same user payment requests in parallel'));
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_daua_5',
+ api_error_identifier: 'airdrop_adjust_failed',
+ error_config: errorConfig,
+ debug_options: { amountAdjustedLog: amountAdjustedLog }
+ };
+ return onResolve(responseHelper.error(errorParams));
}
return onResolve(responseHelper.successWithData({amountAdjustedLog: amountAdjustedLog}));
});
@@ -138,29 +184,51 @@ AdjustAirdropAmountKlass.prototype = {
return new Promise(async function (onResolve, onReject) {
var amountAdjustedLog = {};
try {
- const airdropModel = new airdropKlass();
- const airdropModelResult = await airdropModel.getByContractAddress(oThis.airdropContractAddress);
- const airdropRecord = airdropModelResult[0];
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ , airdropRecord = airdropModelCacheResponse.data[oThis.airdropContractAddress]
+ ;
var totalRemainingAmountToAdjust = new BigNumber(oThis.airdropAmountUsed);
// Zero airdrop amount is possible
if (totalRemainingAmountToAdjust.equals(0)) {
return onResolve(responseHelper.successWithData({}));
}
if (totalRemainingAmountToAdjust.lt(0)) {
- return onResolve(responseHelper.error('l_am_aaa_caua_1', 'negative airdropAmountUsed not allowed'));
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_caua_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['negative_airdrop_amount'],
+ debug_options: {}
+ };
+
+ return onResolve(responseHelper.paramValidationError(errorParams));
}
if (!oThis.userAddress) {
- return onResolve(responseHelper.error('l_am_aaa_caua_2', 'Invalid User Address'));
+
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_caua_2',
+ api_error_identifier: 'invalid_user_address',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
}
var userAirdropDetailModel = new userAirdropDetailKlass();
const userAirdropDetailResults = await userAirdropDetailModel.select("id, airdrop_id, user_address, CONVERT(airdrop_amount, char) as airdrop_amount, CONVERT(airdrop_used_amount, char) as airdrop_used_amount").
where({airdrop_id: airdropRecord.id, user_address: oThis.userAddress}).
where(["airdrop_used_amount > 0 AND airdrop_amount >= airdrop_used_amount"]).fire();
- logger.info("======creditAirdropUsedAmount.userAirdropDetailResults=========");
- logger.info(userAirdropDetailResults);
+ logger.debug("======creditAirdropUsedAmount.userAirdropDetailResults=========");
+ logger.debug(userAirdropDetailResults);
// Return error if no record found to adjust
if (!userAirdropDetailResults[0]) {
- return onResolve(responseHelper.error('l_am_aaa_caua_3', 'no airdrop record available for adjusting: '));
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_caua_3',
+ api_error_identifier: 'record_not_found',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
}
for (var uadIndex in userAirdropDetailResults) {
const uad = userAirdropDetailResults[uadIndex];
@@ -173,13 +241,13 @@ AdjustAirdropAmountKlass.prototype = {
userAirdropDetailModel = new userAirdropDetailKlass();
const updateResult = await userAirdropDetailModel.update(["airdrop_used_amount=airdrop_used_amount-?",toAdjustAmount.toString(10)]).
where(["id = ? AND (airdrop_amount >= airdrop_used_amount) AND (airdrop_used_amount-?)>=0", uad.id, toAdjustAmount.toString(10)]).fire();
- logger.info("\ndebitAirdropUsedAmount.updateResult: ", updateResult);
+ logger.debug("\ndebitAirdropUsedAmount.updateResult: ", updateResult);
if (updateResult.affectedRows < 1) {
continue; // Don't subtract totalRemainingAmountToAdjust if update is failed
} else {
totalRemainingAmountToAdjust = totalRemainingAmountToAdjust.minus(toAdjustAmount);
amountAdjustedLog[uad.id] = toAdjustAmount.toString(10);
- logger.info("\n=====creditAirdropUsedAmount.updateSuccess=======", "\ntotalRemainingAmountToAdjust: ",totalRemainingAmountToAdjust.toString(10));
+ logger.debug("\n=====creditAirdropUsedAmount.updateSuccess=======", "\ntotalRemainingAmountToAdjust: ",totalRemainingAmountToAdjust.toString(10));
}
}
} catch (err) {
@@ -188,7 +256,14 @@ AdjustAirdropAmountKlass.prototype = {
if (Object.keys(amountAdjustedLog).length > 0){
await oThis.rollbackCreditAirdropAdjustedAmount(amountAdjustedLog);
}
- return onResolve(responseHelper.errorWithData({amountAdjustedLog: amountAdjustedLog}, 'l_am_aaa_caua_4', 'Error in updateAirdropUsedAmount: ' + err));
+
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_caua_4',
+ api_error_identifier: 'amount_update_failed',
+ error_config: errorConfig,
+ debug_options: { amountAdjustedLog: amountAdjustedLog, err: err }
+ };
+ return onResolve(responseHelper.error(errorParams));
}
// In case totalRemainingAmountToAdjust > 0 means no record available for adjusting or parallel requests issue
if (totalRemainingAmountToAdjust.gt(0)) {
@@ -196,7 +271,14 @@ AdjustAirdropAmountKlass.prototype = {
if (Object.keys(amountAdjustedLog).length > 0){
await oThis.rollbackCreditAirdropAdjustedAmount(amountAdjustedLog);
}
- return onResolve(responseHelper.errorWithData({amountAdjustedLog: amountAdjustedLog}, 'l_am_aaa_caua_5', 'Airdrop used Amount not adjusted. This could be because of same user payment requests in parallel'));
+ logger.error('%Error - Airdrop used Amount not adjusted. This could be because of same user payment requests in parallel');
+ let errorParams = {
+ internal_error_identifier: 'l_am_aaa_caua_5',
+ api_error_identifier: 'amount_update_failed',
+ error_config: errorConfig,
+ debug_options: { amountAdjustedLog: amountAdjustedLog }
+ };
+ return onResolve(responseHelper.error(errorParams));
}
return onResolve(responseHelper.successWithData({amountAdjustedLog: amountAdjustedLog}));
});
diff --git a/lib/airdrop_management/approve.js b/lib/airdrop_management/approve.js
deleted file mode 100644
index 8480d79..0000000
--- a/lib/airdrop_management/approve.js
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- *
- * This is a utility file which would be used for executing approve by airdrop budget holder.
- *
- * @module lib/airdrop_management/approve
- *
- */
-
-const rootPrefix = '../..'
- , responseHelper = require(rootPrefix + '/lib/formatter/response')
- , airdropContractInteract = require(rootPrefix + '/lib/contract_interact/airdrop')
- , brandedTokenContractInteract = require(rootPrefix + '/lib/contract_interact/branded_token')
- , BigNumber = require('bignumber.js')
- , basicHelper = require(rootPrefix + '/helpers/basic_helper')
- , logger = require(rootPrefix + '/helpers/custom_console_logger')
- , airdropKlass = require(rootPrefix + '/app/models/airdrop')
-;
-
-/**
- * Constructor to create object of approve
- *
- * @constructor
- *
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {String} airdropBudgetHolderPassphrase - airdropBudgetHolder Passphrase
- * @param {String} gasPrice - gas price
- * @param {Number} chainId - chain Id
- * @param {Object} options - chain Id
- *
- * @return {Object}
- *
- */
-const approve = module.exports = function(params) {
- logger.debug("=========Approve.params=========");
- logger.debug(params.airdropContractAddress, params.gasPrice, params.chainId, params.options);
- const oThis = this;
- oThis.airdropContractAddress = params.airdropContractAddress;
- oThis.airdropBudgetHolderPassphrase = params.airdropBudgetHolderPassphrase;
- oThis.gasPrice = params.gasPrice;
- oThis.chainId = params.chainId;
- oThis.options = params.options;
-
- oThis.airdropBudgetHolder = null;
- oThis.brandedTokenContractAddress = null;
- oThis.amount = null;
- oThis.brandedTokenObject = null;
-};
-
-approve.prototype = {
-
- /**
- * Perform approve by airdrop budget holder to contract
- *
- * @return {Promise}
- *
- */
- perform: async function () {
-
- const oThis = this;
-
- var r = null;
-
- r = await oThis.validateParams();
- logger.debug("\n=========Approve.validateParams.result=========");
- logger.debug(r);
- if(r.isFailure()) return r;
-
- r = oThis.doApprove();
- logger.debug("\n=========Approve.doApprove.result=========");
- logger.debug(r);
- return r;
-
- },
-
- /**
- * Validate params
- *
- * @return {Promise}
- *
- */
- validateParams: function(){
- const oThis = this;
- return new Promise(async function (onResolve, onReject) {
-
- if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
- return onResolve(responseHelper.error('l_am_a_vp_1', 'airdrop contract address is invalid'));
- }
-
- // Check if airdropContractAddress is registered or not
- var airdropModel = new airdropKlass();
- var result = await airdropModel.getByContractAddress(oThis.airdropContractAddress);
- oThis.airdropRecord = result[0];
- if (!oThis.airdropRecord){
- return onResolve(responseHelper.error('l_am_ub_vp_2', 'Given airdrop contract is not registered'));
- }
-
- var airdropContractInteractObject = new airdropContractInteract(oThis.airdropContractAddress, oThis.chainId);
- var result = await airdropContractInteractObject.brandedToken();
- oThis.brandedTokenContractAddress = result.data.brandedToken;
- if (!basicHelper.isAddressValid(oThis.brandedTokenContractAddress)) {
- return onResolve(responseHelper.error('l_am_a_vp_2', 'brandedTokenContractAddress set in airdrop contract is invalid'));
- }
-
- result = await airdropContractInteractObject.airdropBudgetHolder();
- oThis.airdropBudgetHolderAddress = result.data.airdropBudgetHolder;
- if (!basicHelper.isAddressValid(oThis.airdropBudgetHolderAddress)) {
- return onResolve(responseHelper.error('l_am_a_vp_3', 'airdropBudgetHolderAddress set in airdrop contract is invalid'));
- }
-
- oThis.brandedTokenObject = new brandedTokenContractInteract(oThis.brandedTokenContractAddress, oThis.chainId);
- result = await oThis.brandedTokenObject.getBalanceOf(oThis.airdropBudgetHolderAddress);
- oThis.amount = result.data.balance;
- const amountInBigNumber = new BigNumber(oThis.amount);
- if (amountInBigNumber.isNaN() || !amountInBigNumber.isInteger()){
- return onResolve(responseHelper.error('l_am_v_vp_4', 'amount is invalid value'));
- }
-
- if (!basicHelper.isValidChainId(oThis.chainId)) {
- return onResolve(responseHelper.error('l_am_v_vp_5', 'ChainId is invalid'));
- }
-
- return onResolve(responseHelper.successWithData({}));
-
- });
-
- },
-
- /**
- * Perform Approve to airdrop budget holder
- *
- * @return {Promise}
- *
- */
- doApprove: async function(){
- const oThis = this;
- return new Promise(async function (onResolve, onReject) {
- // Approve to budget holder
- const approveByBudgetHolderResponse = await oThis.brandedTokenObject.approveByBudgetHolder(oThis.airdropBudgetHolderAddress,
- oThis.airdropBudgetHolderPassphrase,
- oThis.airdropContractAddress,
- oThis.amount,
- oThis.gasPrice,
- oThis.options);
- logger.debug("\n=========Transfer.doApprove.response=========");
- logger.debug(approveByBudgetHolderResponse);
- return onResolve(approveByBudgetHolderResponse);
- });
-
- }
-
-};
-
-module.exports = approve;
\ No newline at end of file
diff --git a/lib/airdrop_management/base.js b/lib/airdrop_management/base.js
deleted file mode 100644
index f155a54..0000000
--- a/lib/airdrop_management/base.js
+++ /dev/null
@@ -1,148 +0,0 @@
-/**
- *
- * This is a utility file which would be used for executing all methods related to airdrop.
- *
- * @module lib/airdrop_management/base
- *
- */
-const rootPrefix = '../..'
- , Register = require(rootPrefix + '/lib/airdrop_management/register')
- , Transfer = require(rootPrefix + '/lib/airdrop_management/transfer')
- , Approve = require(rootPrefix + '/lib/airdrop_management/approve')
- , BatchAllocator = require(rootPrefix + '/lib/airdrop_management/batch_allocator')
- , UserBalance = require(rootPrefix + '/lib/airdrop_management/user_balance')
-;
-
-/**
- * Constructor to create object of base
- *
- * @constructor
- *
- */
-const base = module.exports = function() {};
-
-base.prototype = {
-
- /**
- * Register Airdrop
- *
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {Number} chainId - chain Id
- *
- * @return {Promise}
- *
- */
- registerAirdrop: function(airdropContractAddress, chainId) {
- return new Promise(async function (onResolve, onReject) {
-
- const registerAirdropObject = new Register({
- airdropContractAddress: airdropContractAddress,
- chainId: chainId
- });
- onResolve(registerAirdropObject.perform());
-
- });
-
- },
-
- /**
- * Transfer airdrop amount to airdrop budget holder
- *
- * @param {Hex} senderAddress - Sender Address
- * @param {string} senderPassphrase - passphrase
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {BigNumber} amount - amount to transfer
- * @param {Hex} gasPrice - gasPrice
- * @param {Number} chainId - chainId
- * @param {Object} options - options e.g. {returnType: '', tag: ''}
- *
- * @return {Promise}
- *
- */
- transfer: function (senderAddress, senderPassphrase, airdropContractAddress, amount, gasPrice, chainId, options) {
-
- var transferObject = new Transfer({
- senderAddress: senderAddress,
- senderPassphrase: senderPassphrase,
- airdropContractAddress: airdropContractAddress,
- amount: amount,
- gasPrice: gasPrice,
- chainId: chainId,
- options: options});
- return transferObject.perform();
-
- },
-
- /**
- * approve airdrop amount to airdrop contract address
- *
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {string} airdropBudgetHolderPassphrase - passphrase
- * @param {Hex} gasPrice - gasPrice
- * @param {Number} chainId - chainId
- * @param {Object} options - options e.g. {returnType: '', tag: ''}
- *
- * @return {Promise}
- *
- */
- approve: function (airdropContractAddress, airdropBudgetHolderPassphrase, gasPrice, chainId, options) {
-
- var approveObject = new Approve({
- airdropContractAddress: airdropContractAddress,
- airdropBudgetHolderPassphrase: airdropBudgetHolderPassphrase,
- gasPrice: gasPrice,
- chainId: chainId,
- options: options});
- return approveObject.perform();
-
- },
-
- /**
- * batch allocate to users
- *
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {Hex} transactionHash - transfer transaction hash
- * @param {Object} airdropUsers - airdropUsers => {address: {airdropAmount:2, expiryTimestamp: timestamp}}
- * @param {Number} chainId - chainId
- *
- * @return {response}
- *
- */
- batchAllocate: function (airdropContractAddress, transactionHash, airdropUsers, chainId) {
- const batchAllocatorObject = new BatchAllocator({
- airdropContractAddress: airdropContractAddress,
- transactionHash: transactionHash,
- airdropUsers: airdropUsers,
- chainId: chainId
- });
-
- return batchAllocatorObject.perform();
- },
-
- /**
- * Get user airdrop balance
- *
- * @param {Integer} chainId - chain Id
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {Array} userAddresses - array of user addresses
- *
- * @return {response} - {
- * '0x934ebd34b2a4f16d4de16256df36a6013785557d': {totalAirdropAmount: '10000000000000000', totalAirdropUsedAmount: '10000000000000000', balanceAirdropAmount: '10000000000000000'},
- * '0x934ebd34b2a4f16d4de16256df36a6013785557e': {totalAirdropAmount: '20000000000000000', totalAirdropUsedAmount: '20000000000000000', balanceAirdropAmount: '10000000000000000'}
- * }
- *
- */
- getAirdropBalance: function (chainId, airdropContractAddress, userAddresses) {
- var userBalance = new UserBalance({
- chainId: chainId,
- airdropContractAddress: airdropContractAddress,
- userAddresses: userAddresses
- });
- return userBalance.perform();
- },
-
-
-};
-
-module.exports = new base();
-
diff --git a/lib/airdrop_management/batch_allocator.js b/lib/airdrop_management/batch_allocator.js
deleted file mode 100644
index 55c376a..0000000
--- a/lib/airdrop_management/batch_allocator.js
+++ /dev/null
@@ -1,231 +0,0 @@
-/**
- *
- * This is a utility file which would be used for allocating amount to airdrop users.
- *
- * @module lib/airdrop_management/batch_allocator
- *
- */
-
-const rootPrefix = '../..'
- , responseHelper = require(rootPrefix + '/lib/formatter/response')
- , airdropKlass = require(rootPrefix + '/app/models/airdrop')
- , userAirdropDetailKlass = require(rootPrefix + '/app/models/user_airdrop_detail')
- , airdropAllocationProofDetailKlass = require(rootPrefix + '/app/models/airdrop_allocation_proof_detail')
- , airdropConstants = require(rootPrefix + '/lib/global_constant/airdrop')
- , BigNumber = require('bignumber.js')
- , basicHelper = require(rootPrefix + '/helpers/basic_helper')
- , logger = require(rootPrefix + '/helpers/custom_console_logger')
- , userAirdropDetailCacheKlass = require(rootPrefix + '/lib/cache_management/user_airdrop_detail')
-;
-
-/**
- * Constructor to create object of batch allocator
- *
- * @constructor
- *
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {Hex} transactionHash - airdrop transfer transactio hash
- * @param {Object} airdropUsers - {userAddress: {airdropAmount: inwei, expiryTimestamp: 0}}
- * @param {Number} chainId - chain ID
- *
- * @return {Object}
- */
-const batchAllocator = module.exports = function(params) {
- logger.debug("\n=========batchAllocator.params=========");
- logger.debug(params);
- const oThis = this;
- oThis.airdropContractAddress = params.airdropContractAddress;
- oThis.transactionHash = params.transactionHash;
- oThis.airdropUsers = params.airdropUsers;
- oThis.chainId = params.chainId;
-
- // New Variables
- oThis.airdropRecord = null;
- oThis.airdropAllocationProofDetailRecord = null;
- oThis.tableFields = ['user_address', 'airdrop_id', 'airdrop_amount', 'expiry_timestamp'];
- oThis.bulkInsertData = [];
- oThis.totalInputAirdropAmount = new BigNumber(0);
- oThis.totalAmountAfterAllocatingInputAmount = new BigNumber(0);
- oThis.userAddresses = [];
-};
-
-batchAllocator.prototype = {
-
- /**
- * Perform batch allocation to airdrop users
- *
- * @return {Promise}
- *
- */
- perform: async function () {
-
- const oThis = this;
-
- var r = null;
-
- r = await oThis.validateParams();
- logger.debug("\n=========batchAllocator.validateParams.result=========");
- logger.debug(r);
- if(r.isFailure()) return r;
-
- r = await oThis.allocateAirdropAmountToUsers();
- logger.debug("\n=========batchAllocator.allocateAirdropAmountToUsers.result=========");
- logger.debug(r);
- return r;
- },
-
- /**
- * Validate params
- *
- * @return {Promise}
- *
- */
- validateParams: function() {
- const oThis = this;
- return new Promise(async function (onResolve, onReject) {
-
- if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
- return onResolve(responseHelper.error('l_am_ba_vp_1', 'airdrop contract address is invalid'));
- }
-
- if (!basicHelper.isTxHashValid(oThis.transactionHash)) {
- return onResolve(responseHelper.error('l_am_ba_vp_2', 'transaction hash is invalid'));
- }
-
- var airdropModel = new airdropKlass();
- var result = await airdropModel.getByContractAddress(oThis.airdropContractAddress);
- oThis.airdropRecord = result[0];
- if (!oThis.airdropRecord) {
- return onResolve(responseHelper.error('l_am_ba_vp_3', 'given airdrop record is not present in DB'));
- }
- var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
- result = await airdropAllocationProofDetailModel.getByTransactionHash(oThis.transactionHash);
- oThis.airdropAllocationProofDetailRecord = result[0];
- if (!oThis.airdropAllocationProofDetailRecord) {
- return onResolve(responseHelper.error('l_am_ba_vp_4', 'Invalid transactionHash. Given airdropAllocationProofDetailRecord is not present in DB'));
- }
-
- if (new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_allocated_amount).gte(new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_amount))) {
- return onResolve(responseHelper.error('l_am_ba_vp_5', 'Allocated amount is greater or equal to airdrop amount'));
- }
-
- if(!oThis.airdropUsers || !(typeof oThis.airdropUsers === "object")) {
- return onResolve(responseHelper.error('l_am_ba_vp_6', 'Invalid airdrop users object'));
- }
-
- const batchSize = Object.keys(oThis.airdropUsers).length;
- if (batchSize > airdropConstants.batchSize()) {
- return onResolve(responseHelper.error('l_am_ba_vp_7', 'airdrop Users Batch size should be: '+batchSize));
- }
-
- var value = null
- , userAddress = ''
- , userAirdropAmount = 0
- , expiryTimestamp = 0
- , insertData = []
- ;
- for (var userAddress in oThis.airdropUsers) {
- value = oThis.airdropUsers[userAddress];
-
- if (!basicHelper.isAddressValid(userAddress)) {
- return onResolve(responseHelper.error('l_am_ba_vp_8', 'userAddress'+ userAddress +' is invalid'));
- }
-
- userAirdropAmount = new BigNumber(value.airdropAmount);
- if (userAirdropAmount.isNaN() || !userAirdropAmount.isInteger()) {
- return onResolve(responseHelper.error('l_am_ba_vp_9', 'userAddress'+ userAddress +' airdrop amount is invalid'));
- }
-
- if (userAirdropAmount.lte(0)) {
- return onResolve(responseHelper.error('l_am_ba_vp_10', 'Airdrop amount 0 or less than 0 for user'+ userAddress +' is not allowed'));
- }
-
- expiryTimestamp = new BigNumber(value.expiryTimestamp);
- if (expiryTimestamp.isNaN() || !expiryTimestamp.isInteger()) {
- return onResolve(responseHelper.error('l_am_ba_vp_11', 'userAddress: '+ userAddress +' expiry Timestamp is invalid'));
- }
-
- oThis.totalInputAirdropAmount = oThis.totalInputAirdropAmount.plus(userAirdropAmount);
- insertData = [
- userAddress,
- oThis.airdropRecord.id,
- userAirdropAmount.toString(10),
- expiryTimestamp.toNumber()
- ];
- oThis.userAddresses.push(userAddress);
- oThis.bulkInsertData.push(insertData);
- }
-
- // Calculate totalAmountToAllocate after adding input amount
- oThis.totalAmountAfterAllocatingInputAmount = (new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_allocated_amount)).
- plus(oThis.totalInputAirdropAmount);
- const airdropAmountBigNumber = new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_amount);
- if (oThis.totalAmountAfterAllocatingInputAmount.gt(airdropAmountBigNumber)) {
- return onResolve(responseHelper.error('l_am_ba_vp_12', 'totalAmountAfterAllocatingInputAmount is greater than transferred airdrop amount'));
- }
- return onResolve(responseHelper.successWithData({}));
-
- });
-
- },
-
- /**
- * Allocate airdrop amount to users
- *
- * @return {Promise}
- *
- */
- allocateAirdropAmountToUsers: async function() {
- const oThis = this;
-
- return new Promise(async function (onResolve, onReject) {
- try {
- // Allocate and update Amount in db
- var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
- var r = await airdropAllocationProofDetailModel.updateAllocatedAmount(
- oThis.airdropAllocationProofDetailRecord.id,
- oThis.totalAmountAfterAllocatingInputAmount.toString(10)
- );
-
- logger.debug("=========allocateAirdropAmountToUsers.airdropAllocationProofDetailModel===========");
- logger.debug(r);
- if(r.isFailure()) return r;
- var userAirdropDetailModel = new userAirdropDetailKlass();
- await userAirdropDetailModel.insertMultiple(oThis.tableFields, oThis.bulkInsertData).fire();
- oThis.clearCache();
- return onResolve(responseHelper.successWithData({}));
-
- } catch(err){
- // If it fails rollback allocated amount
- r = await airdropAllocationProofDetailModel.updateAllocatedAmount(
- oThis.airdropAllocationProofDetailRecord.id,
- (oThis.totalAmountAfterAllocatingInputAmount.minus(oThis.totalInputAirdropAmount)).toString(10)
- );
- logger.debug("=========allocateAirdropAmountToUsers.airdropAllocationProofDetailModel===========");
- logger.debug(r);
- return onResolve(responseHelper.error('l_am_ba_vp_13', 'Error:'+ err +' in inserting for transaction hash: '+oThis.transactionHash, ));
- }
-
- });
-
- },
-
- /**
- * Clear all users cache
- *
- * @return {nil}
- *
- */
- clearCache: async function() {
- const oThis = this;
- const userAirdropDetailCacheKlassObject = new userAirdropDetailCacheKlass({
- chainId: oThis.chainId,
- airdropId: oThis.airdropRecord.id,
- userAddresses: oThis.userAddresses
- });
- await userAirdropDetailCacheKlassObject.clear();
- }
-
-};
-
-module.exports = batchAllocator;
\ No newline at end of file
diff --git a/lib/airdrop_management/register.js b/lib/airdrop_management/register.js
deleted file mode 100644
index fd1ac3b..0000000
--- a/lib/airdrop_management/register.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- *
- * This class would be used for executing airdrop register.
- *
- * @module lib/airdrop_management/register
- *
- */
-
-const rootPrefix = '../..'
- , responseHelper = require(rootPrefix + '/lib/formatter/response')
- , airdropKlass = require(rootPrefix + '/app/models/airdrop')
- , airdropContractInteract = require(rootPrefix + '/lib/contract_interact/airdrop')
- , basicHelper = require(rootPrefix + '/helpers/basic_helper')
- , logger = require(rootPrefix + '/helpers/custom_console_logger')
-;
-
-/**
- * Constructor to create object of register
- *
- * @constructor
- *
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {Number} chainId - chain Id
- *
- * @return {Object}
- *
- */
-const register = module.exports = function (params) {
- logger.debug("=======register.params=======");
- logger.debug(params);
- this.airdropContractAddress = params.airdropContractAddress;
- this.chainId = params.chainId;
-
-};
-
-register.prototype = {
-
- /**
- * Perform method
- *
- * @return {responseHelper}
- *
- */
- perform: async function () {
-
- const oThis = this
- ;
-
- var r = null;
-
- r = await oThis.validateParams();
- logger.debug("=======register.validateParams.result=======");
- logger.debug(r);
- if (r.isFailure()) return r;
-
- r = await oThis.runRegister();
- logger.debug("=======register.runRegister.result=======");
- logger.debug(r);
- return r;
-
- },
-
- /**
- * Validation of params
- *
- * @return {promise
}
- *
- */
- validateParams: function () {
- const oThis = this;
- return new Promise(async function (onResolve, onReject) {
-
- if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
- return onResolve(responseHelper.error('l_am_r_validateParams_1', 'airdrop contract address is invalid'));
- }
-
- if (!basicHelper.isValidChainId(oThis.chainId)) {
- return onResolve(responseHelper.error('l_am_r_validateParams_2', 'ChainId is invalid'));
- }
-
- const airdropContractInteractObject = new airdropContractInteract(oThis.airdropContractAddress, oThis.chainId);
- var result = await airdropContractInteractObject.airdropBudgetHolder();
- const airdropBudgetHolderAddress = result.data.airdropBudgetHolder;
- if (!basicHelper.isAddressValid(airdropBudgetHolderAddress)) {
- return onResolve(responseHelper.error('l_am_r_validateParams_3', 'airdrop contract is invalid'));
- }
-
- // if address already present
- var airdropModel = new airdropKlass();
- result = await airdropModel.getByContractAddress(oThis.airdropContractAddress);
- const airdropRecord = result[0];
- if (airdropRecord) {
- return onResolve(responseHelper.error('l_am_r_validateParams_4', 'airdrop contract address is already registered'));
- }
-
- return onResolve(responseHelper.successWithData({}));
- });
- },
-
- /**
- * Run the register
- *
- * @return {promise}
- *
- */
- runRegister: function () {
- const oThis = this
- ;
-
- return new Promise(async function (onResolve, onReject) {
- try {
- const airdropModelObject = {
- contract_address: oThis.airdropContractAddress
- };
- logger.debug("========register.runRegister.airdropModelObject=======");
- logger.debug(airdropModelObject);
- var airdropModel = new airdropKlass();
- const insertedRecord = await airdropModel.create(airdropModelObject);
- logger.debug("========register.runRegister.insertedRecord=======");
- logger.debug(insertedRecord);
- return onResolve(responseHelper.successWithData({insertId: insertedRecord.insertId}));
- } catch (err) {
- return onResolve(responseHelper.error('l_am_s_rs_1', 'Error creating airdrop record. ' + err));
- }
- });
-
- }
-
-};
-
-module.exports = register;
-
diff --git a/lib/airdrop_management/transfer.js b/lib/airdrop_management/transfer.js
deleted file mode 100644
index 6987d27..0000000
--- a/lib/airdrop_management/transfer.js
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- *
- * This is a utility file which would be used for executing transfer amount to airdrop budget holder.
- *
- * @module lib/airdrop_management/transfer
- *
- */
-
-const rootPrefix = '../..'
- , responseHelper = require(rootPrefix + '/lib/formatter/response')
- , airdropAllocationProofDetailKlass = require(rootPrefix + '/app/models/airdrop_allocation_proof_detail')
- , airdropContractInteract = require(rootPrefix + '/lib/contract_interact/airdrop')
- , brandedTokenContractInteract = require(rootPrefix + '/lib/contract_interact/branded_token')
- , BigNumber = require('bignumber.js')
- , basicHelper = require(rootPrefix + '/helpers/basic_helper')
- , logger = require(rootPrefix + '/helpers/custom_console_logger')
- , airdropKlass = require(rootPrefix + '/app/models/airdrop')
-;
-
-/**
- * Constructor to create object of transfer
- *
- * @constructor
- *
- * @param {Hex} senderAddress - sender address
- * @param {String} senderPassphrase - sender Passphrase
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {String} amount - amount in wei
- * @param {String} gasPrice - gas price
- * @param {Number} chainId - chain Id
- * @param {Object} options - chain Id
- *
- * @return {Object}
- *
- */
-const transfer = module.exports = function(params) {
- logger.debug("\n=========Transfer params=========");
- logger.debug(params);
- const oThis = this;
- oThis.senderAddress = params.senderAddress;
- oThis.senderPassphrase = params.senderPassphrase;
- oThis.airdropContractAddress = params.airdropContractAddress;
- oThis.amount = params.amount;
- oThis.gasPrice = params.gasPrice;
- oThis.chainId = params.chainId;
- oThis.options = params.options;
-
- oThis.airdropBudgetHolder = null;
- oThis.brandedTokenContractAddress = null;
-
-};
-
-transfer.prototype = {
-
- /**
- * Perform method
- *
- * @return {Promise}
- *
- */
- perform: async function () {
-
- const oThis = this;
-
- var r = null;
-
- r = await oThis.validateParams();
- logger.debug("\n=========Transfer.validateParams.result=========");
- logger.debug(r);
- if(r.isFailure()) return r;
-
- r = oThis.doTransfer();
- logger.debug("\n=========Transfer.doTransfer.result=========");
- logger.debug(r);
- return r;
-
- },
-
- /**
- * validation of params
- *
- * @return {Promise}
- *
- */
- validateParams: function() {
- const oThis = this;
- return new Promise(async function (onResolve, onReject) {
-
- if (!basicHelper.isAddressValid(oThis.senderAddress)) {
- return onResolve(responseHelper.error('l_am_t_vp_1', 'sender address is invalid'));
- }
-
- if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
- return onResolve(responseHelper.error('l_am_v_vp_2', 'airdrop contract address is invalid'));
- }
-
- // Check if airdropContractAddress is registered or not
- var airdropModel = new airdropKlass();
- var result = await airdropModel.getByContractAddress(oThis.airdropContractAddress);
- oThis.airdropRecord = result[0];
- if (!oThis.airdropRecord){
- return onResolve(responseHelper.error('l_am_ub_vp_3', 'Given airdrop contract is not registered'));
- }
-
- const airdropContractInteractObject = new airdropContractInteract(oThis.airdropContractAddress, oThis.chainId);
- var result = await airdropContractInteractObject.brandedToken();
- oThis.brandedTokenContractAddress = result.data.brandedToken;
- logger.debug("\n==========transfer.validateParams.brandedToken===========");
- logger.debug("\nairdropContractInteractObject.brandedToken():", result,"\noThis.brandedTokenContractAddress:", oThis.brandedTokenContractAddress);
- if (!basicHelper.isAddressValid(oThis.brandedTokenContractAddress)) {
- return onResolve(responseHelper.error('l_am_v_vp_4', 'brandedTokenContractAddress set in airdrop contract is invalid'));
- }
-
- result = await airdropContractInteractObject.airdropBudgetHolder();
- oThis.airdropBudgetHolderAddress = result.data.airdropBudgetHolder;
- if (!basicHelper.isAddressValid(oThis.brandedTokenContractAddress)) {
- return onResolve(responseHelper.error('l_am_v_vp_5', 'airdropBudgetHolderAddress set in airdrop contract is invalid'));
- }
-
- const amountInBigNumber = new BigNumber(oThis.amount);
- if (amountInBigNumber.isNaN() || !amountInBigNumber.isInteger()){
- return onResolve(responseHelper.error('l_am_v_vp_6', 'amount is invalid value'));
- }
-
- if (!basicHelper.isValidChainId(oThis.chainId)) {
- return onResolve(responseHelper.error('l_am_v_vp_7', 'ChainId is invalid'));
- }
-
- return onResolve(responseHelper.successWithData({}));
-
- });
-
- },
-
- /**
- * Transfer amount to airdrop budget holder
- *
- * @return {Promise}
- *
- */
- doTransfer: async function() {
- const oThis = this;
-
- return new Promise(async function (onResolve, onReject) {
- // BrandedToken transfer
- logger.debug("\n==========doTransfer.oThis.brandedTokenContractAddress===========");
- logger.debug(oThis.brandedTokenContractAddress);
- var brandedTokenObject = new brandedTokenContractInteract(oThis.brandedTokenContractAddress, oThis.chainId);
- const transactionResponse = await brandedTokenObject.transferToAirdropBudgetHolder(oThis.senderAddress,
- oThis.senderPassphrase,
- oThis.airdropBudgetHolderAddress,
- oThis.amount,
- oThis.gasPrice,
- oThis.options);
- if (transactionResponse.isSuccess()){
- var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
- const airdropAllocationProofDetailCreateResult = await airdropAllocationProofDetailModel.createRecord(transactionResponse.data.transaction_hash, oThis.amount, 0);
- if (airdropAllocationProofDetailCreateResult.isFailure()) {
- return onResolve(airdropAllocationProofDetailCreateResult);
- }
- }
- return onResolve(transactionResponse);
- });
- }
-
-};
-
-module.exports = transfer;
-
diff --git a/lib/airdrop_management/user_balance.js b/lib/airdrop_management/user_balance.js
deleted file mode 100644
index 132e33d..0000000
--- a/lib/airdrop_management/user_balance.js
+++ /dev/null
@@ -1,124 +0,0 @@
-/**
- *
- * This class would be used for calculating user airdrop balance.
- *
- * @module lib/airdrop_management/user_balance
- *
- */
-
-const rootPrefix = '../..'
- , responseHelper = require(rootPrefix + '/lib/formatter/response')
- , airdropKlass = require(rootPrefix + '/app/models/airdrop')
- , basicHelper = require(rootPrefix + '/helpers/basic_helper')
- , logger = require(rootPrefix + '/helpers/custom_console_logger')
- , userAirdropDetailCacheKlass = require(rootPrefix + '/lib/cache_management/user_airdrop_detail')
-;
-
-/**
- * Constructor to create object of userBalance
- *
- * @constructor
- *
- * @param {Number} chainId - chain Id
- * @param {Hex} airdropContractAddress - airdrop contract address
- * @param {Array} userAddresses - Array of user addressed
- *
- * @return {Object}
- *
- */
-const AirdropUserBalanceKlass = function(params) {
- logger.debug("=======user_balance.params=======");
- logger.debug(params);
- const oThis = this;
- oThis.airdropContractAddress = params.airdropContractAddress;
- oThis.chainId = params.chainId;
- oThis.userAddresses = params.userAddresses;
-
- oThis.airdropRecord = null;
-
-};
-
-AirdropUserBalanceKlass.prototype = {
-
- /**
- * Perform method
- *
- * @return {responseHelper}
- *
- */
- perform: async function () {
-
- const oThis = this;
-
- var r = null;
-
- r = await oThis.validateParams();
- logger.debug("=======userBalance.validateParams.result=======");
- logger.debug(r);
- if(r.isFailure()) return r;
-
- r = await oThis.getUserAirdropBalance();
- logger.debug("=======userBalance.getUserAirdropBalance.result=======");
- logger.debug(r);
- return r;
-
- },
-
- /**
- * Validation of params
- *
- * @return {Promise}
- *
- */
- validateParams: function(){
- const oThis = this;
- return new Promise(async function (onResolve, onReject) {
-
- if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
- return onResolve(responseHelper.error('l_am_ub_vp_1', 'airdrop contract address is invalid'));
- }
-
- if (!basicHelper.isValidChainId(oThis.chainId)) {
- return onResolve(responseHelper.error('l_am_ub_vp_2', 'ChainId is invalid'));
- }
-
- // if address already present
- var airdropModel = new airdropKlass();
- var result = await airdropModel.getByContractAddress(oThis.airdropContractAddress);
- oThis.airdropRecord = result[0];
- if (!oThis.airdropRecord){
- return onResolve(responseHelper.error('l_am_ub_vp_3', 'Given airdrop contract is not registered'));
- }
-
- return onResolve(responseHelper.successWithData({}));
- });
-
- },
-
- /**
- * Run the register
- *
- * @return {Promise}
- *
- */
- getUserAirdropBalance: function() {
- const oThis = this;
- return new Promise(async function (onResolve, onReject) {
- try {
- const userAirdropDetailCacheKlassObject = new userAirdropDetailCacheKlass({
- chainId: oThis.chainId,
- airdropId: oThis.airdropRecord.id,
- userAddresses: oThis.userAddresses
- });
- return onResolve(await userAirdropDetailCacheKlassObject.fetch());
- } catch(err){
- return onResolve(responseHelper.error('l_am_ub_vp_4', 'getUserAirdropBalance error: '+err));
- }
- });
-
- }
-
-};
-
-module.exports = AirdropUserBalanceKlass;
-
diff --git a/lib/cache_management/airdrop_model.js b/lib/cache_management/airdrop_model.js
new file mode 100644
index 0000000..fc6514b
--- /dev/null
+++ b/lib/cache_management/airdrop_model.js
@@ -0,0 +1,93 @@
+"use strict";
+
+const rootPrefix = '../..'
+ , baseCache = require(rootPrefix + '/lib/cache_management/base')
+ , AirdropModelKlass = require(rootPrefix + '/app/models/airdrop')
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+;
+
+/**
+ * constructor
+ *
+ * @param {object} cache get/set related arguments
+ * @constructor
+ *
+ */
+const AirdropModelCacheKlass = function(params) {
+
+ const oThis = this;
+
+ oThis.contractAddress = params.contractAddress;
+ baseCache.call(oThis, params);
+
+};
+
+AirdropModelCacheKlass.prototype = Object.create(baseCache.prototype);
+
+const AirdropModelCacheKlassPrototype = {
+
+ /**
+ * set cache key
+ *
+ * @return {String}
+ */
+ setCacheKey: function() {
+
+ const oThis = this;
+
+ oThis.cacheKey = oThis._cacheKeyPrefix() + "airdrop_"+oThis.contractAddress.toLowerCase();
+
+ return oThis.cacheKey;
+
+ },
+
+ /**
+ * set cache expiry in oThis.cacheExpiry and return it
+ *
+ * @return {Number}
+ */
+ setCacheExpiry: function() {
+
+ const oThis = this;
+
+ oThis.cacheExpiry = 86400; // 24 hours ;
+
+ return oThis.cacheExpiry;
+
+ },
+
+ /**
+ * Fetch data from source
+ *
+ * @return {Result}
+ */
+ fetchDataFromSource: function() {
+
+ const oThis = this;
+
+ return new Promise(async function(onResolve, onReject){
+
+ const airdropModelObject = new AirdropModelKlass()
+ , airdropResponse = await airdropModelObject.getByContractAddress(oThis.contractAddress)
+ , airdropRecord = airdropResponse[0]
+ ;
+
+ // Return null if airdrop record not found
+ if (!airdropRecord){
+ return onResolve(responseHelper.successWithData({id: 0}));
+ }
+
+ var formattedAirdropDetails = {};
+ formattedAirdropDetails[airdropRecord.contract_address] = {id: airdropRecord.id};
+
+ return onResolve(responseHelper.successWithData(formattedAirdropDetails));
+
+ });
+
+ }
+
+};
+
+Object.assign(AirdropModelCacheKlass.prototype, AirdropModelCacheKlassPrototype);
+
+module.exports = AirdropModelCacheKlass;
\ No newline at end of file
diff --git a/lib/cache_management/base.js b/lib/cache_management/base.js
index 7b0e7d8..ee8e5e5 100644
--- a/lib/cache_management/base.js
+++ b/lib/cache_management/base.js
@@ -1,13 +1,11 @@
"use strict";
const rootPrefix = '../..'
- , coreConstants = require(rootPrefix + '/config/core_constants')
- , openStCache = require('@openstfoundation/openst-cache')
- , openStCacheKeys = openStCache.OpenSTCacheKeys
- , cacheImplementer = new openStCache.cache(coreConstants.CACHING_ENGINE, true)
- , responseHelper = require(rootPrefix + '/lib/formatter/response')
- , logger = require(rootPrefix+'/helpers/custom_console_logger')
- , utils = require(rootPrefix + '/lib/utils')
+ , openStCache = require('@openstfoundation/openst-cache')
+ , coreConstants = require(rootPrefix + '/config/core_constants')
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , logger = require(rootPrefix+'/helpers/custom_console_logger')
+ , cacheImplementer = new openStCache.cache(coreConstants.CACHING_ENGINE, true);
;
/**
@@ -17,24 +15,33 @@ const rootPrefix = '../..'
*
* @constructor
*/
-const baseCacheMultiManagementKlass = function(params) {
+const baseCacheManagementKlass = function(params) {
const oThis = this;
- if (!params) {
+ if(!params){
params = {};
}
oThis.params = params;
- oThis.cacheKeys = {};
+ oThis.useObject = params.useObject === true;
- // call sub class method to set cache keys using params provided
- oThis.setCacheKeys();
+ oThis.cacheKey = null;
+
+ oThis.cacheExpiry = null;
+
+ // Set cacheImplementer to perform caching operations
+ oThis.cacheImplementer = cacheImplementer;
+ // call sub class method to set cache key using params provided
+ oThis.setCacheKey();
+
+ // call sub class method to set cache expiry using params provided
+ oThis.setCacheExpiry();
};
-baseCacheMultiManagementKlass.prototype = {
+baseCacheManagementKlass.prototype = {
/**
* Fetch data from cache, in case of cache miss calls sub class method to fetch data from source
@@ -46,31 +53,26 @@ baseCacheMultiManagementKlass.prototype = {
const oThis = this;
var data = await oThis._fetchFromCache()
- , fetchDataRsp = null;
+ , fetchDataRsp = null;
- // if there are any cache misses then fetch that data from source.
- if (data['cacheMiss'].length > 0) {
+ // if cache miss call sub class method to fetch data from source and set cache
+ if (!data) {
- fetchDataRsp = await oThis.fetchDataFromSource(data['cacheMiss']);
+ fetchDataRsp = await oThis.fetchDataFromSource();
// if fetch from source failed do not set cache and return error response
if (fetchDataRsp.isFailure()) {
- logger.notify('l_cm_b_1', 'Something Went Wrong', fetchDataRsp);
- return Promise.resolve(fetchDataRsp);
+ logger.error('l_cm_b_fetch_1', 'Something Went Wrong', fetchDataRsp);
+ return fetchDataRsp;
} else {
- // DO NOT WAIT for cache being set
- var cacheKeys = Object.keys(fetchDataRsp.data);
- for (var i=0; iError while getting from cache: ", JSON.stringify(cacheFetchResponse));
- for (var i = 0; i < cacheKeys.length; i++) {
- var cacheKey = cacheKeys[i];
- cacheMiss.push(oThis.cacheKeys[cacheKey]);
- }
+ cacheFetchResponse = await oThis.cacheImplementer.get(oThis.cacheKey);
+ }
+
+ if (cacheFetchResponse.isSuccess()) {
+ cacheData = cacheFetchResponse.data.response;
}
- return {cacheMiss: cacheMiss, cachedData: cachedResponse};
+ return cacheData;
+
},
/**
* set data in cache.
*
- * @param {Object} dataToSet - data to set in cache
+ * @param {Object} dataToSet - data to se tin cache
*
* @return {Result}
*/
- _setCache: function (key, dataToSet) {
+ _setCache: function (dataToSet) {
const oThis = this;
- var setCacheFunction = function(k, v) {
- var cacheKey = utils.invert(oThis.cacheKeys)[k];
- return cacheImplementer.set(cacheKey, JSON.stringify(v), oThis.cacheExpiry);
+ var setCacheFunction = function() {
+ if(oThis.useObject) {
+ return oThis.cacheImplementer.setObject(oThis.cacheKey, dataToSet, oThis.cacheExpiry);
+ } else {
+ return oThis.cacheImplementer.set(oThis.cacheKey, dataToSet, oThis.cacheExpiry);
+ }
+
};
- setCacheFunction(key, dataToSet).then(function(cacheSetResponse) {
+ setCacheFunction().then(function(cacheSetResponse){
if (cacheSetResponse.isFailure()) {
- logger.notify('cmm_b_2', 'Something Went Wrong', cacheSetResponse);
+ logger.notify('l_cm_b_setCache_1', 'Something Went Wrong', cacheSetResponse);
}
});
+ },
+
+ /**
+ * cache key prefix
+ *
+ * @return {String}
+ */
+ _cacheKeyPrefix: function () {
+ return 'ost_payment_';
+ },
+
+ /**
+ * Shared cache key prefix
+ * This cache is shared between company api and saas
+ * Cache keys with these prefixes can be flushed via company api or saas.
+ *
+ * @return {String}
+ */
+ _sharedCacheKeyPrefix: function () {
+ return 'ost_payment__shared_';
}
-};
+}
-module.exports = baseCacheMultiManagementKlass;
+module.exports = baseCacheManagementKlass;
diff --git a/lib/cache_multi_management/base.js b/lib/cache_multi_management/base.js
new file mode 100644
index 0000000..ba63e25
--- /dev/null
+++ b/lib/cache_multi_management/base.js
@@ -0,0 +1,189 @@
+"use strict";
+
+const rootPrefix = '../..'
+ , coreConstants = require(rootPrefix + '/config/core_constants')
+ , openStCache = require('@openstfoundation/openst-cache')
+ , cacheImplementer = new openStCache.cache(coreConstants.CACHING_ENGINE, true)
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , logger = require(rootPrefix+'/helpers/custom_console_logger')
+ , utils = require(rootPrefix + '/lib/utils')
+;
+
+/**
+ * constructor
+ *
+ * @param {Object} params - cache key generation & expiry related params
+ *
+ * @constructor
+ */
+const baseCacheMultiManagementKlass = function(params) {
+
+ const oThis = this;
+
+ if (!params) {
+ params = {};
+ }
+
+ oThis.params = params;
+
+ oThis.cacheKeys = {};
+
+ // call sub class method to set cache keys using params provided
+ oThis.setCacheKeys();
+
+};
+
+baseCacheMultiManagementKlass.prototype = {
+
+ /**
+ * Fetch data from cache, in case of cache miss calls sub class method to fetch data from source
+ *
+ * @return {Promise} - On success, data.value has value. On failure, error details returned.
+ */
+ fetch: async function () {
+
+ const oThis = this;
+
+ var data = await oThis._fetchFromCache()
+ , fetchDataRsp = null;
+
+ // if there are any cache misses then fetch that data from source.
+ if (data['cacheMiss'].length > 0) {
+
+ fetchDataRsp = await oThis.fetchDataFromSource(data['cacheMiss']);
+
+ // if fetch from source failed do not set cache and return error response
+ if (fetchDataRsp.isFailure()) {
+ logger.notify('l_cm_b_1', 'Something Went Wrong', fetchDataRsp);
+ return Promise.resolve(fetchDataRsp);
+ } else {
+ // DO NOT WAIT for cache being set
+ var cacheKeys = Object.keys(fetchDataRsp.data);
+ for (var i=0; i}
+ */
+ clear: function () {
+
+ const oThis = this;
+
+ for (var i=0; iError while getting from cache: ", JSON.stringify(cacheFetchResponse));
+ for (var i = 0; i < cacheKeys.length; i++) {
+ var cacheKey = cacheKeys[i];
+ cacheMiss.push(oThis.cacheKeys[cacheKey]);
+ }
+ }
+
+ return {cacheMiss: cacheMiss, cachedData: cachedResponse};
+ },
+
+ /**
+ * set data in cache.
+ *
+ * @param {Object} dataToSet - data to set in cache
+ *
+ * @return {Result}
+ */
+ _setCache: function (key, dataToSet) {
+
+ const oThis = this;
+
+ var setCacheFunction = function(k, v) {
+ var cacheKey = utils.invert(oThis.cacheKeys)[k];
+ return cacheImplementer.set(cacheKey, JSON.stringify(v), oThis.cacheExpiry);
+ };
+
+ setCacheFunction(key, dataToSet).then(function(cacheSetResponse) {
+
+ if (cacheSetResponse.isFailure()) {
+ logger.error('cmm_b_2', 'Something Went Wrong', cacheSetResponse);
+ }
+ });
+
+ }
+
+};
+
+module.exports = baseCacheMultiManagementKlass;
diff --git a/lib/cache_management/user_airdrop_detail.js b/lib/cache_multi_management/user_airdrop_detail.js
similarity index 76%
rename from lib/cache_management/user_airdrop_detail.js
rename to lib/cache_multi_management/user_airdrop_detail.js
index b64fcb8..c97db4e 100644
--- a/lib/cache_management/user_airdrop_detail.js
+++ b/lib/cache_multi_management/user_airdrop_detail.js
@@ -1,12 +1,19 @@
"use strict";
const rootPrefix = '../..'
- , baseCache = require(rootPrefix + '/lib/cache_management/base')
+ , baseCache = require(rootPrefix + '/lib/cache_multi_management/base')
, UserAirdropDetailKlass = require(rootPrefix + '/app/models/user_airdrop_detail')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
/**
* @constructor
* @augments userAirdropDetailCache
@@ -42,9 +49,14 @@ userAirdropDetailCache.prototype.fetchDataFromSource = async function (cacheIds)
logger.debug("===========cacheManagement.user_airdrop_details.fetchDataFromSource.cacheIds===============");
logger.debug(cacheIds);
if (!cacheIds) {
- return responseHelper.error(
- 'l_cm_uad_1', 'blank addresses'
- );
+
+ let errorParams = {
+ internal_error_identifier: 'l_cm_uad_1',
+ api_error_identifier: 'user_address_invalid',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
}
logger.debug("===========cacheManagement.user_airdrop_details.callingFromDB===============");
@@ -54,9 +66,15 @@ userAirdropDetailCache.prototype.fetchDataFromSource = async function (cacheIds)
if (queryResponse.isSuccess()) {
return queryResponse;
} else {
- return responseHelper.error(
- 'l_cm_uad_2', 'No Data found'
- );
+
+ let errorParams = {
+ internal_error_identifier: 'l_cm_uad_2',
+ api_error_identifier: 'data_not_found',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+
+ return responseHelper.error(errorParams);
}
};
diff --git a/lib/contract_interact/EIP20TokenMock.js b/lib/contract_interact/EIP20TokenMock.js
index 104c438..488a6af 100644
--- a/lib/contract_interact/EIP20TokenMock.js
+++ b/lib/contract_interact/EIP20TokenMock.js
@@ -10,12 +10,12 @@
const rootPrefix = '../..';
const helper = require(rootPrefix + '/lib/contract_interact/helper');
const coreAddresses = require(rootPrefix + '/config/core_addresses');
-const web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc');
+const web3Provider = require(rootPrefix + '/lib/web3/providers/ws');
const coreConstants = require(rootPrefix + '/config/core_constants');
const contractName = 'eip20tokenmock';
const contractAbi = coreAddresses.getAbiForContract(contractName);
-const gasLimit = coreConstants.OST_GAS_LIMIT;
-const currContract = new web3RpcProvider.eth.Contract(contractAbi);
+const gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+const currContract = new web3Provider.eth.Contract(contractAbi);
/**
@@ -40,7 +40,7 @@ MockToken.prototype = {
const transactionObject = currContract.methods.balanceOf(ownerAddress);
const encodedABI = transactionObject.encodeABI();
const transactionOutputs = helper.getTransactionOutputs(transactionObject);
- const response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ const response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(response[0]);
},
@@ -64,16 +64,16 @@ MockToken.prototype = {
helper.assertAddress(senderAddress);
currContract.options.address = this.contractAddress;
- currContract.setProvider( web3RpcProvider.currentProvider );
+ //currContract.setProvider( web3Provider.currentProvider );
const transactionObject = currContract.methods.setBalance(ownerAddress, value);
const encodedABI = transactionObject.encodeABI();
return helper.safeSendFromAddr(
- web3RpcProvider,
+ web3Provider,
this.contractAddress,
encodedABI,
senderAddress,
senderPassphrase,
- { gasPrice: gasPrice, gas: gasLimit }
+ { gasPrice: gasPrice, gas: gasLimitGlobalConstant.default() }
).then(function(transactionReceipt) {
return Promise.resolve(transactionReceipt);
});
@@ -97,16 +97,16 @@ MockToken.prototype = {
helper.assertAddress(senderAddress);
currContract.options.address = this.contractAddress;
- currContract.setProvider( web3RpcProvider.currentProvider );
+ //currContract.setProvider( web3Provider.currentProvider );
const transactionObject = currContract.methods.setConverionRate(conversionRate);
const encodedABI = transactionObject.encodeABI();
return helper.safeSendFromAddr(
- web3RpcProvider,
+ web3Provider,
this.contractAddress,
encodedABI,
senderAddress,
senderPassphrase,
- { gasPrice: gasPrice, gas: gasLimit }
+ { gasPrice: gasPrice, gas: gasLimitGlobalConstant.default() }
).then(function(transactionReceipt) {
return Promise.resolve(transactionReceipt);
});
@@ -132,16 +132,16 @@ MockToken.prototype = {
helper.assertAddress(spenderAddress);
currContract.options.address = this.contractAddress;
- currContract.setProvider( web3RpcProvider.currentProvider );
+ //currContract.setProvider( web3Provider.currentProvider );
const transactionObject = currContract.methods.approve(spenderAddress, value);
const encodedABI = transactionObject.encodeABI();
return helper.safeSendFromAddr(
- web3RpcProvider,
+ web3Provider,
this.contractAddress,
encodedABI,
senderAddress,
senderPassphrase,
- { gasPrice: gasPrice, gas: gasLimit }
+ { gasPrice: gasPrice, gas: gasLimitGlobalConstant.default() }
).then(function(transactionReceipt) {
return Promise.resolve(transactionReceipt);
});
diff --git a/lib/contract_interact/airdrop.js b/lib/contract_interact/airdrop.js
index 8c1e47c..9b18640 100644
--- a/lib/contract_interact/airdrop.js
+++ b/lib/contract_interact/airdrop.js
@@ -13,21 +13,27 @@ const BigNumber = require('bignumber.js')
const rootPrefix = '../..'
, helper = require(rootPrefix + '/lib/contract_interact/helper')
, coreAddresses = require(rootPrefix + '/config/core_addresses')
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
- , coreConstants = require(rootPrefix + '/config/core_constants')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
, basicHelper = require(rootPrefix + '/helpers/basic_helper')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
, eventGlobalConstants = require(rootPrefix+'/lib/global_constant/events')
, notificationGlobalConstant = require(rootPrefix + '/lib/global_constant/notification')
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
, Pricer = require(rootPrefix + '/lib/contract_interact/pricer')
- , AirdropUserBalanceKlass = require(rootPrefix + '/lib/airdrop_management/user_balance')
, AirdropCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop')
+ , AirdropUserBalanceKlass = require(rootPrefix + '/services/airdrop_management/user_balance')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
const contractAbi = coreAddresses.getAbiForContract('airdrop')
- , currContract = new web3RpcProvider.eth.Contract(contractAbi)
- , gasLimit = coreConstants.OST_GAS_LIMIT
+ , currContract = new web3Provider.eth.Contract(contractAbi)
;
/**
@@ -66,6 +72,7 @@ Airdrop.prototype.constructor = Airdrop;
* @param {string} currency - quote currency
* @param {BigNumber} intendedPricePoint - price point at which the pay is intended (in wei)
* @param {string} spender - User address
+ * @param {Hex} gas_price - gas price
* @param {object} options - for params like returnType, tag.
*
* @return {promise}
@@ -113,15 +120,20 @@ Airdrop.prototype.pay = async function (senderWorkerAddress, senderWorkerPassphr
logger.debug("==========airdrop.pay.senderAccountBalanceResponse===========");
logger.debug(spenderAccountBalanceResponse);
if (spenderAccountBalanceResponse.isFailure()) {
- return Promise.resolve(responseHelper.error('l_ci_a_pay_1', 'error while getting balance'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_pay_1',
+ api_error_identifier: 'db_get_failed',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
-
- var airdropUserBalance = new AirdropUserBalanceKlass({
- chainId: oThis.chainId,
- airdropContractAddress: oThis.contractAddress,
- userAddresses: [spender]
+ var AirdropUserBalanceObject = new AirdropUserBalanceKlass({
+ chain_id: oThis.chainId,
+ airdrop_contract_address: oThis.contractAddress,
+ user_addresses: [spender]
});
- const airdropBalanceResult = await airdropUserBalance.perform();
+ const airdropBalanceResult = await AirdropUserBalanceObject.perform();
logger.debug("==========airdrop.pay.airdropBalanceResult===========");
logger.debug(airdropBalanceResult);
if (airdropBalanceResult.isFailure()){
@@ -142,7 +154,13 @@ Airdrop.prototype.pay = async function (senderWorkerAddress, senderWorkerPassphr
logger.debug(`\nuserInitialBalance.plus(airdropAmountToUse): ${(userInitialBalance.plus(airdropAmountToUse)).toString(10)}`);
if ((userInitialBalance.plus(airdropAmountToUse)).lt(totalAmount)) {
- return Promise.resolve(responseHelper.error('l_ci_a_pay_2', 'insufficient balance for the transaction. (spender+airdropAmountToUse) balance is insufficient for transaction.'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_pay_2',
+ api_error_identifier: 'insufficient_funds',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
var brandedTokenAddress = null;
@@ -169,10 +187,10 @@ Airdrop.prototype.pay = async function (senderWorkerAddress, senderWorkerPassphr
transferAmount,
commissionBeneficiaryAddress,
commissionAmount,
- web3RpcProvider.utils.asciiToHex(currency),
+ web3Provider.utils.asciiToHex(currency),
intendedPricePoint,
spender,
- userAirdropAmount.toString());
+ userAirdropAmount.toString(10));
const notificationData = helper.getNotificationData(
['transfer.payments.airdrop.pay'],
@@ -180,12 +198,28 @@ Airdrop.prototype.pay = async function (senderWorkerAddress, senderWorkerPassphr
'pay',
oThis.contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
notificationData.message.payload.erc20_contract_address = brandedTokenAddress;
+ const postPayParams = {
+ beneficiaryAddress: beneficiaryAddress,
+ commissionBeneficiaryAddress: commissionBeneficiaryAddress,
+ spender: spender,
+ brandedTokenAddress: brandedTokenAddress,
+ contractAddress: oThis.contractAddress,
+ totalAmount: totalAmount.toString(10),
+ airdropAmountToUse: airdropAmountToUse.toString(10),
+ airdropBudgetHolder: airdropBudgetHolder,
+ chainId: oThis.chainId
+ };
+
+ const failCallback = async function(reason) {
+ return await oThis.onAirdropPayFailure(postPayParams);;
+ };
+
const successCallback = async function(receipt) {
const setAddressToNameMapResponse = await oThis.setAddressToNameMap();
@@ -193,61 +227,13 @@ Airdrop.prototype.pay = async function (senderWorkerAddress, senderWorkerPassphr
return setAddressToNameMapResponse;
}
- const actualAmountFromReceipt = oThis.transactionHelper.getActualAmountsFromReceipt(receipt, oThis.addressToNameMap, eventGlobalConstants.eventAirdropPayment());
- logger.debug("========airdrop.pay.actualAmountFromReceipt Response========");
- logger.debug(actualAmountFromReceipt);
- if (actualAmountFromReceipt.isSuccess()) {
- const afterSuccessResponse = await oThis.transactionHelper.afterAirdropPaySuccess(
- brandedTokenAddress,
- oThis.contractAddress,
- spender,
- totalAmount,
- airdropAmountToUse,
- beneficiaryAddress,
- actualAmountFromReceipt.data.actualBeneficiaryAmount,
- commissionBeneficiaryAddress,
- actualAmountFromReceipt.data.actualCommissionAmount,
- actualAmountFromReceipt.data.actualAirdropAmount,
- airdropBudgetHolder);
-
- const isAllResponseSuccessful = oThis.transactionHelper.isAllResponseSuccessful(afterSuccessResponse);
- if (isAllResponseSuccessful) {
- return afterSuccessResponse;
- } else {
- return responseHelper.error('l_ci_a_pay_3', 'Something went wrong');
- }
- } else {
- const afterFailureResponse = await oThis.transactionHelper.afterAirdropPayFailure(
- brandedTokenAddress,
- oThis.contractAddress,
- spender,
- totalAmount,
- airdropAmountToUse,
- airdropBudgetHolder);
-
- const isAllResponseSuccessful = oThis.transactionHelper.isAllResponseSuccessful(afterFailureResponse);
- if (isAllResponseSuccessful) {
- return responseHelper.error('l_ci_a_pay_4', 'Something went wrong');
- } else {
- return responseHelper.error('l_ci_a_pay_5', 'Something went wrong');
- }
- }
- };
-
- const failCallback = async function(reason) {
- const afterFailureResponse = await oThis.transactionHelper.afterAirdropPayFailure(
- brandedTokenAddress,
- oThis.contractAddress,
- spender,
- totalAmount,
- airdropAmountToUse,
- airdropBudgetHolder);
-
- const isAllResponseSuccessful = oThis.transactionHelper.isAllResponseSuccessful(afterFailureResponse);
- if (isAllResponseSuccessful) {
- return responseHelper.error('l_ci_a_pay_6', 'Something went wrong');
+ const actualAmountsFromReceipt = oThis.transactionHelper.getActualAmountsFromReceipt(receipt, oThis.addressToNameMap, eventGlobalConstants.eventAirdropPayment());
+ logger.debug("========airdrop.pay.actualAmountsFromReceipt Response========");
+ logger.debug(actualAmountsFromReceipt);
+ if (actualAmountsFromReceipt.isSuccess()) {
+ return await oThis.onAirdropPaySuccess(postPayParams, actualAmountsFromReceipt.data);
} else {
- return responseHelper.error('l_ci_a_pay_7', 'Something went wrong');
+ return failCallback("Status 0x0");
}
};
@@ -258,13 +244,20 @@ Airdrop.prototype.pay = async function (senderWorkerAddress, senderWorkerPassphr
senderPassphrase: senderWorkerPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: coreConstants.OST_PAY_GAS_LIMIT,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.airdropPay(),
+ web3Provider: web3Provider,
successCallback: successCallback,
failCallback: failCallback,
errorCode: "l_ci_ad_p_3"
};
+ if (options && options.shouldHandlePostPay == 0) {
+ params.processReceipt = 0;
+ params.postReceiptProcessParams = postPayParams;
+ } else {
+ params.processReceipt = 1;
+ }
+
const beforePayResponse = await oThis.transactionHelper.beforeAirdropPay(
brandedTokenAddress,
oThis.contractAddress,
@@ -277,11 +270,194 @@ Airdrop.prototype.pay = async function (senderWorkerAddress, senderWorkerPassphr
if (isAllResponseSuccessful) {
return Promise.resolve(helper.performSend(params, returnType));
} else {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_pay_8',
+ api_error_identifier: 'could_not_process',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ logger.error('%Error - Something went wrong. It could be that either cache or airdrop used amount promise failed.');
// TODO: Discuss: we may need to do some revert ?
- return Promise.resolve(responseHelper.error('l_ci_a_pay_8', 'Something went wrong. It could be that either cache or airdrop used amount promise failed.'));
+ return Promise.resolve(responseHelper.error(errorParams));
+ }
+};
+
+
+/**
+ * postAirdropPay
+ *
+ * @param {Object} airdropPostPayParams - airdrop post pay params
+ * @param {string} airdropPostPayParams.beneficiaryAddress - beneficiary address
+ * @param {string} airdropPostPayParams.commissionBeneficiaryAddress - commission beneficiary address
+ * @param {string} airdropPostPayParams.spender - spender address
+ * @param {string} airdropPostPayParams.brandedTokenAddress - branded token address
+ * @param {string} airdropPostPayParams.contractAddress - contractAddress address
+ * @param {string} airdropPostPayParams.airdropBudgetHolder - airdrop budget holder address
+ * @param {number} airdropPostPayParams.totalAmount - total amount that was debited from spender account
+ * @param {number} airdropPostPayParams.airdropAmountToUse - airdrop amount that was used in the transaction
+ * @param {number} airdropPostPayParams.chainId - chain id
+ * @param {Object} decodedEvents - decoded events from trasaction receipt
+ * @param {number} status - transactions status (0 => failure, 1 => success)
+ *
+ * @return {promise}
+ *
+ */
+Airdrop.prototype.postAirdropPay = async function(airdropPostPayParams, decodedEvents, status) {
+ const oThis = this
+ ;
+
+ if (status == 1) {
+
+ const actualAmountsFromReceipt = oThis.transactionHelper.getActualAmountsFromDecodedEvents(decodedEvents,
+ eventGlobalConstants.eventAirdropPayment());
+
+ if (actualAmountsFromReceipt.isSuccess()) {
+ return await oThis.onAirdropPaySuccess(airdropPostPayParams, actualAmountsFromReceipt.data);
+ }
}
+
+ return await oThis.onAirdropPayFailure(airdropPostPayParams);
+
};
+
+/**
+ * onAirdropPaySuccess
+ *
+ * @param {Object} airdropPostPayParams - airdrop post pay params
+ * @param {string} airdropPostPayParams.beneficiaryAddress - beneficiary address
+ * @param {string} airdropPostPayParams.commissionBeneficiaryAddress - commission beneficiary address
+ * @param {string} airdropPostPayParams.spender - spender address
+ * @param {string} airdropPostPayParams.brandedTokenAddress - branded token address
+ * @param {string} airdropPostPayParams.contractAddress - contractAddress address
+ * @param {string} airdropPostPayParams.airdropBudgetHolder - airdrop budget holder address
+ * @param {number} airdropPostPayParams.totalAmount - total amount that was debited from spender account
+ * @param {number} airdropPostPayParams.airdropAmountToUse - airdrop amount that was used in the transaction
+ * @param {number} airdropPostPayParams.chainId - chain id
+ * @param {Object} actualAmountsFromReceipt - Actual transfer amounts from receipt
+ *
+ * @return {promise}
+ *
+ */
+Airdrop.prototype.onAirdropPaySuccess = async function (airdropPostPayParams, actualAmountsFromReceipt) {
+
+ const oThis = this;
+ try {
+ const validationResponse = helper.validatePostAirdropPayParams(airdropPostPayParams);
+ if (validationResponse.isFailure()) return Promise.resolve(validationResponse);
+
+ const brandedTokenAddress = airdropPostPayParams.brandedTokenAddress
+ , contractAddress = airdropPostPayParams.contractAddress
+ , spender = airdropPostPayParams.spender
+ , totalAmount = new BigNumber(airdropPostPayParams.totalAmount)
+ , airdropAmountToUse = new BigNumber(airdropPostPayParams.airdropAmountToUse)
+ , beneficiaryAddress = airdropPostPayParams.beneficiaryAddress
+ , commissionBeneficiaryAddress = airdropPostPayParams.commissionBeneficiaryAddress
+ , airdropBudgetHolder = airdropPostPayParams.airdropBudgetHolder
+ ;
+
+ const afterSuccessResponse = await oThis.transactionHelper.afterAirdropPaySuccess(
+ brandedTokenAddress,
+ contractAddress,
+ spender,
+ totalAmount,
+ airdropAmountToUse,
+ beneficiaryAddress,
+ actualAmountsFromReceipt.actualBeneficiaryAmount,
+ commissionBeneficiaryAddress,
+ actualAmountsFromReceipt.actualCommissionAmount,
+ actualAmountsFromReceipt.actualAirdropAmount,
+ airdropBudgetHolder);
+
+ const isAllResponseSuccessful = oThis.transactionHelper.isAllResponseSuccessful(afterSuccessResponse);
+ if (isAllResponseSuccessful) {
+ return Promise.resolve(responseHelper.successWithData({}));
+ }
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_onAirdropPaySuccess_1',
+ api_error_identifier: 'could_not_process',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
+ } catch (err) {
+ logger.error("lib/contract_interact/airdrop.js:onAirdropPaySuccess inside catch ", err);
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_onAirdropPaySuccess_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
+ }
+
+};
+
+/**
+ * onAirdropPayFailure
+ *
+ * @param {Object} airdropPostPayParams - airdrop post pay params
+ * @param {string} airdropPostPayParams.beneficiaryAddress - beneficiary address
+ * @param {string} airdropPostPayParams.commissionBeneficiaryAddress - commission beneficiary address
+ * @param {string} airdropPostPayParams.spender - spender address
+ * @param {string} airdropPostPayParams.brandedTokenAddress - branded token address
+ * @param {string} airdropPostPayParams.contractAddress - contractAddress address
+ * @param {string} airdropPostPayParams.airdropBudgetHolder - airdrop budget holder address
+ * @param {number} airdropPostPayParams.totalAmount - total amount that was debited from spender account
+ * @param {number} airdropPostPayParams.airdropAmountToUse - airdrop amount that was used in the transaction
+ * @param {number} airdropPostPayParams.chainId - chain id
+ *
+ * @return {promise}
+ *
+ */
+Airdrop.prototype.onAirdropPayFailure = async function (airdropPostPayParams) {
+
+ const oThis = this;
+ try {
+ const validationResponse = helper.validatePostAirdropPayParams(airdropPostPayParams);
+ if (validationResponse.isFailure()) return Promise.resolve(validationResponse);
+
+ const brandedTokenAddress = airdropPostPayParams.brandedTokenAddress
+ , contractAddress = airdropPostPayParams.contractAddress
+ , spender = airdropPostPayParams.spender
+ , totalAmount = new BigNumber(airdropPostPayParams.totalAmount)
+ , airdropAmountToUse = new BigNumber(airdropPostPayParams.airdropAmountToUse)
+ , airdropBudgetHolder = airdropPostPayParams.airdropBudgetHolder
+ ;
+
+ const afterFailureResponse = await oThis.transactionHelper.afterAirdropPayFailure(
+ brandedTokenAddress,
+ contractAddress,
+ spender,
+ totalAmount,
+ airdropAmountToUse,
+ airdropBudgetHolder);
+
+ const isAllResponseSuccessful = oThis.transactionHelper.isAllResponseSuccessful(afterFailureResponse);
+ if (isAllResponseSuccessful) {
+ return Promise.resolve(responseHelper.successWithData({}));
+ }
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_onAirdropPayFailure_1',
+ api_error_identifier: 'could_not_process',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
+ } catch(err) {
+ logger.error("lib/contract_interact/airdrop.js:onAirdropPayFailure inside catch ", err);
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_onAirdropPayFailure_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
+ }
+
+};
+
+
/**
* Get airdrop budget holder address of airdrop
*
@@ -305,8 +481,14 @@ Airdrop.prototype.airdropBudgetHolder = async function() {
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_a_airdropBudgetHolder_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error("lib/contract_interact/airdrop.js:airdropBudgetHolder inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_a_airdropBudgetHolder_1', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
};
@@ -324,7 +506,7 @@ Airdrop.prototype.getAirdropBudgetHolderFromContract = async function() {
const transactionObject = currContract.methods.airdropBudgetHolder()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, oThis.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, oThis.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({airdropBudgetHolder: response[0]}));
};
@@ -342,7 +524,7 @@ Airdrop.prototype.getWorkers = async function() {
const transactionObject = currContract.methods.workers()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, oThis.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, oThis.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({workerContractAddress: response[0]}));
};
diff --git a/lib/contract_interact/branded_token.js b/lib/contract_interact/branded_token.js
index 1a4233e..56eac1a 100644
--- a/lib/contract_interact/branded_token.js
+++ b/lib/contract_interact/branded_token.js
@@ -13,19 +13,26 @@ const BigNumber = require('bignumber.js')
const rootPrefix = '../..'
, helper = require(rootPrefix + '/lib/contract_interact/helper')
, coreAddresses = require(rootPrefix + '/config/core_addresses')
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
, coreConstants = require(rootPrefix + '/config/core_constants')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
, basicHelper = require(rootPrefix + '/helpers/basic_helper')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
, notificationGlobalConstant = require(rootPrefix + '/lib/global_constant/notification')
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
, BalanceCacheKlass = require(rootPrefix + '/lib/cache_management/balance')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
const contractName = 'brandedToken'
, contractAbi = coreAddresses.getAbiForContract(contractName)
- , currContract = new web3RpcProvider.eth.Contract(contractAbi)
- , gasLimit = coreConstants.OST_GAS_LIMIT
+ , currContract = new web3Provider.eth.Contract(contractAbi)
;
/**
@@ -44,7 +51,7 @@ const BrandedToken = function (brandedTokenAddress, chainId) {
oThis.brandedTokenAddress = brandedTokenAddress;
oThis.chainId = chainId;
oThis.balanceCache = new BalanceCacheKlass(chainId, brandedTokenAddress);
- currContract.setProvider(web3RpcProvider.currentProvider);
+ //currContract.setProvider(web3Provider.currentProvider);
};
BrandedToken.prototype = {
@@ -80,24 +87,36 @@ BrandedToken.prototype = {
var cacheResult = await oThis.balanceCache.getBalance(owner);
if (cacheResult.isSuccess() && cacheResult.data.response != null) {
- return Promise.resolve(responseHelper.successWithData({balance: cacheResult.data.response}));
+ return Promise.resolve(responseHelper.successWithData({
+ balance: cacheResult.data.response,
+ source: "cache"}));
} else {
const getBalanceFromContractResponse = await oThis.getBalanceFromContract(owner);
cacheResult = await oThis.balanceCache.getBalance(owner);
if (cacheResult.isSuccess() && cacheResult.data.response != null) {
- return Promise.resolve(responseHelper.successWithData({balance: cacheResult.data.response}));
+ return Promise.resolve(responseHelper.successWithData({
+ balance: cacheResult.data.response,
+ source: "cache"}));
}
if (getBalanceFromContractResponse.isFailure()) return Promise.resolve(getBalanceFromContractResponse);
await oThis.balanceCache.setBalance(owner, new BigNumber(getBalanceFromContractResponse.data.balance));
- return Promise.resolve(responseHelper.successWithData({balance: getBalanceFromContractResponse.data.balance}));
+ return Promise.resolve(responseHelper.successWithData({
+ balance: getBalanceFromContractResponse.data.balance,
+ source: "chain"}));
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_getBalanceOf_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/branded_token.js:getBalanceOf inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_bt_getBalanceOf_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -117,12 +136,18 @@ BrandedToken.prototype = {
const transactionObject = currContract.methods.balanceOf(owner)
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, oThis.brandedTokenAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, oThis.brandedTokenAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({balance: response[0]}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_getBalanceFromContract_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/branded_token.js:getBalanceFromContract inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_bt_getBalanceFromContract_1', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -155,7 +180,7 @@ BrandedToken.prototype = {
'transferToBudgetHolder',
contractName,
oThis.brandedTokenAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
notificationData.message.payload.erc20_contract_address = oThis.brandedTokenAddress;
@@ -174,8 +199,8 @@ BrandedToken.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.brandedTokenAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.transferToAirdropBudgetHolder(),
+ web3Provider: web3Provider,
successCallback: onSuccess,
failCallback: onFail,
errorCode: "l_ci_bt_transferToAirdropBudgetHolder_1"
@@ -189,8 +214,14 @@ BrandedToken.prototype = {
return Promise.resolve(beforeTransferResponse);
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_transferToAirdropBudgetHolder_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/branded_token.js:transferToAirdropBudgetHolder inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_bt_transferToAirdropBudgetHolder_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -211,13 +242,14 @@ BrandedToken.prototype = {
if (bigAmount.gt(0)) {
const getBalanceOfResponse = await oThis.getBalanceOf(owner);
-
if (getBalanceOfResponse.isSuccess()) {
- const balance = new BigNumber(getBalanceOfResponse.data.balance);
- const newBalance = balance.plus(bigAmount);
- logger.debug('creditBalance called with params:', JSON.stringify({owner: owner,
- bigAmount: bigAmount.toString(10)}));
- await oThis.setBalanceInCache(owner, newBalance);
+ if (getBalanceOfResponse.data.source == 'cache'){
+ const balance = new BigNumber(getBalanceOfResponse.data.balance);
+ const newBalance = balance.plus(bigAmount);
+ logger.debug('creditBalance called with params:', JSON.stringify({owner: owner,
+ bigAmount: bigAmount.toString(10)}));
+ await oThis.setBalanceInCache(owner, newBalance);
+ }
} else {
logger.error('lib/contract_interact/branded_token.js:creditBalance getBalanceOfResponse error',
JSON.stringify(getBalanceOfResponse));
@@ -226,8 +258,14 @@ BrandedToken.prototype = {
return Promise.resolve(responseHelper.successWithData({}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_creditBalance_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/branded_token.js:creditBalance inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_bt_creditBalance_1', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -263,8 +301,14 @@ BrandedToken.prototype = {
return Promise.resolve(responseHelper.successWithData({}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_debitBalance_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/branded_token.js:debitBalance inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_bt_debitBalance_1', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -286,10 +330,23 @@ BrandedToken.prototype = {
if (setBalanceResponse.isSuccess() && setBalanceResponse.data.response != null) {
return Promise.resolve(responseHelper.successWithData({}));
}
- return Promise.resolve(responseHelper.error('l_ci_bt_setBalanceInCache_1', setBalanceResponse));
+
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_setBalanceInCache_1',
+ api_error_identifier: 'could_not_process',
+ error_config: errorConfig,
+ debug_options: { setBalanceResponse: setBalanceResponse }
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_setBalanceInCache_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/branded_token.js:setBalanceInCache inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_bt_setBalanceInCache_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -322,7 +379,7 @@ BrandedToken.prototype = {
'approveByBudgetHolder',
contractName,
oThis.brandedTokenAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -333,8 +390,8 @@ BrandedToken.prototype = {
senderPassphrase: airdropBudgetHolderPassphrase,
contractAddress: oThis.brandedTokenAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.approveByBudgetHolder(),
+ web3Provider: web3Provider,
successCallback: null,
failCallback: null,
errorCode: "l_ci_bt_approveByBudgetHolder_1"
@@ -342,8 +399,14 @@ BrandedToken.prototype = {
return helper.performSend(params, returnType);
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_bt_approveByBudgetHolder_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/branded_token.js:approveByBudgetHolder inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_bt_approveByBudgetHolder_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
diff --git a/lib/contract_interact/helper.js b/lib/contract_interact/helper.js
index 7403989..4fd1bb0 100644
--- a/lib/contract_interact/helper.js
+++ b/lib/contract_interact/helper.js
@@ -18,8 +18,15 @@ const rootPrefix = '../..'
, responseHelper = require(rootPrefix + '/lib/formatter/response')
, basicHelper = require(rootPrefix + '/helpers/basic_helper')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
/**
* contract interact helper constructor
*
@@ -31,7 +38,7 @@ ContractInteractHelper.prototype = {
/**
* Call methods (execute methods which DO NOT modify state of contracts)
*
- * @param {object} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {object} web3Provider - It could be value chain or utility chain provider
* @param {String} currContractAddr - current contract address
* @param {Object} encodeABI - encoded method ABI data
* @param {Object} [options] - optional params
@@ -40,7 +47,7 @@ ContractInteractHelper.prototype = {
* @return {promise}
*
*/
- call: async function (web3RpcProvider, currContractAddr, encodeABI, options, transactionOutputs) {
+ call: async function (web3Provider, currContractAddr, encodeABI, options, transactionOutputs) {
const params = {
to: currContractAddr,
data: encodeABI
@@ -49,11 +56,11 @@ ContractInteractHelper.prototype = {
Object.assign(params, options);
}
- const response = await web3RpcProvider.eth.call(params);
+ const response = await web3Provider.eth.call(params);
if (transactionOutputs) {
try {
- return Promise.resolve(web3RpcProvider.eth.abi.decodeParameters(transactionOutputs, response));
+ return Promise.resolve(web3Provider.eth.abi.decodeParameters(transactionOutputs, response));
}
catch (err) {
return Promise.reject(err);
@@ -78,7 +85,7 @@ ContractInteractHelper.prototype = {
/**
* Send methods (execute methods which modify state of a contracts)
*
- * @param {Web3} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {Web3} web3Provider - It could be value chain or utility chain provider
* @param {String} currContractAddr - current contract address
* @param {Object} encodeABI - encoded method ABI data
* @param {Object} [options] - optional params
@@ -87,7 +94,7 @@ ContractInteractHelper.prototype = {
* @return {promise}
*
*/
- send: async function (web3RpcProvider, currContractAddr, encodeABI, options, transactionOutputs) {
+ send: async function (web3Provider, currContractAddr, encodeABI, options, transactionOutputs) {
const params = {
to: currContractAddr,
data: encodeABI
@@ -96,10 +103,10 @@ ContractInteractHelper.prototype = {
Object.assign(params, options);
}
- const response = web3RpcProvider.eth.sendTransaction(params);
+ const response = web3Provider.eth.sendTransaction(params);
if ( transactionOutputs ) {
- return Promise.resolve(web3RpcProvider.eth.abi.decodeParameters(transactionOutputs, response));
+ return Promise.resolve(web3Provider.eth.abi.decodeParameters(transactionOutputs, response));
} else {
return Promise.resolve(response);
}
@@ -108,19 +115,19 @@ ContractInteractHelper.prototype = {
/**
* @ignore
*/
- sendTxAsync: function (web3RpcProvider, currContractAddr, encodeABI, senderName, txOptions) {
+ sendTxAsync: function (web3Provider, currContractAddr, encodeABI, senderName, txOptions) {
const oThis = this
, senderAddr = coreAddresses.getAddressForUser(senderName)
,senderPassphrase = coreAddresses.getPassphraseForUser(senderName)
;
- return oThis.sendTxAsyncFromAddr(web3RpcProvider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions);
+ return oThis.sendTxAsyncFromAddr(web3Provider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions);
},
/**
* @ignore
*/
- sendTxAsyncFromAddr: function (web3RpcProvider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions) {
+ sendTxAsyncFromAddr: function (web3Provider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions) {
const txParams = {
from: senderAddr,
to: currContractAddr,
@@ -128,12 +135,12 @@ ContractInteractHelper.prototype = {
};
Object.assign(txParams, txOptions);
- return web3RpcProvider.eth.personal.unlockAccount( senderAddr, senderPassphrase)
+ return web3Provider.eth.personal.unlockAccount( senderAddr, senderPassphrase)
.then( _ => {
var isPromiseSettled = false;
return new Promise(async function (onResolve, onReject) {
try {
- web3RpcProvider.eth.sendTransaction(txParams ,function (error, result) {
+ web3Provider.eth.sendTransaction(txParams ,function (error, result) {
//THIS CALLBACK IS IMPORTANT -> on('error') Does not explain the reason.
if ( error ) {
!isPromiseSettled && onReject( error );
@@ -156,7 +163,7 @@ ContractInteractHelper.prototype = {
/**
* Safe Send a transaction (this internally waits for transaction to be mined)
*
- * @param {Web3} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {Web3} web3Provider - It could be value chain or utility chain provider
* @param {String} currContractAddr - current contract address
* @param {String} senderName - name of transaction's sender
* @param {Object} encodeABI - encoded method ABI data
@@ -166,13 +173,13 @@ ContractInteractHelper.prototype = {
* @return {Promise}
*
*/
- safeSend: function (web3RpcProvider, currContractAddr, encodeABI, senderName, txOptions, addressToNameMap) {
+ safeSend: function (web3Provider, currContractAddr, encodeABI, senderName, txOptions, addressToNameMap) {
const oThis = this
;
- return oThis.sendTxAsync(web3RpcProvider, currContractAddr, encodeABI, senderName, txOptions)
+ return oThis.sendTxAsync(web3Provider, currContractAddr, encodeABI, senderName, txOptions)
.then(function(transactionHash) {
- return oThis.getTxReceipt(web3RpcProvider, transactionHash, addressToNameMap)
+ return oThis.getTxReceipt(web3Provider, transactionHash, addressToNameMap)
.then(function(txReceipt) {
/*if (txReceipt.gasUsed == txOptions.gasPrice) {
console.error("safeSend used complete gas gasPrice : " + txOptions.gasPrice);
@@ -187,7 +194,7 @@ ContractInteractHelper.prototype = {
/**
* Safe Send a transaction (this internally waits for transaction to be mined)
*
- * @param {Web3} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {Web3} web3Provider - It could be value chain or utility chain provider
* @param {String} currContractAddr - current contract address
* @param {String} senderAddr - address of transaction's sender senderAddr
* @param {String} senderPassphrase - passphrase of
@@ -198,12 +205,12 @@ ContractInteractHelper.prototype = {
* @return {Promise}
*
*/
- safeSendFromAddr: function (web3RpcProvider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions, addressToNameMap) {
+ safeSendFromAddr: function (web3Provider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions, addressToNameMap) {
const oThis = this
;
- return oThis.sendTxAsyncFromAddr(web3RpcProvider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions).then(
+ return oThis.sendTxAsyncFromAddr(web3Provider, currContractAddr, encodeABI, senderAddr, senderPassphrase, txOptions).then(
function(transactionHash) {
- return oThis.getTxReceipt(web3RpcProvider, transactionHash, addressToNameMap);
+ return oThis.getTxReceipt(web3Provider, transactionHash, addressToNameMap);
}
);
},
@@ -211,12 +218,12 @@ ContractInteractHelper.prototype = {
/**
* @ignore
*/
- getTxReceipt: function(web3RpcProvider, transactionHash, addressToNameMap) {
+ getTxReceipt: function(web3Provider, transactionHash, addressToNameMap) {
return new Promise (function(onResolve, onReject) {
var tryReceipt = function() {
setTimeout( function() {
- web3RpcProvider.eth.getTransactionReceipt(transactionHash).then(handleResponse);
+ web3Provider.eth.getTransactionReceipt(transactionHash).then(handleResponse);
},
5000
);
@@ -240,54 +247,54 @@ ContractInteractHelper.prototype = {
/**
* Decode result and typecast it to an Address
*
- * @param {Web3} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {Web3} web3Provider - It could be value chain or utility chain provider
* @param {String} result - current contract address
*
* @return {Promise}
*
*/
- toAddress: function (web3RpcProvider, result) {
+ toAddress: function (web3Provider, result) {
return new Promise(function(onResolve, onReject){
- onResolve(web3RpcProvider.eth.abi.decodeParameter('address', result));
+ onResolve(web3Provider.eth.abi.decodeParameter('address', result));
});
},
/**
* Decode result and typecast it to a String
*
- * @param {Web3} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {Web3} web3Provider - It could be value chain or utility chain provider
* @param {String} result - current contract address
*
* @return {Promise}
*
*/
- toString: function (web3RpcProvider, result) {
+ toString: function (web3Provider, result) {
return new Promise(function(onResolve, onReject){
- onResolve(web3RpcProvider.eth.abi.decodeParameter('bytes32', result));
+ onResolve(web3Provider.eth.abi.decodeParameter('bytes32', result));
});
},
/**
* Decode result and typecast it to a Number
*
- * @param {Web3} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {Web3} web3Provider - It could be value chain or utility chain provider
* @param {String} result - current contract address
*
* @return {Promise}
*
*/
- toNumber: function (web3RpcProvider, result) {
+ toNumber: function (web3Provider, result) {
return new Promise(function(onResolve, onReject){
- onResolve(web3RpcProvider.utils.hexToNumber(result));
+ onResolve(web3Provider.utils.hexToNumber(result));
});
},
/**
* @ignore
*/
- decodeUint256: function (web3RpcProvider, result) {
+ decodeUint256: function (web3Provider, result) {
return new Promise(function(onResolve, onReject){
- onResolve(web3RpcProvider.eth.abi.decodeParameter('uint256', result));
+ onResolve(web3Provider.eth.abi.decodeParameter('uint256', result));
});
},
@@ -314,13 +321,13 @@ ContractInteractHelper.prototype = {
/**
* Get transaction receipt
*
- * @param {Web3} web3RpcProvider - It could be value chain or utility chain provider
+ * @param {Web3} web3Provider - It could be value chain or utility chain provider
* @param {String} transactionHash - transaction hash
*
* @return {Promise}
*
*/
- getTransactionReceiptFromTrasactionHash: function (web3RpcProvider, transactionHash) {
+ getTransactionReceiptFromTrasactionHash: function (web3Provider, transactionHash) {
return new Promise(function(onResolve, onReject) {
// number of times it will attempt to fetch
var maxAttempts = 1000;
@@ -331,7 +338,7 @@ ContractInteractHelper.prototype = {
var getReceipt = async function() {
if (maxAttempts > 0) {
logger.debug(`\n====== Attempting to get receipt ======\n`);
- const receipt = await web3RpcProvider.eth.getTransactionReceipt(transactionHash);
+ const receipt = await web3Provider.eth.getTransactionReceipt(transactionHash);
logger.debug(`\n====== receipt: ${receipt} ======\n`);
if (receipt) {
logger.debug(`\n====== got the receipt ======\n`);
@@ -340,9 +347,14 @@ ContractInteractHelper.prototype = {
setTimeout(getReceipt, timeInterval);
}
} else {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_pse_gtrfth',
+ api_error_identifier: 'get_receipt_failed',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.debug(`\n====== unable to get receipt ======\n`);
- const errorReason = "Unable to get receipt";
- return onResolve(responseHelper.error("l_ci_h_pse_gtrfth", errorReason));
+ return onResolve(responseHelper.error(errorParams));
}
maxAttempts--;
};
@@ -363,163 +375,226 @@ ContractInteractHelper.prototype = {
*
*/
performSend: function (params, returnType) {
- const oThis = this;
- const notificationData = params.notificationData;
- const txUUID = notificationData.message.payload.uuid;
+ const oThis = this
+ , notificationData = params.notificationData
+ , txUUID = notificationData.message.payload.uuid
+ ;
- var isValueReturned = false;
+ var isValueReturned = false
+ , processReceipt = 1
+ ;
- const asyncPerform = function () {
+ if (params.processReceipt != undefined) {
+ processReceipt = params.processReceipt;
+ }
+ const transactionObject = params.transactionObject;
+
+ const encodedABI = transactionObject.encodeABI();
+
+ //TODO: calculate the gas limit
+ const txParams = {
+ from: params.senderAddress,
+ to: params.contractAddress,
+ data: encodedABI,
+ gasPrice: params.gasPrice,
+ gas: params.gasLimit
+ };
- const transactionObject = params.transactionObject;
+ // set params in notification data
+ notificationData.message.payload.params.txParams = txParams;
- const encodedABI = transactionObject.encodeABI();
+ const web3Provider = params.web3Provider;
- //TODO: calculate the gas limit
- const txParams = {
- from: params.senderAddress,
- to: params.contractAddress,
- data: encodedABI,
- gasPrice: params.gasPrice,
- gas: params.gasLimit
+ const successCallback = params.successCallback;
+ const failCallback = params.failCallback;
+ var transactionHashRef = null;
+
+
+ const notifyTransactionInitiated = function (transactionHash) {
+ transactionHashRef = transactionHash;
+ // set transaction hash in notification data
+ // eslint-disable-next-line camelcase
+ notificationData.message.payload.transaction_hash = transactionHash;
+ // Publish event
+ notificationData.message.kind = 'transaction_initiated';
+ openSTNotification.publishEvent.perform(notificationData);
+ };
+
+ const notifyTrasactionMined = function (receipt) {
+ // Publish event
+ notificationData.message.kind = 'transaction_mined';
+ notificationData.message.payload.receipt = receipt;
+ openSTNotification.publishEvent.perform(notificationData);
+ };
+
+ const notifyTransactionError = function(errorReason) {
+ // set error data in notification data
+ notificationData.message.payload.error_data = errorReason;
+
+ // Publish event
+ notificationData.message.kind = 'transaction_error';
+ openSTNotification.publishEvent.perform(notificationData);
+ };
+
+ const onTransactionHash = function (transactionHash) {
+ notifyTransactionInitiated(transactionHash);
+ const transactionResponseData = {
+ transaction_uuid: txUUID,
+ transaction_hash: transactionHash,
+ transaction_receipt: {}
};
- // set params in notification data
- notificationData.message.payload.params.txParams = txParams;
+ if (params.postReceiptProcessParams) {
+ transactionResponseData.post_receipt_process_params = params.postReceiptProcessParams;
+ }
+
+ return responseHelper.successWithData(transactionResponseData);
+ };
+ const onReceiptSuccess = async function (receipt) {
+ // call success callback.
+ if (successCallback != undefined && successCallback != null) {
+ logger.debug("======helper.Calling successCallback=======");
+ await successCallback(receipt);
+ }
+ notifyTrasactionMined(receipt);
+ return responseHelper.successWithData(
+ {
+ transaction_uuid: txUUID,
+ transaction_hash: receipt.transactionHash,
+ transaction_receipt: receipt
+ });
+ };
+ const onReceiptFail = async function (errorCode, errorReason, receipt) {
+ // call fail callback
+ if (failCallback != undefined && failCallback != null) {
+ logger.debug("======helper.Calling failCallback=======");
+ await failCallback(receipt);
+ }
+ notifyTransactionError(errorReason);
- const web3RpcProvider = params.web3RpcProvider;
+ let errorParams = {
+ internal_error_identifier: `${params.errorCode}|${errorCode}`,
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ const errorMessage = (errorReason && errorReason.message) ? errorReason.message : `Something went wrong: l_ci_h_pse`;
+ logger.error(errorMessage);
+ return responseHelper.error(errorParams);
- const successCallback = params.successCallback;
- const failCallback = params.failCallback;
- var transactionHashRef = null;
- return new Promise(function (onResolve, onReject) {
+ };
+ const onReceipt = function(receipt) {
+ logger.debug("\n=======receipt========\n");
+ logger.debug(receipt);
+ if (receipt.status == 0x1) {
+ return onReceiptSuccess(receipt);
+ } else {
+ const errorReason = "Transaction status is 0";
+ return onReceiptFail('l_ci_h_pse_status_0', errorReason, receipt);
+ }
+ };
- const notifyTransactionInitiated = function (transactionHash) {
- transactionHashRef = transactionHash;
- // set transaction hash in notification data
- // eslint-disable-next-line camelcase
- notificationData.message.payload.transaction_hash = transactionHash;
- // Publish event
- notificationData.message.kind = 'transaction_initiated';
- openSTNotification.publishEvent.perform(notificationData);
- };
-
- const notifyTrasactionMined = function (receipt) {
- // Publish event
- notificationData.message.kind = 'transaction_mined';
- notificationData.message.payload.receipt = receipt;
- openSTNotification.publishEvent.perform(notificationData);
- };
-
- const notifyTransactionError = function(errorReason) {
- // set error data in notification data
- notificationData.message.payload.error_data = errorReason;
-
- // Publish event
- notificationData.message.kind = 'transaction_error';
- openSTNotification.publishEvent.perform(notificationData);
- };
-
- const onTransactionHash = function (transactionHash) {
- notifyTransactionInitiated(transactionHash);
- return responseHelper.successWithData(
- {
- transaction_uuid: txUUID,
- transaction_hash: transactionHash,
- transaction_receipt: {}
- });
- };
- const onReceiptSuccess = async function (receipt) {
- // call success callback.
- if (successCallback != undefined && successCallback != null) {
- logger.debug("======helper.Calling successCallback=======");
- await successCallback(receipt);
- }
- notifyTrasactionMined(receipt);
- return responseHelper.successWithData(
- {
- transaction_uuid: txUUID,
- transaction_hash: receipt.transactionHash,
- transaction_receipt: receipt
- });
- };
- const onReceiptFail = async function (errorReason, receipt) {
- // call fail callback
- if (failCallback != undefined && failCallback != null) {
- logger.debug("======helper.Calling failCallback=======");
- await failCallback(receipt);
- }
- notifyTransactionError(errorReason);
- const errorCode = params.errorCode || "l_ci_h_pse";
- const errorMessage = (errorReason && errorReason.message) ? errorReason.message : `Something went wrong: l_ci_h_pse`;
- return responseHelper.error(errorCode, errorMessage);
-
- };
- const onReceipt = function(receipt) {
- logger.debug("\n=======receipt========\n");
- logger.debug(receipt);
- if (receipt.status == 0x1) {
- return onReceiptSuccess(receipt);
+ const onCatch = function (reason) {
+ if (reason && reason.message && reason.message.includes('not mined within')) {
+ oThis.getTransactionReceiptFromTrasactionHash(web3Provider, transactionHashRef).then( function(getReceiptResponse) {
+ if (getReceiptResponse.isSuccess()) {
+ const onReceiptResponse = onReceipt(getReceiptResponse.data.receipt);
+ return onReceiptResponse;
} else {
- const errorReason = "Transaction status is 0";
- return onReceiptFail(errorReason, receipt);
+ const errorReason = "Unable to get receipt";
+ const receiptFailResponse = onReceiptFail('l_ci_h_pse_1', errorReason, {});
+ return receiptFailResponse;
}
- };
+ });
+
+ } else {
+ var errorCode = 'l_ci_h_pse_2';
+ if (reason && reason.message && reason.message.includes('insufficient funds for gas * price + value')) {
+ errorCode = 'l_ci_h_pse_gas_low';
+ reason.message = "insufficient gas"
+ }
+ const receiptFailResponse =onReceiptFail(errorCode, reason, {});
+ return receiptFailResponse;
+ }
+ };
+
+ if (basicHelper.isReturnTypeTxReceipt(returnType) && processReceipt==0){
+ const errorCode = 'l_ci_h_pse_3'
+ , reason = 'not supported for returnType=txReceipt and processReceipt=0'
+ , receiptFailResponse =onReceiptFail(errorCode, reason, {});
+ ;
+ if (isValueReturned == false) {
+ isValueReturned = true;
+ return Promise.resolve(receiptFailResponse);
+ }
+ }
+
+ /* if (processReceipt==0 && !params.postReceiptProcessParams) {
+ const errorCode = 'l_ci_h_pse_4'
+ , reason = 'post pay params mandatory'
+ , receiptFailResponse =onReceiptFail(errorCode, reason, {});
+ ;
+ if (isValueReturned == false) {
+ isValueReturned = true;
+ return Promise.resolve(receiptFailResponse);
+ }
+ }
+*/
+ const asyncPerform = function () {
+ return new Promise(function (onResolve, onReject) {
// Unlock account
- web3RpcProvider.eth.personal.unlockAccount(
+ web3Provider.eth.personal.unlockAccount(
params.senderAddress,
params.senderPassphrase)
.then(function() {
- web3RpcProvider.eth.sendTransaction(txParams)
- .on('transactionHash', function(transactionHash) {
- logger.debug(`\n=======transactionHash received========: ${transactionHash} \n`);
- const onTransactionHashResponse = onTransactionHash(transactionHash);
- if (basicHelper.isReturnTypeTxHash(returnType)) {
- isValueReturned = true;
- return onResolve(onTransactionHashResponse);
- }
- })
- .on('receipt', function(receipt) {
- logger.debug(`\n=======receipt received========: ${receipt} \n`);
- const onReceiptResponse = onReceipt(receipt);
- if (basicHelper.isReturnTypeTxReceipt(returnType)) {
- isValueReturned = true;
- return onResolve(onReceiptResponse);
- }
- })
- .catch( function(reason) {
- logger.error(`\n=======Exception at location 1========: ${reason} \n`);
- if (reason && reason.message && reason.message.includes('not mined within')) {
- oThis.getTransactionReceiptFromTrasactionHash(web3RpcProvider, transactionHashRef).then( function(getReceiptResponse) {
- if (getReceiptResponse.isSuccess()) {
- const onReceiptResponse = onReceipt(getReceiptResponse.data.receipt);
- if (isValueReturned == false) {
- isValueReturned = true;
- return onResolve(onReceiptResponse);
- }
- } else {
- const errorReason = "Unable to get receipt";
- const receiptFailResponse = onReceiptFail(errorReason, {});
- if (isValueReturned == false) {
- isValueReturned = true;
- return onResolve(receiptFailResponse);
- }
- }
- });
-
- } else {
- const receiptFailResponse =onReceiptFail(reason, {});
+ if (processReceipt) {
+ web3Provider.eth.sendTransaction(txParams)
+ .on('transactionHash', function(transactionHash) {
+ logger.debug(`\n=======transactionHash received========: ${transactionHash} \n`);
+ const onTransactionHashResponse = onTransactionHash(transactionHash);
+ if (basicHelper.isReturnTypeTxHash(returnType)) {
+ isValueReturned = true;
+ return onResolve(onTransactionHashResponse);
+ }
+ })
+ .on('receipt', function(receipt) {
+ logger.debug(`\n=======receipt received========: ${receipt} \n`);
+ const onReceiptResponse = onReceipt(receipt);
+ if (basicHelper.isReturnTypeTxReceipt(returnType)) {
+ isValueReturned = true;
+ return onResolve(onReceiptResponse);
+ }
+ })
+ .catch( function(reason) {
+ logger.error(`\n=======Exception at location 1========: ${reason} \n`);
if (isValueReturned == false) {
isValueReturned = true;
- return onResolve(receiptFailResponse);
+ return onResolve(onCatch(reason));
}
- }
- });
+ });
+ } else {
+ web3Provider.eth.sendTransaction(txParams)
+ .on('transactionHash', function(transactionHash) {
+ logger.debug(`\n=======transactionHash received========: ${transactionHash} \n`);
+ const onTransactionHashResponse = onTransactionHash(transactionHash);
+ if (basicHelper.isReturnTypeTxHash(returnType)) {
+ isValueReturned = true;
+ return onResolve(onTransactionHashResponse);
+ }
+ })
+ .catch( function(reason) {
+ logger.error(`\n=======Exception at location 1========: ${reason} \n`);
+ if (isValueReturned == false) {
+ isValueReturned = true;
+ return onResolve(onCatch(reason));
+ }
+ });
+ }
})
.catch(function(reason) {
logger.error(`\n=======Exception at location 2========: ${reason} \n`);
- const receiptFailResponse =onReceiptFail(reason, {});
+ const receiptFailResponse =onReceiptFail('l_ci_h_pse_3', reason, {});
if (isValueReturned == false) {
isValueReturned = true;
return onResolve(receiptFailResponse);
@@ -532,13 +607,15 @@ ContractInteractHelper.prototype = {
if (basicHelper.isReturnTypeUUID(returnType)) {
isValueReturned = true;
asyncPerform();
- return Promise.resolve(
- responseHelper.successWithData(
- {
- transaction_uuid: txUUID,
- transaction_hash: "",
- transaction_receipt: {}
- }));
+ const transactionResponseData = {
+ transaction_uuid: txUUID,
+ transaction_hash: "",
+ transaction_receipt: {}
+ };
+ if (params.postReceiptProcessParams) {
+ transactionResponseData.post_receipt_process_params = params.postReceiptProcessParams;
+ }
+ return Promise.resolve(responseHelper.successWithData(transactionResponseData));
} else {
return asyncPerform();
}
@@ -552,7 +629,7 @@ ContractInteractHelper.prototype = {
* @param {String} method - method name
* @param {String} contractName - name of contract
* @param {String} contractAddress - address of contract
- * @param {Object} web3RpcProvider - address of contract
+ * @param {Object} web3Provider - address of contract
* @param {Object} options - options
*
* @return {Promise}
@@ -564,7 +641,7 @@ ContractInteractHelper.prototype = {
method,
contractName,
contractAddress,
- web3RpcProvider,
+ web3Provider,
chainId,
options) {
@@ -630,7 +707,7 @@ ContractInteractHelper.prototype = {
},
/**
- * Validate Airdrop params
+ * Validate common pay params
*
* @param {string} senderAddress - address of sender
* @param {string} beneficiaryAddress - address of beneficiary account
@@ -638,55 +715,159 @@ ContractInteractHelper.prototype = {
* @param {string} commissionBeneficiaryAddress - address of commision beneficiary account
* @param {BigNumber} commissionAmount - commission amount (in wei)
* @param {string} currency - quote currency
- * @param {BigNumber} intendedPricePoint - price point at which the pay is intended (in wei)
- * @param {BigNumber} gasPrice - gas price
*
- * @return {Promise}
+ * @return {result}
*
*/
- validatePayParams: function(
- senderAddress,
- beneficiaryAddress,
- transferAmount,
- commissionBeneficiaryAddress,
- commissionAmount,
- currency,
- intendedPricePoint,
- gasPrice) {
-
+ validateCommonPayParams: function (senderAddress,
+ beneficiaryAddress,
+ transferAmount,
+ commissionBeneficiaryAddress,
+ commissionAmount,
+ currency) {
const oThis = this
;
transferAmount = new BigNumber(transferAmount);
commissionAmount = new BigNumber(commissionAmount);
- intendedPricePoint = new BigNumber(intendedPricePoint);
if (!basicHelper.isAddressValid(senderAddress)) {
- return responseHelper.error('l_ci_h_vpp_1', 'senderAddress address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vcpp_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+
+ return responseHelper.paramValidationError(errorParams);
}
if (transferAmount.isNaN() || !transferAmount.isInteger()) {
- return responseHelper.error('l_ci_h_vpp_2', 'transfer amount cannot be negative or floating value');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vcpp_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['negative_transfer_amount'],
+ debug_options: {}
+ };
+
+ return responseHelper.paramValidationError(errorParams);
}
if (transferAmount.equals(0)) {
- return responseHelper.error('l_ci_h_vpp_3', 'transfer amount cannot be 0');
+
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vcpp_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['zero_transfer_amount'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (commissionAmount.isNaN() || !commissionAmount.isInteger()) {
- return responseHelper.error('l_ci_h_vpp_4', 'Commission amount cannot be negative or floating value');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vcpp_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_commission_amount'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!basicHelper.isAddressValid(beneficiaryAddress)) {
- return responseHelper.error('l_ci_h_vpp_5', 'beneficiaryAddress address is invalid');
+
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vcpp_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['beneficiary_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!basicHelper.isAddressValid(commissionBeneficiaryAddress)) {
- return responseHelper.error('l_ci_h_vpp_6', 'commissionBeneficiaryAddress is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vcpp_6',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['commission_beneficiary_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!oThis.isValidCurrency(currency, true)) {
- return responseHelper.error('l_ci_h_vpp_7', 'Given Currency is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vcpp_7',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * Validate Airdrop params
+ *
+ * @param {string} senderAddress - address of sender
+ * @param {string} beneficiaryAddress - address of beneficiary account
+ * @param {BigNumber} transferAmount - transfer amount (in wei)
+ * @param {string} commissionBeneficiaryAddress - address of commision beneficiary account
+ * @param {BigNumber} commissionAmount - commission amount (in wei)
+ * @param {string} currency - quote currency
+ * @param {BigNumber} intendedPricePoint - price point at which the pay is intended (in wei)
+ * @param {BigNumber} gasPrice - gas price
+ *
+ * @return {result}
+ *
+ */
+ validatePayParams: function(
+ senderAddress,
+ beneficiaryAddress,
+ transferAmount,
+ commissionBeneficiaryAddress,
+ commissionAmount,
+ currency,
+ intendedPricePoint,
+ gasPrice) {
+
+ const oThis = this
+ ;
+
+ intendedPricePoint = new BigNumber(intendedPricePoint);
+
+ const commonParamsValidationResponse = oThis.validateCommonPayParams(senderAddress,
+ beneficiaryAddress,
+ transferAmount,
+ commissionBeneficiaryAddress,
+ commissionAmount,
+ currency);
+
+ if (commonParamsValidationResponse.isFailure()) {
+ return commonParamsValidationResponse;
}
if (intendedPricePoint.isNaN() || !intendedPricePoint.isInteger()) {
- return responseHelper.error('l_ci_h_vpp_8', 'intendedPricePoint is invalid for given currency');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vpp_8',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['price_point_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!gasPrice ) {
- return responseHelper.error('l_ci_h_vpp_9', 'gas price is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vpp_9',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
return responseHelper.successWithData({});
},
@@ -735,7 +916,145 @@ ContractInteractHelper.prototype = {
}
if (!basicHelper.isAddressValid(user)) {
- return responseHelper.error('l_ci_h_vapp_2', 'user address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_user_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * Validate post airdrop pay params
+ *
+ * @params {object} params -
+ * @param {string} params.beneficiaryAddress - beneficiary address
+ * @param {string} params.commissionBeneficiaryAddress - commission beneficiary address
+ * @param {string} params.spender - spender address
+ * @param {string} params.brandedTokenAddress - branded token address
+ * @param {string} params.contractAddress - contractAddress address
+ * @param {string} params.airdropBudgetHolder - airdrop budget holder address
+ * @param {number} params.totalAmount - total amount that was debited from spender account
+ * @param {number} params.airdropAmountToUse - airdrop amount that was used in the transaction
+ *
+ * @return {Promise}
+ *
+ */
+
+ validatePostAirdropPayParams: function(postPayParams) {
+
+ const oThis = this
+ , beneficiaryAddress = postPayParams.beneficiaryAddress
+ , commissionBeneficiaryAddress = postPayParams.commissionBeneficiaryAddress
+ , spender = postPayParams.spender
+ , brandedTokenAddress = postPayParams.brandedTokenAddress
+ , contractAddress = postPayParams.contractAddress
+ , totalAmount = postPayParams.totalAmount
+ , airdropAmountToUse = postPayParams.airdropAmountToUse
+ , airdropBudgetHolder = postPayParams.airdropBudgetHolder
+ , chainId = postPayParams.chainId
+ ;
+
+
+ if (!basicHelper.isValidChainId(chainId)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(beneficiaryAddress)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['beneficiary_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(commissionBeneficiaryAddress)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['commission_beneficiary_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(spender)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_spender_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(brandedTokenAddress)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['branded_token_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(contractAddress)) {
+
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_6',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['branded_token_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(airdropBudgetHolder)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_7',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_budget_holder_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ const bnTotalAmount = new BigNumber(totalAmount);
+ if (bnTotalAmount.isNaN() || !bnTotalAmount.isInteger()) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_9',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['total_amount_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ const bnAirdropAmountToUse = new BigNumber(airdropAmountToUse);
+ if (bnAirdropAmountToUse.isNaN() || !bnAirdropAmountToUse.isInteger()) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_h_vapp_10',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_amount_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
return responseHelper.successWithData({});
diff --git a/lib/contract_interact/ops_managed_contract.js b/lib/contract_interact/ops_managed_contract.js
index 06f5713..d29f24f 100644
--- a/lib/contract_interact/ops_managed_contract.js
+++ b/lib/contract_interact/ops_managed_contract.js
@@ -11,17 +11,24 @@ const rootPrefix = '../..'
, coreAddresses = require(rootPrefix + '/config/core_addresses')
, basicHelper = require(rootPrefix + '/helpers/basic_helper')
, coreConstants = require(rootPrefix + '/config/core_constants')
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
, notificationGlobalConstant = require(rootPrefix + '/lib/global_constant/notification')
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
, OwnedContract = require(rootPrefix + '/lib/contract_interact/owned_contract')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
const contractName = 'opsManaged'
, contractAbi = coreAddresses.getAbiForContract(contractName)
- , currContract = new web3RpcProvider.eth.Contract(contractAbi)
- , gasLimit = coreConstants.OST_GAS_LIMIT
+ , currContract = new web3Provider.eth.Contract(contractAbi)
;
/**
@@ -37,13 +44,13 @@ const contractName = 'opsManaged'
*/
const OpsManagedContract = function (contractAddress, defaultGasPrice, chainId) {
this.contractAddress = contractAddress;
- this.web3RpcProvider = web3RpcProvider;
+ this.web3Provider = web3Provider;
this.currContract = currContract;
this.defaultGasPrice = defaultGasPrice;
this.currContract.options.address = contractAddress;
- this.currContract.setProvider(web3RpcProvider.currentProvider);
+ //this.currContract.setProvider(web3Provider.currentProvider);
this.chainId = chainId;
- OwnedContract.call(this, contractAddress, web3RpcProvider, currContract, defaultGasPrice);
+ OwnedContract.call(this, contractAddress, web3Provider, currContract, defaultGasPrice);
};
OpsManagedContract.prototype = Object.create(OwnedContract.prototype);
@@ -61,12 +68,18 @@ OpsManagedContract.prototype.getOpsAddress = async function() {
const transactionObject = this.currContract.methods.opsAddress()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs( transactionObject )
- , response = await helper.call(this.web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(this.web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
- return Promise.resolve(response[0]);
+ return Promise.resolve(responseHelper.successWithData({opsAddress: response[0]}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_omc_getOpsAddress_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/ops_managed_contract.js:getOpsAddress inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_omc_getOpsAddress_1', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
};
@@ -95,7 +108,7 @@ OpsManagedContract.prototype.setOpsAddress = async function(senderAddress, sende
'setOpsAddress',
contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -106,8 +119,8 @@ OpsManagedContract.prototype.setOpsAddress = async function(senderAddress, sende
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: oThis.defaultGasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.setOps(),
+ web3Provider: web3Provider,
successCallback: null,
failCallback: null,
errorCode: "l_ci_omc_setOpsAddress_1"
@@ -115,8 +128,14 @@ OpsManagedContract.prototype.setOpsAddress = async function(senderAddress, sende
return Promise.resolve(helper.performSend(params, returnType));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_omc_setOpsAddress_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/ops_managed_contract.js:setOpsAddress inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_omc_setOpsAddress_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
};
diff --git a/lib/contract_interact/owned_contract.js b/lib/contract_interact/owned_contract.js
index a38194b..9b1f3da 100644
--- a/lib/contract_interact/owned_contract.js
+++ b/lib/contract_interact/owned_contract.js
@@ -9,25 +9,32 @@
const rootPrefix = '../..'
, helper = require(rootPrefix + '/lib/contract_interact/helper')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
/**
* Owned contract interact constructor
*
* @param {String} contractAddress - address where Contract has been deployed
- * @param {String} web3RpcProvider - webRpc provider of network where currContract has been deployed
+ * @param {String} web3Provider - web3 provider of network where currContract has been deployed
* @param {String} currContract - Contract Instance
* @param {String} defaultGasPrice - default Gas Price
*
* @constructor
*/
-const OwnedContract = function (contractAddress, web3RpcProvider, currContract, defaultGasPrice) {
+const OwnedContract = function (contractAddress, web3Provider, currContract, defaultGasPrice) {
this.contractAddress = contractAddress;
- this.web3RpcProvider = web3RpcProvider;
+ this.web3Provider = web3Provider;
this.currContract = currContract;
this.defaultGasPrice = defaultGasPrice;
this.currContract.options.address = contractAddress;
- this.currContract.setProvider( web3RpcProvider.currentProvider );
+ //this.currContract.setProvider( web3Provider.currentProvider );
};
OwnedContract.prototype = {
@@ -49,7 +56,7 @@ OwnedContract.prototype = {
Object.assign(options, customOptions);
const transactionResponse = await helper.safeSend(
- this.web3RpcProvider,
+ this.web3Provider,
this.contractAddress,
encodedABI,
senderName,
@@ -58,8 +65,14 @@ OwnedContract.prototype = {
return Promise.resolve(transactionResponse);
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_oc_initiateOwnerShipTransfer_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/owned_contract.js:initiateOwnerShipTransfer inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_oc_initiateOwnerShipTransfer_1', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -73,12 +86,18 @@ OwnedContract.prototype = {
const transactionObject = this.currContract.methods.proposedOwner()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs( transactionObject )
- , response = await helper.call(this.web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(this.web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({owner: response[0]}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_oc_getOwner_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/owned_contract.js:getOwner inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_oc_getOwner_1', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
}
};
diff --git a/lib/contract_interact/pricer.js b/lib/contract_interact/pricer.js
index 70e61a5..67bc24a 100644
--- a/lib/contract_interact/pricer.js
+++ b/lib/contract_interact/pricer.js
@@ -19,17 +19,24 @@ const rootPrefix = '../..'
, web3EventsDecoder = require(rootPrefix + '/lib/web3/events/decoder')
, helper = require(rootPrefix + '/lib/contract_interact/helper')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
, TrasactionHelperKlass = require(rootPrefix + '/lib/transaction_helper')
, PricerCacheKlass = require(rootPrefix + '/lib/cache_management/pricer')
, eventGlobalConstants = require(rootPrefix+'/lib/global_constant/events')
, notificationGlobalConstant = require(rootPrefix + '/lib/global_constant/notification')
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
-const gasLimit = coreConstants.OST_GAS_LIMIT
- , contractAbi = coreAddresses.getAbiForContract('pricer')
- , currContract = new web3RpcProvider.eth.Contract(contractAbi)
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+const contractAbi = coreAddresses.getAbiForContract('pricer')
+ , currContract = new web3Provider.eth.Contract(contractAbi)
;
/**
@@ -165,8 +172,14 @@ Pricer.prototype = {
return Promise.resolve(getBrandedTokenAddressFromContractResponse);
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_brandedToken_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error("lib/contract_interact/pricer.js:brandedToken inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_brandedToken_1', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -180,7 +193,7 @@ Pricer.prototype = {
const transactionObject = currContract.methods.brandedToken()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({brandedToken: response[0]}));
},
@@ -198,7 +211,15 @@ Pricer.prototype = {
try {
if (!helper.isValidCurrency(currency, false)) {
- return Promise.resolve(responseHelper.error('l_ci_p_acceptedMargins_1', 'currency is mandatory'));
+
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_acceptedMargins_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
}
const cacheResult = await oThis.pricerCache.getAcceptedMargins(currency);
@@ -212,9 +233,15 @@ Pricer.prototype = {
return Promise.resolve(getAcceptedMarginsFromContractResponse);
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_acceptedMargins_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:acceptedMargins inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_acceptedMargins_2', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -232,13 +259,20 @@ Pricer.prototype = {
;
if (!helper.isValidCurrency(currency, false)) {
- return Promise.resolve(responseHelper.error('l_ci_p_getAcceptedMarginsFromContract_1', 'currency is mandatory'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getAcceptedMarginsFromContract_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
}
- const transactionObject = currContract.methods.acceptedMargins(web3RpcProvider.utils.asciiToHex(currency))
+ const transactionObject = currContract.methods.acceptedMargins(web3Provider.utils.asciiToHex(currency))
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({acceptedMargins: response[0]}));
},
@@ -257,7 +291,14 @@ Pricer.prototype = {
try {
if (!helper.isValidCurrency(currency, false)) {
- return Promise.resolve(responseHelper.error('l_ci_p_priceOracles_1', 'currency is mandatory'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_priceOracles_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
}
const cacheResult = await oThis.pricerCache.getPriceOracles(currency);
@@ -273,9 +314,16 @@ Pricer.prototype = {
return Promise.resolve(getPriceOraclesFromContractResponse);
}
} catch(err) {
+
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_priceOracles_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:priceOracles inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_priceOracles_2', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -289,13 +337,21 @@ Pricer.prototype = {
*/
getPriceOraclesFromContract: async function (currency) {
if (!helper.isValidCurrency(currency, false)) {
- return Promise.resolve(responseHelper.error('l_ci_p_getPriceOraclesFromContract_1', 'currency is mandatory'));
+
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPriceOraclesFromContract_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
- const transactionObject = currContract.methods.priceOracles(web3RpcProvider.utils.asciiToHex(currency))
+ const transactionObject = currContract.methods.priceOracles(web3Provider.utils.asciiToHex(currency))
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({priceOracles: response[0]}));
},
@@ -310,10 +366,10 @@ Pricer.prototype = {
const transactionObject = currContract.methods.baseCurrency()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData(
- {baseCurrency: response[0], symbol: web3RpcProvider.utils.hexToString(response[0])}));
+ {baseCurrency: response[0], symbol: web3Provider.utils.hexToString(response[0])}));
},
/**
@@ -340,9 +396,15 @@ Pricer.prototype = {
return Promise.resolve(getDecimalsFromContractResponse);
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_decimals_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:decimals inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_decimals_1', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -356,7 +418,7 @@ Pricer.prototype = {
const transactionObject = currContract.methods.decimals()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({decimals: response[0]}));
},
@@ -385,9 +447,15 @@ Pricer.prototype = {
return Promise.resolve(getConversionRateFromContractResponse);
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_conversionRate_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:conversionRate inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_conversionRate_1', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -401,7 +469,7 @@ Pricer.prototype = {
const transactionObject = currContract.methods.conversionRate()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({conversionRate: response[0]}));
},
@@ -431,9 +499,15 @@ Pricer.prototype = {
return Promise.resolve(getConversionRateDecimalsFromContractResponse);
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_conversionRateDecimals_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:conversionRateDecimals inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_conversionRateDecimals_1', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -448,37 +522,64 @@ Pricer.prototype = {
const transactionObject = currContract.methods.conversionRateDecimals()
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({conversionRateDecimals: response[0]}));
},
/**
- * Validate set price oracle parameters
- *
- * @param {string} senderAddress - address of sender
- * @param {string} currency - quote currency
- * @param {string} address - address of price pracle
- * @param {BigNumber} gasPrice - gas price
- *
- * @return {result}
- *
- */
+ * Validate set price oracle parameters
+ *
+ * @param {string} senderAddress - address of sender
+ * @param {string} currency - quote currency
+ * @param {string} address - address of price pracle
+ * @param {BigNumber} gasPrice - gas price
+ *
+ * @return {result}
+ *
+ */
validateSetPriceOracleParams: function (senderAddress, currency, address, gasPrice) {
if (!helper.isValidCurrency(currency, false)) {
- return responseHelper.error('l_ci_p_validateSetPriceOracleParams_1', 'currency is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetPriceOracleParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
}
if (!gasPrice) {
- return responseHelper.error('l_ci_p_validateSetPriceOracleParams_2', 'gas is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetPriceOracleParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!basicHelper.isAddressValid(address)) {
- return responseHelper.error('l_ci_p_validateSetPriceOracleParams_3', 'address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetPriceOracleParams_3',
+ api_error_identifier: 'contract_address_invalid',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
}
if (!basicHelper.isAddressValid(senderAddress)) {
- return responseHelper.error('l_ci_p_validateSetPriceOracleParams_4', 'address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetPriceOracleParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
return responseHelper.successWithData({});
@@ -508,7 +609,7 @@ Pricer.prototype = {
const returnType = basicHelper.getReturnType(options.returnType);
const transactionObject = currContract.methods.setPriceOracle(
- web3RpcProvider.utils.asciiToHex(currency),
+ web3Provider.utils.asciiToHex(currency),
address);
const notificationData = helper.getNotificationData(
@@ -517,7 +618,7 @@ Pricer.prototype = {
'setPriceOracle',
oThis.contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -532,8 +633,8 @@ Pricer.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.setPriceOracle(),
+ web3Provider: web3Provider,
successCallback: successCallback,
failCallback: null,
errorCode: "l_ci_p_spo_5"
@@ -555,13 +656,36 @@ Pricer.prototype = {
*/
validateUnsetPriceOracleParams: function (senderAddress, currency, gasPrice) {
if (!helper.isValidCurrency(currency, false)) {
- return responseHelper.error('l_ci_p_validateUnsetPriceOracleParams_1', 'currency is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateUnsetPriceOracleParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
- if (!gasPrice) return responseHelper.error('l_ci_p_validateUnsetPriceOracleParams_2', 'gas is mandatory');
+ if (!gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateUnsetPriceOracleParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
if (!basicHelper.isAddressValid(senderAddress)) {
- return responseHelper.error('l_ci_p_validateUnsetPriceOracleParams_3', 'address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateUnsetPriceOracleParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
}
return responseHelper.successWithData({});
@@ -589,7 +713,7 @@ Pricer.prototype = {
if (validationResponse.isFailure()) return Promise.resolve(validationResponse);
const returnType = basicHelper.getReturnType(options.returnType)
- , transactionObject = currContract.methods.unsetPriceOracle(web3RpcProvider.utils.asciiToHex(currency));
+ , transactionObject = currContract.methods.unsetPriceOracle(web3Provider.utils.asciiToHex(currency));
const notificationData = helper.getNotificationData(
['payments.pricer.unsetPriceOracle'],
@@ -597,7 +721,7 @@ Pricer.prototype = {
'unsetPriceOracle',
oThis.contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -612,8 +736,8 @@ Pricer.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.default(),
+ web3Provider: web3Provider,
successCallback: successCallback,
failCallback: null,
errorCode: "l_ci_p_uspo_4"
@@ -623,33 +747,61 @@ Pricer.prototype = {
},
/**
- * Validate set accepted margin params parameters
- *
- * @param {string} senderAddress - address of sender
- * @param {string} currency - quote currency
- * @param {BigNumber} acceptedMargin - accepted margin for the given currency (in wei)
- * @param {BigNumber} gasPrice - gas price
- *
- * @return {result}
- *
- */
+ * Validate set accepted margin params parameters
+ *
+ * @param {string} senderAddress - address of sender
+ * @param {string} currency - quote currency
+ * @param {BigNumber} acceptedMargin - accepted margin for the given currency (in wei)
+ * @param {BigNumber} gasPrice - gas price
+ *
+ * @return {result}
+ *
+ */
validateSetAcceptedMarginParams: function (senderAddress, currency, acceptedMargin, gasPrice) {
if (!helper.isValidCurrency(currency, false)) {
- return responseHelper.error('l_ci_p_validateSetAcceptedMarginParams_1', 'currency is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetAcceptedMarginParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!gasPrice) {
- return responseHelper.error('l_ci_p_validateSetAcceptedMarginParams_2', 'gas price is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetAcceptedMarginParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
- acceptedMargin = new BigNumber(acceptedMargin);
-
- if (acceptedMargin.isNaN() || !acceptedMargin.isInteger() || acceptedMargin.lt(0)) {
- return responseHelper.error('l_ci_p_validateSetAcceptedMarginParams_3', 'accepted margin cannot be negative');
+ const bigNumberAcceptedMargin = new BigNumber(acceptedMargin);
+
+ if (bigNumberAcceptedMargin.isNaN() || !bigNumberAcceptedMargin.isInteger() || bigNumberAcceptedMargin.lt(0)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetAcceptedMarginParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['accepted_margin_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!basicHelper.isAddressValid(senderAddress)) {
- return responseHelper.error('l_ci_p_validateSetAcceptedMarginParams_4', 'address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_validateSetAcceptedMarginParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
return responseHelper.successWithData({});
@@ -679,7 +831,7 @@ Pricer.prototype = {
const returnType = basicHelper.getReturnType(options.returnType);
const transactionObject = currContract.methods.setAcceptedMargin(
- web3RpcProvider.utils.asciiToHex(currency),
+ web3Provider.utils.asciiToHex(currency),
acceptedMargin);
const notificationData = helper.getNotificationData(
@@ -688,7 +840,7 @@ Pricer.prototype = {
'setAcceptedMargin',
oThis.contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -703,8 +855,8 @@ Pricer.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.setAcceptedMargin(),
+ web3Provider: web3Provider,
successCallback: successCallback,
failCallback: null,
errorCode: "l_ci_p_sam_6"
@@ -755,8 +907,13 @@ Pricer.prototype = {
// update cache
return oThis.pricerCache.clearAcceptedMargins(currency);
} else {
- return Promise.resolve(responseHelper.error('l_ci_p_verifyReceiptAndUpdateAcceptedMarginCache_1',
- 'Invalid event in receipt'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_verifyReceiptAndUpdateAcceptedMarginCache_1',
+ api_error_identifier: 'invalid_receipt',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -811,11 +968,23 @@ Pricer.prototype = {
const senderAccountBalanceResponse = await oThis.getBalanceOf(senderAddress);
if (senderAccountBalanceResponse.isFailure()) {
- return Promise.resolve(responseHelper.error('l_ci_p_pay_1', 'error while getting balance'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_pay_1',
+ api_error_identifier: 'get_balance_failed',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
const userInitialBalance = new BigNumber(senderAccountBalanceResponse.data.balance);
if (userInitialBalance.lt(totalAmount)) {
- return Promise.resolve(responseHelper.error('l_ci_p_pay_2', 'insufficient balance'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_pay_2',
+ api_error_identifier: 'insufficient_funds',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
var brandedTokenAddress = null;
@@ -833,7 +1002,7 @@ Pricer.prototype = {
transferAmount,
commissionBeneficiaryAddress,
commissionAmount,
- web3RpcProvider.utils.asciiToHex(currency),
+ web3Provider.utils.asciiToHex(currency),
intendedPricePoint);
const notificationData = helper.getNotificationData(
@@ -842,7 +1011,7 @@ Pricer.prototype = {
'pay',
oThis.contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
notificationData.message.payload.erc20_contract_address = brandedTokenAddress;
@@ -881,8 +1050,8 @@ Pricer.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: coreConstants.OST_PAY_GAS_LIMIT,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.airdropPay(),
+ web3Provider: web3Provider,
successCallback: successCallback,
failCallback: failCallback,
errorCode: "l_ci_p_p_8"
@@ -943,12 +1112,25 @@ Pricer.prototype = {
try {
if (!helper.isValidCurrency(currency, false)) {
- return Promise.resolve(responseHelper.error('l_ci_p_getPricePoint_1', 'currency is mandatory'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPricePoint_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
}
const priceOraclesResponse = await oThis.priceOracles(currency);
if (priceOraclesResponse.isFailure()) {
- return Promise.resolve(responseHelper.error('l_ci_p_getPricePoint_2', 'Something went wrong'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPricePoint_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
const poAddress = priceOraclesResponse.data.priceOracles;
@@ -964,9 +1146,15 @@ Pricer.prototype = {
}
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPricePoint_3',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:getPricePoint inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_getPricePoint_3', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -979,20 +1167,34 @@ Pricer.prototype = {
*
*/
getPricePointFromContract: async function (currency) {
- if (!helper.isValidCurrency(currency, false))
- return Promise.resolve(responseHelper.error('l_ci_p_getPricePointFromContract_1', 'currency is mandatory'));
+ if (!helper.isValidCurrency(currency, false)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPricePointFromContract_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
+ }
- const transactionObject = currContract.methods.getPricePoint(web3RpcProvider.utils.asciiToHex(currency))
+ const transactionObject = currContract.methods.getPricePoint(web3Provider.utils.asciiToHex(currency))
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject);
try {
- const response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ const response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({pricePoint: response[0]}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPriceOraclesFromContract_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:getPricePointFromContract inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_getPricePointFromContract_2', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -1007,23 +1209,37 @@ Pricer.prototype = {
*
*/
getPricePointAndCalculatedAmounts: async function (transferAmount, commissionAmount, currency) {
- if (!helper.isValidCurrency(currency, false))
- return Promise.resolve(responseHelper.error('l_ci_p_getPricePointAndCalculatedAmounts_1', 'currency is mandatory'));
+ if (!helper.isValidCurrency(currency, false)) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPricePointAndCalculatedAmounts_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
+ }
const transactionObject = currContract.methods.getPricePointAndCalculatedAmounts(transferAmount, commissionAmount,
- web3RpcProvider.utils.asciiToHex(currency));
+ web3Provider.utils.asciiToHex(currency));
const encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject);
try {
- const response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs);
+ const response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs);
return Promise.resolve(responseHelper.successWithData({pricePoint: response[0], tokenAmount: response[1],
commissionTokenAmount: response[2]}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getPricePointAndCalculatedAmounts_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
//Format the error
logger.error("lib/contract_interact/pricer.js:getPricePointAndCalculatedAmounts inside catch ", err);
- return Promise.resolve(responseHelper.error('l_ci_p_getPricePointAndCalculatedAmounts_2', 'Something went wrong'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -1036,7 +1252,7 @@ Pricer.prototype = {
*
*/
toWei: function(value) {
- return web3RpcProvider.utils.toWei(value, "ether");
+ return web3Provider.utils.toWei(value, "ether");
},
/**
@@ -1049,9 +1265,16 @@ Pricer.prototype = {
*/
getTxReceipt: async function(transactionHash) {
if (!transactionHash) {
- return responseHelper.error('l_ci_p_getTxReceipt_1', 'transaction hash is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getTxReceipt_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_transaction_hash'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
- const transactionReceipt = await helper.getTxReceipt(web3RpcProvider, transactionHash, {});
+ const transactionReceipt = await helper.getTxReceipt(web3Provider, transactionHash, {});
return Promise.resolve(responseHelper.successWithData({transactionReceipt: transactionReceipt}));
},
@@ -1067,7 +1290,14 @@ Pricer.prototype = {
const oThis = this;
// Validate addresses
if (!basicHelper.isAddressValid(owner)) {
- return Promise.resolve(responseHelper.error('l_ci_p_getBalanceOf_1', 'address is invalid'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_p_getBalanceOf_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
}
const setTokenResponse = await oThis.setTokenObj();
diff --git a/lib/contract_interact/workers.js b/lib/contract_interact/workers.js
index 76c678e..40501a3 100644
--- a/lib/contract_interact/workers.js
+++ b/lib/contract_interact/workers.js
@@ -16,15 +16,22 @@ const rootPrefix = '../..'
, coreConstants = require(rootPrefix + '/config/core_constants')
, helper = require(rootPrefix + '/lib/contract_interact/helper')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
, notificationGlobalConstant = require(rootPrefix + '/lib/global_constant/notification')
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
const contractName = 'workers'
- , gasLimit = coreConstants.OST_GAS_LIMIT
, contractAbi = coreAddresses.getAbiForContract(contractName)
- , currContract = new web3RpcProvider.eth.Contract(contractAbi)
+ , currContract = new web3Provider.eth.Contract(contractAbi)
;
/**
@@ -69,10 +76,6 @@ Workers.prototype = {
;
try {
- const validationResponse = oThis._validateSetWorkersParams(senderAddress, workerAddress, deactivationHeight, gasPrice);
-
- if (validationResponse.isFailure()) return Promise.resolve(validationResponse);
-
const returnType = basicHelper.getReturnType(options.returnType)
, transactionObject = currContract.methods.setWorker(workerAddress, deactivationHeight);
@@ -82,7 +85,7 @@ Workers.prototype = {
'setWorker',
contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -93,8 +96,8 @@ Workers.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.setWorker(),
+ web3Provider: web3Provider,
successCallback: null,
failCallback: null,
errorCode: "l_ci_w_setWorker_1"
@@ -102,8 +105,14 @@ Workers.prototype = {
return Promise.resolve(helper.performSend(params, returnType));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_setWorker_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/workers.js:setWorker inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_w_setWorker_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -136,7 +145,7 @@ Workers.prototype = {
'removeWorker',
contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -147,8 +156,8 @@ Workers.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.default(),
+ web3Provider: web3Provider,
successCallback: null,
failCallback: null,
errorCode: "l_ci_w_removeWorker_1"
@@ -156,8 +165,14 @@ Workers.prototype = {
return Promise.resolve(helper.performSend(params, returnType));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_removeWorker_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/workers.js:removeWorker inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_w_removeWorker_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -189,7 +204,7 @@ Workers.prototype = {
'remove',
contractName,
oThis.contractAddress,
- web3RpcProvider,
+ web3Provider,
oThis.chainId,
options);
@@ -200,8 +215,8 @@ Workers.prototype = {
senderPassphrase: senderPassphrase,
contractAddress: oThis.contractAddress,
gasPrice: gasPrice,
- gasLimit: gasLimit,
- web3RpcProvider: web3RpcProvider,
+ gasLimit: gasLimitGlobalConstant.default(),
+ web3Provider: web3Provider,
successCallback: null,
failCallback: null,
errorCode: "l_ci_w_remove_1"
@@ -209,8 +224,14 @@ Workers.prototype = {
return Promise.resolve(helper.performSend(params, returnType));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_remove_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/workers.js:remove inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_w_remove_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
@@ -225,53 +246,35 @@ Workers.prototype = {
isWorker: async function (workerAddress) {
try {
if (!basicHelper.isAddressValid(workerAddress)) {
- return Promise.resolve(responseHelper.error('l_ci_w_isWorker_1', 'worker address is invalid'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_isWorker_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_worker_address'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
}
const transactionObject = currContract.methods.isWorker(workerAddress)
, encodedABI = transactionObject.encodeABI()
, transactionOutputs = helper.getTransactionOutputs(transactionObject)
- , response = await helper.call(web3RpcProvider, this.contractAddress, encodedABI, {}, transactionOutputs)
+ , response = await helper.call(web3Provider, this.contractAddress, encodedABI, {}, transactionOutputs)
;
return Promise.resolve(responseHelper.successWithData({isValid: response[0]}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_isWorker_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/workers.js:isWorker inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_w_isWorker_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
},
- /**
- * Validate set workers params
- *
- * @param {string} senderAddress - address of sender
- * @param {string} workerAddress - worker address
- * @param {number} deactivationHeight - block number till which the worker is valid
- * @param {BigNumber} gasPrice - gas price
- *
- * @return {result}
- *
- */
- _validateSetWorkersParams: function (senderAddress, workerAddress, deactivationHeight, gasPrice ) {
- if (!gasPrice) {
- return responseHelper.error('l_ci_w_validateSetWorkersParams_1', 'gas is mandatory');
- }
- if (!basicHelper.isAddressValid(senderAddress)) {
- return responseHelper.error('l_ci_w_validateSetWorkersParams_2', 'sender address is invalid');
- }
- if (!basicHelper.isAddressValid(workerAddress)) {
- return responseHelper.error('l_ci_w_validateSetWorkersParams_3', 'worker address is invalid');
- }
- if (!deactivationHeight) {
- return responseHelper.error('l_ci_w_validateSetWorkersParams_4', 'deactivation height is mandatory');
- }
- deactivationHeight = new BigNumber(deactivationHeight);
- if (deactivationHeight.isNaN() || deactivationHeight.lt(0) || !deactivationHeight.isInteger()) {
- return responseHelper.error('l_ci_w_validateSetWorkersParams_5', 'deactivation height value is invalid');
- }
- return responseHelper.successWithData({});
- },
-
/**
* Validate remove worker params
*
@@ -284,13 +287,34 @@ Workers.prototype = {
*/
_validateRemoveWorkerParams: function (senderAddress, workerAddress, gasPrice) {
if (!gasPrice) {
- return responseHelper.error('l_ci_w_validateRemoveWorkerParams_1', 'gas is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_validateRemoveWorkerParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!basicHelper.isAddressValid(senderAddress)) {
- return responseHelper.error('l_ci_w_validateRemoveWorkerParams_2', 'sender address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_validateRemoveWorkerParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
}
if (!basicHelper.isAddressValid(workerAddress)) {
- return responseHelper.error('l_ci_w_validateRemoveWorkerParams_3', 'worker address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_validateRemoveWorkerParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_worker_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
return responseHelper.successWithData({});
@@ -307,10 +331,24 @@ Workers.prototype = {
*/
_validateRemoveParams: function (senderAddress, gasPrice) {
if (!gasPrice) {
- return responseHelper.error('l_ci_w_validateRemoveParams_1', 'gas is mandatory');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_validateRemoveParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
if (!basicHelper.isAddressValid(senderAddress)) {
- return responseHelper.error('l_ci_w_validateRemoveParams_2', 'sender address is invalid');
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_validateRemoveParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
}
return responseHelper.successWithData({});
},
@@ -326,14 +364,27 @@ Workers.prototype = {
getTxReceipt: async function(transactionHash) {
try {
if (!transactionHash) {
- return Promise.resolve(responseHelper.error('l_ci_w_getTxReceipt_1', 'transaction hash is mandatory'));
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_getTxReceipt_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_transaction_hash'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.error(errorParams));
}
- const transactionReceipt = await helper.getTxReceipt(web3RpcProvider, transactionHash, {});
+ const transactionReceipt = await helper.getTxReceipt(web3Provider, transactionHash, {});
return Promise.resolve(responseHelper.successWithData({transactionReceipt: transactionReceipt}));
} catch(err) {
+ let errorParams = {
+ internal_error_identifier: 'l_ci_w_getTxReceipt_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
logger.error('lib/contract_interact/workers.js:getTxReceipt inside catch:', err);
- return Promise.resolve(responseHelper.error('l_ci_w_getTxReceipt_2', 'Something went wrong.'));
+ return Promise.resolve(responseHelper.error(errorParams));
}
}
};
diff --git a/lib/deployer.js b/lib/deployer.js
deleted file mode 100644
index 49bfc82..0000000
--- a/lib/deployer.js
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * This is script for deploying any contract.
- *
- * Prerequisite:
- *
- * Deployer Address
- *
- *
- *
- *
- *
- * @module lib/deployer
- */
-
-const uuid = require('uuid');
-const fs = require('fs');
-const Path = require('path');
-
-const rootPrefix = '..';
-const web3Provider = require(rootPrefix + '/lib/web3/providers/rpc');
-const coreConstants = require(rootPrefix + '/config/core_constants');
-const coreAddresses = require(rootPrefix + '/config/core_addresses');
-const logger = require(rootPrefix + '/helpers/custom_console_logger');
-const responseHelper = require(rootPrefix + '/lib/formatter/response');
-const basicHelper = require(rootPrefix + '/helpers/basic_helper');
-
-const deployerName = 'deployer';
-
-/**
- * @constructor
- *
- */
-const Deploy = module.exports = function () {};
-
-Deploy.prototype = {
-
- /**
- * Validate deploy parameters
- *
- * @param {string} contractName - Contract name
- * @param {BigNumber} gasPrice - Gas price
- *
- * @return {response}
- *
- */
- validateDeployParams: function(
- contractName,
- gasPrice) {
-
- if (!contractName) {
- logger.error("Error: Contract name is mandatory");
- return responseHelper.error('l_d_1', 'Contract name is mandatory');
- }
-
- if (!gasPrice) {
- logger.error("Error: Gas price is mandatory");
- return responseHelper.error('l_d_2', 'Gas price is mandatory');
- }
-
- const deployerAddress = coreAddresses.getAddressForUser(deployerName);
- if (!deployerAddress) {
- logger.error("Error: Deployer address is invalid");
- return responseHelper.error('l_d_3', 'Deployer address is invalid');
- }
-
- const deployerAddrPassphrase = coreAddresses.getPassphraseForUser(deployerName);
- if (!deployerAddrPassphrase) {
- logger.error("Error: Deployer passphrase is invalid");
- return responseHelper.error('l_d_4', 'Deployer passphrase is invalid');
- }
-
- return responseHelper.successWithData({});
-
- },
-
- /**
- * Deploy contract
- *
- * @param {string} contractName - Contract name - pricer / airdrop / workers
- * @param {Array} constructorArgs - Contract constructor params
- * @param {BigNumber} gasPrice - Gas price
- * @param {object} options - for params like returnType, tag.
- *
- * @return {response}
- *
- */
- deploy: function(
- contractName,
- constructorArgs,
- gasPrice,
- options) {
-
- const oThis = this;
-
- return new Promise(function (onResolve, onReject) {
-
- logger.debug("Contract name: " + contractName);
- logger.debug("Gas price: " + gasPrice);
- logger.debug("Constructor arguments: " + constructorArgs);
-
- const validationResult = oThis.validateDeployParams(
- contractName,
- gasPrice);
-
- if (validationResult.isFailure()) {
- return onResolve(validationResult);
- }
-
- const txUUID = uuid.v4();
- const returnType = basicHelper.getReturnType(options.returnType);
-
- const asyncPerform = function () {
-
- const deployerAddress = coreAddresses.getAddressForUser(deployerName);
- const deployerAddrPassphrase = coreAddresses.getPassphraseForUser(deployerName);
-
- const contractAbi = coreAddresses.getAbiForContract(contractName);
- const contractBin = coreAddresses.getBinForContract(contractName);
-
- const txParams = {
- from: deployerAddress,
- data: (web3Provider.utils.isHexStrict(contractBin) ? "" : "0x") + contractBin,
- gasPrice: gasPrice,
- gas: coreConstants.OST_GAS_LIMIT
- };
-
- if (constructorArgs) {
- txParams.arguments = constructorArgs;
- }
-
- var contract = new web3Provider.eth.Contract(
- contractAbi,
- null,
- txParams
- );
-
- // this is needed since the contract object
- contract.setProvider(web3Provider.currentProvider);
-
- // Unlock account
- web3Provider.eth.personal.unlockAccount(
- deployerAddress,
- deployerAddrPassphrase)
- .then(function() {
- const encodeABI = contract.deploy(txParams).encodeABI();
- txParams.data = encodeABI;
-
- web3Provider.eth.sendTransaction(txParams)
- .on('transactionHash', function(transactionHash) {
- logger.debug(`Transaction hash received for ${txUUID} :${transactionHash}`);
- if (basicHelper.isReturnTypeTxHash(returnType)) {
- return onResolve(
- responseHelper.successWithData(
- {
- transaction_uuid: txUUID,
- transaction_hash: transactionHash,
- transaction_receipt: {}
- }));
- }
- })
- .on('receipt', function(receipt) {
-
- const contractAddress = receipt.contractAddress;
- web3Provider.eth.getCode(contractAddress).then(function(code) {
- if (code.length <= 2) {
- const errorCode = "l_d_6";
- logger.error(`${errorCode}: Contract deployment failed`);
- if (basicHelper.isReturnTypeTxReceipt(returnType)) {
- return onResolve(responseHelper.error(errorCode, 'Contract deployment failed'));
- }
- } else if (basicHelper.isReturnTypeTxReceipt(returnType)) {
- logger.debug(`Contract deployment success: ${txUUID}`);
- return onResolve(
- responseHelper.successWithData(
- {
- transaction_uuid: txUUID,
- transaction_hash: receipt.transactionHash,
- transaction_receipt: receipt
- }));
- }
- })
- .catch(function(reason) {
- const errorCode = "l_d_7";
- logger.error(`${errorCode}: Contract deployment failed`);
- if (basicHelper.isReturnTypeTxReceipt(returnType)) {
- return onResolve(responseHelper.error(errorCode, 'Contract deployment failed'));
- }
- });
- });
- })
- .catch(function(reason) {
- const errorCode = "l_d_5";
- logger.error(`${errorCode}: Contract deployment failed`);
- return onResolve(responseHelper.error(errorCode, 'transaction failed'));
- });
-
- };
- if (basicHelper.isReturnTypeUUID(returnType)) {
- asyncPerform();
- return onResolve(
- responseHelper.successWithData(
- {
- transaction_uuid: txUUID,
- transaction_hash: "",
- transaction_receipt: {}
- }));
- } else {
- return asyncPerform();
- }
-
- });
- },
-
- /**
- * Write contract address to file based on parameter
- *
- * @param {String} fileName - file name
- * @param {Hex} contractAddress - contract Address
- *
- * @return {}
- */
- writeContractAddressToFile: function(fileName, contractAddress) {
- // Write contract address to file
- if ( fileName !== '') {
- fs.writeFileSync(Path.join(__dirname, '/' + fileName), contractAddress);
- }
- }
-};
-
diff --git a/lib/formatter/response.js b/lib/formatter/response.js
index 975c87f..8085dc9 100644
--- a/lib/formatter/response.js
+++ b/lib/formatter/response.js
@@ -5,80 +5,11 @@
*
*/
-const shortId = require('shortid');
+const rootPrefix = '../..'
+ , OSTBase = require('@openstfoundation/openst-base')
+ , responseHelper = new OSTBase.responseHelper({
+ moduleName: 'openst-payments'
+ });
-function Result(data, errCode, errMsg) {
- this.success = (typeof errCode === undefined || typeof errCode === "undefined");
-
- this.data = data || {};
-
- if (!this.success) {
- this.err = {
- code: errCode,
- msg: errMsg
- };
- }
-
- // Check if response has success
- this.isSuccess = function () {
- return this.success;
- };
-
- // Check if response is not success. More often not success is checked, so adding a method.
- this.isFailure = function () {
- return !this.isSuccess();
- };
-
- // Format data to hash
- this.toHash = function () {
- var s = {};
- if (this.success) {
- s.success = true;
- s.data = this.data;
- } else {
- s.success = false;
- if ( this.data instanceof Object && Object.keys( this.data ).length > 0 ) {
- //Error with data case.
- s.data = this.data;
- }
- s.err = this.err;
- }
-
- return s;
- };
-
- // Render final error or success response
- this.renderResponse = function (res, status) {
- status = status || 200;
- return res.status(status).json(this.toHash());
- };
-}
-
-const responseHelper = {
-
- // Generate success response object
- successWithData: function (data) {
- return new Result(data);
- },
-
- // Generate error response object
- error: function(errCode, errMsg, errPrefix) {
- errCode = 'ost_pricer(' + errCode + ":" + shortId.generate() + ')';
- if (errPrefix) {
- errCode = errPrefix + "*" + errCode;
- }
- return new Result({}, errCode, errMsg);
- },
-
- // Generate error response object
- errorWithData: function (data, errCode, errMsg, errPrefix) {
- errCode = 'ost_pricer(' + errCode + ":" + shortId.generate() + ')';
- if (errPrefix) {
- errCode = errPrefix + "*" + errCode;
- }
- return new Result(data, errCode, errMsg);
- },
-
-};
module.exports = responseHelper;
\ No newline at end of file
diff --git a/lib/global_constant/gas_limit.js b/lib/global_constant/gas_limit.js
new file mode 100644
index 0000000..ec4b048
--- /dev/null
+++ b/lib/global_constant/gas_limit.js
@@ -0,0 +1,64 @@
+"use strict";
+
+const gasLimit = {
+
+ buffer: function() {
+ return 10000;
+ },
+
+ default: function() {
+ return 9000000;
+ },
+
+ setOps: function() {
+ return 45822+this.buffer();
+ },
+
+ deployWorker: function() {
+ return 569731+this.buffer();
+ },
+
+ deployAirdrop: function() {
+ return 1583725+this.buffer();
+ },
+
+ deployPriceOracle: function() {
+ return 579067+this.buffer();
+ },
+
+ deployOpsManaged: function() {
+ return 45690+this.buffer();
+ },
+
+ setPriceOracle: function() {
+ return 64585+this.buffer();
+ },
+
+ setAcceptedMargin: function() {
+ return 44726+this.buffer();
+ },
+
+ setWorker: function() {
+ return 46402+this.buffer();
+ },
+
+ transferToAirdropBudgetHolder: function() {
+ return 51705+this.buffer();
+ },
+
+ approveByBudgetHolder: function() {
+ return 45675+this.buffer();
+ },
+
+ approveToUser: function() {
+ return 45611+this.buffer();
+ },
+
+ airdropPay: function(){
+ return 134842+this.buffer();
+ },
+
+
+};
+
+module.exports = gasLimit;
\ No newline at end of file
diff --git a/lib/set_worker_and_ops.js b/lib/set_worker_and_ops.js
index fdee9f5..8f07e28 100644
--- a/lib/set_worker_and_ops.js
+++ b/lib/set_worker_and_ops.js
@@ -6,13 +6,22 @@
* @module lib/set_worker_and_ops
*/
const rootPrefix = ".."
- , OpsManagedContract = require(rootPrefix + "/lib/contract_interact/ops_managed_contract")
, logger = require(rootPrefix + '/helpers/custom_console_logger')
- , Deployer = require(rootPrefix + '/lib/deployer')
, returnTypes = require(rootPrefix + "/lib/global_constant/return_types")
, coreAddresses = require(rootPrefix + '/config/core_addresses')
, responseHelper = require(rootPrefix + '/lib/formatter/response')
- ;
+ , openstPayment = require(rootPrefix + '/index')
+ , SetOpsKlass = openstPayment.services.opsManaged.setOps
+ , GetOpsKlass = openstPayment.services.opsManaged.getOps
+ , DeployWorkersKlass = openstPayment.services.deploy.workers
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
// Different addresses used for deployment
const deployerName = "deployer"
@@ -45,23 +54,26 @@ SetWorkerOps.prototype = {
*/
perform: async function(options){
- const contractName = 'workers'
- , gasPrice = (options || {}).gasPrice
+ const gasPrice = (options || {}).gasPrice
, chainId = (options || {}).chainId
- , constructorArgs = []
- , deployerInstance = new Deployer()
, deployOptions = {returnType: returnTypes.transactionReceipt()}
- ;
+ ;
if(!gasPrice || !chainId){
- return Promise.resolve(responseHelper.error("l_swao_2", "Gas price and Chain Id are mandatory"));
+ let errorParams = {
+ internal_error_identifier: 'l_swao_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid', 'chain_id_invalid'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
}
-
- const deployResult = await deployerInstance.deploy(
- contractName,
- constructorArgs,
- gasPrice,
- deployOptions);
+ const DeployWorkerObject = new DeployWorkersKlass({
+ gas_price: gasPrice,
+ options: deployOptions
+ });
+ const deployResult = await DeployWorkerObject.perform();
if (deployResult.isSuccess()) {
const contractAddress = deployResult.data.transaction_receipt.contractAddress;
@@ -72,14 +84,26 @@ SetWorkerOps.prototype = {
returnType: returnTypes.transactionReceipt(),
tag: ''
}
- , opsManaged = new OpsManagedContract(contractAddress, gasPrice, chainId)
;
- var result = await opsManaged.setOpsAddress(deployerAddress,
- deployerPassphrase,
- opsAddress,
- setOpsOptions);
+ const SetOpsObject = new SetOpsKlass({
+ contract_address: contractAddress,
+ gas_price: gasPrice,
+ chain_id: chainId,
+ deployer_address: deployerAddress,
+ deployer_passphrase: deployerPassphrase,
+ ops_address: opsAddress,
+ options: setOpsOptions
+ });
+ var result = await SetOpsObject.perform();
logger.debug(result);
- var contractOpsAddress = await opsManaged.getOpsAddress();
+
+ const GetOpsObject = new GetOpsKlass({
+ contract_address: contractAddress,
+ gas_price: gasPrice,
+ chain_id: chainId
+ });
+ const getOpsResult = await GetOpsObject.perform();
+ const contractOpsAddress = getOpsResult.data.opsAddress;
logger.debug("Ops Address Set to: ", contractOpsAddress);
return Promise.resolve(responseHelper.successWithData({workerContractAddress: contractAddress}));
} else{
@@ -88,7 +112,14 @@ SetWorkerOps.prototype = {
return Promise.resolve(deployResult);
}
- return Promise.resolve(responseHelper.error("l_swao_1", "Something went wrong."));
+ let errorParams = {
+ internal_error_identifier: 'l_swao_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+
+ return Promise.resolve(responseHelper.error(errorParams));
}
};
diff --git a/lib/transaction_helper.js b/lib/transaction_helper.js
index c4e66b0..bd818b6 100644
--- a/lib/transaction_helper.js
+++ b/lib/transaction_helper.js
@@ -13,15 +13,22 @@ const BigNumber = require('bignumber.js')
const rootPrefix = '..'
, responseHelper = require(rootPrefix + '/lib/formatter/response')
, Token = require(rootPrefix + '/lib/contract_interact/branded_token')
- , UserAirdropDetailCacheKlass = require(rootPrefix + '/lib/cache_management/user_airdrop_detail')
+ , UserAirdropDetailCacheKlass = require(rootPrefix + '/lib/cache_multi_management/user_airdrop_detail')
, AdjustAirdropAmountKlass = require(rootPrefix + '/lib/airdrop_management/adjust_airdrop_amount')
, web3EventsDecoder = require(rootPrefix + '/lib/web3/events/decoder')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
, eventGlobalConstants = require(rootPrefix+'/lib/global_constant/events')
- , airdropKlass = require(rootPrefix + '/app/models/airdrop')
, basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
/**
* constructor
*
@@ -201,9 +208,9 @@ TransactionHelper.prototype = {
*/
clearUserDetailCache: async function(airdropContractAddress, owner) {
const oThis = this
- , airdropModel = new airdropKlass()
- , airdropModelResult = await airdropModel.getByContractAddress(airdropContractAddress)
- , airdropRecord = airdropModelResult[0]
+ , airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ , airdropRecord = airdropModelCacheResponse.data[airdropContractAddress]
;
const userAirdropDetailCache = new UserAirdropDetailCacheKlass({
@@ -480,6 +487,7 @@ TransactionHelper.prototype = {
*
* @param {Object} transactionReceipt - transaction receipt
* @param {Object} addressToNameMap - address to name map object
+ * @param {string} eventName - Event name
*
* @return {result}
*/
@@ -488,6 +496,19 @@ TransactionHelper.prototype = {
const oThis = this;
// decode events
const decodedEvent = web3EventsDecoder.perform(transactionReceipt, addressToNameMap);
+ return oThis.getActualAmountsFromDecodedEvents(decodedEvent.formattedTransactionReceipt.eventsData, eventName);
+
+ },
+
+ /**
+ * Get actual beneficiary amount, actual commission amount and actual airdrop amount from decoded events
+ *
+ * @param {Object} decodedEvent - Decoded event from receipt
+ * @param {string} eventName - Event name
+ *
+ * @return {result}
+ */
+ getActualAmountsFromDecodedEvents: function(events, eventName) {
var actualBeneficiaryAmount = new BigNumber(0)
, actualCommissionAmount = new BigNumber(0)
@@ -495,31 +516,28 @@ TransactionHelper.prototype = {
, isEventDecoded = false
;
- if (decodedEvent != undefined && decodedEvent != null) {
- // get event data
- const events =decodedEvent.formattedTransactionReceipt.eventsData;
- if (events != undefined && events != null) {
- // get whats the actual transfer amounts
- for (var i = 0; i < events.length; i++) {
- const eventData = events[i];
- if (eventData.name === eventName) {
- const paymentEvents = eventData.events;
- for (var eventCount = 0; eventCount < paymentEvents.length; eventCount++) {
- const paymentEventsData = paymentEvents[eventCount];
- if (paymentEventsData.name === eventGlobalConstants.eventAttribute.tokenAmount()) {
- isEventDecoded = true;
- actualBeneficiaryAmount = new BigNumber(paymentEventsData.value);
- } else if (paymentEventsData.name === eventGlobalConstants.eventAttribute.commissionTokenAmount()) {
- isEventDecoded = true;
- actualCommissionAmount = new BigNumber(paymentEventsData.value);
- } else if (paymentEventsData.name === eventGlobalConstants.eventAttribute.airdropAmount()) {
- isEventDecoded = true;
- actualAirdropAmount = new BigNumber(paymentEventsData.value);
- }
+ // get event data
+ if (events != undefined && events != null) {
+ // get whats the actual transfer amounts
+ for (var i = 0; i < events.length; i++) {
+ const eventData = events[i];
+ if (eventData.name === eventName) {
+ const paymentEvents = eventData.events;
+ for (var eventCount = 0; eventCount < paymentEvents.length; eventCount++) {
+ const paymentEventsData = paymentEvents[eventCount];
+ if (paymentEventsData.name === eventGlobalConstants.eventAttribute.tokenAmount()) {
+ isEventDecoded = true;
+ actualBeneficiaryAmount = new BigNumber(paymentEventsData.value);
+ } else if (paymentEventsData.name === eventGlobalConstants.eventAttribute.commissionTokenAmount()) {
+ isEventDecoded = true;
+ actualCommissionAmount = new BigNumber(paymentEventsData.value);
+ } else if (paymentEventsData.name === eventGlobalConstants.eventAttribute.airdropAmount()) {
+ isEventDecoded = true;
+ actualAirdropAmount = new BigNumber(paymentEventsData.value);
}
}
-
}
+
}
}
if (isEventDecoded) {
@@ -527,7 +545,13 @@ TransactionHelper.prototype = {
{actualBeneficiaryAmount: actualBeneficiaryAmount, actualCommissionAmount: actualCommissionAmount,
actualAirdropAmount: actualAirdropAmount});
} else {
- return responseHelper.error('l_th_getActualAmountsFromReceipt_1', "No events found in the transaction receipt");
+ let errorParams = {
+ internal_error_identifier: 'l_th_getActualAmountsFromDecodedEvents_1',
+ api_error_identifier: 'no_events_in_receipt',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
}
},
diff --git a/lib/web3/providers/rpc.js b/lib/web3/providers/rpc.js
index 8e49a40..68ca949 100644
--- a/lib/web3/providers/rpc.js
+++ b/lib/web3/providers/rpc.js
@@ -1,9 +1,13 @@
"use strict";
-const coreConstants = require('../../../config/core_constants');
-const Web3 = require('web3')
- , provider = new Web3.providers.HttpProvider(coreConstants.OST_UTILITY_GETH_RPC_PROVIDER)
- , web3RpcProvider = new Web3(provider);
+const OSTBase = require("@openstfoundation/openst-base");
+
+const rootPrefix = '../../..'
+ , coreConstants = require(rootPrefix + '/config/core_constants')
+ , OstWeb3 = OSTBase.OstWeb3
+;
+
+const web3RpcProvider = new OstWeb3(coreConstants.OST_UTILITY_GETH_RPC_PROVIDER);
module.exports = web3RpcProvider;
diff --git a/lib/web3/providers/ws.js b/lib/web3/providers/ws.js
new file mode 100644
index 0000000..5495496
--- /dev/null
+++ b/lib/web3/providers/ws.js
@@ -0,0 +1,12 @@
+"use strict";
+
+const OstBase = require("@openstfoundation/openst-base");
+
+const rootPrefix = '../../..'
+ , coreConstants = require(rootPrefix + '/config/core_constants')
+ , OstWeb3 = OstBase.OstWeb3
+;
+
+const web3WSProvider = new OstWeb3(coreConstants.OST_UTILITY_GETH_WS_PROVIDER);
+
+module.exports = web3WSProvider;
diff --git a/migrations/create_tables.js b/migrations/create_tables.js
index ba68659..e891877 100644
--- a/migrations/create_tables.js
+++ b/migrations/create_tables.js
@@ -30,10 +30,10 @@ const createTables = {
for(var i in allQueries){
query = allQueries[i];
logger.win("\nRunning Query");
- logger.info(query);
+ logger.debug(query);
var response = await QueryDB.migrate(query);
logger.win("\nQuery Response");
- logger.info(response);
+ logger.debug(response);
}
logger.win("\nCompleted Table Creation");
diff --git a/mocha_test/lib/populate_env_vars.js b/mocha_test/lib/populate_env_vars.js
index 4e7410b..3747494 100644
--- a/mocha_test/lib/populate_env_vars.js
+++ b/mocha_test/lib/populate_env_vars.js
@@ -46,8 +46,8 @@ const populateEnvVars = {
}
var existingSourceFileData = fs.readFileSync(Path.join(__dirname, '/' + envVarsSourceFile));
var dataToWrite = existingSourceFileData.toString() + "\n\n" + renderData;
- //console.log("ENV Constants to Write");
- //console.log(dataToWrite);
+ //logger.debug("ENV Constants to Write");
+ //logger.debug(dataToWrite);
fs.writeFileSync(Path.join(__dirname, '/' + envVarsSourceFile), dataToWrite);
} catch (e) {
console.error("Error Reading and Populating Source File");
diff --git a/mocha_test/scripts/_init_addresses.js b/mocha_test/scripts/_init_addresses.js
index 05222a0..c239249 100644
--- a/mocha_test/scripts/_init_addresses.js
+++ b/mocha_test/scripts/_init_addresses.js
@@ -14,6 +14,7 @@ const _addresses = {
const rootPrefix = "../.."
, coreConstants = require( rootPrefix + '/config/core_constants' )
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
, populateEnvVars = require( rootPrefix + "/mocha_test/lib/populate_env_vars.js")
, poaGenesis = require( rootPrefix + "/mocha_test/scripts/poa-genesis.json")
;
@@ -96,7 +97,7 @@ function writeJsonToFile( jsObject, relativeFilePath, tab_space ) {
jsonFilePath = Path.join(__dirname, '/' + relativeFilePath );
}
- console.log("writeJsonToFile :: jsonFilePath :: ", jsonFilePath);
+ logger.debug("writeJsonToFile :: jsonFilePath :: ", jsonFilePath);
fs.writeFileSync(jsonFilePath, json );
}
diff --git a/mocha_test/scripts/deploy_all.sh b/mocha_test/scripts/deploy_all.sh
index 822d059..7475a23 100644
--- a/mocha_test/scripts/deploy_all.sh
+++ b/mocha_test/scripts/deploy_all.sh
@@ -6,57 +6,57 @@ sh ../contracts/compile.sh
echo "\n********* Deploying test coin 1 *************"
node ../tools/deploy/EIP20TokenMock.js 5 TC1 TestCoin1 18 0x12A05F200 travis tc1.txt
-export OST_UTILITY_TEST_COIN1_C5_ADDRESS=$(cat ../lib/tc1.txt)
+export OST_UTILITY_TEST_COIN1_C5_ADDRESS=$(cat ../tools/deploy/tc1.txt)
echo '\nexport OST_UTILITY_TEST_COIN1_C5_ADDRESS='\'$OST_UTILITY_TEST_COIN1_C5_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/tc1.txt
+rm ../tools/deploy/tc1.txt
echo "\n********* Done *************"
echo "\n********* Deploying test coin 2 *************"
. ./scripts/env_vars.sh
node ../tools/deploy/EIP20TokenMock.js 2 TC2 TestCoin2 18 0x12A05F200 travis tc2.txt
-export OST_UTILITY_TEST_COIN2_C2_ADDRESS=$(cat ../lib/tc2.txt)
+export OST_UTILITY_TEST_COIN2_C2_ADDRESS=$(cat ../tools/deploy/tc2.txt)
echo '\nexport OST_UTILITY_TEST_COIN2_C2_ADDRESS='\'$OST_UTILITY_TEST_COIN2_C2_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/tc2.txt
+rm ../tools/deploy/tc2.txt
echo "\n********* Done *************"
echo "\n********* Deploying test coin 3 *************"
. ./scripts/env_vars.sh
node ../tools/deploy/EIP20TokenMock.js 3 TC3 TestCoin3 10 0x12A05F200 travis tc3.txt
-export OST_UTILITY_TEST_COIN3_C3_ADDRESS=$(cat ../lib/tc3.txt)
+export OST_UTILITY_TEST_COIN3_C3_ADDRESS=$(cat ../tools/deploy/tc3.txt)
echo '\nexport OST_UTILITY_TEST_COIN3_C3_ADDRESS='\'$OST_UTILITY_TEST_COIN3_C3_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/tc3.txt
+rm ../tools/deploy/tc3.txt
echo "\n********* Done *************"
echo "\n********* Deploying Pricer 1 *************"
. ./scripts/env_vars.sh
node ../tools/deploy/pricer.js $OST_UTILITY_TEST_COIN1_C5_ADDRESS OST 0x12A05F200 $OST_UTILITY_CHAIN_ID travis tp1.txt
-export OST_UTILITY_TEST_PRICER_C5_ADDRESS=$(cat ../lib/tp1.txt)
+export OST_UTILITY_TEST_PRICER_C5_ADDRESS=$(cat ../tools/deploy/tp1.txt)
echo '\nexport OST_UTILITY_TEST_PRICER_C5_ADDRESS='\'$OST_UTILITY_TEST_PRICER_C5_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/tp1.txt
+rm ../tools/deploy/tp1.txt
echo "\n********* Done *************"
echo "\n********* Deploying Pricer 2 *************"
. ./scripts/env_vars.sh
node ../tools/deploy/pricer.js $OST_UTILITY_TEST_COIN2_C2_ADDRESS OST 0x12A05F200 $OST_UTILITY_CHAIN_ID travis tp2.txt
-export OST_UTILITY_TEST_PRICER_C2_ADDRESS=$(cat ../lib/tp2.txt)
+export OST_UTILITY_TEST_PRICER_C2_ADDRESS=$(cat ../tools/deploy/tp2.txt)
echo '\nexport OST_UTILITY_TEST_PRICER_C2_ADDRESS='\'$OST_UTILITY_TEST_PRICER_C2_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/tp2.txt
+rm ../tools/deploy/tp2.txt
echo "\n********* Done *************"
echo "\n********* Deploying Pricer 3 *************"
. ./scripts/env_vars.sh
node ../tools/deploy/pricer.js $OST_UTILITY_TEST_COIN3_C3_ADDRESS OST 0x12A05F200 $OST_UTILITY_CHAIN_ID travis tp3.txt
-export OST_UTILITY_TEST_PRICER_C3_ADDRESS=$(cat ../lib/tp3.txt)
+export OST_UTILITY_TEST_PRICER_C3_ADDRESS=$(cat ../tools/deploy/tp3.txt)
echo '\nexport OST_UTILITY_TEST_PRICER_C3_ADDRESS='\'$OST_UTILITY_TEST_PRICER_C3_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/tp3.txt
+rm ../tools/deploy/tp3.txt
echo "\n********* Done *************"
echo "\n********* Deploying Worker Contract Address *************"
node ../tools/deploy/workers.js 0x12A05F200 $OST_UTILITY_CHAIN_ID travis w1.txt
-export OST_UTILITY_WORKER_CONTRACT_ADDRESS=$(cat ../lib/w1.txt)
+export OST_UTILITY_WORKER_CONTRACT_ADDRESS=$(cat ../tools/deploy/w1.txt)
echo '\nexport OST_UTILITY_WORKER_CONTRACT_ADDRESS='\'$OST_UTILITY_WORKER_CONTRACT_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/w1.txt
+rm ../tools/deploy/w1.txt
echo "\n********* Done *************"
echo "\n Sourcing env_vars again"
@@ -65,9 +65,9 @@ echo "\n Sourcing env_vars again"
echo "\n********* Deploying Airdrop Contract Address *************"
. ./scripts/env_vars.sh
node ../tools/deploy/airdrop.js $OST_UTILITY_TEST_COIN1_C5_ADDRESS OST $OST_UTILITY_WORKER_CONTRACT_ADDRESS $OST_AIRDROP_BUDGET_HOLDER 0x12A05F200 $OST_UTILITY_CHAIN_ID travis ad1.txt
-export OST_UTILITY_TEST_AIRDROP1_CONTRACT_ADDRESS=$(cat ../lib/ad1.txt)
+export OST_UTILITY_TEST_AIRDROP1_CONTRACT_ADDRESS=$(cat ../tools/deploy/ad1.txt)
echo '\nexport OST_UTILITY_TEST_AIRDROP1_CONTRACT_ADDRESS='\'$OST_UTILITY_TEST_AIRDROP1_CONTRACT_ADDRESS\'>>scripts/env_vars.sh
-rm ../lib/ad1.txt
+rm ../tools/deploy/ad1.txt
echo "\n********* Done *************"
diff --git a/mocha_test/scripts/deploy_price_oracle.sh b/mocha_test/scripts/deploy_price_oracle.sh
index 9ed67ed..d5d7028 100644
--- a/mocha_test/scripts/deploy_price_oracle.sh
+++ b/mocha_test/scripts/deploy_price_oracle.sh
@@ -1,7 +1,7 @@
#!/bin/bash
echo "\n********* Preparing price oracle deployment *************"
-npm install @ostdotcom/ost-price-oracle@1.0.0
+npm install @ostdotcom/ost-price-oracle@1.0.1-beta.3
cd ../../node_modules/@ostdotcom/ost-price-oracle/
echo "\n********* Done *************"
diff --git a/mocha_test/scripts/geth_checker.js b/mocha_test/scripts/geth_checker.js
index 4d1ba6c..79b24a3 100644
--- a/mocha_test/scripts/geth_checker.js
+++ b/mocha_test/scripts/geth_checker.js
@@ -2,7 +2,7 @@
const rootPrefix = '../..'
, logger = require(rootPrefix + '/helpers/custom_console_logger')
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
;
const performer = async function () {
@@ -20,11 +20,11 @@ const performer = async function () {
if (totalTime <= timeoutValue) {
if (isInProcess == false) {
isInProcess = true;
- web3RpcProvider.eth.getBlockNumber(function (err, blocknumber) {
+ web3Provider.eth.getBlockNumber(function (err, blocknumber) {
if (err || blocknumber < 1) {
- logger.info("Unable to get blocknumber");
+ logger.debug("Unable to get blocknumber");
} else {
- logger.info("blocknumber", blocknumber);
+ logger.debug("blocknumber", blocknumber);
process.exit(0);
}
isInProcess = false;
diff --git a/mocha_test/scripts/install_geth_1_8_3.sh b/mocha_test/scripts/install_geth_1_8_3.sh
new file mode 100644
index 0000000..3ea630d
--- /dev/null
+++ b/mocha_test/scripts/install_geth_1_8_3.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+curl https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.8.3-329ac18e.tar.gz | tar xvz
+mv geth-linux-amd64-1.8.3-329ac18e /usr/local/bin
+ln -s /usr/local/bin/geth-linux-amd64-1.8.3-329ac18e/geth /usr/local/bin/geth
+export PATH="$PATH:/usr/local/bin/geth-linux-amd64-1.8.3-329ac18e"
+
+
+
diff --git a/mocha_test/scripts/run_chain.sh b/mocha_test/scripts/run_chain.sh
index d34497a..de9607e 100755
--- a/mocha_test/scripts/run_chain.sh
+++ b/mocha_test/scripts/run_chain.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-DATADIR=./st-poa
+DATADIR=$(pwd)/st-poa
LOCAL_NETWORK_ID="--networkid 20171010"
-geth --datadir "$DATADIR" $LOCAL_NETWORK_ID --port 30301 --rpcport 9546 --ws --wsport 19546 --wsorigins "*" --gasprice 0 --targetgaslimit 100000000 --etherbase 0 --unlock 0 --password pw --rpc --maxpeers 0 --mine --minerthreads 4 --rpcapi net,eth,web3,personal
+geth --datadir "$DATADIR" $LOCAL_NETWORK_ID --port 30301 --rpcport 9546 --rpcapi net,eth,web3,personal --wsapi net,eth,web3,personal --ws --wsport 19546 --wsorigins "*" --gasprice 0 --targetgaslimit 100000000 --etherbase 0 --unlock 0 --password pw --rpc --maxpeers 0 --mine --minerthreads 4
diff --git a/mocha_test/scripts/set_env_vars.sh b/mocha_test/scripts/set_env_vars.sh
index 260f350..186e522 100644
--- a/mocha_test/scripts/set_env_vars.sh
+++ b/mocha_test/scripts/set_env_vars.sh
@@ -3,6 +3,8 @@
export OST_UTILITY_GAS_PRICE='0x12A05F200'
export OST_UTILITY_GETH_RPC_PROVIDER='http://127.0.0.1:9546'
+export OST_UTILITY_GETH_WS_PROVIDER='ws://127.0.0.1:19546'
+
export OST_UTILITY_DEPLOYER_ADDR=''
export OST_UTILITY_DEPLOYER_PASSPHRASE='testtest'
export OST_UTILITY_OPS_ADDR=''
@@ -18,4 +20,4 @@ export OP_MYSQL_DATABASE='payment_development'
export OP_MYSQL_CONNECTION_POOL_SIZE='5'
export OST_CACHING_ENGINE='none'
-export OST_DEBUG_ENABLED=0
\ No newline at end of file
+export OST_DEBUG_ENABLED=1
\ No newline at end of file
diff --git a/mocha_test/scripts/start_test_chain.sh b/mocha_test/scripts/start_test_chain.sh
index 17a8ae8..44bee8b 100644
--- a/mocha_test/scripts/start_test_chain.sh
+++ b/mocha_test/scripts/start_test_chain.sh
@@ -5,5 +5,6 @@ cat set_env_vars.sh>env_vars.sh
sh init_keys.sh
sh init_chain.sh
nohup sh run_chain.sh /dev/null 2>&1 &
+sleep 10
node ./geth_checker.js
diff --git a/mocha_test/scripts/travis_test.sh b/mocha_test/scripts/travis_test.sh
index 0c0c815..44c80ff 100644
--- a/mocha_test/scripts/travis_test.sh
+++ b/mocha_test/scripts/travis_test.sh
@@ -3,7 +3,7 @@ sh start_test_chain.sh
sh deploy_all.sh
. ./env_vars.sh
node ./../../migrations/create_tables.js
-./../../node_modules/mocha/bin/mocha ./../../mocha_test/services/pricer
-./../../node_modules/mocha/bin/mocha ./../../mocha_test/services/airdrop
+./../../node_modules/mocha/bin/mocha ./../../mocha_test/services/pricer --exit
+./../../node_modules/mocha/bin/mocha ./../../mocha_test/services/airdrop --exit
# run worker test at last, as in the test case it removes the worker contract that is needed for other tests.
-./../../node_modules/mocha/bin/mocha ./../../mocha_test/services/workers
\ No newline at end of file
+./../../node_modules/mocha/bin/mocha ./../../mocha_test/services/workers --exit
\ No newline at end of file
diff --git a/mocha_test/services/airdrop/airdrop_budget_holder.js b/mocha_test/services/airdrop/airdrop_budget_holder.js
index cd049a4..f766af2 100644
--- a/mocha_test/services/airdrop/airdrop_budget_holder.js
+++ b/mocha_test/services/airdrop/airdrop_budget_holder.js
@@ -6,7 +6,7 @@ const rootPrefix = "../../.."
, constants = require(rootPrefix + '/mocha_test/lib/constants')
, airdrop = require(rootPrefix + '/lib/contract_interact/airdrop')
, airdropContract = new airdrop(constants.airdropOstUsdAddress, constants.chainId)
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
;
describe('Get Airdrop Budget Holder', function() {
@@ -16,7 +16,7 @@ describe('Get Airdrop Budget Holder', function() {
const airdropWorkersResult = await airdropContract.airdropBudgetHolder();
assert.equal(airdropWorkersResult.isSuccess(), true);
assert.equal(airdropWorkersResult.data.airdropBudgetHolder,
- web3RpcProvider.utils.toChecksumAddress(constants.airdropBudgetHolder));
+ web3Provider.utils.toChecksumAddress(constants.airdropBudgetHolder));
});
diff --git a/mocha_test/services/airdrop/get_workers.js b/mocha_test/services/airdrop/get_workers.js
index af67520..1a5b92e 100644
--- a/mocha_test/services/airdrop/get_workers.js
+++ b/mocha_test/services/airdrop/get_workers.js
@@ -6,7 +6,7 @@ const rootPrefix = "../../.."
, constants = require(rootPrefix + '/mocha_test/lib/constants')
, airdrop = require(rootPrefix + '/lib/contract_interact/airdrop')
, airdropContract = new airdrop(constants.airdropOstUsdAddress, constants.chainId)
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
;
describe('Get Workers', function() {
@@ -16,7 +16,7 @@ describe('Get Workers', function() {
const airdropWorkersResult = await airdropContract.getWorkers();
assert.equal(airdropWorkersResult.isSuccess(), true);
assert.equal(airdropWorkersResult.data.workerContractAddress,
- web3RpcProvider.utils.toChecksumAddress(constants.workersContractAddress));
+ web3Provider.utils.toChecksumAddress(constants.workersContractAddress));
});
diff --git a/mocha_test/services/airdrop/pay.js b/mocha_test/services/airdrop/pay.js
index 63163e4..369f389 100644
--- a/mocha_test/services/airdrop/pay.js
+++ b/mocha_test/services/airdrop/pay.js
@@ -1,5 +1,5 @@
/* global describe, it */
-/*
+
const chai = require('chai')
, assert = chai.assert;
@@ -8,293 +8,817 @@ const rootPrefix = "../../.."
, BigNumber = require('bignumber.js')
, utils = require(rootPrefix+'/mocha_test/lib/utils')
, airdrop = require(rootPrefix + '/lib/contract_interact/airdrop')
- , workers = require(rootPrefix + '/lib/contract_interact/workers')
- , workersContract = new workers(constants.workersContractAddress, constants.chainId)
- , airdropOstUsd = new airdrop(constants.airdropOstUsdAddress, constants.chainId)
, mockToken = require(rootPrefix + '/lib/contract_interact/EIP20TokenMock')
- , TC5 = new mockToken(constants.TC5Address)
, BrandedTokenKlass = require(rootPrefix + '/lib/contract_interact/branded_token')
- , brandedTokenObject = new BrandedTokenKlass(constants.TC5Address, constants.chainId)
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
, logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+const airdropOstUsd = new airdrop(constants.airdropOstUsdAddress, constants.chainId)
+ , TC5 = new mockToken(constants.TC5Address)
+ , brandedTokenObject = new BrandedTokenKlass(constants.TC5Address, constants.chainId)
+;
-const airdropKlass = require(rootPrefix + '/app/models/airdrop')
- , airdropManager = require(rootPrefix + '/lib/airdrop_management/base')
- , BalanceCacheKlass = require(rootPrefix + '/lib/cache_management/balance')
- , balanceCache = new BalanceCacheKlass(constants.chainId, constants.TC5Address)
+const AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
+ , openstPayment = require(rootPrefix + '/index')
+ , SetWorkerKlass = openstPayment.services.workers.setWorker
+ , IsWorkerKlass = openstPayment.services.workers.isWorker
+ , RegisterKlass = openstPayment.services.airdropManager.registerAirdrop
+ , TransferKlass = openstPayment.services.airdropManager.transfer
+ , ApproveKlass = openstPayment.services.airdropManager.approve
+ , BatchAllocatorKlass = openstPayment.services.airdropManager.batchAllocator
+ , UserBalanceKlass = openstPayment.services.airdropManager.userBalance
+ , PayKlass = openstPayment.services.airdropManager.pay
+ , SetPriceOracleKlass = openstPayment.services.airdropManager.setPriceOracle
+ , SetAcceptedMarginKlass = openstPayment.services.airdropManager.setAcceptedMargin
, airdropAllocationProofDetailKlass = require(rootPrefix + '/app/models/airdrop_allocation_proof_detail')
+ , UserAirdropDetailKlass = require(rootPrefix + '/app/models/user_airdrop_detail')
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
;
var transferToAirdropBudgetHolderTransactionHash = ''
;
-async function getAmountFromCache(address) {
- console.log("========getAmountFromCache===== for address: "+address);
- const response = await balanceCache.getBalance(address);
- console.log(response);
- return new BigNumber(response.data.response);
-};
+/**
+ * Utitlity function to test set accepted margin
+ *
+ * @param {Object} airdropObject - airdrop object
+ * @param {string} currency - currency
+ * @param {string} margin - accepted margin
+ *
+ */
+
+async function setAcceptedMargin(airdropObject, currency, margin) {
+ // set accepted margin
+ const SetAcceptedMarginObject = new SetAcceptedMarginKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ chain_id: constants.chainId,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ currency: currency,
+ accepted_margin: margin,
+ gas_price: constants.gasUsed,
+ options: constants.optionsReceipt
+ });
+ const amResponse = await SetAcceptedMarginObject.perform();
+ assert.equal(amResponse.isSuccess(), true);
+ // verify if the transaction receipt is valid
+ utils.verifyTransactionReceipt(amResponse);
+ // verify if the transaction has was actually mined
+ await utils.verifyIfMined(airdropObject, amResponse.data.transaction_hash);
+ // verify if its set
+ const amResult = await airdropObject.acceptedMargins(currency);
+ assert.equal(amResult.isSuccess(), true);
+ assert.equal(margin, amResult.data.acceptedMargins);
+}
+
+
+/**
+ * Utitlity function to test set price oracle
+ *
+ * @param {Object} airdropObject - airdrop object
+ * @param {string} currency - currency
+ * @param {string} address - price oracle address
+ *
+ */
+async function setPriceOracle(airdropObject, currency, address) {
+ // Set Price Oracle
+ const SetPriceOracleObject = new SetPriceOracleKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ chain_id: constants.chainId,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ currency: currency,
+ price_oracle_contract_address: address,
+ gas_price: constants.gasUsed,
+ options: constants.optionsReceipt
+ });
+ const spoResponse = await SetPriceOracleObject.perform();
+ assert.equal(spoResponse.isSuccess(), true);
+ // verify if the transaction receipt is valid
+ utils.verifyTransactionReceipt(spoResponse);
+ // verify if the transaction has was actually mined
+ await utils.verifyIfMined(airdropObject, spoResponse.data.transaction_hash);
+ // verify if its set
+ const poResult = await airdropObject.priceOracles(currency);
+ assert.equal(poResult.isSuccess(), true);
+ assert.equal(address, poResult.data.priceOracles);
+}
+
+
+/**
+ * Utitlity function to test set worker
+ *
+ * @param {string} workerAddress - worker address
+ * @param {Bignumber} deactivationHeight - deactivation height of the worker
+ *
+ */
+async function setWorker(workerAddress, deactivationHeight) {
+ const SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: workerAddress,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const setWorkerResponse = await SetWorkerObject.perform();
+
+ assert.equal(setWorkerResponse.isSuccess(), true);
+ // verify if the transaction receipt is valid
+ utils.verifyTransactionReceipt(setWorkerResponse);
+
+ // confirm that worker is a set
+ const IsWorkerObject = new IsWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ worker_address: workerAddress,
+ chain_id: constants.chainId
+ });
+ const isWorkerResponse = await IsWorkerObject.perform();
+ assert.equal(isWorkerResponse.isSuccess(), true);
+ assert.equal(isWorkerResponse.data.isValid, true);
+}
+
+
+/**
+ * Utitlity function to test setBalance
+ *
+ * @param {Object} token - branded token object
+ * @param {string} address - account address
+ * @param {string} amount - amount that need to be set
+ * @param {BigNumber} gasPrice - gas price
+ *
+ */
+async function setBalance(token, address, amount) {
+ const amountInWei = airdropOstUsd.toWei(amount);
+ await token.setBalance(
+ constants.ops,
+ constants.opsPassphrase,
+ address,
+ amountInWei,
+ constants.gasUsed);
+ // check if the balance was set
+ const accountBalance = await token.balanceOf(address);
+ assert.equal(accountBalance, amountInWei);
+}
+
+/**
+ * Utitlity function to get airdrop id from airdrop address
+ *
+ * @param {string} airdropAddress - airdrop address
+ *
+ * @return {Object} - formatted response
+ */
+
+async function getAirdropIdFromAirdropAddress(airdropAddress) {
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: airdropAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ , airdropRecord = airdropModelCacheResponse.data[airdropAddress]
+ ;
+ if (airdropRecord) {
+ return responseHelper.successWithData({airdropId: airdropRecord.id});
+ }
+ let errorParams = {
+ internal_error_identifier: 'gaidfad',
+ api_error_identifier: 'data_not_found',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
+}
+
+/**
+ * Utitlity function to register airdrop if not already registered
+ *
+ * @param {string} airdropAddress - airdrop address
+ *
+ */
+async function registerAirdrop(airdropAddress) {
+ // Do Airdrop Setup if setup was not done
+ const airDropIdResponse = await getAirdropIdFromAirdropAddress(airdropAddress);
+ if (airDropIdResponse.isFailure()) {
+ const RegisterObject = new RegisterKlass({
+ airdrop_contract_address: airdropAddress,
+ chain_id: constants.chainId
+ });
+ const registerAirdropResponse = await RegisterObject.perform();
+ assert.equal(registerAirdropResponse.isSuccess(), true);
+
+ // check again if the database awas set;
+ const airDropIdAfterRegisterResponse = await getAirdropIdFromAirdropAddress(airdropAddress);
+ assert.equal(airDropIdAfterRegisterResponse.isSuccess(), true);
+ }
+}
+
+/**
+ * Utitlity function to transfer token to airdrop budget holder
+ *
+ * @param {Object} token - Branded token object
+ * @param {string} airdropAddress - airdrop address
+ * @param {string} fromAddress - reserve address
+ * @param {string} fromPassphrase - passphrase
+ * @param {string} budgetHolderAddress - budget holder address
+ * @param {string} amount - amount to transfer to budget holder
+ *
+ * @return {transaction hash}
+ */
+async function transferTokenToAirdropBugetHolder (token, airdropAddress, fromAddress, fromPassphrase, budgetHolderAddress, amount) {
+
+ const airdropBudgetAmountInWei = new BigNumber(airdropOstUsd.toWei(amount));
+ const initialBalance = new BigNumber(await token.balanceOf(fromAddress));
+ const beforeTransferAirdropBudgetHolderBalance = new BigNumber(await token.balanceOf(budgetHolderAddress));
+
+ logger.debug("initialBalance:", initialBalance.toString(10),
+ "\nairdropBudgetAmount:", airdropBudgetAmountInWei.toString(10),
+ "\nairdropAddress:", airdropAddress);
+
+ assert.equal(initialBalance.gte(airdropBudgetAmountInWei), true, "insufficent balance to transfer amount to budgetHolderAddress");
+
+ const TransferObject = new TransferKlass({
+ sender_address: fromAddress,
+ sender_passphrase: fromPassphrase,
+ airdrop_contract_address: airdropAddress,
+ amount: airdropBudgetAmountInWei,
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const transferToAirdropBudgetHolderResult = await TransferObject.perform();
+ logger.debug("=======transferToAirdropBudgetHolderResult=======");
+ logger.debug(transferToAirdropBudgetHolderResult);
+ assert.equal(transferToAirdropBudgetHolderResult.isSuccess(), true);
+ // verify if the transaction receipt is valid
+ await utils.verifyTransactionReceipt(transferToAirdropBudgetHolderResult);
+ // verify if the transaction was actually mined
+ await utils.verifyIfMined(airdropOstUsd, transferToAirdropBudgetHolderResult.data.transaction_hash);
+
+ const afterTransferAirdropBudgetHolderBalance = new BigNumber(await token.balanceOf(budgetHolderAddress));
+ assert.equal((beforeTransferAirdropBudgetHolderBalance.plus(airdropBudgetAmountInWei)).equals( afterTransferAirdropBudgetHolderBalance), true);
+
+ // set transaction hash
+ transferToAirdropBudgetHolderTransactionHash = transferToAirdropBudgetHolderResult.data.transaction_hash;
+ return transferToAirdropBudgetHolderTransactionHash;
+}
+
+/**
+ * Utitlity function get user airdrop balance
+ *
+ * @param {string} airdropAddress - airdrop address
+ * @param {Array} userAddressArray - user address array
+ *
+ * @return {Object} - formatted response
+ */
+async function getUserAirdropBalanceFromCache(airdropAddress, userAddressArray) {
+ // Get cache value
+ const UserBalanceObject = new UserBalanceKlass({
+ chain_id: constants.chainId,
+ airdrop_contract_address: airdropAddress,
+ user_addresses: userAddressArray
+ });
+ const airdropBalanceResult = await UserBalanceObject.perform();
+ const zeroAmount = {
+ totalAirdropAmount: '0',
+ totalAirdropUsedAmount: '0',
+ balanceAirdropAmount: '0'
+ };
+ var responseData = {};
+ if (airdropBalanceResult.isSuccess()) {
+ responseData = airdropBalanceResult.data;
+ }
+ var data = {};
+ for (var i = userAddressArray.length - 1; i >= 0; i--) {
+ if(responseData[userAddressArray[i]]) {
+ data[userAddressArray[i]] = responseData[userAddressArray[i]];
+ } else {
+ data[userAddressArray[i]] = zeroAmount;
+ }
+ }
+ return responseHelper.successWithData(data);
+}
+
+/**
+ * Utitlity function get user airdrop balance form DB, bypass cache layer
+ *
+ * @param {string} airdropAddress - airdrop address
+ * @param {Array} userAddressArray - user address array
+ *
+ * @return {Object} - formatted response
+ */
+async function getUserAirdropBalanceFromDB(airdropAddress, userAddressArray) {
+
+ const airDropIdResponse = await getAirdropIdFromAirdropAddress(airdropAddress);
+ if (airDropIdResponse.isSuccess()) {
+ const airdropId = airDropIdResponse.data.airdropId;
+ const userAirdropDetailModel = new UserAirdropDetailKlass();
+
+ const queryResponse = await userAirdropDetailModel.getByUserAddresses(airdropId, userAddressArray);
+
+ var responseData = {};
+ if (queryResponse.isSuccess()) {
+ responseData = queryResponse.data;
+ }
+ var data = {};
+ for (var i = userAddressArray.length - 1; i >= 0; i--) {
+ if(responseData[userAddressArray[i]]) {
+ data[userAddressArray[i]] = responseData[userAddressArray[i]];
+ } else {
+ data[userAddressArray[i]] = {
+ totalAirdropAmount: '0',
+ totalAirdropUsedAmount: '0',
+ balanceAirdropAmount: '0'
+ };
+ }
+ }
+ return responseHelper.successWithData(data);
+ }
+ return airDropIdResponse;
+}
+
+/**
+ * Utitlity function to compare the airdrop balances from DB and cache
+ *
+ * @param {Object} dbBalance - airdrop balance from DB
+ * @param {Object} cacheBalance - airdrop balance from cache
+ *
+ */
+function validateDBandCacheAirdropBalances(dbBalance, cacheBalance) {
+
+ const compare = function(obj1, obj2) {
+ assert.equal(obj1.totalAirdropAmount, obj2.totalAirdropAmount);
+ assert.equal(obj1.totalAirdropUsedAmount, obj2.totalAirdropUsedAmount);
+ assert.equal(obj1.balanceAirdropAmount, obj2.balanceAirdropAmount);
+ };
+
+ const dbUserKeys = Object.keys(dbBalance);
+ const cacheUserKeys = Object.keys(cacheBalance);
+ assert.equal(dbUserKeys.length, cacheUserKeys.length);
+ for (var i = dbUserKeys.length - 1; i >= 0; i--) {
+ const dbObject = dbBalance[dbUserKeys[i]];
+ const cacheObject = cacheBalance[cacheUserKeys[i]];
+ assert.isDefined(dbObject);
+ assert.isDefined(cacheObject);
+ compare(dbObject, cacheObject);
+ }
+}
+
+/**
+ * Utitlity function to get balance of address from contract
+ *
+ * @param {Object} token - token
+ * @param {string} address - address whose balances need to be found
+ *
+ */
+async function getBalanceFromContract(token, address) {
+ var balances = {};
+ for (var i = address.length - 1; i >= 0; i--) {
+ const addressKey = address[i];
+ balances[addressKey] = new BigNumber(await token.balanceOf(addressKey));
+ }
+ return balances;
+}
+/**
+ * Utitlity function to get balance of address from cache
+ *
+ * @param {Object} token - token
+ * @param {string} address - address whose balances need to be found
+ *
+ */
+async function getBalanceFromCache(tokenObj, address) {
+ var balances = {};
+ for (var i = address.length - 1; i >= 0; i--) {
+ const addressKey = address[i];
+ const balance = await tokenObj.getBalanceOf(addressKey);
+ assert.equal(balance.isSuccess(), true);
+ balances[addressKey] = new BigNumber(balance.data.balance);
+ }
+ return balances;
+}
+
+/**
+ * Utitlity function to compare balances from cache and contract
+ *
+ * @param {Object} contractBalances - balances from contract
+ * @param {Object} cacheBalance - balances from cache
+ *
+ */
+
+function validateContractAndCacheBalance(cacheBalance, contractBalances) {
+ const contractKeys = Object.keys(cacheBalance);
+ const cacheKeys = Object.keys(contractBalances);
+ assert.equal(contractKeys.length, cacheKeys.length);
+ for (var i = contractKeys.length - 1; i >= 0; i--) {
+ const balanceFromContract = contractBalances[contractKeys[i]];
+ const balanceFromCache = cacheBalance[contractKeys[i]];
+ assert.isDefined(balanceFromContract);
+ assert.isDefined(balanceFromCache);
+ assert.equal(balanceFromCache.equals(balanceFromContract), true);
+ }
+}
+
+/**
+ * Utitlity function to validate if airdrop was transfered successfully
+ *
+ * @param {string} accountAddress - user address
+ * @param {Object} initialAirdropBalance - Initial airdrop balance
+ * @param {Object} currentAirdropBalance - Current airdrop balance
+ * @param {BigNumber} airdropAmountTransfered - estimated airdrop amount that was transfered
+ */
+function validateAirdropTransferSuccess(accountAddress, initialAirdropBalance, currentAirdropBalance, airdropAmountTransfered) {
+
+ const initialAirdropBalanceData = initialAirdropBalance.data[accountAddress];
+ const currentAirdropBalanceData = currentAirdropBalance.data[accountAddress];
+
+ assert.isDefined(initialAirdropBalanceData);
+ assert.isDefined(currentAirdropBalanceData);
+
+ const intialTotalAirdropAmount = new BigNumber(initialAirdropBalanceData.totalAirdropAmount);
+ const initialTotalAirdropUsedAmount = new BigNumber(initialAirdropBalanceData.totalAirdropUsedAmount);
+ const initialBalanceAirdropAmount = new BigNumber(initialAirdropBalanceData.balanceAirdropAmount);
+
+ const totalAirdropAmount = new BigNumber(currentAirdropBalanceData.totalAirdropAmount);
+ const totalAirdropUsedAmount = new BigNumber(currentAirdropBalanceData.totalAirdropUsedAmount);
+ const balanceAirdropAmount = new BigNumber(currentAirdropBalanceData.balanceAirdropAmount);
+
+ assert.equal(intialTotalAirdropAmount.equals(totalAirdropAmount), true);
+ assert.equal((initialTotalAirdropUsedAmount.plus(airdropAmountTransfered)).equals(totalAirdropUsedAmount), true);
+ assert.equal((initialBalanceAirdropAmount.minus(airdropAmountTransfered)).equals(balanceAirdropAmount), true);
+}
+
+function validateTransferSuccess(
+ estimatedTokenAmount,
+ estimatedCommissionTokenAmount,
+ estimatedAirdropUsed,
+ spenderAddress,
+ beneficiary,
+ commissionBeneficiary,
+ airdropBudgetHolder,
+ initialBalances,
+ currentBalances) {
+
+ assert.isDefined(estimatedTokenAmount);
+ assert.isDefined(estimatedCommissionTokenAmount);
+ assert.isDefined(estimatedAirdropUsed);
+ assert.isDefined(spenderAddress);
+ assert.isDefined(beneficiary);
+ assert.isDefined(commissionBeneficiary);
+ assert.isDefined(airdropBudgetHolder);
+ assert.isDefined(initialBalances);
+ assert.isDefined(currentBalances);
+
+ const estimatedTotalAmount = estimatedTokenAmount.plus(estimatedCommissionTokenAmount);
+ const actualTransferAmount = estimatedTotalAmount.minus(estimatedAirdropUsed);
+ const calculatedBenficiaryAmount = initialBalances[beneficiary].plus(estimatedTokenAmount);
+ const calculatedCommisionAmount = initialBalances[commissionBeneficiary].plus(estimatedCommissionTokenAmount);
+ const calculatedSpenderAmount = initialBalances[spenderAddress].minus(actualTransferAmount);
+ const calculatesBugdetHolderAmount = initialBalances[airdropBudgetHolder].minus(estimatedAirdropUsed);
+
+ assert.equal(calculatedBenficiaryAmount.equals(currentBalances[beneficiary]), true);
+ assert.equal(calculatedCommisionAmount.equals(currentBalances[commissionBeneficiary]), true);
+ assert.equal(calculatedSpenderAmount.equals(currentBalances[spenderAddress]), true);
+ assert.equal(calculatesBugdetHolderAmount.equals(currentBalances[airdropBudgetHolder]), true);
+}
+
+/**
+ * Utitlity function to populate the cache of all test accounts
+ *
+ */
+async function populateCache() {
+ // Populate Cache
+ await brandedTokenObject.getBalanceOf(constants.account1);
+ await brandedTokenObject.getBalanceOf(constants.account2);
+ await brandedTokenObject.getBalanceOf(constants.account3);
+ await brandedTokenObject.getBalanceOf(constants.account4);
+ await brandedTokenObject.getBalanceOf(constants.account5);
+ await brandedTokenObject.getBalanceOf(constants.airdropBudgetHolder);
+}
+// Tests starts here
describe('Airdrop Pay', function() {
it('should pass the initial checks', async function() {
// eslint-disable-next-line no-invalid-this
this.timeout(500000);
+ // check if the address required for the testing are defined.
assert.isDefined(constants.deployer);
assert.isDefined(constants.ops);
assert.isDefined(constants.account1);
+ assert.isDefined(constants.workerAccount1);
+ assert.isDefined(constants.airdropBudgetHolder);
+
assert.notEqual(constants.deployer, constants.ops);
assert.notEqual(constants.deployer, constants.account1);
assert.notEqual(constants.ops, constants.account1);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
- , deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
- ;
// set worker
- const setWorkerResponse = await workersContract.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- deactivationHeight.toNumber(),
- constants.gasUsed,
- constants.optionsReceipt);
-
- const isWorkerResponse = await workersContract.isWorker(constants.workerAccount1);
- assert.equal(isWorkerResponse.isSuccess(), true);
- assert.equal(isWorkerResponse.data.isValid, true);
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(setWorkerResponse);
- // TODO Check for get Worker
+ logger.debug("============= Set worker =============");
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber();
+ await setWorker(constants.workerAccount1, new BigNumber(currentBlockNumber).plus(100000000000));
// Set Price Oracle
- const spoResponse = await airdropOstUsd.setPriceOracle(
- constants.ops,
- constants.opsPassphrase,
- constants.currencyUSD,
- constants.priceOracles.OST.USD,
- constants.gasUsed,
- constants.optionsReceipt);
-
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(spoResponse);
-
- // verify if the transaction has was actually mined
- await utils.verifyIfMined(airdropOstUsd, spoResponse.data.transaction_hash);
+ logger.debug("============= Set Price Oracle =============");
+ await setPriceOracle(airdropOstUsd, constants.currencyUSD, constants.priceOracles.OST.USD);
// set accepted margin
- const amResponse = await airdropOstUsd.setAcceptedMargin(
- constants.ops,
- constants.opsPassphrase,
- constants.currencyUSD,
- 50,
- constants.gasUsed,
- constants.optionsReceipt);
-
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(amResponse);
-
- // verify if the transaction has was actually mined
- await utils.verifyIfMined(airdropOstUsd, amResponse.data.transaction_hash);
-
- // verify if its set
- const amResult = await airdropOstUsd.acceptedMargins(constants.currencyUSD);
- assert.equal(amResult.isSuccess(), true);
- assert.equal(50, amResult.data.acceptedMargins);
+ logger.debug("============= Set accepted margin =============");
+ await setAcceptedMargin(airdropOstUsd, constants.currencyUSD, 50);
- // verify if its set
- const poResult = await airdropOstUsd.priceOracles(constants.currencyUSD);
- assert.equal(poResult.isSuccess(), true);
- assert.equal(constants.priceOracles.OST.USD, poResult.data.priceOracles);
-
- // Do Airdrop Setup if setup was not done
- var airdropModel = new airdropKlass();
- var result = await airdropModel.getByContractAddress(constants.airdropOstUsdAddress);
- const airdropRecord = result[0];
- if (!airdropRecord) {
- const registerAirdropResponse = await airdropManager.registerAirdrop(
- constants.airdropOstUsdAddress,
- constants.chainId
- );
- assert.equal(registerAirdropResponse.isSuccess(), true);
- }
-
- await TC5.setBalance(
- constants.ops,
- constants.opsPassphrase,
- constants.account1,
- airdropOstUsd.toWei(constants.account1InitialBrandedTokenBalance),
- constants.gasUsed);
+ // set balance for account 1 (Spender)
+ logger.debug("============= Set account 1 balance =============");
+ await setBalance(TC5, constants.account1, constants.account1InitialBrandedTokenBalance);
+ // reset balance for account 2 to 100
+ logger.debug("============= Set account 2 balance =============");
+ await setBalance(TC5, constants.account2, '100');
- const account1Balance = await TC5.balanceOf(constants.account1);
- assert.equal(account1Balance, airdropOstUsd.toWei(constants.account1InitialBrandedTokenBalance));
+ // reset balance for account 3 to 0
+ logger.debug("============= Set account 3 balance =============");
+ await setBalance(TC5, constants.account3, '0');
- await TC5.setBalance(
- constants.ops,
- constants.opsPassphrase,
- constants.account2,
- airdropOstUsd.toWei('0'),
- constants.gasUsed);
+ // reset balance for account 4 to 0
+ logger.debug("============= Set account 4 balance =============");
+ await setBalance(TC5, constants.account4, '0');
- const account2Balance = await TC5.balanceOf(constants.account2);
- assert.equal(account2Balance, airdropOstUsd.toWei('0'));
+ // reset balance of account airdropBudgetHolder to 0
+ logger.debug("============= Set airdropBudgetHolder balance =============");
+ await setBalance(TC5, constants.airdropBudgetHolder, '0');
- await TC5.setBalance(
- constants.ops,
- constants.opsPassphrase,
- constants.account3,
- airdropOstUsd.toWei('0'),
- constants.gasUsed);
+ // Do Airdrop Setup if setup was not done
+ logger.debug("============= Do Airdrop Setup if setup was not done =============");
+ await registerAirdrop(constants.airdropOstUsdAddress);
- const account3Balance = await TC5.balanceOf(constants.account3);
- assert.equal(account3Balance, airdropOstUsd.toWei('0'));
+ });
- await TC5.setBalance(
- constants.ops,
- constants.opsPassphrase,
- constants.account4,
- airdropOstUsd.toWei('0'),
- constants.gasUsed);
+ it('AirdropManager: transfer branded token from reserve to airdropBudgetHolder and approve airdrop contract', async function() {
+ // eslint-disable-next-line no-invalid-this
+ this.timeout(100000);
- const account4Balance = await TC5.balanceOf(constants.account4);
- assert.equal(account4Balance, airdropOstUsd.toWei('0'));
+ const address = [
+ constants.account1,
+ constants.airdropBudgetHolder
+ ];
+ const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
+ const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
- // Populate Cache
- brandedTokenObject.getBalanceOf(constants.account1);
- brandedTokenObject.getBalanceOf(constants.account2);
- brandedTokenObject.getBalanceOf(constants.account3);
- brandedTokenObject.getBalanceOf(constants.account4);
- });
-
- it('AirdropManager: transfer branded token from reserve to airdropBudgetHolder', async function() {
- this.timeout(100000);
- const airdropBudgetAmountInWei = new BigNumber(constants.airdropBudgetBrandedTokenBalance)
- , initialAccount1Balance = new BigNumber(await TC5.balanceOf(constants.account1));
- ;
- assert.isAbove(
- initialAccount1Balance.toNumber(),
- airdropBudgetAmountInWei.toNumber(),
- "account1 balance should be greater than airdropBudgetAmount")
- ;
- logger.info("=======initialAccount1Balance:", initialAccount1Balance.toString(),
- "\nairdropBudgetAmount:",airdropBudgetAmountInWei.toString(),
- "\nairdropOstUsdAddress:",constants.airdropOstUsdAddress);
- var transferToAirdropBudgetHolderResult = await airdropManager.transfer(
+ // transfer amount
+ await transferTokenToAirdropBugetHolder(TC5,
+ constants.airdropOstUsdAddress,
constants.account1,
constants.accountPassphrase1,
- constants.airdropOstUsdAddress,
- airdropBudgetAmountInWei.toString(),
- constants.gasUsed,
- constants.chainId,
- {returnType: constants.returnTypeReceipt}
- );
- logger.info("=======transferToAirdropBudgetHolderResult=======");
- logger.info(transferToAirdropBudgetHolderResult);
- const afterTransferAirdropBudgetHolderBalance = new BigNumber(await TC5.balanceOf(constants.airdropBudgetHolder));
- assert.equal(afterTransferAirdropBudgetHolderBalance.toString(), airdropBudgetAmountInWei.toString());
- // verify if the transaction receipt is valid
- await utils.verifyTransactionReceipt(transferToAirdropBudgetHolderResult);
+ constants.airdropBudgetHolder,
+ constants.airdropBudgetBrandedTokenBalance);
- // verify if the transaction was actually mined
- await utils.verifyIfMined(airdropOstUsd, transferToAirdropBudgetHolderResult.data.transaction_hash);
- transferToAirdropBudgetHolderTransactionHash = transferToAirdropBudgetHolderResult.data.transaction_hash;
- });
+ const balanceFromContract = await getBalanceFromContract(TC5, address);
+ const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
+
+ // approve
+ const ApproveObject = new ApproveKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ airdrop_budget_holder_passphrase: constants.airdropBudgetHolderPassphrase,
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const approveToAirdropBudgetHolderResult = await ApproveObject.perform();
+ logger.debug("=======approveToAirdropBudgetHolderResult=======");
+ logger.debug(approveToAirdropBudgetHolderResult);
- it('AirdropManager: aidropBudgetHolder is approving airdrop contract', async function() {
- this.timeout(100000);
- var approveToAirdropBudgetHolderResult = await airdropManager.approve(
- constants.airdropOstUsdAddress,
- constants.airdropBudgetHolderPassphrase,
- constants.gasUsed,
- constants.chainId,
- {returnType: constants.returnTypeReceipt}
- );
assert.equal(approveToAirdropBudgetHolderResult.isSuccess(), true);
- logger.info("=======approveToAirdropBudgetHolderResult=======");
- logger.info(approveToAirdropBudgetHolderResult);
// verify if the transaction receipt is valid
await utils.verifyTransactionReceipt(approveToAirdropBudgetHolderResult);
-
// verify if the transaction was actually mined
await utils.verifyIfMined(airdropOstUsd, approveToAirdropBudgetHolderResult.data.transaction_hash);
-
});
- it('AirdropManager: batch allocate to airdrop users', async function() {
+
+ it('AirdropManager: batch allocate to airdrop users and check user balance', async function() {
+ // eslint-disable-next-line no-invalid-this
this.timeout(10000);
- var batchAllocateAirdropAmountResult = await airdropManager.batchAllocate(
- constants.airdropOstUsdAddress,
- transferToAirdropBudgetHolderTransactionHash,
- constants.airdropUsers,
- constants.chainId
- );
+
+ var airdropUsers = constants.airdropUsers;
+ airdropUsers[constants.account2] = {airdropAmount: '100000000000000000000', expiryTimestamp: 0};
+
+ // checks for cache and DB consistency
+ const beforeAllocationBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
+ const beforeAllocationBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
+ validateDBandCacheAirdropBalances(beforeAllocationBalanceFromDB.data, beforeAllocationBalanceFromCache.data);
+
+ const BatchAllocatorObject = new BatchAllocatorKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ transaction_hash: transferToAirdropBudgetHolderTransactionHash,
+ airdrop_users: airdropUsers,
+ chain_id: constants.chainId
+ });
+ const batchAllocateAirdropAmountResult = await BatchAllocatorObject.perform();
+
assert.equal(batchAllocateAirdropAmountResult.isSuccess(), true);
var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
var result = await airdropAllocationProofDetailModel.getByTransactionHash(transferToAirdropBudgetHolderTransactionHash);
var airdropAllocationProofDetailRecord = result[0];
// airdrop_allocated_amount is less than or equal to airdrop_amount
- assert.isAtMost(new BigNumber(airdropAllocationProofDetailRecord.airdrop_allocated_amount).toNumber(),
- new BigNumber(airdropAllocationProofDetailRecord.airdrop_amount).toNumber());
- });
+ assert.equal(new BigNumber(airdropAllocationProofDetailRecord.airdrop_allocated_amount).lte(new BigNumber(airdropAllocationProofDetailRecord.airdrop_amount)), true);
- it('AirdropManager: Get User Balance and validate balance', async function() {
- this.timeout(5000);
- var userAddressArray = [];
- for (var ua in constants.airdropUsers){
- userAddressArray.push(ua);
- }
- // Without Cache
- var airdropBalanceResult = await airdropManager.getAirdropBalance(
- constants.chainId,
- constants.airdropOstUsdAddress,
- userAddressArray
- );
- assert.equal(airdropBalanceResult.isSuccess(), true);
- // With Cache
- var airdropBalanceResult = await airdropManager.getAirdropBalance(
- constants.chainId,
- constants.airdropOstUsdAddress,
- userAddressArray
- );
- assert.equal(airdropBalanceResult.isSuccess(), true);
- for (var userAddress in constants.airdropUsers){
- // Match airdrop allocated Balance
- assert.equal(airdropBalanceResult.data[userAddress].total_airdrop_amount, constants.airdropUsers[userAddress].airdrop_amount);
+
+ // checks for cache and DB consistency
+ const afterAllocationBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
+ const afterAllocationBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
+ validateDBandCacheAirdropBalances(afterAllocationBalanceFromDB.data, afterAllocationBalanceFromCache.data);
+
+ // check if the airdrop balance reflects the proper value.
+ const allUserKeys = Object.keys(airdropUsers);
+ for (var i = allUserKeys.length - 1; i >= 0; i--) {
+ const userKey = allUserKeys[i];
+ const initialTotalAirdropAmount = new BigNumber(beforeAllocationBalanceFromDB.data[userKey].totalAirdropAmount);
+ const initialTotalAirdropUsedAmount = new BigNumber(beforeAllocationBalanceFromDB.data[userKey].totalAirdropUsedAmount);
+ const initialBalanceAirdropAmount = new BigNumber(beforeAllocationBalanceFromDB.data[userKey].balanceAirdropAmount);
+
+ const totalAirdropAmount = new BigNumber(afterAllocationBalanceFromDB.data[userKey].totalAirdropAmount);
+ const totalAirdropUsedAmount = new BigNumber(afterAllocationBalanceFromDB.data[userKey].totalAirdropUsedAmount);
+ const balanceAirdropAmount = new BigNumber(afterAllocationBalanceFromDB.data[userKey].balanceAirdropAmount);
+
+ assert.equal((initialTotalAirdropAmount.plus(new BigNumber(airdropUsers[userKey].airdropAmount))).equals(totalAirdropAmount), true);
+
+ assert.equal(initialTotalAirdropUsedAmount.equals(totalAirdropUsedAmount), true);
+ assert.equal(initialTotalAirdropUsedAmount.equals(0), true);
+
+ assert.equal((initialBalanceAirdropAmount.plus(new BigNumber(airdropUsers[userKey].airdropAmount))).equals(balanceAirdropAmount), true);
}
});
- it('should pass when all parameters are valid with currency USD and account1 allocated airdrop amount is 0', async function() {
+
+ it('should fail when worker is not whitelisted', async function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- logger.info("========Get Amount from Contract=========");
- const initialAccount1Balance = new BigNumber(await TC5.balanceOf(constants.account1))
- , initialAccount3Balance = new BigNumber(await TC5.balanceOf(constants.account3))
- , initialAccount4Balance = new BigNumber(await TC5.balanceOf(constants.account4))
+ // Populate Cache
+ populateCache();
+
+ const beneficiary = constants.account3
+ , commissionAmount = new BigNumber(airdropOstUsd.toWei('0.9'))
+ , commissionBeneficiary = constants.account4
+ , currency = constants.currencyUSD
+ , transferAmount = new BigNumber(airdropOstUsd.toWei('1.18'))
+ , spenderAddress = constants.account2
+ , spenderPassphrase = constants.accountPassphrase2
+ , airdropBudgetHolder = constants.airdropBudgetHolder
;
- // Cache check
- logger.info("========Get Amount from Cache=========");
- // const initialAccount1BalanceCache = await brandedTokenObject.getBalanceOf(constants.account1)
- // , initialAccount3BalanceCache = await brandedTokenObject.getBalanceOf(constants.account3)
- // , initialAccount4BalanceCache = await brandedTokenObject.getBalanceOf(constants.account4)
- // ;
- logger.info("========Asserting amount of cache and DB=========");
- // assert.equal(initialAccount1Balance.toString(), new BigNumber(initialAccount1BalanceCache.data.balance).toString(), "account1: Actual and cacheValue mismatch");
- // assert.equal(initialAccount3Balance.toString(), new BigNumber(initialAccount3BalanceCache.data.balance).toString(), "account3: Actual and cacheValue mismatch");
- // assert.equal(initialAccount4Balance.toString(), new BigNumber(initialAccount4BalanceCache.data.balance).toString(), "account4: Actual and cacheValue mismatch");
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract =============");
+ const address = [
+ spenderAddress,
+ beneficiary,
+ commissionBeneficiary,
+ airdropBudgetHolder
+ ];
+ const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
+ const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
+
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB =============");
+ const airdropUserAddress = [spenderAddress];
+ const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
+
+ const UserBalanceObject = new UserBalanceKlass({
+ chain_id: constants.chainId,
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ user_addresses: [spenderAddress]
+ });
+ const airdropBalanceResult = await UserBalanceObject.perform();
+ assert.equal(airdropBalanceResult.isSuccess(), true);
+ const availableAirdropBalance = new BigNumber(airdropBalanceResult.data[spenderAddress].balanceAirdropAmount);
+
+ const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
+ transferAmount,
+ commissionAmount,
+ currency);
+ assert.equal(estimatedValues.isSuccess(), true);
+
+ const estimatedTokenAmount = new BigNumber(estimatedValues.data.tokenAmount);
+ const estimatedCommissionTokenAmount = new BigNumber(estimatedValues.data.commissionTokenAmount);
+ const intendedPricePoint = estimatedValues.data.pricePoint;
+
+ const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
+
+ const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
+ logger.debug("============ estimatedAirdropUsed ============");
+ logger.debug(estimatedAirdropUsed);
+
+ // Approve account1 for transfer
+ const accountApproveResponse = await TC5.approve(
+ spenderAddress,
+ spenderPassphrase,
+ constants.airdropOstUsdAddress,
+ estimatedTotalAmount.plus(100),
+ constants.gasUsed);
+
+ logger.debug("============spender approving to contract=============");
+ logger.debug(accountApproveResponse);
+ var worker1Balance = await web3Provider.eth.getBalance(constants.workerAccount1);
+ logger.debug("\nconstants.workerAccount1.balance: ", worker1Balance);
+
+ const PayObject = new PayKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ chain_id: constants.chainId,
+ sender_worker_address: constants.ops,
+ sender_worker_passphrase: constants.opsPassphrase,
+ beneficiary_address: beneficiary,
+ transfer_amount: transferAmount.toString(10),
+ commission_beneficiary_address: commissionBeneficiary,
+ commission_amount: commissionAmount.toString(10),
+ currency: currency,
+ intended_price_point: intendedPricePoint,
+ spender: spenderAddress,
+ gas_price: constants.gasUsed,
+ options: constants.optionsReceipt
+ });
+ const payResponse = await PayObject.perform();
+
+ assert.equal(payResponse.isFailure(), true);
+ logger.debug("============airdrop.pay response=============");
+ logger.debug(payResponse);
+
+
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract after pay =============");
+ const balanceFromContract = await getBalanceFromContract(TC5, address);
+ const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
+ //check if the initial and current balances are reverted properly
+ validateContractAndCacheBalance(initalBalancesFromContract, balanceFromContract);
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB after pay =============");
+ const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
+ // validate if the airdrop transfer was reverted properly
+ validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, airdropBalanceFromDB.data);
+
+ });
+
+ it('should pass when transfer amount is less than available airdrop amount', async function() {
+ // eslint-disable-next-line no-invalid-this
+ this.timeout(100000);
+
+ // Populate Cache
+ populateCache();
const beneficiary = constants.account3
- , commissionAmount = new BigNumber(airdropOstUsd.toWei('1'))
+ , commissionAmount = new BigNumber(airdropOstUsd.toWei('0.7'))
, commissionBeneficiary = constants.account4
, currency = constants.currencyUSD
- , transferAmount = new BigNumber(airdropOstUsd.toWei('9'))
+ , transferAmount = new BigNumber(airdropOstUsd.toWei('1.91'))
+ , spenderAddress = constants.account2
+ , spenderPassphrase = constants.accountPassphrase2
+ , airdropBudgetHolder = constants.airdropBudgetHolder
;
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract =============");
+ const address = [
+ spenderAddress,
+ beneficiary,
+ commissionBeneficiary,
+ airdropBudgetHolder
+ ];
+ const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
+ const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
+
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB =============");
+ const airdropUserAddress = [spenderAddress];
+ const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
+
+ const UserBalanceObject = new UserBalanceKlass({
+ chain_id: constants.chainId,
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ user_addresses: [spenderAddress]
+ });
+ const airdropBalanceResult = await UserBalanceObject.perform();
+ assert.equal(airdropBalanceResult.isSuccess(), true);
+ const availableAirdropBalance = new BigNumber(airdropBalanceResult.data[spenderAddress].balanceAirdropAmount);
+
const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
transferAmount,
commissionAmount,
@@ -307,74 +831,264 @@ describe('Airdrop Pay', function() {
const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
+ const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
+ logger.debug("============ estimatedAirdropUsed ============");
+ logger.debug(estimatedAirdropUsed);
+ // here we make sure that airdrop amount used will be greater than 0
+ assert.equal(estimatedAirdropUsed.gt(0), true);
// Approve account1 for transfer
- const account1ApproveResponse = await TC5.approve(
- constants.account1,
- constants.accountPassphrase1,
+ const accountApproveResponse = await TC5.approve(
+ spenderAddress,
+ spenderPassphrase,
constants.airdropOstUsdAddress,
- estimatedTotalAmount.plus(100).toString(),
+ estimatedTotalAmount.plus(100),
constants.gasUsed);
- logger.info("============spender approving to contract=============");
- logger.info(account1ApproveResponse);
- var worker1Balance = await web3RpcProvider.eth.getBalance(constants.workerAccount1);
- logger.info("\nconstants.workerAccount1.balance: ", worker1Balance);
- const payResponse = await airdropOstUsd.pay(
- constants.workerAccount1,
- constants.workerAccountPassphrase1,
+ logger.debug("============spender approving to contract=============");
+ logger.debug(accountApproveResponse);
+ var worker1Balance = await web3Provider.eth.getBalance(constants.workerAccount1);
+ logger.debug("\nconstants.workerAccount1.balance: ", worker1Balance);
+
+ const PayObject = new PayKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ chain_id: constants.chainId,
+ sender_worker_address: constants.workerAccount1,
+ sender_worker_passphrase: constants.workerAccountPassphrase1,
+ beneficiary_address: beneficiary,
+ transfer_amount: transferAmount.toString(10),
+ commission_beneficiary_address: commissionBeneficiary,
+ commission_amount: commissionAmount.toString(10),
+ currency: currency,
+ intended_price_point: intendedPricePoint,
+ spender: spenderAddress,
+ gas_price: constants.gasUsed,
+ options: constants.optionsReceipt
+ });
+ const payResponse = await PayObject.perform();
+
+ assert.equal(payResponse.isSuccess(), true);
+ logger.debug("============airdrop.pay response=============");
+ logger.debug(payResponse);
+
+ // verify if the transaction receipt is valid
+ utils.verifyTransactionReceipt(payResponse);
+ // verify if the transaction is actually mined
+ await utils.verifyIfMined(airdropOstUsd, payResponse.data.transaction_hash);
+
+
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract after pay =============");
+ const balanceFromContract = await getBalanceFromContract(TC5, address);
+ const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
+ //check if the transfer was propre
+ validateTransferSuccess(
+ estimatedTokenAmount,
+ estimatedCommissionTokenAmount,
+ estimatedAirdropUsed,
+ spenderAddress,
beneficiary,
- transferAmount.toString(),
commissionBeneficiary,
- commissionAmount.toString(),
- currency,
- intendedPricePoint,
- constants.account1,
- constants.gasUsed,
- {returnType: constants.returnTypeReceipt, tag: 'airdrop.pay'});
- logger.info("============airdrop.pay response=============");
- logger.info(payResponse);
+ airdropBudgetHolder,
+ initalBalancesFromContract,
+ balanceFromContract);
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB after pay =============");
+ const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
+ // validate if the airdrop transfer was proper
+ validateAirdropTransferSuccess(
+ spenderAddress,
+ initialAirdropBalanceFromDB,
+ airdropBalanceFromDB,
+ estimatedAirdropUsed);
+
+ });
+
+ // This is with an assumption that pervious test was passed and due to that constants.account3 has some balance
+ it('should pass when airdrop amount is 0', async function() {
+ // eslint-disable-next-line no-invalid-this
+ this.timeout(100000);
+ // Populate Cache
+ populateCache();
+
+ const beneficiary = constants.account1
+ , commissionAmount = new BigNumber(airdropOstUsd.toWei('0.0000000001'))
+ , commissionBeneficiary = constants.account4
+ , currency = constants.currencyUSD
+ , transferAmount = new BigNumber(airdropOstUsd.toWei('0.000000033'))
+ , spenderAddress = constants.account3
+ , spenderPassphrase = constants.accountPassphrase3
+ , airdropBudgetHolder = constants.airdropBudgetHolder
+ ;
+
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract =============");
+ const address = [
+ spenderAddress,
+ beneficiary,
+ commissionBeneficiary,
+ airdropBudgetHolder
+ ];
+ const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
+ const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
+
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB =============");
+ const airdropUserAddress = [spenderAddress];
+ const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
+
+ const UserBalanceObject = new UserBalanceKlass({
+ chain_id: constants.chainId,
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ user_addresses: [spenderAddress]
+ });
+ const airdropBalanceResult = await UserBalanceObject.perform();
+ assert.equal(airdropBalanceResult.isSuccess(), true);
+ // this line is to make sure that the airdropBalance is not availalbe for the user. This is because this user was never allocated airdrop.
+ assert.isUndefined(airdropBalanceResult.data[spenderAddress]);
+ const availableAirdropBalance = new BigNumber(0);
+
+ const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
+ transferAmount,
+ commissionAmount,
+ currency);
+ assert.equal(estimatedValues.isSuccess(), true);
+
+ const estimatedTokenAmount = new BigNumber(estimatedValues.data.tokenAmount);
+ const estimatedCommissionTokenAmount = new BigNumber(estimatedValues.data.commissionTokenAmount);
+ const intendedPricePoint = estimatedValues.data.pricePoint;
+
+ const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
+
+ const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
+ logger.debug("============ estimatedAirdropUsed ============");
+ logger.debug(estimatedAirdropUsed);
+ // Here we make sure that the airdrop amount is 0;
+ assert.equal(estimatedAirdropUsed.equals(0), true);
+ // Approve account1 for transfer
+ const accountApproveResponse = await TC5.approve(
+ spenderAddress,
+ spenderPassphrase,
+ constants.airdropOstUsdAddress,
+ estimatedTotalAmount.plus(100),
+ constants.gasUsed);
+
+ logger.debug("============spender approving to contract=============");
+ logger.debug(accountApproveResponse);
+ var worker1Balance = await web3Provider.eth.getBalance(constants.workerAccount1);
+ logger.debug("\nconstants.workerAccount1.balance: ", worker1Balance);
+
+ const PayObject = new PayKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ chain_id: constants.chainId,
+ sender_worker_address: constants.workerAccount1,
+ sender_worker_passphrase: constants.workerAccountPassphrase1,
+ beneficiary_address: beneficiary,
+ transfer_amount: transferAmount.toString(10),
+ commission_beneficiary_address: commissionBeneficiary,
+ commission_amount: commissionAmount.toString(10),
+ currency: currency,
+ intended_price_point: intendedPricePoint,
+ spender: spenderAddress,
+ gas_price: constants.gasUsed,
+ options: constants.optionsReceipt
+ });
+ const payResponse = await PayObject.perform();
+ assert.equal(payResponse.isSuccess(), true);
+ logger.debug("============airdrop.pay response=============");
+ logger.debug(payResponse);
// verify if the transaction receipt is valid
utils.verifyTransactionReceipt(payResponse);
-
// verify if the transaction is actually mined
await utils.verifyIfMined(airdropOstUsd, payResponse.data.transaction_hash);
- // const account1Balance = new BigNumber(await TC5.balanceOf(constants.account1))
- // , account3Balance = new BigNumber(await TC5.balanceOf(constants.account3))
- // , account4Balance = new BigNumber(await TC5.balanceOf(constants.account4))
- // ;
- //
- // assert.equal(
- // new BigNumber(0).plus(initialAccount1Balance)
- // .minus(estimatedTokenAmount)
- // .minus(estimatedCommissionTokenAmount)
- // .toNumber(), account1Balance.toNumber());
- //
- // assert.equal(
- // new BigNumber(0).plus(initialAccount3Balance)
- // .plus(estimatedTokenAmount)
- // .toNumber(), account3Balance.toNumber());
- //
- // assert.equal(
- // new BigNumber(0).plus(initialAccount4Balance)
- // .plus(estimatedCommissionTokenAmount)
- // .toNumber(), account4Balance.toNumber());
- //
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract after pay =============");
+ const balanceFromContract = await getBalanceFromContract(TC5, address);
+ const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
+ //check if the transfer was propre
+ validateTransferSuccess(
+ estimatedTokenAmount,
+ estimatedCommissionTokenAmount,
+ estimatedAirdropUsed,
+ spenderAddress,
+ beneficiary,
+ commissionBeneficiary,
+ airdropBudgetHolder,
+ initalBalancesFromContract,
+ balanceFromContract);
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB after pay =============");
+ const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
+ // validate if the airdrop transfer was proper
+ validateAirdropTransferSuccess(
+ spenderAddress,
+ initialAirdropBalanceFromDB,
+ airdropBalanceFromDB,
+ estimatedAirdropUsed);
});
- it('should pass when all parameters are valid with currency USD and allocated airdrop amount is greater than 0', async function() {
+ it('should pass when all airdrop amount is used and partial user balance is used', async function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
+
+ // Populate Cache
+ populateCache();
+ const spenderAddress = constants.account2
+ , spenderPassphrase = constants.accountPassphrase2
+ ;
+ const UserBalanceObject = new UserBalanceKlass({
+ chain_id: constants.chainId,
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ user_addresses: [spenderAddress]
+ });
+ const airdropBalanceResult = await UserBalanceObject.perform();
+ assert.equal(airdropBalanceResult.isSuccess(), true);
+
+ const availableAirdropBalance = new BigNumber(airdropBalanceResult.data[spenderAddress].balanceAirdropAmount);
+ const partialAmount = new BigNumber(10);
+
const beneficiary = constants.account3
- , commissionAmount = new BigNumber(airdropOstUsd.toWei('1'))
+ , commissionAmount = partialAmount
, commissionBeneficiary = constants.account4
, currency = constants.currencyUSD
- , transferAmount = new BigNumber(airdropOstUsd.toWei('9'))
+ , transferAmount = availableAirdropBalance.div(6).floor()
+ , airdropBudgetHolder = constants.airdropBudgetHolder
;
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract =============");
+ const address = [
+ spenderAddress,
+ beneficiary,
+ commissionBeneficiary,
+ airdropBudgetHolder
+ ];
+ const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
+ const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB =============");
+ const airdropUserAddress = [spenderAddress];
+ const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
+
const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
transferAmount,
commissionAmount,
@@ -386,61 +1100,82 @@ describe('Airdrop Pay', function() {
const intendedPricePoint = estimatedValues.data.pricePoint;
const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
- // Batch allocate airdrop amount to account1
- var airdropUsers = {};
- airdropUsers[constants.account1] = {airdropAmount: '50000000000000000000', expiryTimestamp: 0};
- var batchAllocateAirdropAmountResult = await airdropManager.batchAllocate(
- constants.airdropOstUsdAddress,
- transferToAirdropBudgetHolderTransactionHash,
- airdropUsers,
- constants.chainId
- );
- assert.equal(batchAllocateAirdropAmountResult.isSuccess(), true);
- var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
- var result = await airdropAllocationProofDetailModel.getByTransactionHash(transferToAirdropBudgetHolderTransactionHash);
- var airdropAllocationProofDetailRecord = result[0];
- assert.isAtMost(new BigNumber(airdropAllocationProofDetailRecord.airdrop_allocated_amount).toNumber(),
- new BigNumber(airdropAllocationProofDetailRecord.airdrop_amount).toNumber());
+ const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
+ logger.debug("============ estimatedAirdropUsed ============");
+ logger.debug(estimatedAirdropUsed);
+ // here we make sure that airdrop amount used will be greater than 0
+ assert.equal(estimatedAirdropUsed.gt(0), true);
// Approve account1 for transfer
- const account1ApproveResponse = await TC5.approve(
- constants.account1,
- constants.accountPassphrase1,
+ const accountApproveResponse = await TC5.approve(
+ spenderAddress,
+ spenderPassphrase,
constants.airdropOstUsdAddress,
- estimatedTotalAmount.plus(100).toString(),
+ estimatedTotalAmount.plus(100),
constants.gasUsed);
- logger.info("============spender approving to contract=============");
- logger.info(account1ApproveResponse);
- var worker1Balance = await web3RpcProvider.eth.getBalance(constants.workerAccount1);
- logger.info("\nconstants.workerAccount1.balance: ", worker1Balance);
- const payResponse = await airdropOstUsd.pay(
- constants.workerAccount1,
- constants.workerAccountPassphrase1,
- beneficiary,
- transferAmount.toString(),
- commissionBeneficiary,
- commissionAmount.toString(),
- currency,
- intendedPricePoint,
- constants.account1,
- constants.gasUsed,
- {returnType: constants.returnTypeReceipt, tag: 'airdrop.pay'});
- logger.info("============mocha_test.airdrop.pay response=============");
- logger.info(payResponse);
+ logger.debug("============spender approving to contract=============");
+ logger.debug(accountApproveResponse);
+ var worker1Balance = await web3Provider.eth.getBalance(constants.workerAccount1);
+ logger.debug("\nconstants.workerAccount1.balance: ", worker1Balance);
+
+ const PayObject = new PayKlass({
+ airdrop_contract_address: constants.airdropOstUsdAddress,
+ chain_id: constants.chainId,
+ sender_worker_address: constants.workerAccount1,
+ sender_worker_passphrase: constants.workerAccountPassphrase1,
+ beneficiary_address: beneficiary,
+ transfer_amount: transferAmount.toString(10),
+ commission_beneficiary_address: commissionBeneficiary,
+ commission_amount: commissionAmount.toString(10),
+ currency: currency,
+ intended_price_point: intendedPricePoint,
+ spender: spenderAddress,
+ gas_price: constants.gasUsed,
+ options: constants.optionsReceipt
+ });
+ const payResponse = await PayObject.perform();
+ assert.equal(payResponse.isSuccess(), true);
+ logger.debug("============airdrop.pay response=============");
+ logger.debug(payResponse);
// verify if the transaction receipt is valid
utils.verifyTransactionReceipt(payResponse);
-
// verify if the transaction is actually mined
await utils.verifyIfMined(airdropOstUsd, payResponse.data.transaction_hash);
- });
- it('Airdrop.Pay: It exits', async function() {
- process.exit(0);
+ // checks for account balance cache and DB consistency
+ logger.debug("============ Validating consistency for account balance form cache and contract after pay =============");
+ const balanceFromContract = await getBalanceFromContract(TC5, address);
+ const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
+ validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
+ //check if the transfer was propre
+ validateTransferSuccess(
+ estimatedTokenAmount,
+ estimatedCommissionTokenAmount,
+ estimatedAirdropUsed,
+ spenderAddress,
+ beneficiary,
+ commissionBeneficiary,
+ airdropBudgetHolder,
+ initalBalancesFromContract,
+ balanceFromContract);
+
+ // checks for airdrop balance cache and DB consistency
+ logger.debug("============ Validating consistency for airdrop balance form cache and DB after pay =============");
+ const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
+ const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
+ validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
+ // validate if the airdrop transfer was proper
+ validateAirdropTransferSuccess(
+ spenderAddress,
+ initialAirdropBalanceFromDB,
+ airdropBalanceFromDB,
+ estimatedAirdropUsed);
+
});
-});
-*/
\ No newline at end of file
+
+});
\ No newline at end of file
diff --git a/mocha_test/services/airdrop/pay_1.js b/mocha_test/services/airdrop/pay_1.js
deleted file mode 100644
index c487eec..0000000
--- a/mocha_test/services/airdrop/pay_1.js
+++ /dev/null
@@ -1,1125 +0,0 @@
-/* global describe, it */
-
-const chai = require('chai')
- , assert = chai.assert;
-
-const rootPrefix = "../../.."
- , constants = require(rootPrefix + '/mocha_test/lib/constants')
- , BigNumber = require('bignumber.js')
- , utils = require(rootPrefix+'/mocha_test/lib/utils')
- , airdrop = require(rootPrefix + '/lib/contract_interact/airdrop')
- , workers = require(rootPrefix + '/lib/contract_interact/workers')
- , mockToken = require(rootPrefix + '/lib/contract_interact/EIP20TokenMock')
- , BrandedTokenKlass = require(rootPrefix + '/lib/contract_interact/branded_token')
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
- , logger = require(rootPrefix + '/helpers/custom_console_logger')
-;
-
-const workersContract = new workers(constants.workersContractAddress, constants.chainId)
- , airdropOstUsd = new airdrop(constants.airdropOstUsdAddress, constants.chainId)
- , TC5 = new mockToken(constants.TC5Address)
- , brandedTokenObject = new BrandedTokenKlass(constants.TC5Address, constants.chainId)
-;
-
-
-const airdropKlass = require(rootPrefix + '/app/models/airdrop')
- , airdropManager = require(rootPrefix + '/lib/airdrop_management/base')
- , airdropAllocationProofDetailKlass = require(rootPrefix + '/app/models/airdrop_allocation_proof_detail')
- , UserAirdropDetailKlass = require(rootPrefix + '/app/models/user_airdrop_detail')
- , responseHelper = require(rootPrefix + '/lib/formatter/response')
-;
-
-var transferToAirdropBudgetHolderTransactionHash = ''
-;
-
-/**
- * Utitlity function to test set accepted margin
- *
- * @param {Object} airdropObject - airdrop object
- * @param {string} currency - currency
- * @param {string} margin - accepted margin
- *
- */
-
-async function setAcceptedMargin(airdropObject, currency, margin) {
- // set accepted margin
- const amResponse = await airdropObject.setAcceptedMargin(
- constants.ops,
- constants.opsPassphrase,
- currency,
- margin,
- constants.gasUsed,
- constants.optionsReceipt);
- assert.equal(amResponse.isSuccess(), true);
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(amResponse);
- // verify if the transaction has was actually mined
- await utils.verifyIfMined(airdropObject, amResponse.data.transaction_hash);
- // verify if its set
- const amResult = await airdropObject.acceptedMargins(currency);
- assert.equal(amResult.isSuccess(), true);
- assert.equal(margin, amResult.data.acceptedMargins);
-}
-
-
-/**
- * Utitlity function to test set price oracle
- *
- * @param {Object} airdropObject - airdrop object
- * @param {string} currency - currency
- * @param {string} address - price oracle address
- *
- */
-async function setPriceOracle(airdropObject, currency, address) {
- // Set Price Oracle
- const spoResponse = await airdropObject.setPriceOracle(
- constants.ops,
- constants.opsPassphrase,
- currency,
- address,
- constants.gasUsed,
- constants.optionsReceipt);
- assert.equal(spoResponse.isSuccess(), true);
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(spoResponse);
- // verify if the transaction has was actually mined
- await utils.verifyIfMined(airdropObject, spoResponse.data.transaction_hash);
- // verify if its set
- const poResult = await airdropObject.priceOracles(currency);
- assert.equal(poResult.isSuccess(), true);
- assert.equal(address, poResult.data.priceOracles);
-}
-
-
-/**
- * Utitlity function to test set worker
- *
- * @param {string} workerAddress - worker address
- * @param {Bignumber} deactivationHeight - deactivation height of the worker
- *
- */
-async function setWorker(workerAddress, deactivationHeight) {
- const setWorkerResponse = await workersContract.setWorker(
- constants.ops,
- constants.opsPassphrase,
- workerAddress,
- deactivationHeight.toString(10),
- constants.gasUsed,
- constants.optionsReceipt);
-
- assert.equal(setWorkerResponse.isSuccess(), true);
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(setWorkerResponse);
-
- // confirm that worker is a set
- const isWorkerResponse = await workersContract.isWorker(workerAddress);
- assert.equal(isWorkerResponse.isSuccess(), true);
- assert.equal(isWorkerResponse.data.isValid, true);
-}
-
-
-/**
- * Utitlity function to test setBalance
- *
- * @param {Object} token - branded token object
- * @param {string} address - account address
- * @param {string} amount - amount that need to be set
- * @param {BigNumber} gasPrice - gas price
- *
- */
-async function setBalance(token, address, amount) {
- const amountInWei = airdropOstUsd.toWei(amount);
- await token.setBalance(
- constants.ops,
- constants.opsPassphrase,
- address,
- amountInWei,
- constants.gasUsed);
- // check if the balance was set
- const accountBalance = await token.balanceOf(address);
- assert.equal(accountBalance, amountInWei);
-}
-
-/**
- * Utitlity function to get airdrop id from airdrop address
- *
- * @param {string} airdropAddress - airdrop address
- *
- * @return {Object} - formatted response
- */
-
-async function getAirdropIdFromAirdropAddress(airdropAddress) {
- var airdropModel = new airdropKlass();
- var result = await airdropModel.getByContractAddress(airdropAddress);
- const airdropRecord = result[0];
- if (airdropRecord) {
- return responseHelper.successWithData({airdropId: airdropRecord.id});
- }
- return responseHelper.error("gaidfad", "No data found");
-}
-
-/**
- * Utitlity function to register airdrop if not already registered
- *
- * @param {string} airdropAddress - airdrop address
- *
- */
-async function registerAirdrop(airdropAddress) {
- // Do Airdrop Setup if setup was not done
- const airDropIdResponse = await getAirdropIdFromAirdropAddress(airdropAddress);
- if (airDropIdResponse.isFailure()) {
- const registerAirdropResponse = await airdropManager.registerAirdrop(
- airdropAddress,
- constants.chainId
- );
- assert.equal(registerAirdropResponse.isSuccess(), true);
-
- // check again if the database awas set;
- const airDropIdAfterRegisterResponse = await getAirdropIdFromAirdropAddress(airdropAddress);
- assert.equal(airDropIdAfterRegisterResponse.isSuccess(), true);
- }
-}
-
-/**
- * Utitlity function to transfer token to airdrop budget holder
- *
- * @param {Object} token - Branded token object
- * @param {string} airdropAddress - airdrop address
- * @param {string} fromAddress - reserve address
- * @param {string} fromPassphrase - passphrase
- * @param {string} budgetHolderAddress - budget holder address
- * @param {string} amount - amount to transfer to budget holder
- *
- * @return {transaction hash}
- */
-async function transferTokenToAirdropBugetHolder (token, airdropAddress, fromAddress, fromPassphrase, budgetHolderAddress, amount) {
-
- const airdropBudgetAmountInWei = new BigNumber(airdropOstUsd.toWei(amount));
- const initialBalance = new BigNumber(await token.balanceOf(fromAddress));
- const beforeTransferAirdropBudgetHolderBalance = new BigNumber(await token.balanceOf(budgetHolderAddress));
-
- logger.info("initialBalance:", initialBalance.toString(10),
- "\nairdropBudgetAmount:", airdropBudgetAmountInWei.toString(10),
- "\nairdropAddress:", airdropAddress);
-
- assert.equal(initialBalance.gte(airdropBudgetAmountInWei), true, "insufficent balance to transfer amount to budgetHolderAddress");
-
- var transferToAirdropBudgetHolderResult = await airdropManager.transfer(
- fromAddress,
- fromPassphrase,
- airdropAddress,
- airdropBudgetAmountInWei,
- constants.gasUsed,
- constants.chainId,
- constants.optionsReceipt
- );
- logger.info("=======transferToAirdropBudgetHolderResult=======");
- logger.info(transferToAirdropBudgetHolderResult);
- assert.equal(transferToAirdropBudgetHolderResult.isSuccess(), true);
- // verify if the transaction receipt is valid
- await utils.verifyTransactionReceipt(transferToAirdropBudgetHolderResult);
- // verify if the transaction was actually mined
- await utils.verifyIfMined(airdropOstUsd, transferToAirdropBudgetHolderResult.data.transaction_hash);
-
- const afterTransferAirdropBudgetHolderBalance = new BigNumber(await token.balanceOf(budgetHolderAddress));
- assert.equal((beforeTransferAirdropBudgetHolderBalance.plus(airdropBudgetAmountInWei)).equals( afterTransferAirdropBudgetHolderBalance), true);
-
- // set transaction hash
- transferToAirdropBudgetHolderTransactionHash = transferToAirdropBudgetHolderResult.data.transaction_hash;
- return transferToAirdropBudgetHolderTransactionHash;
-}
-
-/**
- * Utitlity function get user airdrop balance
- *
- * @param {string} airdropAddress - airdrop address
- * @param {Array} userAddressArray - user address array
- *
- * @return {Object} - formatted response
- */
-async function getUserAirdropBalanceFromCache(airdropAddress, userAddressArray) {
- // Get cache value
- var airdropBalanceResult = await airdropManager.getAirdropBalance(
- constants.chainId,
- airdropAddress,
- userAddressArray
- );
- const zeroAmount = {
- totalAirdropAmount: '0',
- totalAirdropUsedAmount: '0',
- balanceAirdropAmount: '0'
- };
- var responseData = {};
- if (airdropBalanceResult.isSuccess()) {
- responseData = airdropBalanceResult.data;
- }
- var data = {};
- for (var i = userAddressArray.length - 1; i >= 0; i--) {
- if(responseData[userAddressArray[i]]) {
- data[userAddressArray[i]] = responseData[userAddressArray[i]];
- } else {
- data[userAddressArray[i]] = zeroAmount;
- }
- }
- return responseHelper.successWithData(data);
-}
-
-/**
- * Utitlity function get user airdrop balance form DB, bypass cache layer
- *
- * @param {string} airdropAddress - airdrop address
- * @param {Array} userAddressArray - user address array
- *
- * @return {Object} - formatted response
- */
-async function getUserAirdropBalanceFromDB(airdropAddress, userAddressArray) {
-
- const airDropIdResponse = await getAirdropIdFromAirdropAddress(airdropAddress);
- if (airDropIdResponse.isSuccess()) {
- const airdropId = airDropIdResponse.data.airdropId;
- const userAirdropDetailModel = new UserAirdropDetailKlass();
-
- const queryResponse = await userAirdropDetailModel.getByUserAddresses(airdropId, userAddressArray);
-
- var responseData = {};
- if (queryResponse.isSuccess()) {
- responseData = queryResponse.data;
- }
- var data = {};
- for (var i = userAddressArray.length - 1; i >= 0; i--) {
- if(responseData[userAddressArray[i]]) {
- data[userAddressArray[i]] = responseData[userAddressArray[i]];
- } else {
- data[userAddressArray[i]] = {
- totalAirdropAmount: '0',
- totalAirdropUsedAmount: '0',
- balanceAirdropAmount: '0'
- };
- }
- }
- return responseHelper.successWithData(data);
- }
- return airDropIdResponse;
-}
-
-/**
- * Utitlity function to compare the airdrop balances from DB and cache
- *
- * @param {Object} dbBalance - airdrop balance from DB
- * @param {Object} cacheBalance - airdrop balance from cache
- *
- */
-function validateDBandCacheAirdropBalances(dbBalance, cacheBalance) {
-
- const compare = function(obj1, obj2) {
- assert.equal(obj1.totalAirdropAmount, obj2.totalAirdropAmount);
- assert.equal(obj1.totalAirdropUsedAmount, obj2.totalAirdropUsedAmount);
- assert.equal(obj1.balanceAirdropAmount, obj2.balanceAirdropAmount);
- };
-
- const dbUserKeys = Object.keys(dbBalance);
- const cacheUserKeys = Object.keys(cacheBalance);
- assert.equal(dbUserKeys.length, cacheUserKeys.length);
- for (var i = dbUserKeys.length - 1; i >= 0; i--) {
- const dbObject = dbBalance[dbUserKeys[i]];
- const cacheObject = cacheBalance[cacheUserKeys[i]];
- assert.isDefined(dbObject);
- assert.isDefined(cacheObject);
- compare(dbObject, cacheObject);
- }
-}
-
-/**
- * Utitlity function to get balance of address from contract
- *
- * @param {Object} token - token
- * @param {string} address - address whose balances need to be found
- *
- */
-async function getBalanceFromContract(token, address) {
- var balances = {};
- for (var i = address.length - 1; i >= 0; i--) {
- const addressKey = address[i];
- balances[addressKey] = new BigNumber(await token.balanceOf(addressKey));
- }
- return balances;
-}
-
-/**
- * Utitlity function to get balance of address from cache
- *
- * @param {Object} token - token
- * @param {string} address - address whose balances need to be found
- *
- */
-async function getBalanceFromCache(tokenObj, address) {
- var balances = {};
- for (var i = address.length - 1; i >= 0; i--) {
- const addressKey = address[i];
- const balance = await tokenObj.getBalanceOf(addressKey);
- assert.equal(balance.isSuccess(), true);
- balances[addressKey] = new BigNumber(balance.data.balance);
- }
- return balances;
-}
-
-/**
- * Utitlity function to compare balances from cache and contract
- *
- * @param {Object} contractBalances - balances from contract
- * @param {Object} cacheBalance - balances from cache
- *
- */
-
-function validateContractAndCacheBalance(cacheBalance, contractBalances) {
- const contractKeys = Object.keys(cacheBalance);
- const cacheKeys = Object.keys(contractBalances);
- assert.equal(contractKeys.length, cacheKeys.length);
- for (var i = contractKeys.length - 1; i >= 0; i--) {
- const balanceFromContract = contractBalances[contractKeys[i]];
- const balanceFromCache = cacheBalance[contractKeys[i]];
- assert.isDefined(balanceFromContract);
- assert.isDefined(balanceFromCache);
- assert.equal(balanceFromCache.equals(balanceFromContract), true);
- }
-}
-
-/**
- * Utitlity function to validate if airdrop was transfered successfully
- *
- * @param {string} accountAddress - user address
- * @param {Object} initialAirdropBalance - Initial airdrop balance
- * @param {Object} currentAirdropBalance - Current airdrop balance
- * @param {BigNumber} airdropAmountTransfered - estimated airdrop amount that was transfered
- */
-function validateAirdropTransferSuccess(accountAddress, initialAirdropBalance, currentAirdropBalance, airdropAmountTransfered) {
-
- const initialAirdropBalanceData = initialAirdropBalance.data[accountAddress];
- const currentAirdropBalanceData = currentAirdropBalance.data[accountAddress];
-
- assert.isDefined(initialAirdropBalanceData);
- assert.isDefined(currentAirdropBalanceData);
-
- const intialTotalAirdropAmount = new BigNumber(initialAirdropBalanceData.totalAirdropAmount);
- const initialTotalAirdropUsedAmount = new BigNumber(initialAirdropBalanceData.totalAirdropUsedAmount);
- const initialBalanceAirdropAmount = new BigNumber(initialAirdropBalanceData.balanceAirdropAmount);
-
- const totalAirdropAmount = new BigNumber(currentAirdropBalanceData.totalAirdropAmount);
- const totalAirdropUsedAmount = new BigNumber(currentAirdropBalanceData.totalAirdropUsedAmount);
- const balanceAirdropAmount = new BigNumber(currentAirdropBalanceData.balanceAirdropAmount);
-
- assert.equal(intialTotalAirdropAmount.equals(totalAirdropAmount), true);
- assert.equal((initialTotalAirdropUsedAmount.plus(airdropAmountTransfered)).equals(totalAirdropUsedAmount), true);
- assert.equal((initialBalanceAirdropAmount.minus(airdropAmountTransfered)).equals(balanceAirdropAmount), true);
-}
-
-function validateTransferSuccess(
- estimatedTokenAmount,
- estimatedCommissionTokenAmount,
- estimatedAirdropUsed,
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder,
- initialBalances,
- currentBalances) {
-
- assert.isDefined(estimatedTokenAmount);
- assert.isDefined(estimatedCommissionTokenAmount);
- assert.isDefined(estimatedAirdropUsed);
- assert.isDefined(spenderAddress);
- assert.isDefined(beneficiary);
- assert.isDefined(commissionBeneficiary);
- assert.isDefined(airdropBudgetHolder);
- assert.isDefined(initialBalances);
- assert.isDefined(currentBalances);
-
- const estimatedTotalAmount = estimatedTokenAmount.plus(estimatedCommissionTokenAmount);
- const actualTransferAmount = estimatedTotalAmount.minus(estimatedAirdropUsed);
- const calculatedBenficiaryAmount = initialBalances[beneficiary].plus(estimatedTokenAmount);
- const calculatedCommisionAmount = initialBalances[commissionBeneficiary].plus(estimatedCommissionTokenAmount);
- const calculatedSpenderAmount = initialBalances[spenderAddress].minus(actualTransferAmount);
- const calculatesBugdetHolderAmount = initialBalances[airdropBudgetHolder].minus(estimatedAirdropUsed);
-
- assert.equal(calculatedBenficiaryAmount.equals(currentBalances[beneficiary]), true);
- assert.equal(calculatedCommisionAmount.equals(currentBalances[commissionBeneficiary]), true);
- assert.equal(calculatedSpenderAmount.equals(currentBalances[spenderAddress]), true);
- assert.equal(calculatesBugdetHolderAmount.equals(currentBalances[airdropBudgetHolder]), true);
-}
-
-/**
- * Utitlity function to populate the cache of all test accounts
- *
- */
-async function populateCache() {
- // Populate Cache
- await brandedTokenObject.getBalanceOf(constants.account1);
- await brandedTokenObject.getBalanceOf(constants.account2);
- await brandedTokenObject.getBalanceOf(constants.account3);
- await brandedTokenObject.getBalanceOf(constants.account4);
- await brandedTokenObject.getBalanceOf(constants.account5);
- await brandedTokenObject.getBalanceOf(constants.airdropBudgetHolder);
-}
-// Tests starts here
-describe('Airdrop Pay', function() {
-
- it('should pass the initial checks', async function() {
- // eslint-disable-next-line no-invalid-this
- this.timeout(500000);
-
- // check if the address required for the testing are defined.
- assert.isDefined(constants.deployer);
- assert.isDefined(constants.ops);
- assert.isDefined(constants.account1);
- assert.isDefined(constants.workerAccount1);
- assert.isDefined(constants.airdropBudgetHolder);
-
- assert.notEqual(constants.deployer, constants.ops);
- assert.notEqual(constants.deployer, constants.account1);
- assert.notEqual(constants.ops, constants.account1);
-
- // set worker
- logger.info("============= Set worker =============");
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber();
- await setWorker(constants.workerAccount1, new BigNumber(currentBlockNumber).plus(100000000000));
-
- // Set Price Oracle
- logger.info("============= Set Price Oracle =============");
- await setPriceOracle(airdropOstUsd, constants.currencyUSD, constants.priceOracles.OST.USD);
-
- // set accepted margin
- logger.info("============= Set accepted margin =============");
- await setAcceptedMargin(airdropOstUsd, constants.currencyUSD, 50);
-
- // set balance for account 1 (Spender)
- logger.info("============= Set account 1 balance =============");
- await setBalance(TC5, constants.account1, constants.account1InitialBrandedTokenBalance);
-
- // reset balance for account 2 to 100
- logger.info("============= Set account 2 balance =============");
- await setBalance(TC5, constants.account2, '100');
-
- // reset balance for account 3 to 0
- logger.info("============= Set account 3 balance =============");
- await setBalance(TC5, constants.account3, '0');
-
- // reset balance for account 4 to 0
- logger.info("============= Set account 4 balance =============");
- await setBalance(TC5, constants.account4, '0');
-
- // reset balance of account airdropBudgetHolder to 0
- logger.info("============= Set airdropBudgetHolder balance =============");
- await setBalance(TC5, constants.airdropBudgetHolder, '0');
-
- // Do Airdrop Setup if setup was not done
- logger.info("============= Do Airdrop Setup if setup was not done =============");
- await registerAirdrop(constants.airdropOstUsdAddress);
-
- });
-
- it('AirdropManager: transfer branded token from reserve to airdropBudgetHolder and approve airdrop contract', async function() {
- // eslint-disable-next-line no-invalid-this
- this.timeout(100000);
-
- const address = [
- constants.account1,
- constants.airdropBudgetHolder
- ];
- const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
- const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
-
-
- // transfer amount
- await transferTokenToAirdropBugetHolder(TC5,
- constants.airdropOstUsdAddress,
- constants.account1,
- constants.accountPassphrase1,
- constants.airdropBudgetHolder,
- constants.airdropBudgetBrandedTokenBalance);
-
- const balanceFromContract = await getBalanceFromContract(TC5, address);
- const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
-
- // approve
- var approveToAirdropBudgetHolderResult = await airdropManager.approve(
- constants.airdropOstUsdAddress,
- constants.airdropBudgetHolderPassphrase,
- constants.gasUsed,
- constants.chainId,
- constants.optionsReceipt
- );
- logger.info("=======approveToAirdropBudgetHolderResult=======");
- logger.info(approveToAirdropBudgetHolderResult);
-
- assert.equal(approveToAirdropBudgetHolderResult.isSuccess(), true);
- // verify if the transaction receipt is valid
- await utils.verifyTransactionReceipt(approveToAirdropBudgetHolderResult);
- // verify if the transaction was actually mined
- await utils.verifyIfMined(airdropOstUsd, approveToAirdropBudgetHolderResult.data.transaction_hash);
- });
-
-
- it('AirdropManager: batch allocate to airdrop users and check user balance', async function() {
- // eslint-disable-next-line no-invalid-this
- this.timeout(10000);
-
- var airdropUsers = constants.airdropUsers;
- airdropUsers[constants.account2] = {airdropAmount: '100000000000000000000', expiryTimestamp: 0};
-
- // checks for cache and DB consistency
- const beforeAllocationBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
- const beforeAllocationBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
- validateDBandCacheAirdropBalances(beforeAllocationBalanceFromDB.data, beforeAllocationBalanceFromCache.data);
-
- var batchAllocateAirdropAmountResult = await airdropManager.batchAllocate(
- constants.airdropOstUsdAddress,
- transferToAirdropBudgetHolderTransactionHash,
- airdropUsers,
- constants.chainId
- );
-
- assert.equal(batchAllocateAirdropAmountResult.isSuccess(), true);
- var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
- var result = await airdropAllocationProofDetailModel.getByTransactionHash(transferToAirdropBudgetHolderTransactionHash);
- var airdropAllocationProofDetailRecord = result[0];
- // airdrop_allocated_amount is less than or equal to airdrop_amount
- assert.equal(new BigNumber(airdropAllocationProofDetailRecord.airdrop_allocated_amount).lte(new BigNumber(airdropAllocationProofDetailRecord.airdrop_amount)), true);
-
-
- // checks for cache and DB consistency
- const afterAllocationBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
- const afterAllocationBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, Object.keys(airdropUsers));
- validateDBandCacheAirdropBalances(afterAllocationBalanceFromDB.data, afterAllocationBalanceFromCache.data);
-
- // check if the airdrop balance reflects the proper value.
- const allUserKeys = Object.keys(airdropUsers);
- for (var i = allUserKeys.length - 1; i >= 0; i--) {
- const userKey = allUserKeys[i];
- const initialTotalAirdropAmount = new BigNumber(beforeAllocationBalanceFromDB.data[userKey].totalAirdropAmount);
- const initialTotalAirdropUsedAmount = new BigNumber(beforeAllocationBalanceFromDB.data[userKey].totalAirdropUsedAmount);
- const initialBalanceAirdropAmount = new BigNumber(beforeAllocationBalanceFromDB.data[userKey].balanceAirdropAmount);
-
- const totalAirdropAmount = new BigNumber(afterAllocationBalanceFromDB.data[userKey].totalAirdropAmount);
- const totalAirdropUsedAmount = new BigNumber(afterAllocationBalanceFromDB.data[userKey].totalAirdropUsedAmount);
- const balanceAirdropAmount = new BigNumber(afterAllocationBalanceFromDB.data[userKey].balanceAirdropAmount);
-
- assert.equal((initialTotalAirdropAmount.plus(new BigNumber(airdropUsers[userKey].airdropAmount))).equals(totalAirdropAmount), true);
-
- assert.equal(initialTotalAirdropUsedAmount.equals(totalAirdropUsedAmount), true);
- assert.equal(initialTotalAirdropUsedAmount.equals(0), true);
-
- assert.equal((initialBalanceAirdropAmount.plus(new BigNumber(airdropUsers[userKey].airdropAmount))).equals(balanceAirdropAmount), true);
- }
- });
-
-
- it('should fail when worker is not whitelisted', async function() {
- // eslint-disable-next-line no-invalid-this
- this.timeout(100000);
-
- // Populate Cache
- populateCache();
-
- const beneficiary = constants.account3
- , commissionAmount = new BigNumber(airdropOstUsd.toWei('0.9'))
- , commissionBeneficiary = constants.account4
- , currency = constants.currencyUSD
- , transferAmount = new BigNumber(airdropOstUsd.toWei('1.18'))
- , spenderAddress = constants.account2
- , spenderPassphrase = constants.accountPassphrase2
- , airdropBudgetHolder = constants.airdropBudgetHolder
- ;
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract =============");
- const address = [
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder
- ];
- const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
- const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
-
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB =============");
- const airdropUserAddress = [spenderAddress];
- const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
-
- var airdropBalanceResult = await airdropManager.getAirdropBalance(
- constants.chainId,
- constants.airdropOstUsdAddress,
- [spenderAddress]
- );
- assert.equal(airdropBalanceResult.isSuccess(), true);
- const availableAirdropBalance = new BigNumber(airdropBalanceResult.data[spenderAddress].balanceAirdropAmount);
-
- const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
- transferAmount,
- commissionAmount,
- currency);
- assert.equal(estimatedValues.isSuccess(), true);
-
- const estimatedTokenAmount = new BigNumber(estimatedValues.data.tokenAmount);
- const estimatedCommissionTokenAmount = new BigNumber(estimatedValues.data.commissionTokenAmount);
- const intendedPricePoint = estimatedValues.data.pricePoint;
-
- const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
-
- const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
- logger.info("============ estimatedAirdropUsed ============");
- logger.info(estimatedAirdropUsed);
-
- // Approve account1 for transfer
- const accountApproveResponse = await TC5.approve(
- spenderAddress,
- spenderPassphrase,
- constants.airdropOstUsdAddress,
- estimatedTotalAmount.plus(100),
- constants.gasUsed);
-
- logger.info("============spender approving to contract=============");
- logger.info(accountApproveResponse);
- var worker1Balance = await web3RpcProvider.eth.getBalance(constants.workerAccount1);
- logger.info("\nconstants.workerAccount1.balance: ", worker1Balance);
-
- const payResponse = await airdropOstUsd.pay(
- constants.ops,
- constants.opsPassphrase,
- beneficiary,
- transferAmount.toString(10),
- commissionBeneficiary,
- commissionAmount.toString(10),
- currency,
- intendedPricePoint,
- spenderAddress,
- constants.gasUsed,
- constants.optionsReceipt);
-
- assert.equal(payResponse.isFailure(), true);
- logger.info("============airdrop.pay response=============");
- logger.info(payResponse);
-
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract after pay =============");
- const balanceFromContract = await getBalanceFromContract(TC5, address);
- const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
- //check if the initial and current balances are reverted properly
- validateContractAndCacheBalance(initalBalancesFromContract, balanceFromContract);
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB after pay =============");
- const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
- // validate if the airdrop transfer was reverted properly
- validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, airdropBalanceFromDB.data);
-
- });
-
- it('should pass when transfer amount is less than available airdrop amount', async function() {
- // eslint-disable-next-line no-invalid-this
- this.timeout(100000);
-
- // Populate Cache
- populateCache();
-
- const beneficiary = constants.account3
- , commissionAmount = new BigNumber(airdropOstUsd.toWei('0.7'))
- , commissionBeneficiary = constants.account4
- , currency = constants.currencyUSD
- , transferAmount = new BigNumber(airdropOstUsd.toWei('1.91'))
- , spenderAddress = constants.account2
- , spenderPassphrase = constants.accountPassphrase2
- , airdropBudgetHolder = constants.airdropBudgetHolder
- ;
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract =============");
- const address = [
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder
- ];
- const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
- const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
-
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB =============");
- const airdropUserAddress = [spenderAddress];
- const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
-
- var airdropBalanceResult = await airdropManager.getAirdropBalance(
- constants.chainId,
- constants.airdropOstUsdAddress,
- [spenderAddress]
- );
- assert.equal(airdropBalanceResult.isSuccess(), true);
- const availableAirdropBalance = new BigNumber(airdropBalanceResult.data[spenderAddress].balanceAirdropAmount);
-
- const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
- transferAmount,
- commissionAmount,
- currency);
- assert.equal(estimatedValues.isSuccess(), true);
-
- const estimatedTokenAmount = new BigNumber(estimatedValues.data.tokenAmount);
- const estimatedCommissionTokenAmount = new BigNumber(estimatedValues.data.commissionTokenAmount);
- const intendedPricePoint = estimatedValues.data.pricePoint;
-
- const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
-
- const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
- logger.info("============ estimatedAirdropUsed ============");
- logger.info(estimatedAirdropUsed);
- // here we make sure that airdrop amount used will be greater than 0
- assert.equal(estimatedAirdropUsed.gt(0), true);
- // Approve account1 for transfer
- const accountApproveResponse = await TC5.approve(
- spenderAddress,
- spenderPassphrase,
- constants.airdropOstUsdAddress,
- estimatedTotalAmount.plus(100),
- constants.gasUsed);
-
- logger.info("============spender approving to contract=============");
- logger.info(accountApproveResponse);
- var worker1Balance = await web3RpcProvider.eth.getBalance(constants.workerAccount1);
- logger.info("\nconstants.workerAccount1.balance: ", worker1Balance);
-
- const payResponse = await airdropOstUsd.pay(
- constants.workerAccount1,
- constants.workerAccountPassphrase1,
- beneficiary,
- transferAmount.toString(10),
- commissionBeneficiary,
- commissionAmount.toString(10),
- currency,
- intendedPricePoint,
- spenderAddress,
- constants.gasUsed,
- constants.optionsReceipt);
-
- assert.equal(payResponse.isSuccess(), true);
- logger.info("============airdrop.pay response=============");
- logger.info(payResponse);
-
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(payResponse);
- // verify if the transaction is actually mined
- await utils.verifyIfMined(airdropOstUsd, payResponse.data.transaction_hash);
-
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract after pay =============");
- const balanceFromContract = await getBalanceFromContract(TC5, address);
- const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
- //check if the transfer was propre
- validateTransferSuccess(
- estimatedTokenAmount,
- estimatedCommissionTokenAmount,
- estimatedAirdropUsed,
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder,
- initalBalancesFromContract,
- balanceFromContract);
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB after pay =============");
- const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
- // validate if the airdrop transfer was proper
- validateAirdropTransferSuccess(
- spenderAddress,
- initialAirdropBalanceFromDB,
- airdropBalanceFromDB,
- estimatedAirdropUsed);
-
- });
-
- // This is with an assumption that pervious test was passed and due to that constants.account3 has some balance
- it('should pass when airdrop amount is 0', async function() {
- // eslint-disable-next-line no-invalid-this
- this.timeout(100000);
-
- // Populate Cache
- populateCache();
-
- const beneficiary = constants.account1
- , commissionAmount = new BigNumber(airdropOstUsd.toWei('0.0000000001'))
- , commissionBeneficiary = constants.account4
- , currency = constants.currencyUSD
- , transferAmount = new BigNumber(airdropOstUsd.toWei('0.000000033'))
- , spenderAddress = constants.account3
- , spenderPassphrase = constants.accountPassphrase3
- , airdropBudgetHolder = constants.airdropBudgetHolder
- ;
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract =============");
- const address = [
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder
- ];
- const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
- const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
-
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB =============");
- const airdropUserAddress = [spenderAddress];
- const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
-
- var airdropBalanceResult = await airdropManager.getAirdropBalance(
- constants.chainId,
- constants.airdropOstUsdAddress,
- [spenderAddress]
- );
- assert.equal(airdropBalanceResult.isSuccess(), true);
- // this line is to make sure that the airdropBalance is not availalbe for the user. This is because this user was never allocated airdrop.
- assert.isUndefined(airdropBalanceResult.data[spenderAddress]);
- const availableAirdropBalance = new BigNumber(0);
-
- const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
- transferAmount,
- commissionAmount,
- currency);
- assert.equal(estimatedValues.isSuccess(), true);
-
- const estimatedTokenAmount = new BigNumber(estimatedValues.data.tokenAmount);
- const estimatedCommissionTokenAmount = new BigNumber(estimatedValues.data.commissionTokenAmount);
- const intendedPricePoint = estimatedValues.data.pricePoint;
-
- const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
-
- const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
- logger.info("============ estimatedAirdropUsed ============");
- logger.info(estimatedAirdropUsed);
- // Here we make sure that the airdrop amount is 0;
- assert.equal(estimatedAirdropUsed.equals(0), true);
- // Approve account1 for transfer
- const accountApproveResponse = await TC5.approve(
- spenderAddress,
- spenderPassphrase,
- constants.airdropOstUsdAddress,
- estimatedTotalAmount.plus(100),
- constants.gasUsed);
-
- logger.info("============spender approving to contract=============");
- logger.info(accountApproveResponse);
- var worker1Balance = await web3RpcProvider.eth.getBalance(constants.workerAccount1);
- logger.info("\nconstants.workerAccount1.balance: ", worker1Balance);
-
- const payResponse = await airdropOstUsd.pay(
- constants.workerAccount1,
- constants.workerAccountPassphrase1,
- beneficiary,
- transferAmount.toString(10),
- commissionBeneficiary,
- commissionAmount.toString(10),
- currency,
- intendedPricePoint,
- spenderAddress,
- constants.gasUsed,
- constants.optionsReceipt);
-
- assert.equal(payResponse.isSuccess(), true);
- logger.info("============airdrop.pay response=============");
- logger.info(payResponse);
-
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(payResponse);
- // verify if the transaction is actually mined
- await utils.verifyIfMined(airdropOstUsd, payResponse.data.transaction_hash);
-
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract after pay =============");
- const balanceFromContract = await getBalanceFromContract(TC5, address);
- const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
- //check if the transfer was propre
- validateTransferSuccess(
- estimatedTokenAmount,
- estimatedCommissionTokenAmount,
- estimatedAirdropUsed,
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder,
- initalBalancesFromContract,
- balanceFromContract);
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB after pay =============");
- const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
- // validate if the airdrop transfer was proper
- validateAirdropTransferSuccess(
- spenderAddress,
- initialAirdropBalanceFromDB,
- airdropBalanceFromDB,
- estimatedAirdropUsed);
- });
-
- it('should pass when all airdrop amount is used and partial user balance is used', async function() {
- // eslint-disable-next-line no-invalid-this
- this.timeout(100000);
-
- // Populate Cache
- populateCache();
- const spenderAddress = constants.account2
- , spenderPassphrase = constants.accountPassphrase2
- ;
-
- var airdropBalanceResult = await airdropManager.getAirdropBalance(
- constants.chainId,
- constants.airdropOstUsdAddress,
- [spenderAddress]
- );
- assert.equal(airdropBalanceResult.isSuccess(), true);
-
- const availableAirdropBalance = new BigNumber(airdropBalanceResult.data[spenderAddress].balanceAirdropAmount);
- const partialAmount = new BigNumber(10);
-
- const beneficiary = constants.account3
- , commissionAmount = partialAmount
- , commissionBeneficiary = constants.account4
- , currency = constants.currencyUSD
- , transferAmount = availableAirdropBalance.div(6).floor()
- , airdropBudgetHolder = constants.airdropBudgetHolder
- ;
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract =============");
- const address = [
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder
- ];
- const initalBalancesFromContract = await getBalanceFromContract(TC5, address);
- const initalBalancesCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(initalBalancesFromContract, initalBalancesCache);
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB =============");
- const airdropUserAddress = [spenderAddress];
- const initialAirdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const initialAirdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(initialAirdropBalanceFromDB.data, initialAirdropBalanceFromCache.data);
-
- const estimatedValues = await airdropOstUsd.getPricePointAndCalculatedAmounts(
- transferAmount,
- commissionAmount,
- currency);
- assert.equal(estimatedValues.isSuccess(), true);
-
- const estimatedTokenAmount = new BigNumber(estimatedValues.data.tokenAmount);
- const estimatedCommissionTokenAmount = new BigNumber(estimatedValues.data.commissionTokenAmount);
- const intendedPricePoint = estimatedValues.data.pricePoint;
-
- const estimatedTotalAmount = new BigNumber(0).plus(estimatedTokenAmount).plus(estimatedCommissionTokenAmount);
-
- const estimatedAirdropUsed = BigNumber.min(estimatedTotalAmount, availableAirdropBalance);
- logger.info("============ estimatedAirdropUsed ============");
- logger.info(estimatedAirdropUsed);
- // here we make sure that airdrop amount used will be greater than 0
- assert.equal(estimatedAirdropUsed.gt(0), true);
- // Approve account1 for transfer
- const accountApproveResponse = await TC5.approve(
- spenderAddress,
- spenderPassphrase,
- constants.airdropOstUsdAddress,
- estimatedTotalAmount.plus(100),
- constants.gasUsed);
-
- logger.info("============spender approving to contract=============");
- logger.info(accountApproveResponse);
- var worker1Balance = await web3RpcProvider.eth.getBalance(constants.workerAccount1);
- logger.info("\nconstants.workerAccount1.balance: ", worker1Balance);
-
- const payResponse = await airdropOstUsd.pay(
- constants.workerAccount1,
- constants.workerAccountPassphrase1,
- beneficiary,
- transferAmount.toString(10),
- commissionBeneficiary,
- commissionAmount.toString(10),
- currency,
- intendedPricePoint,
- spenderAddress,
- constants.gasUsed,
- constants.optionsReceipt);
-
- assert.equal(payResponse.isSuccess(), true);
- logger.info("============airdrop.pay response=============");
- logger.info(payResponse);
-
- // verify if the transaction receipt is valid
- utils.verifyTransactionReceipt(payResponse);
- // verify if the transaction is actually mined
- await utils.verifyIfMined(airdropOstUsd, payResponse.data.transaction_hash);
-
-
- // checks for account balance cache and DB consistency
- logger.info("============ Validating consistency for account balance form cache and contract after pay =============");
- const balanceFromContract = await getBalanceFromContract(TC5, address);
- const balancesFromCache = await getBalanceFromCache(brandedTokenObject, address);
- validateContractAndCacheBalance(balanceFromContract, balancesFromCache);
- //check if the transfer was propre
- validateTransferSuccess(
- estimatedTokenAmount,
- estimatedCommissionTokenAmount,
- estimatedAirdropUsed,
- spenderAddress,
- beneficiary,
- commissionBeneficiary,
- airdropBudgetHolder,
- initalBalancesFromContract,
- balanceFromContract);
-
- // checks for airdrop balance cache and DB consistency
- logger.info("============ Validating consistency for airdrop balance form cache and DB after pay =============");
- const airdropBalanceFromDB = await getUserAirdropBalanceFromDB(constants.airdropOstUsdAddress, airdropUserAddress);
- const airdropBalanceFromCache = await getUserAirdropBalanceFromCache(constants.airdropOstUsdAddress, airdropUserAddress);
- validateDBandCacheAirdropBalances(airdropBalanceFromDB.data, airdropBalanceFromCache.data);
- // validate if the airdrop transfer was proper
- validateAirdropTransferSuccess(
- spenderAddress,
- initialAirdropBalanceFromDB,
- airdropBalanceFromDB,
- estimatedAirdropUsed);
-
- });
-
-
- it('Airdrop.Pay: It exits', async function() {
- process.exit(0);
- });
-
-
-});
\ No newline at end of file
diff --git a/mocha_test/services/workers/_is_worker.js b/mocha_test/services/workers/_is_worker.js
index cd1159b..215aa94 100644
--- a/mocha_test/services/workers/_is_worker.js
+++ b/mocha_test/services/workers/_is_worker.js
@@ -5,8 +5,9 @@ const chai = require('chai')
const rootPrefix = "../../.."
, constants = require(rootPrefix + '/mocha_test/lib/constants')
- , workersModule = require(rootPrefix + '/lib/contract_interact/workers')
- , workers = new workersModule(constants.workersContractAddress, constants.chainId)
+ , openstPayment = require(rootPrefix + '/index')
+ , IsWorkerKlass = openstPayment.services.workers.isWorker
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
describe('Is worker', function() {
@@ -17,12 +18,16 @@ describe('Is worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- // set worker
- const response = await workers.isWorker(0);
+ const IsWorkerObject = new IsWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ worker_address: 0,
+ chain_id: constants.chainId
+ });
+ const response = await IsWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'worker address is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
});
diff --git a/mocha_test/services/workers/_remove_worker.js b/mocha_test/services/workers/_remove_worker.js
index 438c672..2033c29 100644
--- a/mocha_test/services/workers/_remove_worker.js
+++ b/mocha_test/services/workers/_remove_worker.js
@@ -8,6 +8,7 @@ const rootPrefix = "../../.."
, utils = require(rootPrefix+'/mocha_test/lib/utils')
, workersModule = require(rootPrefix + '/lib/contract_interact/workers')
, workers = new workersModule(constants.workersContractAddress, constants.chainId)
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
describe('Remove worker', function() {
@@ -35,7 +36,7 @@ describe('Remove worker', function() {
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'gas is mandatory');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -54,7 +55,7 @@ describe('Remove worker', function() {
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'sender address is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -73,7 +74,7 @@ describe('Remove worker', function() {
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'worker address is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
diff --git a/mocha_test/services/workers/_set_worker.js b/mocha_test/services/workers/_set_worker.js
index b9a34e0..ee25764 100644
--- a/mocha_test/services/workers/_set_worker.js
+++ b/mocha_test/services/workers/_set_worker.js
@@ -7,9 +7,11 @@ const rootPrefix = "../../.."
, constants = require(rootPrefix + '/mocha_test/lib/constants')
, BigNumber = require('bignumber.js')
, utils = require(rootPrefix+'/mocha_test/lib/utils')
- , workersModule = require(rootPrefix + '/lib/contract_interact/workers')
- , workers = new workersModule(constants.workersContractAddress, constants.chainId)
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
+ , openstPayment = require(rootPrefix + '/index')
+ , SetWorkerKlass = openstPayment.services.workers.setWorker
+ , IsWorkerKlass = openstPayment.services.workers.isWorker
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
describe('Set worker', function() {
@@ -27,22 +29,26 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- deactivationHeight.toNumber(),
- 0,
- constants.optionsReceipt);
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: 0,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'gas is mandatory');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -51,22 +57,25 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- 0,
- constants.opsPassphrase,
- constants.workerAccount1,
- deactivationHeight.toNumber(),
- constants.gasUsed,
- constants.optionsReceipt);
-
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: 0,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'sender address is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -75,22 +84,26 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- 0,
- deactivationHeight.toNumber(),
- constants.gasUsed,
- constants.optionsReceipt);
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: 0,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'worker address is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -99,22 +112,26 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- null,
- constants.gasUsed,
- constants.optionsReceipt);
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: null,
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'deactivation height is mandatory');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -123,22 +140,25 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- 'NaN',
- constants.gasUsed,
- constants.optionsReceipt);
-
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: 'NaN',
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'deactivation height value is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -147,22 +167,25 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- -1,
- constants.gasUsed,
- constants.optionsReceipt);
-
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: -1,
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'deactivation height value is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -171,22 +194,25 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- 0.1,
- constants.gasUsed,
- constants.optionsReceipt);
-
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: 0.1,
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'deactivation height value is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -195,32 +221,43 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// confirm that worker is not a worker
- const isWorkerBefore = await workers.isWorker(constants.workerAccount1);
+ var IsWorkerObject = new IsWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ worker_address: constants.workerAccount1,
+ chain_id: constants.chainId
+ });
+ const isWorkerBefore = await IsWorkerObject.perform();
assert.equal(isWorkerBefore.isSuccess(), true);
assert.equal(isWorkerBefore.data.isValid, false);
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- deactivationHeight.toNumber(),
- constants.gasUsed,
- constants.optionsReceipt);
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// verify if the transaction receipt is valid
utils.verifyTransactionReceipt(response);
- // verify if the transaction has was actually mined
- await utils.verifyIfMined(workers, response.data.transaction_hash);
-
// confirm that worker is a worker
- const isWorkerAfter = await workers.isWorker(constants.workerAccount1);
+ var IsWorkerObject = new IsWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ worker_address: constants.workerAccount1,
+ chain_id: constants.chainId
+ });
+ const isWorkerAfter = await IsWorkerObject.perform();
assert.equal(isWorkerAfter.isSuccess(), true);
assert.equal(isWorkerAfter.data.isValid, true);
@@ -231,18 +268,22 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- deactivationHeight.toNumber(),
- constants.gasUsed,
- constants.optionsUUID);
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsUUID
+ });
+ const response = await SetWorkerObject.perform();
// verify transaction UUID
// we will not verify if it got mined as its just interaction layer testing
@@ -255,18 +296,22 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- deactivationHeight.toNumber(),
- constants.gasUsed,
- constants.optionsHash);
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsHash
+ });
+ const response = await SetWorkerObject.perform();
// verify transaction hash
utils.verifyTransactionHash(response);
@@ -278,18 +323,22 @@ describe('Set worker', function() {
// eslint-disable-next-line no-invalid-this
this.timeout(100000);
- const currentBlockNumber = await web3RpcProvider.eth.getBlockNumber()
+ const currentBlockNumber = await web3Provider.eth.getBlockNumber()
, deactivationHeight = new BigNumber(currentBlockNumber).plus(10000)
;
// set worker
- const response = await workers.setWorker(
- constants.ops,
- constants.opsPassphrase,
- constants.workerAccount1,
- deactivationHeight.toNumber(),
- constants.gasUsed,
- constants.optionsReceipt);
+ var SetWorkerObject = new SetWorkerKlass({
+ workers_contract_address: constants.workersContractAddress,
+ sender_address: constants.ops,
+ sender_passphrase: constants.opsPassphrase,
+ worker_address: constants.workerAccount1,
+ deactivation_height: deactivationHeight.toString(10),
+ gas_price: constants.gasUsed,
+ chain_id: constants.chainId,
+ options: constants.optionsReceipt
+ });
+ const response = await SetWorkerObject.perform();
// verify transaction receipt
utils.verifyTransactionReceipt(response);
diff --git a/mocha_test/services/workers/remove.js b/mocha_test/services/workers/remove.js
index 43641e0..2dbd08a 100644
--- a/mocha_test/services/workers/remove.js
+++ b/mocha_test/services/workers/remove.js
@@ -8,7 +8,8 @@ const rootPrefix = "../../.."
, utils = require(rootPrefix+'/mocha_test/lib/utils')
, workersModule = require(rootPrefix + '/lib/contract_interact/workers')
, workers = new workersModule(constants.workersContractAddress, constants.chainId)
- , web3RpcProvider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
;
describe('Remove', function() {
@@ -35,7 +36,7 @@ describe('Remove', function() {
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'gas is mandatory');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -53,7 +54,7 @@ describe('Remove', function() {
// confirm failure reponse and message
assert.equal(response.isFailure(), true);
- assert.equal(response.err.msg, 'sender address is invalid');
+ assert.equal(response.toHash().err.msg, apiErrorConfig['invalid_api_params'].message);
});
@@ -76,7 +77,7 @@ describe('Remove', function() {
await utils.verifyIfMined(workers, response.data.transaction_hash);
// confirm worker address has no code
- const getCodeResult = await web3RpcProvider.eth.getCode(constants.workersContractAddress);
+ const getCodeResult = await web3Provider.eth.getCode(constants.workersContractAddress);
assert.equal(getCodeResult, '0x');
});
diff --git a/package.json b/package.json
index a48816e..fb3ed43 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@openstfoundation/openst-payments",
- "version": "1.0.0",
+ "version": "1.0.5",
"description": "Payment infrastructure on top of the OpenST network.",
"keywords": [
"openst",
@@ -22,13 +22,14 @@
"make-docs": "node_modules/.bin/jsdoc -c .jsdoc.json"
},
"dependencies": {
- "@openstfoundation/openst-cache": "1.0.1",
- "@openstfoundation/openst-notification": "1.0.0",
+ "@openstfoundation/openst-base": "0.9.0",
+ "@openstfoundation/openst-cache": "1.0.3",
+ "@openstfoundation/openst-notification": "1.0.1",
"bignumber.js": "4.1.0",
"mustache": "2.3.0",
"mysql": "2.14.1",
"shortid": "2.2.8",
- "web3": "1.0.0-beta.26"
+ "web3": "1.0.0-beta.33"
},
"devDependencies": {
"abi-decoder": "1.0.9",
@@ -40,7 +41,7 @@
"eslint-plugin-standard": "^3.0.1",
"ethereumjs-testrpc": "6.0.3",
"ganache-cli": "6.0.3",
- "truffle": "4.0.1",
+ "truffle": "^4.1.8",
"ink-docstrap": "1.3.2",
"jsdoc-route-plugin": "0.1.0",
"jsdoc": "3.5.5",
diff --git a/services/airdrop_management/approve.js b/services/airdrop_management/approve.js
new file mode 100644
index 0000000..dde31b3
--- /dev/null
+++ b/services/airdrop_management/approve.js
@@ -0,0 +1,230 @@
+"use strict";
+
+/**
+ *
+ * This is a utility file which would be used for executing approve by airdrop budget holder.
+ *
+ * @module services/airdrop_management/approve
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , airdropContractInteract = require(rootPrefix + '/lib/contract_interact/airdrop')
+ , brandedTokenContractInteract = require(rootPrefix + '/lib/contract_interact/branded_token')
+ , BigNumber = require('bignumber.js')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of approve
+ *
+ * @constructor
+ *
+ * @param {object} params -
+ * @param {string} params.airdrop_contract_address - airdrop contract address
+ * @param {string} params.airdrop_budget_holder_passphrase - airdropBudgetHolder Passphrase
+ * @param {string} params.gas_price - gas price
+ * @param {number} params.chain_id - chain Id
+ * @param {object} params.options - options
+ *
+ * @return {object}
+ *
+ */
+const ApproveKlass = function(params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=========Approve.params=========");
+ // Don't log passphrase
+ logger.debug(params.airdrop_contract_address, params.gas_price, params.chain_id, params.options);
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.airdropBudgetHolderPassphrase = params.airdrop_budget_holder_passphrase;
+ oThis.gasPrice = params.gas_price;
+ oThis.chainId = params.chain_id;
+ oThis.options = params.options;
+
+ oThis.airdropBudgetHolder = null;
+ oThis.brandedTokenContractAddress = null;
+ oThis.amount = null;
+ oThis.brandedTokenObject = null;
+};
+
+ApproveKlass.prototype = {
+
+ /**
+ * Perform approve by airdrop budget holder to contract
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+
+ const oThis = this;
+
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("\n=========Approve.validateParams.result=========");
+ logger.debug(r);
+ if(r.isFailure()) return r;
+
+ r = oThis.doApprove();
+ logger.debug("\n=========Approve.doApprove.result=========");
+ logger.debug(r);
+ return r;
+ } catch(err) {
+ let errorParams = {
+ internal_error_identifier: 's_am_a_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ logger.error(err.message);
+ return responseHelper.error(errorParams)
+ }
+
+ },
+
+ /**
+ * Validate params
+ *
+ * @return {promise}
+ *
+ */
+ validateParams: function(){
+ const oThis = this;
+ return new Promise(async function (onResolve, onReject) {
+
+ if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_a_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ // Check if airdropContractAddress is registered or not
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ ;
+ oThis.airdropRecord = airdropModelCacheResponse.data[oThis.airdropContractAddress];
+ if (!oThis.airdropRecord){
+ let errorParams = {
+ internal_error_identifier: 's_am_a_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['unregistered_airdrop_contract'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ var airdropContractInteractObject = new airdropContractInteract(oThis.airdropContractAddress, oThis.chainId);
+ var result = await airdropContractInteractObject.brandedToken();
+ oThis.brandedTokenContractAddress = result.data.brandedToken;
+ if (!basicHelper.isAddressValid(oThis.brandedTokenContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_a_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['branded_token_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ result = await airdropContractInteractObject.airdropBudgetHolder();
+ oThis.airdropBudgetHolderAddress = result.data.airdropBudgetHolder;
+ if (!basicHelper.isAddressValid(oThis.airdropBudgetHolderAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_a_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_budget_holder_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ oThis.brandedTokenObject = new brandedTokenContractInteract(oThis.brandedTokenContractAddress, oThis.chainId);
+ result = await oThis.brandedTokenObject.getBalanceOf(oThis.airdropBudgetHolderAddress);
+ oThis.amount = result.data.balance;
+ const amountInBigNumber = new BigNumber(oThis.amount);
+ if (amountInBigNumber.isNaN() || !amountInBigNumber.isInteger()){
+ let errorParams = {
+ internal_error_identifier: 's_am_a_validateParams_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_amount'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_a_validateParams_6',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_chain_id'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_am_a_validateParams_7',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ return onResolve(responseHelper.successWithData({}));
+
+ });
+
+ },
+
+ /**
+ * Perform Approve to airdrop budget holder
+ *
+ * @return {promise}
+ *
+ */
+ doApprove: async function(){
+ const oThis = this;
+ return new Promise(async function (onResolve, onReject) {
+ // Approve to budget holder
+ const approveByBudgetHolderResponse = await oThis.brandedTokenObject.approveByBudgetHolder(oThis.airdropBudgetHolderAddress,
+ oThis.airdropBudgetHolderPassphrase,
+ oThis.airdropContractAddress,
+ oThis.amount,
+ oThis.gasPrice,
+ oThis.options);
+ logger.debug("\n=========Transfer.doApprove.response=========");
+ logger.debug(approveByBudgetHolderResponse);
+ return onResolve(approveByBudgetHolderResponse);
+ });
+
+ }
+
+};
+
+module.exports = ApproveKlass;
\ No newline at end of file
diff --git a/services/airdrop_management/batch_allocator.js b/services/airdrop_management/batch_allocator.js
new file mode 100644
index 0000000..c0c032b
--- /dev/null
+++ b/services/airdrop_management/batch_allocator.js
@@ -0,0 +1,353 @@
+"use strict";
+
+/**
+ *
+ * This is a utility file which would be used for allocating amount to airdrop users.
+ *
+ * @module services/airdrop_management/batch_allocator
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , userAirdropDetailKlass = require(rootPrefix + '/app/models/user_airdrop_detail')
+ , airdropAllocationProofDetailKlass = require(rootPrefix + '/app/models/airdrop_allocation_proof_detail')
+ , airdropConstants = require(rootPrefix + '/lib/global_constant/airdrop')
+ , BigNumber = require('bignumber.js')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , userAirdropDetailCacheKlass = require(rootPrefix + '/lib/cache_multi_management/user_airdrop_detail')
+ , AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of batch allocator
+ *
+ * @constructor
+ *
+ * @param {object} params -
+ * @param {string} params.airdrop_contract_address - airdrop contract address
+ * @param {string} params.transaction_hash - airdrop transfer transactio hash
+ * @param {object} params.airdrop_users - {userAddress: {airdropAmount: amountInWei, expiryTimestamp: 0}}
+ * @param {number} params.chain_id - chain ID
+ *
+ * @return {object}
+ */
+const BatchAllocatorKlass = function(params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("\n=========batchAllocator.params=========");
+ logger.debug(params);
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.transactionHash = params.transaction_hash;
+ oThis.airdropUsers = params.airdrop_users;
+ oThis.chainId = params.chain_id;
+
+ // New Variables
+ oThis.airdropRecord = null;
+ oThis.airdropAllocationProofDetailRecord = null;
+ oThis.tableFields = ['user_address', 'airdrop_id', 'airdrop_amount', 'expiry_timestamp'];
+ oThis.bulkInsertData = [];
+ oThis.totalInputAirdropAmount = new BigNumber(0);
+ oThis.totalAmountAfterAllocatingInputAmount = new BigNumber(0);
+ oThis.userAddresses = [];
+};
+
+BatchAllocatorKlass.prototype = {
+
+ /**
+ * Perform batch allocation to airdrop users
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+
+ const oThis = this;
+
+ try {
+
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("\n=========batchAllocator.validateParams.result=========");
+ logger.debug(r);
+ if(r.isFailure()) return r;
+
+ r = await oThis.allocateAirdropAmountToUsers();
+ logger.debug("\n=========batchAllocator.allocateAirdropAmountToUsers.result=========");
+ logger.debug(r);
+ return r;
+
+ } catch(err){
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ logger.error(err.message);
+ return responseHelper.error(errorParams)
+ }
+ },
+
+ /**
+ * Validate params
+ *
+ * @return {promise}
+ *
+ */
+ validateParams: function() {
+ const oThis = this;
+ return new Promise(async function (onResolve, onReject) {
+
+ if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isTxHashValid(oThis.transactionHash)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_transaction_hash'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ // Check if airdropContractAddress is registered or not
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ ;
+ oThis.airdropRecord = airdropModelCacheResponse.data[oThis.airdropContractAddress];
+ if (!oThis.airdropRecord) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_3',
+ api_error_identifier: 'db_get_failed',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+ var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
+ const result = await airdropAllocationProofDetailModel.getByTransactionHash(oThis.transactionHash);
+ oThis.airdropAllocationProofDetailRecord = result[0];
+ if (!oThis.airdropAllocationProofDetailRecord) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_4',
+ api_error_identifier: 'db_get_failed',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ logger.error('%Error - Invalid transactionHash. Given airdropAllocationProofDetailRecord is not present in DB')
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ if (new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_allocated_amount).gte(new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_amount))) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_5',
+ api_error_identifier: 'invalid_amount',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ if(!oThis.airdropUsers || !(typeof oThis.airdropUsers === "object")) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_6',
+ api_error_identifier: 'invalid_object',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ const batchSize = Object.keys(oThis.airdropUsers).length;
+ if (batchSize > airdropConstants.batchSize()) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_7',
+ api_error_identifier: 'airdrop_batch_size_exceeded',
+ error_config: errorConfig,
+ debug_options: { batchSize: batchSize }
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ var value = null
+ , userAddress = ''
+ , userAirdropAmount = 0
+ , expiryTimestamp = 0
+ , insertData = []
+ ;
+ for (var userAddress in oThis.airdropUsers) {
+ value = oThis.airdropUsers[userAddress];
+
+ if (!basicHelper.isAddressValid(userAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_8',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_user_address'],
+ debug_options: { userAddress: userAddress }
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ userAirdropAmount = new BigNumber(value.airdropAmount);
+ if (userAirdropAmount.isNaN() || !userAirdropAmount.isInteger()) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_9',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_amount_invalid'],
+ debug_options: { userAddress: userAddress }
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (userAirdropAmount.lte(0)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_10',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_amount_invalid'],
+ debug_options: { userAddress: userAddress }
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ expiryTimestamp = new BigNumber(value.expiryTimestamp);
+ if (expiryTimestamp.isNaN() || !expiryTimestamp.isInteger()) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_11',
+ api_error_identifier: 'timestamp_invalid',
+ error_config: errorConfig,
+ debug_options: { userAddress: userAddress }
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ oThis.totalInputAirdropAmount = oThis.totalInputAirdropAmount.plus(userAirdropAmount);
+ insertData = [
+ userAddress,
+ oThis.airdropRecord.id,
+ userAirdropAmount.toString(10),
+ expiryTimestamp.toNumber()
+ ];
+ oThis.userAddresses.push(userAddress);
+ oThis.bulkInsertData.push(insertData);
+ }
+
+ // Calculate totalAmountToAllocate after adding input amount
+ oThis.totalAmountAfterAllocatingInputAmount = (new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_allocated_amount)).
+ plus(oThis.totalInputAirdropAmount);
+ const airdropAmountBigNumber = new BigNumber(oThis.airdropAllocationProofDetailRecord.airdrop_amount);
+ if (oThis.totalAmountAfterAllocatingInputAmount.gt(airdropAmountBigNumber)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_12',
+ api_error_identifier: 'invalid_amount',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ba_validateParams_14',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_chain_id'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ return onResolve(responseHelper.successWithData({}));
+
+ });
+
+ },
+
+ /**
+ * Allocate airdrop amount to users
+ *
+ * @return {promise}
+ *
+ */
+ allocateAirdropAmountToUsers: async function() {
+ const oThis = this;
+
+ return new Promise(async function (onResolve, onReject) {
+ try {
+ // Allocate and update Amount in db
+ var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
+ var r = await airdropAllocationProofDetailModel.updateAllocatedAmount(
+ oThis.airdropAllocationProofDetailRecord.id,
+ oThis.totalAmountAfterAllocatingInputAmount.toString(10)
+ );
+
+ logger.debug("=========allocateAirdropAmountToUsers.airdropAllocationProofDetailModel===========");
+ logger.debug(r);
+ if(r.isFailure()) return r;
+ var userAirdropDetailModel = new userAirdropDetailKlass();
+ await userAirdropDetailModel.insertMultiple(oThis.tableFields, oThis.bulkInsertData).fire();
+ oThis.clearCache();
+ return onResolve(responseHelper.successWithData({}));
+
+ } catch(err){
+ // If it fails rollback allocated amount
+ r = await airdropAllocationProofDetailModel.updateAllocatedAmount(
+ oThis.airdropAllocationProofDetailRecord.id,
+ (oThis.totalAmountAfterAllocatingInputAmount.minus(oThis.totalInputAirdropAmount)).toString(10)
+ );
+ logger.debug("=========allocateAirdropAmountToUsers.airdropAllocationProofDetailModel===========");
+ logger.debug(r);
+
+ let errorParams = {
+ internal_error_identifier: 'l_am_ba_vp_13',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err, transactionHash: oThis.transactionHash }
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ });
+
+ },
+
+ /**
+ *
+ * Clear all users cache
+ *
+ */
+ clearCache: async function() {
+ const oThis = this;
+ const userAirdropDetailCacheKlassObject = new userAirdropDetailCacheKlass({
+ chainId: oThis.chainId,
+ airdropId: oThis.airdropRecord.id,
+ userAddresses: oThis.userAddresses
+ });
+ await userAirdropDetailCacheKlassObject.clear();
+ }
+
+};
+
+module.exports = BatchAllocatorKlass;
\ No newline at end of file
diff --git a/services/airdrop_management/pay.js b/services/airdrop_management/pay.js
new file mode 100644
index 0000000..802b1fa
--- /dev/null
+++ b/services/airdrop_management/pay.js
@@ -0,0 +1,183 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing airdrop pay.
+ *
+ * @module services/airdrop/pay
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , AirdropContractInteractKlass = require(rootPrefix + '/lib/contract_interact/airdrop')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of airdrop PayKlass
+ *
+ * @params {object} params -
+ * @param {string} params.airdrop_contract_address - airdrop contract address
+ * @param {number} params.chain_id - chain Id
+ * @param {string} params.sender_worker_address - address of worker
+ * @param {string} params.sender_worker_passphrase - passphrase of worker
+ * @param {string} params.beneficiary_address - address of beneficiary account
+ * @param {bignumber} params.transfer_amount - transfer amount (in wei)
+ * @param {string} params.commission_beneficiary_address - address of commision beneficiary account
+ * @param {bignumber} params.commission_amount - commission amount (in wei)
+ * @param {string} params.currency - quote currency
+ * @param {bignumber} params.intended_price_point - price point at which the pay is intended (in wei)
+ * @param {string} params.spender - User address
+ * @param {string} params.gas_price - gas price
+ * @param {object} params.options - for params like returnType, tag.
+ *
+ * @constructor
+ *
+ */
+const PayKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======PayKlass.params=======");
+ logger.debug(params.airdrop_contract_address, params.chain_id, params.sender_worker_address, params.beneficiary_address,
+ params.transfer_amount, params.commission_beneficiary_address, params.commission_amount, params.currency, params.intended_price_point,
+ params.spender, params.gas_price, params.options);
+
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.chainId = params.chain_id;
+ oThis.senderWorkerAddress = params.sender_worker_address;
+ oThis.senderWorkerPassphrase = params.sender_worker_passphrase;
+ oThis.beneficiaryAddress = params.beneficiary_address;
+ oThis.transferAmount = params.transfer_amount;
+ oThis.commissionBeneficiaryAddress = params.commission_beneficiary_address;
+ oThis.commissionAmount = params.commission_amount;
+ oThis.currency = params.currency;
+ oThis.intendedPricePoint = params.intended_price_point;
+ oThis.spender = params.spender;
+ oThis.gasPrice = params.gas_price;
+ oThis.options = params.options;
+};
+
+PayKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======PayKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.pay();
+ logger.debug("=======PayKlass.pay.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_a_p_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ logger.error(err.message);
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+ if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_a_p_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_a_p_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_a_p_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * Airdrop pay
+ *
+ * @return {promise}
+ *
+ */
+ pay: function () {
+ const oThis = this
+ ;
+ const AirdropContractInteractObject = new AirdropContractInteractKlass(
+ oThis.airdropContractAddress,
+ oThis.chainId
+ );
+ return AirdropContractInteractObject.pay(
+ oThis.senderWorkerAddress,
+ oThis.senderWorkerPassphrase,
+ oThis.beneficiaryAddress,
+ oThis.transferAmount,
+ oThis.commissionBeneficiaryAddress,
+ oThis.commissionAmount,
+ oThis.currency,
+ oThis.intendedPricePoint,
+ oThis.spender,
+ oThis.gasPrice,
+ oThis.options
+ );
+ }
+
+};
+
+module.exports = PayKlass;
\ No newline at end of file
diff --git a/services/airdrop_management/post_airdrop_pay.js b/services/airdrop_management/post_airdrop_pay.js
new file mode 100644
index 0000000..b1c9701
--- /dev/null
+++ b/services/airdrop_management/post_airdrop_pay.js
@@ -0,0 +1,129 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing airdrop postAirdropPay.
+ *
+ * @module services/airdrop_management/post_airdrop_pay
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , helper = require(rootPrefix + '/lib/contract_interact/helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , AirdropContractInteractKlass = require(rootPrefix + '/lib/contract_interact/airdrop')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of airdrop PostPayKlass
+ *
+ * @params {object} params -
+ * @param {string} params.beneficiaryAddress - beneficiary address
+ * @param {string} params.commissionBeneficiaryAddress - commission beneficiary address
+ * @param {string} params.spender - spender address
+ * @param {string} params.brandedTokenAddress - branded token address
+ * @param {string} params.contractAddress - contractAddress address
+ * @param {string} params.airdropBudgetHolder - airdrop budget holder address
+ * @param {number} params.totalAmount - total amount that was debited from spender account
+ * @param {number} params.airdropAmountToUse - airdrop amount that was used in the transaction
+ * @param {number} params.chainId - chain id
+ * @params {object} decodedEvents - decoded events from receipt
+ * @param {number} status - transactions status (0 => failure, 1 => success)
+ *
+ * @constructor
+ *
+ */
+const PostPayKlass = function (params, decodedEvents, status) {
+
+ const oThis = this;
+ params = params || {};
+
+ oThis.postAirdropPayParams = params;
+ oThis.decodedEvents = decodedEvents;
+ oThis.status = status;
+
+};
+
+PostPayKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+
+ try {
+
+ if (!oThis.decodedEvents) {
+ let errorParams = {
+ internal_error_identifier: 's_a_pap_perform_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_decoded_events'],
+ debug_options: {}
+ };
+ return Promise.resolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ const validationResponse = helper.validatePostAirdropPayParams(oThis.postAirdropPayParams);
+ if (validationResponse.isFailure()) return Promise.resolve(validationResponse);
+
+ return Promise.resolve(await oThis.postAirdropPay());
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_a_pap_perform_2',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ logger.error("services/airdrop_management/post_airdrop_pay.js:perform inside catch ", err);
+ return Promise.resolve(responseHelper.error(errorParams));
+ }
+
+ },
+
+
+ /**
+ * Post airdrop pay
+ *
+ * @return {promise}
+ *
+ */
+ postAirdropPay: function () {
+ const oThis = this
+ ;
+
+ try {
+ const AirdropContractInteractObject = new AirdropContractInteractKlass(
+ oThis.postAirdropPayParams.contractAddress,
+ oThis.postAirdropPayParams.chainId
+ );
+ return AirdropContractInteractObject.postAirdropPay(oThis.postAirdropPayParams, oThis.decodedEvents, oThis.status);
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_a_pap_postAirdropPay_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ logger.error("services/airdrop_management/postAirdropPay.js:perform inside catch ", err);
+ return Promise.resolve(responseHelper.error(errorParams));
+ }
+ }
+
+};
+
+module.exports = PostPayKlass;
\ No newline at end of file
diff --git a/services/airdrop_management/register.js b/services/airdrop_management/register.js
new file mode 100644
index 0000000..78ca978
--- /dev/null
+++ b/services/airdrop_management/register.js
@@ -0,0 +1,203 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing airdrop register.
+ *
+ * @module services/airdrop_management/register
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , airdropKlass = require(rootPrefix + '/app/models/airdrop')
+ , airdropContractInteract = require(rootPrefix + '/lib/contract_interact/airdrop')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of register
+ *
+ * @constructor
+ *
+ * @params {object} params -
+ * @param {string} params.airdrop_contract_address - airdrop contract address
+ * @param {number} params.chain_id - chain Id
+ *
+ * @return {Object}
+ *
+ */
+const RegisterKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======register.params=======");
+ logger.debug(params);
+
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.chainId = params.chain_id;
+
+};
+
+RegisterKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======register.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.runRegister();
+ logger.debug("=======register.runRegister.result=======");
+ logger.debug(r);
+ return r;
+ } catch(err) {
+ let errorParams = {
+ internal_error_identifier: 's_am_r_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {promise}
+ *
+ */
+ validateParams: function () {
+ const oThis = this;
+ return new Promise(async function (onResolve, onReject) {
+
+ if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_r_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_r_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ const airdropContractInteractObject = new airdropContractInteract(oThis.airdropContractAddress, oThis.chainId);
+ var result = await airdropContractInteractObject.airdropBudgetHolder();
+ const airdropBudgetHolderAddress = result.data.airdropBudgetHolder;
+ if (!basicHelper.isAddressValid(airdropBudgetHolderAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_r_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ // Check if airdropContractAddress is registered or not
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ , airdropRecord = airdropModelCacheResponse.data[oThis.airdropContractAddress];
+ ;
+ if (airdropRecord) {
+ let errorParams = {
+ internal_error_identifier: 's_am_r_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_already_registered'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_r_validateParams_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ return onResolve(responseHelper.successWithData({}));
+ });
+ },
+
+ /**
+ * Run the register
+ *
+ * @return {promise}
+ *
+ */
+ runRegister: function () {
+ const oThis = this
+ ;
+
+ return new Promise(async function (onResolve, onReject) {
+ try {
+ const airdropModelObject = {
+ contract_address: oThis.airdropContractAddress
+ };
+ logger.debug("========register.runRegister.airdropModelObject=======");
+ logger.debug(airdropModelObject);
+ var airdropModel = new airdropKlass();
+ const insertedRecord = await airdropModel.create(airdropModelObject);
+ logger.debug("========register.runRegister.insertedRecord=======");
+ logger.debug(insertedRecord);
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress});
+ await airdropModelCacheObject.clear();
+ return onResolve(responseHelper.successWithData({insertId: insertedRecord.insertId}));
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_am_r_runRegister_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+ });
+
+ }
+
+};
+
+module.exports = RegisterKlass;
+
diff --git a/services/airdrop_management/set_accepted_margin.js b/services/airdrop_management/set_accepted_margin.js
new file mode 100644
index 0000000..639393b
--- /dev/null
+++ b/services/airdrop_management/set_accepted_margin.js
@@ -0,0 +1,204 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing worker is_worker.
+ *
+ * @module services/airdrop_management/set_accepted_margin
+ *
+ */
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , helper = require(rootPrefix + '/lib/contract_interact/helper')
+ , AirdropContractInteractKlass = require(rootPrefix + '/lib/contract_interact/airdrop')
+ , BigNumber = require('bignumber.js')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of SetAcceptedMarginKlass
+ *
+ * @constructor
+ *
+ * @param {object} - params
+ * @param {string} params.airdrop_contract_address - airdrop contract address
+ * @param {number} params.chain_id - chain id
+ * @param {string} params.sender_address - address of sender
+ * @param {string} params.sender_passphrase - passphrase of sender
+ * @param {string} params.currency - quote currency
+ * @param {bignumber} params.accepted_margin - accepted margin for the given currency (in wei)
+ * @param {bignumber} params.gas_price - gas price
+ * @param {object} params.options - for params like returnType, tag.
+ *
+ * @return {Object}
+ *
+ */
+const SetAcceptedMarginKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======SetAcceptedMarginKlass.params=======");
+ // Don't log passphrase
+ logger.debug(params.airdrop_contract_address, params.chain_id, params.sender_address, params.currency,
+ params.accepted_margin, params.gas_price, params.options);
+
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.chainId = params.chain_id;
+ oThis.senderAddress = params.sender_address;
+ oThis.senderPassphrase = params.sender_passphrase;
+ oThis.currency = params.currency;
+ oThis.acceptedMargin = params.accepted_margin;
+ oThis.gasPrice = params.gas_price;
+ oThis.options = params.options;
+};
+
+SetAcceptedMarginKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======SetAcceptedMarginKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.setAcceptedMargin();
+ logger.debug("=======SetAcceptedMarginKlass.setAcceptedMargin.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sam_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+ if (!helper.isValidCurrency(oThis.currency, false)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_sam_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_currency'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_am_sam_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ const acceptedMargin = new BigNumber(oThis.acceptedMargin);
+
+ if (acceptedMargin.isNaN() || !acceptedMargin.isInteger() || acceptedMargin.lt(0)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_sam_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['accepted_margin_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isAddressValid(oThis.senderAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_sam_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_am_sam_validateParams_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_sam_validateParams_6',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * Set accepted margin value in airdrop contract
+ *
+ * @return {promise}
+ *
+ */
+ setAcceptedMargin: function () {
+ const oThis = this
+ ;
+ const AirdropContractInteractObject = new AirdropContractInteractKlass(
+ oThis.airdropContractAddress,
+ oThis.chainId
+ );
+ return AirdropContractInteractObject.setAcceptedMargin(
+ oThis.senderAddress,
+ oThis.senderPassphrase,
+ oThis.currency,
+ oThis.acceptedMargin,
+ oThis.gasPrice,
+ oThis.options
+ );
+ }
+
+};
+
+module.exports = SetAcceptedMarginKlass;
\ No newline at end of file
diff --git a/services/airdrop_management/set_price_oracle.js b/services/airdrop_management/set_price_oracle.js
new file mode 100644
index 0000000..77173a4
--- /dev/null
+++ b/services/airdrop_management/set_price_oracle.js
@@ -0,0 +1,191 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing worker is_worker.
+ *
+ * @module services/airdrop_management/set_price_oracle
+ *
+ */
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , helper = require(rootPrefix + '/lib/contract_interact/helper')
+ , AirdropContractInteractKlass = require(rootPrefix + '/lib/contract_interact/airdrop')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of register
+ *
+ * @constructor
+ *
+ * @param {object} - params
+ * @param {string} params.airdrop_contract_address - airdrop contract address
+ * @param {number} params.chain_id - chain id
+ * @param {string} params.sender_address - address of sender
+ * @param {string} params.sender_passphrase - passphrase of sender
+ * @param {string} params.currency - quote currency
+ * @param {string} params.address - address of price oracle
+ * @param {bignumber} params.gas_price - gas price
+ * @param {object} params.options - for params like returnType, tag.
+ *
+ * @return {Object}
+ *
+ */
+const SetPriceOracleKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======SetPriceOracleKlass.params=======");
+ // Don't log passphrase
+ logger.debug(params.airdrop_contract_address, params.chain_id, params.sender_address, params.currency,
+ params.price_oracle_contract_address, params.gas_price, params.options);
+
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.chainId = params.chain_id;
+ oThis.senderAddress = params.sender_address;
+ oThis.senderPassphrase = params.sender_passphrase;
+ oThis.currency = params.currency;
+ oThis.priceOracleContractAddress = params.price_oracle_contract_address;
+ oThis.gasPrice = params.gas_price;
+ oThis.options = params.options;
+};
+
+SetPriceOracleKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======SetPriceOracleKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.setPriceOracle();
+ logger.debug("=======SetPriceOracleKlass.setPriceOracle.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_w_spo_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ logger.error(err.message);
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+ if (!helper.isValidCurrency(oThis.currency, false)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_spo_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['currency_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_am_spo_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isAddressValid(oThis.priceOracleContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_spo_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['price_oracle_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isAddressValid(oThis.senderAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_spo_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_spo_validateParams_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * set price oracle contract address in airdrop contract
+ *
+ * @return {promise}
+ *
+ */
+ setPriceOracle: function () {
+ const oThis = this
+ ;
+ const AirdropContractInteractObject = new AirdropContractInteractKlass(
+ oThis.airdropContractAddress,
+ oThis.chainId
+ );
+ return AirdropContractInteractObject.setPriceOracle(
+ oThis.senderAddress,
+ oThis.senderPassphrase,
+ oThis.currency,
+ oThis.priceOracleContractAddress,
+ oThis.gasPrice,
+ oThis.options
+ );
+ }
+
+};
+
+module.exports = SetPriceOracleKlass;
\ No newline at end of file
diff --git a/services/airdrop_management/transfer.js b/services/airdrop_management/transfer.js
new file mode 100644
index 0000000..4813ed5
--- /dev/null
+++ b/services/airdrop_management/transfer.js
@@ -0,0 +1,291 @@
+"use strict";
+
+/**
+ *
+ * This is a utility file which would be used for executing transfer amount to airdrop budget holder.
+ *
+ * @module services/airdrop_management/transfer
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , airdropAllocationProofDetailKlass = require(rootPrefix + '/app/models/airdrop_allocation_proof_detail')
+ , airdropContractInteract = require(rootPrefix + '/lib/contract_interact/airdrop')
+ , brandedTokenContractInteract = require(rootPrefix + '/lib/contract_interact/branded_token')
+ , BigNumber = require('bignumber.js')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
+ , BrandedTokenKlass = require(rootPrefix + '/lib/contract_interact/branded_token')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of transfer
+ *
+ * @constructor
+ *
+ * @params {object} - params
+ * @param {string} sender_address - sender address
+ * @param {string} sender_passphrase - sender Passphrase
+ * @param {string} airdrop_contract_address - airdrop contract address
+ * @param {string} amount - amount in wei
+ * @param {string} gas_price - gas price
+ * @param {number} chain_id - chain Id
+ * @param {object} options - options
+ *
+ * @return {object}
+ *
+ */
+const TransferKlass = function(params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("\n=========Transfer params=========");
+ // Don't log passphrase
+ logger.debug(params.sender_address, params.airdrop_contract_address, params.amount, params.gas_price, params.chain_id, params.options);
+
+ oThis.senderAddress = params.sender_address;
+ oThis.senderPassphrase = params.sender_passphrase;
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.amount = params.amount;
+ oThis.gasPrice = params.gas_price;
+ oThis.chainId = params.chain_id;
+ oThis.options = params.options;
+ oThis.airdropBudgetHolder = null;
+ oThis.brandedTokenContractAddress = null;
+
+};
+
+TransferKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+
+ const oThis = this;
+
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("\n=========Transfer.validateParams.result=========");
+ logger.debug(r);
+ if(r.isFailure()) return r;
+
+ r = oThis.doTransfer();
+ logger.debug("\n=========Transfer.doTransfer.result=========");
+ logger.debug(r);
+ return r;
+ } catch(err) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ logger.error(err.message);
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * validation of params
+ *
+ * @return {promise}
+ *
+ */
+ validateParams: function() {
+ const oThis = this;
+ return new Promise(async function (onResolve, onReject) {
+
+ if (!basicHelper.isAddressValid(oThis.senderAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ // Check if airdropContractAddress is registered or not
+
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ ;
+ oThis.airdropRecord = airdropModelCacheResponse.data[oThis.airdropContractAddress];
+ if (!oThis.airdropRecord){
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ const airdropContractInteractObject = new airdropContractInteract(oThis.airdropContractAddress, oThis.chainId);
+ var result = await airdropContractInteractObject.brandedToken();
+ oThis.brandedTokenContractAddress = result.data.brandedToken;
+ logger.debug("\n==========transfer.validateParams.brandedToken===========");
+ logger.debug("\nairdropContractInteractObject.brandedToken():", result,"\noThis.brandedTokenContractAddress:", oThis.brandedTokenContractAddress);
+ if (!basicHelper.isAddressValid(oThis.brandedTokenContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['branded_token_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ result = await airdropContractInteractObject.airdropBudgetHolder();
+ oThis.airdropBudgetHolderAddress = result.data.airdropBudgetHolder;
+ if (!basicHelper.isAddressValid(oThis.brandedTokenContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_budget_holder_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ const amountInBigNumber = new BigNumber(oThis.amount);
+ if (amountInBigNumber.isNaN() || !amountInBigNumber.isInteger()){
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_6',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_amount'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_7',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ const brandedTokenObject = new BrandedTokenKlass(oThis.brandedTokenContractAddress, oThis.chainId);
+ const senderBalanceResponse = await brandedTokenObject.getBalanceOf(oThis.senderAddress);
+
+ if (senderBalanceResponse.isFailure()) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_8',
+ api_error_identifier: 'get_balance_failed',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ const senderBalance = new BigNumber(senderBalanceResponse.data.balance);
+ //logger.debug("senderBalance: "+senderBalance.toString(10), "amount to transfer: "+amountInBigNumber);
+ if (senderBalance.lt(amountInBigNumber)){
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_9',
+ api_error_identifier: 'insufficient_funds',
+ error_config: errorConfig,
+ debug_options: { senderBalance: senderBalance.toString(10), amountInBigNumber: amountInBigNumber.toString(10) }
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_10',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_t_validateParams_11',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ return onResolve(responseHelper.successWithData({}));
+
+ });
+
+ },
+
+ /**
+ * Transfer amount to airdrop budget holder
+ *
+ * @return {promise}
+ *
+ */
+ doTransfer: async function() {
+ const oThis = this;
+
+ return new Promise(async function (onResolve, onReject) {
+ // BrandedToken transfer
+ logger.debug("\n==========doTransfer.oThis.brandedTokenContractAddress===========");
+ logger.debug(oThis.brandedTokenContractAddress);
+ var brandedTokenObject = new brandedTokenContractInteract(oThis.brandedTokenContractAddress, oThis.chainId);
+ const transactionResponse = await brandedTokenObject.transferToAirdropBudgetHolder(oThis.senderAddress,
+ oThis.senderPassphrase,
+ oThis.airdropBudgetHolderAddress,
+ oThis.amount,
+ oThis.gasPrice,
+ oThis.options);
+ if (transactionResponse.isSuccess()){
+ var airdropAllocationProofDetailModel = new airdropAllocationProofDetailKlass();
+ const airdropAllocationProofDetailCreateResult = await airdropAllocationProofDetailModel.createRecord(transactionResponse.data.transaction_hash, oThis.amount, 0);
+ if (airdropAllocationProofDetailCreateResult.isFailure()) {
+ return onResolve(airdropAllocationProofDetailCreateResult);
+ }
+ }
+ return onResolve(transactionResponse);
+ });
+ }
+
+};
+
+module.exports = TransferKlass;
+
diff --git a/services/airdrop_management/user_balance.js b/services/airdrop_management/user_balance.js
new file mode 100644
index 0000000..63cb84a
--- /dev/null
+++ b/services/airdrop_management/user_balance.js
@@ -0,0 +1,185 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for calculating user airdrop balance.
+ *
+ * @module services/airdrop_management/user_balance
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , userAirdropDetailCacheKlass = require(rootPrefix + '/lib/cache_multi_management/user_airdrop_detail')
+ , AirdropModelCacheKlass = require(rootPrefix + '/lib/cache_management/airdrop_model')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of userBalance
+ *
+ * @constructor
+ *
+ * @param {object} params -
+ * @param {number} chain_id - chain Id
+ * @param {string} airdrop_contract_address - airdrop contract address
+ * @param {array} user_addresses - Array of user addressed
+ *
+ * @return {object}
+ *
+ */
+const AirdropUserBalanceKlass = function(params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======user_balance.params=======");
+ logger.debug(params);
+
+ oThis.airdropContractAddress = params.airdrop_contract_address;
+ oThis.chainId = params.chain_id;
+ oThis.userAddresses = params.user_addresses;
+
+ oThis.airdropRecord = null;
+
+};
+
+AirdropUserBalanceKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+
+ const oThis = this;
+
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======userBalance.validateParams.result=======");
+ logger.debug(r);
+ if(r.isFailure()) return r;
+
+ r = await oThis.getUserAirdropBalance();
+ logger.debug("=======userBalance.getUserAirdropBalance.result=======");
+ logger.debug(r);
+ return r;
+ } catch(err) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ub_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {promise}
+ *
+ */
+ validateParams: function(){
+ const oThis = this;
+ return new Promise(async function (onResolve, onReject) {
+
+ if (!basicHelper.isAddressValid(oThis.airdropContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ub_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ub_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ // if address already present
+ const airdropModelCacheObject = new AirdropModelCacheKlass({useObject: true, contractAddress: oThis.airdropContractAddress})
+ , airdropModelCacheResponse = await airdropModelCacheObject.fetch()
+ ;
+ oThis.airdropRecord = airdropModelCacheResponse.data[oThis.airdropContractAddress];
+ if (!oThis.airdropRecord){
+ let errorParams = {
+ internal_error_identifier: 's_am_ub_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_contract_address_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ub_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return onResolve(responseHelper.paramValidationError(errorParams));
+ }
+
+ return onResolve(responseHelper.successWithData({}));
+ });
+
+ },
+
+ /**
+ * Run the register
+ *
+ * @return {promise}
+ *
+ */
+ getUserAirdropBalance: function() {
+ const oThis = this;
+ return new Promise(async function (onResolve, onReject) {
+ try {
+ const userAirdropDetailCacheKlassObject = new userAirdropDetailCacheKlass({
+ chainId: oThis.chainId,
+ airdropId: oThis.airdropRecord.id,
+ userAddresses: oThis.userAddresses
+ });
+ return onResolve(await userAirdropDetailCacheKlassObject.fetch());
+ } catch(err){
+ let errorParams = {
+ internal_error_identifier: 'l_am_ub_getUserAirdropBalance_4',
+ api_error_identifier: 'get_balance_failed',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+ });
+
+ }
+
+};
+
+module.exports = AirdropUserBalanceKlass;
+
diff --git a/services/deploy/airdrop.js b/services/deploy/airdrop.js
new file mode 100644
index 0000000..3238b75
--- /dev/null
+++ b/services/deploy/airdrop.js
@@ -0,0 +1,203 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for deploying airdrop contract.
+ *
+ * @module services/deploy/airdrop
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , DeployerKlass = require(rootPrefix + '/services/deploy/deployer')
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/rpc')
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of airdrop
+ *
+ * @constructor
+ *
+ * @param {object} params -
+ * @param {string} params.branded_token_contract_address - branded token contract address
+ * @param {string} params.base_currency - base currency
+ * @param {string} params.worker_contract_address - worker contract address
+ * @param {string} params.airdrop_budget_holder - airdrop budget holder address
+ * @param {string} params.gas_price - gas price
+ * @param {object} params.options - deployment options e.g. {returnType: 'txReceipt'}
+ *
+ * @return {object}
+ *
+ */
+const DeployAirdropKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======DeployAirdropKlass.params=======");
+ logger.debug(params);
+
+ oThis.contractName = 'airdrop';
+ oThis.brandedTokenContractAddress = params.branded_token_contract_address;
+ oThis.baseCurrency = params.base_currency;
+ oThis.workerContractAddress = params.worker_contract_address;
+ oThis.airdropBudgetHolder = params.airdrop_budget_holder;
+ oThis.gasPrice = params.gas_price;
+ oThis.options = params.options;
+
+ oThis.constructorArgs = [];
+};
+
+DeployAirdropKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======DeployAirdropKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.deploy();
+ logger.debug("=======DeployAirdropKlass.setOps.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_d_a_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_d_a_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.options) {
+ let errorParams = {
+ internal_error_identifier: 's_d_a_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_options'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isAddressValid(oThis.brandedTokenContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_d_a_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['branded_token_address_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isAddressValid(oThis.workerContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_d_a_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_worker_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.baseCurrency) {
+ let errorParams = {
+ internal_error_identifier: 's_d_a_validateParams_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['base_currency_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isAddressValid(oThis.airdropBudgetHolder)) {
+ let errorParams = {
+ internal_error_identifier: 's_d_a_validateParams_6',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['airdrop_budget_holder_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * deploy
+ *
+ * @return {promise}
+ *
+ */
+ deploy: function () {
+ const oThis = this
+ ;
+ oThis.constructorArgs = [
+ oThis.brandedTokenContractAddress,
+ web3Provider.utils.asciiToHex(oThis.baseCurrency),
+ oThis.workerContractAddress,
+ oThis.airdropBudgetHolder
+ ];
+ const DeployerObject = new DeployerKlass({
+ contract_name: oThis.contractName,
+ constructor_args: oThis.constructorArgs,
+ gas_price: oThis.gasPrice,
+ gas_limit: gasLimitGlobalConstant.deployAirdrop(),
+ options: oThis.options
+ });
+ return DeployerObject.perform();
+ }
+
+};
+
+module.exports = DeployAirdropKlass;
\ No newline at end of file
diff --git a/services/deploy/deployer.js b/services/deploy/deployer.js
new file mode 100644
index 0000000..9a51fe7
--- /dev/null
+++ b/services/deploy/deployer.js
@@ -0,0 +1,315 @@
+"use strict";
+
+/**
+ * This is script for deploying any contract.
+ *
+ * @module services/deploy/deployer
+ */
+
+const uuid = require('uuid')
+ , rootPrefix = '../..'
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
+ , coreConstants = require(rootPrefix + '/config/core_constants')
+ , coreAddresses = require(rootPrefix + '/config/core_addresses')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , deployerName = 'deployer'
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of deployer
+ *
+ * @params {object} params -
+ * @param {string} params.contract_name - name of contract
+ * @param {object} params.constructor_args - contract deployment constructor arguments
+ * @param {string} params.gas_price - gas price
+ * @param {string} params.gas_limit - gas limit
+ * @param {object} params.options - deployment options
+ *
+ * @constructor
+ *
+ */
+const DeployerKlass = function(params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("\n=========deployer params=========");
+ logger.debug(params);
+
+ oThis.contractName = params.contract_name;
+ oThis.constructorArgs = params.constructor_args;
+ oThis.gasPrice = params.gas_price;
+ oThis.gasLimit = params.gas_limit || gasLimitGlobalConstant.default();
+ oThis.options = params.options;
+};
+
+DeployerKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise} - returns a promise which resolves to an object of kind Result
+ *
+ */
+ perform: async function () {
+
+ const oThis = this;
+
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("\n=========Deployer.validateParams.result=========");
+ logger.debug(r);
+ if(r.isFailure()) return r;
+
+ r = oThis.deploy();
+ logger.debug("\n=========Deployer.deploy.result=========");
+ logger.debug(r);
+ return r;
+ } catch(err) {
+ let errorParams = {
+ internal_error_identifier: 's_am_ub_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validate deploy parameters
+ *
+ * @return {result} - returns object of kind Result
+ *
+ */
+ validateParams: function() {
+
+ const oThis = this;
+
+ if (!oThis.contractName) {
+ logger.error("Error: Contract name is mandatory");
+ let errorParams = {
+ internal_error_identifier: 'l_d_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['contract_name_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 'l_d_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ logger.error("%Error - Gas price is mandatory");
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasLimit) {
+ let errorParams = {
+ internal_error_identifier: 'l_d_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_limit_invalid'],
+ debug_options: {}
+ };
+ logger.error("%Error - Gas limit is mandatory");
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ const deployerAddress = coreAddresses.getAddressForUser(deployerName);
+ if (!deployerAddress) {
+ let errorParams = {
+ internal_error_identifier: 'l_d_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['deployer_invalid'],
+ debug_options: {}
+ };
+ logger.error("%Error - Deployer address is invalid");
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ const deployerAddrPassphrase = coreAddresses.getPassphraseForUser(deployerName);
+ if (!deployerAddrPassphrase) {
+ let errorParams = {
+ internal_error_identifier: 'l_d_5',
+ api_error_identifier: 'invalid_deployer_passphrase',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ logger.error("Error: Deployer passphrase is invalid");
+ return responseHelper.error(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+
+ },
+
+ /**
+ * Deploy contract
+ *
+ * @return {promise} - returns a promise which resolves to an object of kind Result
+ *
+ */
+ deploy: function() {
+
+ const oThis = this;
+
+ return new Promise(function (onResolve, onReject) {
+
+ logger.debug("Contract name: " + oThis.contractName);
+ logger.debug("Gas price: " + oThis.gasPrice);
+ logger.debug("Constructor arguments: " + oThis.constructorArgs);
+
+ const txUUID = uuid.v4();
+ const returnType = basicHelper.getReturnType(oThis.options.returnType);
+
+ const asyncPerform = function () {
+
+ const deployerAddress = coreAddresses.getAddressForUser(deployerName);
+ const deployerAddrPassphrase = coreAddresses.getPassphraseForUser(deployerName);
+
+ const contractAbi = coreAddresses.getAbiForContract(oThis.contractName);
+ const contractBin = coreAddresses.getBinForContract(oThis.contractName);
+
+ const txParams = {
+ from: deployerAddress,
+ data: (web3Provider.utils.isHexStrict(contractBin) ? "" : "0x") + contractBin,
+ gasPrice: oThis.gasPrice,
+ gas: oThis.gasLimit
+ };
+
+ if (oThis.constructorArgs) {
+ txParams.arguments = oThis.constructorArgs;
+ }
+
+ var contract = new web3Provider.eth.Contract(
+ contractAbi,
+ null,
+ txParams
+ );
+
+ // this is needed since the contract object
+ //contract.setProvider(web3Provider.currentProvider);
+
+ // Unlock account
+ web3Provider.eth.personal.unlockAccount(
+ deployerAddress,
+ deployerAddrPassphrase)
+ .then(function() {
+ const encodeABI = contract.deploy(txParams).encodeABI();
+ txParams.data = encodeABI;
+
+ web3Provider.eth.sendTransaction(txParams)
+ .on('transactionHash', function(transactionHash) {
+ logger.debug(`Transaction hash received for ${txUUID} :${transactionHash}`);
+ if (basicHelper.isReturnTypeTxHash(returnType)) {
+ return onResolve(
+ responseHelper.successWithData(
+ {
+ transaction_uuid: txUUID,
+ transaction_hash: transactionHash,
+ transaction_receipt: {}
+ }));
+ }
+ })
+ .on('receipt', function(receipt) {
+
+ const contractAddress = receipt.contractAddress;
+ web3Provider.eth.getCode(contractAddress).then(function(code) {
+ if (code.length <= 2) {
+ if (basicHelper.isReturnTypeTxReceipt(returnType)) {
+ let errorParams = {
+ internal_error_identifier: 'l_d_6',
+ api_error_identifier: 'contract_deploy_failed',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+ } else if (basicHelper.isReturnTypeTxReceipt(returnType)) {
+ logger.debug(`Contract deployment success: ${txUUID}`);
+ return onResolve(
+ responseHelper.successWithData(
+ {
+ transaction_uuid: txUUID,
+ transaction_hash: receipt.transactionHash,
+ transaction_receipt: receipt
+ }));
+ }
+ })
+ .catch(function(reason) {
+ logger.error("%Error - Contract deployment failed");
+ if (basicHelper.isReturnTypeTxReceipt(returnType)) {
+ let errorParams = {
+ internal_error_identifier: 'l_d_7',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+ });
+ })
+ .catch(function(reason) {
+ if (basicHelper.isReturnTypeTxReceipt(returnType)) {
+ logger.error("%Error - Contract deployment failed");
+ let errorParams = {
+ internal_error_identifier: 'l_d_8',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ return onResolve(responseHelper.error(errorParams));
+ }
+ });
+ })
+ .catch(function(reason) {
+ let errorParams = {
+ internal_error_identifier: 'l_d_5',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: {}
+ };
+ logger.error('%Error - Transaction failed')
+ return onResolve(responseHelper.error(errorParams));
+ });
+
+ };
+ if (basicHelper.isReturnTypeUUID(returnType)) {
+ asyncPerform();
+ return onResolve(
+ responseHelper.successWithData(
+ {
+ transaction_uuid: txUUID,
+ transaction_hash: "",
+ transaction_receipt: {}
+ }));
+ } else {
+ return asyncPerform();
+ }
+
+ });
+ }
+
+};
+
+module.exports = DeployerKlass;
+
diff --git a/services/deploy/workers.js b/services/deploy/workers.js
new file mode 100644
index 0000000..09b7941
--- /dev/null
+++ b/services/deploy/workers.js
@@ -0,0 +1,143 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for deploying worker contract.
+ *
+ * @module services/deploy/worker
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , DeployerKlass = require(rootPrefix + '/services/deploy/deployer')
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of worker
+ *
+ * @param {object} params -
+ * @param {string} params.gas_price - gas price
+ * @param {number} params.chain_id - chain id
+ * @param {object} params.options - deployment options e.g. {returnType: 'txReceipt'}
+ *
+ * @constructor
+ *
+ */
+const DeployWorkerKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======DeployWorkerKlass.params=======");
+ // Don't log passphrase
+ logger.debug(params);
+
+ oThis.contractName = 'workers';
+ oThis.gasPrice = params.gas_price;
+ oThis.options = params.options;
+
+ oThis.constructorArgs = [];
+};
+
+DeployWorkerKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======DeployWorkerKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.deploy();
+ logger.debug("=======DeployWorkerKlass.setOps.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_d_w_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_d_w_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.options) {
+ let errorParams = {
+ internal_error_identifier: 's_d_w_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_options'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * deploy
+ *
+ * @return {promise}
+ *
+ */
+ deploy: function () {
+ const oThis = this
+ ;
+ const DeployerObject = new DeployerKlass({
+ contract_name: oThis.contractName,
+ constructor_args: oThis.constructorArgs,
+ gas_price: oThis.gasPrice,
+ gas_limit: gasLimitGlobalConstant.deployWorker(),
+ options: oThis.options
+ });
+ return DeployerObject.perform();
+ }
+
+};
+
+module.exports = DeployWorkerKlass;
\ No newline at end of file
diff --git a/services/manifest.js b/services/manifest.js
new file mode 100644
index 0000000..2a5dcd8
--- /dev/null
+++ b/services/manifest.js
@@ -0,0 +1,89 @@
+"use strict";
+
+/**
+ * Service manifest
+ *
+ * @module services/manifest
+ */
+
+const rootPrefix = ".."
+
+ , deployWorkers = require(rootPrefix + '/services/deploy/workers')
+ , deployAirdrop = require(rootPrefix + '/services/deploy/airdrop')
+
+ , register = require(rootPrefix + '/services/airdrop_management/register')
+ , setAcceptedMargin = require(rootPrefix + '/services/airdrop_management/set_accepted_margin')
+ , setPriceOracle = require(rootPrefix + '/services/airdrop_management/set_price_oracle')
+ , transfer = require(rootPrefix + '/services/airdrop_management/transfer')
+ , approve = require(rootPrefix + '/services/airdrop_management/approve')
+ , batchAllocator = require(rootPrefix + '/services/airdrop_management/batch_allocator')
+ , userBalance = require(rootPrefix + '/services/airdrop_management/user_balance')
+ , pay = require(rootPrefix + '/services/airdrop_management/pay')
+ , postAirdropPay = require(rootPrefix + '/services/airdrop_management/post_airdrop_pay')
+
+ , setWorker = require(rootPrefix + '/services/workers/set_worker')
+ , isWorker = require(rootPrefix + '/services/workers/is_worker')
+
+ , getOps = require(rootPrefix + "/services/ops_managed/get_ops")
+ , setOps = require(rootPrefix + "/services/ops_managed/set_ops")
+;
+
+/**
+ * Service Manifest Constructor
+ *
+ * @constructor
+ */
+const ServiceManifestKlass = function() {};
+
+ServiceManifestKlass.prototype = {
+
+ /**
+ * deploy any contract
+ *
+ * @constant {object}
+ */
+ deploy: {
+ workers: deployWorkers,
+ airdrop: deployAirdrop
+ },
+
+ /**
+ * Ops Managed related services
+ *
+ * @constant {object}
+ */
+ opsManaged: {
+ getOps: getOps,
+ setOps: setOps
+ },
+
+ /**
+ * workers
+ *
+ * @constant {object}
+ */
+ workers: {
+ setWorker: setWorker,
+ isWorker: isWorker
+ },
+
+ /**
+ * airdrop Manager
+ *
+ * @constant {object}
+ */
+ airdropManager: {
+ registerAirdrop: register,
+ setPriceOracle: setPriceOracle,
+ setAcceptedMargin: setAcceptedMargin,
+ transfer: transfer,
+ approve: approve,
+ batchAllocator: batchAllocator,
+ userBalance: userBalance,
+ pay: pay,
+ postAirdropPay: postAirdropPay
+ },
+
+};
+
+module.exports = new ServiceManifestKlass();
\ No newline at end of file
diff --git a/services/ops_managed/get_ops.js b/services/ops_managed/get_ops.js
new file mode 100644
index 0000000..1a6cae5
--- /dev/null
+++ b/services/ops_managed/get_ops.js
@@ -0,0 +1,152 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing getOps.
+ *
+ * @module services/ops_managed/get_ops
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , OpsManagedContractInteractKlass = require(rootPrefix + '/lib/contract_interact/ops_managed_contract')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of get_ops
+ *
+ * @constructor
+ *
+ * @param {object} params -
+ * @param {string} params.contract_address - contract address
+ * @param {string} params.gas_price - gas price
+ * @param {object} params.chain_id - chain id
+ *
+ * @return {object}
+ *
+ */
+const GetOpsKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======GetOpsKlass.params=======");
+ logger.debug(params);
+
+ oThis.contractAddress = params.contract_address;
+ oThis.chainId = params.chain_id;
+ oThis.gasPrice = params.gas_price;
+
+};
+
+GetOpsKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======GetOpsKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.getOps();
+ logger.debug("=======GetOpsKlass.getOps.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {promise}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+ if (!basicHelper.isAddressValid(oThis.contractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_contract_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * get Ops
+ *
+ * @return {promise}
+ *
+ */
+ getOps: function () {
+ const oThis = this
+ ;
+
+ const OpsManagedContractInteractObject = new OpsManagedContractInteractKlass(
+ oThis.contractAddress,
+ oThis.gasPrice,
+ oThis.chainId
+ );
+ return OpsManagedContractInteractObject.getOpsAddress();
+ }
+
+};
+
+module.exports = GetOpsKlass;
\ No newline at end of file
diff --git a/services/ops_managed/set_ops.js b/services/ops_managed/set_ops.js
new file mode 100644
index 0000000..d444d74
--- /dev/null
+++ b/services/ops_managed/set_ops.js
@@ -0,0 +1,166 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing setOps.
+ *
+ * @module services/ops_managed/set_ops
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , OpsManagedContractInteractKlass = require(rootPrefix + '/lib/contract_interact/ops_managed_contract')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of set_ops
+ *
+ * @constructor
+ *
+ * @params {object} params -
+ * @param {string} params.contract_address - contract address
+ * @param {string} params.gas_price - gas price
+ * @param {number} params.chain_id - chain id
+ * @param {string} params.deployer_address - deployer address
+ * @param {string} params.deployer_passphrase - deployer passphrase
+ * @param {string} params.ops_address - ops addresses
+ * @param {object} params.options - options
+ *
+ * @return {object}
+ *
+ */
+const SetOpsKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======GetOpsKlass.params=======");
+ // Don't log passphrase
+ logger.debug(params.contract_address, params.gas_price, params.chain_id, params.deployer_address, params.ops_address, params.options);
+
+ oThis.contractAddress = params.contract_address;
+ oThis.gasPrice = params.gas_price;
+ oThis.chainId = params.chain_id;
+ oThis.deployerAddress = params.deployer_address;
+ oThis.deployerPassphrase = params.deployer_passphrase;
+ oThis.opsAddress = params.ops_address;
+ oThis.options = params.options;
+
+};
+
+SetOpsKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======SetOpsKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.setOps();
+ logger.debug("=======SetOpsKlass.setOps.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+ if (!basicHelper.isAddressValid(oThis.contractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_contract_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_om_go_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * set Ops
+ *
+ * @return {promise}
+ *
+ */
+ setOps: function () {
+ const oThis = this
+ ;
+
+ const OpsManagedContractInteractObject = new OpsManagedContractInteractKlass(
+ oThis.contractAddress,
+ oThis.gasPrice,
+ oThis.chainId
+ );
+ return OpsManagedContractInteractObject.setOpsAddress(
+ oThis.deployerAddress,
+ oThis.deployerPassphrase,
+ oThis.opsAddress,
+ oThis.options
+ );
+ }
+
+};
+
+module.exports = SetOpsKlass;
\ No newline at end of file
diff --git a/services/workers/is_worker.js b/services/workers/is_worker.js
new file mode 100644
index 0000000..100e8a0
--- /dev/null
+++ b/services/workers/is_worker.js
@@ -0,0 +1,139 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing worker is_worker.
+ *
+ * @module services/workers/is_worker
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , WorkersContractInteractKlass = require(rootPrefix + '/lib/contract_interact/workers')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of register
+ *
+ * @constructor
+ *
+ * @params {object} params -
+ * @param {string} params.workers_contract_address - contract address of workers
+ * @param {string} params.worker_address - worker address
+ * @param {object} params.chain_id - chain id
+ *
+ * @return {Object}
+ *
+ */
+const IsWorkerKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======IsWorkerKlass.params=======");
+ logger.debug(params);
+
+ oThis.workersContractAddress = params.workers_contract_address;
+ oThis.workerAddress = params.worker_address;
+ oThis.chainId = params.chain_id;
+
+};
+
+IsWorkerKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======IsWorkerKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.isWorker();
+ logger.debug("=======IsWorkerKlass.setWorker.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_w_iw_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this
+ ;
+ if (!basicHelper.isAddressValid(oThis.workerAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_w_iw_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_worker_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_w_iw_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * is Worker
+ *
+ * @return {promise}
+ *
+ */
+ isWorker: function () {
+ const oThis = this
+ ;
+ const workersContractInteractObject = new WorkersContractInteractKlass(
+ oThis.workersContractAddress,
+ oThis.chainId
+ );
+ return workersContractInteractObject.isWorker(oThis.workerAddress);
+ }
+
+};
+
+module.exports = IsWorkerKlass;
\ No newline at end of file
diff --git a/services/workers/set_worker.js b/services/workers/set_worker.js
new file mode 100644
index 0000000..49afd03
--- /dev/null
+++ b/services/workers/set_worker.js
@@ -0,0 +1,221 @@
+"use strict";
+
+/**
+ *
+ * This class would be used for executing airdrop register.
+ *
+ * @module services/workers/set_worker
+ *
+ */
+
+const rootPrefix = '../..'
+ , responseHelper = require(rootPrefix + '/lib/formatter/response')
+ , basicHelper = require(rootPrefix + '/helpers/basic_helper')
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , BigNumber = require('bignumber.js')
+ , WorkersContractInteractKlass = require(rootPrefix + '/lib/contract_interact/workers')
+ , paramErrorConfig = require(rootPrefix + '/config/param_error_config')
+ , apiErrorConfig = require(rootPrefix + '/config/api_error_config')
+;
+
+const errorConfig = {
+ param_error_config: paramErrorConfig,
+ api_error_config: apiErrorConfig
+};
+
+/**
+ * Constructor to create object of register
+ *
+ * @constructor
+ *
+ * @param {object} params -
+ * @param {string} params.workers_contract_address - contract address of workers
+ * @param {string} params.sender_address - address of sender
+ * @param {string} params.sender_passphrase - passphrase of sender
+ * @param {string} params.worker_address - worker address
+ * @param {number} params.deactivation_height - block number till which the worker is valid
+ * @param {bignumber} params.gas_price - gas price
+ * @param {number} params.chain_id - chain id
+ * @param {object} params.options - for params like returnType, tag.
+ *
+ * @return {object}
+ *
+ */
+const SetWorkerKlass = function (params) {
+ const oThis = this;
+ params = params || {};
+ logger.debug("=======SetWorkerKlass.params=======");
+ // Don't log passphrase
+ logger.debug(params.workers_contract_address, params.sender_address, params.worker_address, params.deactivation_height, params.gas_price, params.chain_id, params.options);
+
+ oThis.workersContractAddress = params.workers_contract_address;
+ oThis.senderAddress = params.sender_address;
+ oThis.senderPassphrase = params.sender_passphrase;
+ oThis.workerAddress = params.worker_address;
+ oThis.deactivationHeight = params.deactivation_height;
+ oThis.gasPrice = params.gas_price;
+ oThis.chainId = params.chain_id;
+ oThis.options = params.options
+
+};
+
+SetWorkerKlass.prototype = {
+
+ /**
+ * Perform method
+ *
+ * @return {promise}
+ *
+ */
+ perform: async function () {
+ const oThis = this
+ ;
+
+ try {
+ var r = null;
+
+ r = await oThis.validateParams();
+ logger.debug("=======SetWorkerKlass.validateParams.result=======");
+ logger.debug(r);
+ if (r.isFailure()) return r;
+
+ r = await oThis.setWorker();
+ logger.debug("=======SetWorkerKlass.setWorker.result=======");
+ logger.debug(r);
+
+ return r;
+
+ } catch (err) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_perform_1',
+ api_error_identifier: 'unhandled_api_error',
+ error_config: errorConfig,
+ debug_options: { err: err }
+ };
+ return responseHelper.error(errorParams);
+ }
+
+ },
+
+ /**
+ * Validation of params
+ *
+ * @return {result}
+ *
+ */
+ validateParams: function () {
+ const oThis = this;
+ if (!basicHelper.isAddressValid(oThis.workersContractAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_1',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_worker_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_2',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(oThis.senderAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_3',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_sender_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!basicHelper.isAddressValid(oThis.workerAddress)) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_4',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['invalid_worker_address'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ if (!oThis.deactivationHeight) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_5',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['deactivation_height_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+ const deactivationHeight = new BigNumber(oThis.deactivationHeight);
+ if (deactivationHeight.isNaN() || deactivationHeight.lt(0) || !deactivationHeight.isInteger()) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_6',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['deactivation_height_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!oThis.gasPrice) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_7',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['gas_price_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ if (!basicHelper.isValidChainId(oThis.chainId)) {
+ let errorParams = {
+ internal_error_identifier: 's_w_sw_validateParams_8',
+ api_error_identifier: 'invalid_api_params',
+ error_config: errorConfig,
+ params_error_identifiers: ['chain_id_invalid'],
+ debug_options: {}
+ };
+ return responseHelper.paramValidationError(errorParams);
+ }
+
+ return responseHelper.successWithData({});
+ },
+
+ /**
+ * Set Worker
+ *
+ * @return {promise}
+ *
+ */
+ setWorker: function () {
+ const oThis = this
+ ;
+
+ const workersContractInteractObject = new WorkersContractInteractKlass(
+ oThis.workersContractAddress,
+ oThis.chainId
+ );
+ return workersContractInteractObject.setWorker(
+ oThis.senderAddress,
+ oThis.senderPassphrase,
+ oThis.workerAddress,
+ oThis.deactivationHeight.toString(10),
+ oThis.gasPrice,
+ oThis.options
+ );
+ }
+
+};
+
+module.exports = SetWorkerKlass;
\ No newline at end of file
diff --git a/test/contracts/airdrop/airdrop_utils.js b/test/contracts/airdrop/airdrop_utils.js
index 2d4d1ea..d8bf3cb 100644
--- a/test/contracts/airdrop/airdrop_utils.js
+++ b/test/contracts/airdrop/airdrop_utils.js
@@ -24,8 +24,8 @@ const Utils = require('../../lib/utils.js'),
Workers = artifacts.require('./Workers.sol'),
Airdrop = artifacts.require('./Airdrop.sol'),
EIP20TokenMock = artifacts.require('./EIP20TokenMock.sol'),
- PriceOracle = artifacts.require('./PriceOracleMock.sol')
- ;
+ PriceOracle = artifacts.require('./PriceOracleMock.sol'),
+ web3 = require('../../lib/web3') ;
const ost = 'OST',
abc = 'ABC'
@@ -59,8 +59,8 @@ module.exports.deployAirdrop = async (artifacts, accounts) => {
assert.ok(await workers.setOpsAddress(opsAddress));
assert.ok(await airdrop.setOpsAddress(opsAddress));
-
- assert.ok(await workers.setWorker(worker, web3.eth.blockNumber + 1000, { from: opsAddress }));
+ let blockNumber = await web3.eth.getBlockNumber();
+ assert.ok(await workers.setWorker(worker, blockNumber + 1000, { from: opsAddress }));
assert.ok(await airdrop.setPriceOracle(abc, abcPriceOracle.address, { from: opsAddress }));
return {
diff --git a/test/contracts/workers/remove.js b/test/contracts/workers/remove.js
index 234f17e..282c3c3 100644
--- a/test/contracts/workers/remove.js
+++ b/test/contracts/workers/remove.js
@@ -19,9 +19,10 @@
//
// ----------------------------------------------------------------------------
-const workersUtils = require('./workers_utils.js'),
- Workers = artifacts.require('./Workers.sol')
- ;
+const workersUtils = require('./workers_utils.js'),
+ Workers = artifacts.require('./Workers.sol'),
+ web3 = require('../../lib/web3') ;
+
///
/// Test stories
@@ -31,13 +32,13 @@ const workersUtils = require('./workers_utils.js'),
/// successfully removes when sender is adminAddress
module.exports.perform = (accounts) => {
- const opsAddress = accounts[1],
- adminAddress = accounts[2]
- ;
+ const opsAddress = accounts[1],
+ adminAddress = accounts[2]
+ ;
- var workers = null,
- response = null
- ;
+ var workers = null,
+ response = null
+ ;
beforeEach(async () => {
@@ -49,34 +50,35 @@ module.exports.perform = (accounts) => {
it('fails to remove when sender is neither opsAddress nor adminAddress', async () => {
- await workersUtils.utils.expectThrow(workers.remove.call({ from: accounts[3] }));
+ await workersUtils.utils.expectThrow(workers.remove.call({from: accounts[3]}));
});
it('successfully removes when sender is opsAddress', async () => {
// call remove
- assert.ok(await workers.remove.call({ from: opsAddress }));
- response = await workers.remove({ from: opsAddress });
+ assert.ok(await workers.remove.call({from: opsAddress}));
+ response = await workers.remove({from: opsAddress});
workersUtils.utils.logResponse(response, 'Workers.remove (ops)');
// check if contract is removed
- assert.equal(web3.eth.getCode(workers.address),0x0);
+ let code = await web3.eth.getCode(workers.address);
+ assert.equal(code, 0x0);
});
it('successfully removes when sender is adminAddress', async () => {
// call remove from admin address
- assert.ok(await workers.remove.call({ from: adminAddress }));
- response = await workers.remove({ from: adminAddress });
+ assert.ok(await workers.remove.call({from: adminAddress}));
+ response = await workers.remove({from: adminAddress});
workersUtils.utils.logResponse(response, 'Workers.remove (admin)');
// check if contract is removed
- assert.equal(web3.eth.getCode(workers.address),0x0);
+ let code = await web3.eth.getCode(workers.address);
+ assert.equal(code, 0x0);
});
-
}
diff --git a/test/contracts/workers/remove_worker.js b/test/contracts/workers/remove_worker.js
index bd79f9a..aabfc4d 100644
--- a/test/contracts/workers/remove_worker.js
+++ b/test/contracts/workers/remove_worker.js
@@ -19,9 +19,9 @@
//
// ----------------------------------------------------------------------------
-const workersUtils = require('./workers_utils.js'),
- Workers = artifacts.require('./Workers.sol')
- ;
+const workersUtils = require('./workers_utils.js'),
+ Workers = artifacts.require('./Workers.sol'),
+ web3 = require('../../lib/web3') ;
///
/// Test stories
@@ -31,44 +31,45 @@ const workersUtils = require('./workers_utils.js'),
/// pass to remove worker
module.exports.perform = (accounts) => {
- const opsAddress = accounts[1],
- worker1Address = accounts[2],
- worker2Address = accounts[3],
- worker3Address = accounts[4],
- height1 = new workersUtils.bigNumber(500),
- height2 = new workersUtils.bigNumber(1000)
- ;
-
- var workers = null,
- deactivationHeight = null
- ;
+ const opsAddress = accounts[1],
+ worker1Address = accounts[2],
+ worker2Address = accounts[3],
+ worker3Address = accounts[4],
+ height1 = new workersUtils.bigNumber(500),
+ height2 = new workersUtils.bigNumber(1000)
+ ;
+
+ var workers = null,
+ deactivationHeight = null
+ ;
before(async () => {
workers = await Workers.new();
assert.ok(await workers.setOpsAddress(opsAddress));
// set worker 1
- deactivationHeight = web3.eth.blockNumber + height1.toNumber();
- await workers.setWorker(worker1Address, deactivationHeight, { from: opsAddress });
-
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + height1.toNumber();
+ await workers.setWorker(worker1Address, deactivationHeight, {from: opsAddress});
+ blockNumber = await web3.eth.getBlockNumber();
// set worker 2
- deactivationHeight = web3.eth.blockNumber + height2.toNumber();
- await workers.setWorker(worker2Address, deactivationHeight, { from: opsAddress });
+ deactivationHeight = blockNumber + height2.toNumber();
+ await workers.setWorker(worker2Address, deactivationHeight, {from: opsAddress});
});
it('fails to remove worker if sender is not opsAddress', async () => {
- await workersUtils.utils.expectThrow(workers.removeWorker.call(worker1Address, { from: accounts[5] }));
+ await workersUtils.utils.expectThrow(workers.removeWorker.call(worker1Address, {from: accounts[5]}));
});
it('fails to remove worker if worker was not set', async () => {
- assert.equal(await workers.removeWorker.call(worker3Address, { from: opsAddress }), false);
- response = await workers.removeWorker(worker3Address, { from: opsAddress });
+ assert.equal(await workers.removeWorker.call(worker3Address, {from: opsAddress}), false);
+ response = await workers.removeWorker(worker3Address, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker3Address), false);
workersUtils.checkWorkerRemovedEvent(response.logs[0], worker3Address, false);
workersUtils.utils.logResponse(response, 'Workers.removeWorker (never set)');
@@ -78,20 +79,20 @@ module.exports.perform = (accounts) => {
it('pass to remove worker', async () => {
- assert.equal(await workers.removeWorker.call(worker1Address, { from: opsAddress }), true);
- response = await workers.removeWorker(worker1Address, { from: opsAddress });
+ assert.equal(await workers.removeWorker.call(worker1Address, {from: opsAddress}), true);
+ response = await workers.removeWorker(worker1Address, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker1Address), false);
workersUtils.checkWorkerRemovedEvent(response.logs[0], worker1Address, true);
workersUtils.utils.logResponse(response, 'Workers.removeWorker (w1)');
- assert.equal(await workers.removeWorker.call(worker2Address, { from: opsAddress }), true);
- response = await workers.removeWorker(worker2Address, { from: opsAddress });
+ assert.equal(await workers.removeWorker.call(worker2Address, {from: opsAddress}), true);
+ response = await workers.removeWorker(worker2Address, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker2Address), false);
workersUtils.checkWorkerRemovedEvent(response.logs[0], worker2Address, true);
workersUtils.utils.logResponse(response, 'Workers.removeWorker (w2)');
- assert.equal(await workers.removeWorker.call(worker2Address, { from: opsAddress }), false);
- response = await workers.removeWorker(worker2Address, { from: opsAddress });
+ assert.equal(await workers.removeWorker.call(worker2Address, {from: opsAddress}), false);
+ response = await workers.removeWorker(worker2Address, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker2Address), false);
workersUtils.checkWorkerRemovedEvent(response.logs[0], worker2Address, false);
workersUtils.utils.logResponse(response, 'Workers.removeWorker (w1 again)');
diff --git a/test/contracts/workers/set_is_worker.js b/test/contracts/workers/set_is_worker.js
index bb2c0aa..2403535 100644
--- a/test/contracts/workers/set_is_worker.js
+++ b/test/contracts/workers/set_is_worker.js
@@ -19,9 +19,9 @@
//
// ----------------------------------------------------------------------------
-const workersUtils = require('./workers_utils.js'),
- Workers = artifacts.require('./Workers.sol')
- ;
+const workersUtils = require('./workers_utils.js'),
+ Workers = artifacts.require('./Workers.sol'),
+ web3 = require('../../lib/web3') ;
///
/// Test stories
@@ -37,17 +37,17 @@ const workersUtils = require('./workers_utils.js'),
/// validate expiry
module.exports.perform = (accounts) => {
- const opsAddress = accounts[1],
- worker1Address = accounts[2],
- worker2Address = accounts[3],
- worker3Address = accounts[4],
- height1 = new workersUtils.bigNumber(500),
- height2 = new workersUtils.bigNumber(1000)
- ;
-
- var workers = null,
- deactivationHeight = null
- ;
+ const opsAddress = accounts[1],
+ worker1Address = accounts[2],
+ worker2Address = accounts[3],
+ worker3Address = accounts[4],
+ height1 = new workersUtils.bigNumber(500),
+ height2 = new workersUtils.bigNumber(1000)
+ ;
+
+ var workers = null,
+ deactivationHeight = null
+ ;
before(async () => {
@@ -59,19 +59,20 @@ module.exports.perform = (accounts) => {
it('fails to set worker if worker address is 0', async () => {
- await workersUtils.utils.expectThrow(workers.setWorker.call(0, height1, { from: opsAddress }));
+ await workersUtils.utils.expectThrow(workers.setWorker.call(0, height1, {from: opsAddress}));
});
it('fails to set worker if deactivation height is equal to current block number', async () => {
- deactivationHeight = web3.eth.blockNumber;
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber;
// calling this will not throw any execption
- assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, { from: opsAddress }));
+ assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, {from: opsAddress}));
// Executing this will throw exception
- await workersUtils.utils.expectThrow(workers.setWorker(worker1Address, web3.eth.blockNumber, { from: opsAddress }));
+ await workersUtils.utils.expectThrow(workers.setWorker(worker1Address, blockNumber, {from: opsAddress}));
// Verify if the worker1 is not active
assert.equal(await workers.isWorker.call(worker1Address), false);
@@ -81,8 +82,9 @@ module.exports.perform = (accounts) => {
it('fails to set worker if deactivation height is less than current block number', async () => {
- await workersUtils.utils.expectThrow(workers.setWorker.call(worker1Address, web3.eth.blockNumber-1, { from: opsAddress }));
- await workersUtils.utils.expectThrow(workers.setWorker(worker1Address, web3.eth.blockNumber-1, { from: opsAddress }));
+ let blockNumber = await web3.eth.getBlockNumber();
+ await workersUtils.utils.expectThrow(workers.setWorker.call(worker1Address, blockNumber - 1, {from: opsAddress}));
+ await workersUtils.utils.expectThrow(workers.setWorker(worker1Address, blockNumber - 1, {from: opsAddress}));
// Verify if the worker1 is not active
assert.equal(await workers.isWorker.call(worker1Address), false);
@@ -91,9 +93,10 @@ module.exports.perform = (accounts) => {
it('pass to set worker if deactivation height is equal to current block number + 1', async () => {
- deactivationHeight = web3.eth.blockNumber + 1;
- assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, { from: opsAddress }));
- response = await workers.setWorker(worker1Address, deactivationHeight, { from: opsAddress });
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + 1;
+ assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, {from: opsAddress}));
+ response = await workers.setWorker(worker1Address, deactivationHeight, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker1Address), true);
workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, 0);
workersUtils.utils.logResponse(response, 'Workers.setWorker: w1, blockNumber + 1');
@@ -103,26 +106,28 @@ module.exports.perform = (accounts) => {
it('fails to set worker if sender is not opsAddress', async () => {
- deactivationHeight = web3.eth.blockNumber + height1.toNumber();
- await workersUtils.utils.expectThrow(workers.setWorker.call(worker1Address, deactivationHeight, { from: accounts[5] }));
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + height1.toNumber();
+ await workersUtils.utils.expectThrow(workers.setWorker.call(worker1Address, deactivationHeight, {from: accounts[5]}));
});
it('pass to set worker if worker is not already set', async () => {
- deactivationHeight = web3.eth.blockNumber + height1.toNumber();
- assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, { from: opsAddress }));
- response = await workers.setWorker(worker1Address, deactivationHeight, { from: opsAddress });
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + height1.toNumber();
+ assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, {from: opsAddress}));
+ response = await workers.setWorker(worker1Address, deactivationHeight, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker1Address), true);
- workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height1.toNumber()-1);
+ workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height1.toNumber() - 1);
workersUtils.utils.logResponse(response, 'Workers.setWorker: w1, ' + deactivationHeight);
-
- deactivationHeight = web3.eth.blockNumber + height2.toNumber();
- assert.ok(await workers.setWorker.call(worker2Address, deactivationHeight, { from: opsAddress }));
- response = await workers.setWorker(worker2Address, deactivationHeight, { from: opsAddress });
+ blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + height2.toNumber();
+ assert.ok(await workers.setWorker.call(worker2Address, deactivationHeight, {from: opsAddress}));
+ response = await workers.setWorker(worker2Address, deactivationHeight, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker2Address), true);
- workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height2.toNumber()-1);
+ workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height2.toNumber() - 1);
workersUtils.utils.logResponse(response, 'Workers.setWorker: w2, ' + deactivationHeight);
});
@@ -130,11 +135,12 @@ module.exports.perform = (accounts) => {
it('pass to set worker if worker was already set', async () => {
- deactivationHeight = web3.eth.blockNumber + height2.toNumber();
- assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, { from: opsAddress }));
- response = await workers.setWorker(worker1Address, deactivationHeight, { from: opsAddress });
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + height2.toNumber();
+ assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, {from: opsAddress}));
+ response = await workers.setWorker(worker1Address, deactivationHeight, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker1Address), true);
- workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height2.toNumber()-1);
+ workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height2.toNumber() - 1);
workersUtils.utils.logResponse(response, 'Workers.setWorker: w1, ' + deactivationHeight);
});
@@ -143,11 +149,12 @@ module.exports.perform = (accounts) => {
it('pass to set worker at lower deactivation height if worker was already set to a higher deactivation height', async () => {
// update worker with lower deactivation height
- deactivationHeight = web3.eth.blockNumber + height1.toNumber();
- assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, { from: opsAddress }));
- response = await workers.setWorker(worker1Address, deactivationHeight, { from: opsAddress });
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + height1.toNumber();
+ assert.ok(await workers.setWorker.call(worker1Address, deactivationHeight, {from: opsAddress}));
+ response = await workers.setWorker(worker1Address, deactivationHeight, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker1Address), true);
- workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height1.toNumber()-1);
+ workersUtils.checkWorkerSetEvent(response.logs[0], deactivationHeight, height1.toNumber() - 1);
workersUtils.utils.logResponse(response, 'Workers.setWorker: w1, ' + deactivationHeight);
});
@@ -157,17 +164,18 @@ module.exports.perform = (accounts) => {
// set a worker with expiration height of 30
var height = 30;
- deactivationHeight = web3.eth.blockNumber + height;
- assert.ok(await workers.setWorker.call(worker3Address, deactivationHeight, { from: opsAddress }));
- response = await workers.setWorker(worker3Address, deactivationHeight, { from: opsAddress });
+ let blockNumber = await web3.eth.getBlockNumber();
+ deactivationHeight = blockNumber + height;
+ assert.ok(await workers.setWorker.call(worker3Address, deactivationHeight, {from: opsAddress}));
+ response = await workers.setWorker(worker3Address, deactivationHeight, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker3Address), true);
- for (var i = height-1; i >= 0; i--) {
- // Perform random transaction to increase block number. In this case using removeWorker for worker1Address
- response = await workers.removeWorker(worker1Address, { from: opsAddress });
- assert.equal(await workers.isWorker.call(worker3Address), i>0);
+ for (var i = height - 1; i >= 0; i--) {
+ // Perform random transaction to increase block number. In this case using removeWorker for worker1Address
+ response = await workers.removeWorker(worker1Address, {from: opsAddress});
+ assert.equal(await workers.isWorker.call(worker3Address), i > 0);
}
//Do one more time to confirm.
- response = await workers.removeWorker(worker1Address, { from: opsAddress });
+ response = await workers.removeWorker(worker1Address, {from: opsAddress});
assert.equal(await workers.isWorker.call(worker3Address), false);
});
diff --git a/test/lib/event_decoder.js b/test/lib/event_decoder.js
index bfe65e4..902b3b3 100644
--- a/test/lib/event_decoder.js
+++ b/test/lib/event_decoder.js
@@ -29,9 +29,9 @@ web3EventsDecoder.prototype = {
// decode logs from a transaction receipt
perform: function(txReceipt, contractAddr, contractAbi) {
- //console.log(txReceipt);
- //console.log(contractAddr);
- //console.log(contractAbi);
+ //logger.debug(txReceipt);
+ //logger.debug(contractAddr);
+ //logger.debug(contractAbi);
var decodedEvents = [];
// Transaction receipt not found
diff --git a/test/lib/utils.js b/test/lib/utils.js
index 2dd0978..0622d3c 100644
--- a/test/lib/utils.js
+++ b/test/lib/utils.js
@@ -22,7 +22,10 @@
const Assert = require('assert');
const NullAddress = "0x0000000000000000000000000000000000000000";
-
+const rootPrefix = '../..'
+ , logger = require(rootPrefix + '/helpers/custom_console_logger'),
+ web3 = require('./web3');
+;
/*
* Tracking Gas Usage
*/
@@ -35,7 +38,7 @@ module.exports.logResponse = (response, description) => {
description: description,
response: response
});
-}
+};
module.exports.logReceipt = (receipt, description) => {
receipts.push({
@@ -43,34 +46,34 @@ module.exports.logReceipt = (receipt, description) => {
description: description,
response: null
})
-}
+};
module.exports.logTransaction = async (hash, description) => {
const receipt = await web3.eth.getTransactionReceipt(hash)
await this.logReceipt(receipt, description)
-}
+};
module.exports.printGasStatistics = () => {
- var totalGasUsed = 0
+ var totalGasUsed = 0;
- console.log(" -----------------------------------------------------");
- console.log(" Report gas usage\n");
+ logger.debug(" -----------------------------------------------------");
+ logger.debug(" Report gas usage\n");
for (i = 0; i < receipts.length; i++) {
- const entry = receipts[i]
+ const entry = receipts[i];
- totalGasUsed += entry.receipt.gasUsed
+ totalGasUsed += entry.receipt.gasUsed;
- console.log(" " + entry.description.padEnd(45) + entry.receipt.gasUsed)
+ logger.debug(" " + entry.description.padEnd(45) + entry.receipt.gasUsed)
}
- console.log(" -----------------------------------------------------")
- console.log(" " + "Total gas logged: ".padEnd(45) + totalGasUsed + "\n")
-}
+ logger.debug(" -----------------------------------------------------");
+ logger.debug(" " + "Total gas logged: ".padEnd(45) + totalGasUsed + "\n")
+};
module.exports.clearReceipts = () => {
receipts.splice(0, receipts.length);
-}
+};
/*
@@ -78,7 +81,7 @@ module.exports.clearReceipts = () => {
*/
module.exports.expectNoEvents = (result) => {
Assert.equal(result.receipt.logs.length, 0, "expected empty array of logs")
-}
+};
/*
* Basic Ethereum checks
@@ -88,7 +91,7 @@ module.exports.expectNoEvents = (result) => {
module.exports.isNullAddress = function (address) {
Assert.strictEqual(typeof address, 'string', `address must be of type 'string'`);
return (address == NullAddress);
-}
+};
/// @dev Expect failure from invalid opcode or out of gas,
/// but returns error instead
diff --git a/test/lib/web3.js b/test/lib/web3.js
new file mode 100644
index 0000000..aac9fa7
--- /dev/null
+++ b/test/lib/web3.js
@@ -0,0 +1,7 @@
+"use strict";
+
+
+const Web3 = require('web3'),
+ web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
+
+module.exports = web3;
diff --git a/tools/deploy/EIP20TokenMock.js b/tools/deploy/EIP20TokenMock.js
index aeae046..086e179 100644
--- a/tools/deploy/EIP20TokenMock.js
+++ b/tools/deploy/EIP20TokenMock.js
@@ -1,3 +1,5 @@
+"use strict";
+
/**
* This is script for deploying Pricer contract on any chain.
*
@@ -10,13 +12,15 @@
* @module tools/deploy/EIP20TokenMock
*/
-const readline = require('readline');
-const rootPrefix = '../..';
-const prompts = readline.createInterface(process.stdin, process.stdout);
-const logger = require(rootPrefix + '/helpers/custom_console_logger');
-const Deployer = require(rootPrefix + '/lib/deployer');
-const coreConstants = require(rootPrefix + '/config/core_constants');
-const BigNumber = require('bignumber.js');
+const readline = require('readline')
+ , rootPrefix = '../..'
+ , prompts = readline.createInterface(process.stdin, process.stdout)
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , Deployer = require(rootPrefix + '/services/deploy/deployer')
+ , BigNumber = require('bignumber.js')
+ , helper = require(rootPrefix + "/tools/deploy/helper")
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+;
/**
* It is the main performer method of this deployment script
@@ -88,7 +92,9 @@ async function performer(argv) {
prompts.close();
}
- const contractName = 'eip20tokenmock';
+ const contractName = 'eip20tokenmock'
+ , options = {returnType: "txReceipt"}
+ ;
var constructorArgs = [
conversionRate,
@@ -98,23 +104,24 @@ async function performer(argv) {
decimals
];
- const options = {returnType: "txReceipt"};
-
- const deployerInstance = new Deployer();
+ const deployerInstance = new Deployer({
+ contract_name: contractName,
+ constructor_args: constructorArgs,
+ gas_price: gasPrice,
+ gas_limit: gasLimitGlobalConstant.default(),
+ options: options
+ });
- const deployResult = await deployerInstance.deploy(
- contractName,
- constructorArgs,
- gasPrice,
- options);
+ const deployResult = await deployerInstance.perform();
if (deployResult.isSuccess()) {
const contractAddress = deployResult.data.transaction_receipt.contractAddress;
logger.win("contractAddress: " + contractAddress);
if (fileForContractAddress !== '') {
- deployerInstance.writeContractAddressToFile(fileForContractAddress, contractAddress);
+ await helper.writeContractAddressToFile(fileForContractAddress, contractAddress);
}
}
+ process.exit(0);
}
diff --git a/tools/deploy/airdrop.js b/tools/deploy/airdrop.js
index a9005a6..147f7ab 100644
--- a/tools/deploy/airdrop.js
+++ b/tools/deploy/airdrop.js
@@ -1,3 +1,5 @@
+"use strict";
+
/**
* This is script for deploying Pricer contract on any chain.
*
@@ -15,16 +17,18 @@
* @module tools/deploy/pricer
*/
-const readline = require('readline');
-const rootPrefix = '../..';
-const web3Provider = require(rootPrefix + '/lib/web3/providers/rpc');
-const Deployer = require(rootPrefix + '/lib/deployer');
-const coreConstants = require(rootPrefix + '/config/core_constants');
-const coreAddresses = require(rootPrefix + '/config/core_addresses');
-const prompts = readline.createInterface(process.stdin, process.stdout);
-const logger = require(rootPrefix + '/helpers/custom_console_logger');
-const OpsManagedContract = require(rootPrefix + "/lib/contract_interact/ops_managed_contract");
-const returnTypes = require(rootPrefix + "/lib/global_constant/return_types");
+const readline = require('readline')
+ , rootPrefix = '../..'
+ , coreAddresses = require(rootPrefix + '/config/core_addresses')
+ , prompts = readline.createInterface(process.stdin, process.stdout)
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , returnTypes = require(rootPrefix + "/lib/global_constant/return_types")
+ , helper = require(rootPrefix + "/tools/deploy/helper")
+ , openstPayment = require(rootPrefix + '/index')
+ , SetOpsKlass = openstPayment.services.opsManaged.setOps
+ , GetOpsKlass = openstPayment.services.opsManaged.getOps
+ , DeployAirdropKlass = openstPayment.services.deploy.airdrop
+;
// Different addresses used for deployment
const deployerName = "deployer"
@@ -122,51 +126,56 @@ async function performer(argv) {
prompts.close();
}
- const contractName = 'airdrop'
- , deployerInstance = new Deployer()
+ const deployOptions = {returnType: returnTypes.transactionReceipt()}
;
-
- const constructorArgs = [
- brandedTokenAddress,
- web3Provider.utils.asciiToHex(baseCurrency),
- workerContractAddress,
- airdropBudgetHolder
- ];
- const deployOptions = {returnType: returnTypes.transactionReceipt()};
- const deployResult = await deployerInstance.deploy(
- contractName,
- constructorArgs,
- gasPrice,
- deployOptions);
+ const DeployAirdropObject = new DeployAirdropKlass({
+ branded_token_contract_address: brandedTokenAddress,
+ base_currency: baseCurrency,
+ worker_contract_address: workerContractAddress,
+ airdrop_budget_holder: airdropBudgetHolder,
+ gas_price: gasPrice,
+ options: deployOptions
+ });
+ const deployResult = await DeployAirdropObject.perform();
if (deployResult.isSuccess()) {
const contractAddress = deployResult.data.transaction_receipt.contractAddress;
logger.win("contractAddress: " + contractAddress);
if (fileForContractAddress !== '') {
- deployerInstance.writeContractAddressToFile(fileForContractAddress, contractAddress);
+ helper.writeContractAddressToFile(fileForContractAddress, contractAddress);
}
+ const setOpsOptions = {
+ returnType: returnTypes.transactionReceipt(),
+ tag: ''
+ };
logger.debug("Setting Ops Address to: " + opsAddress);
- const opsManaged = new OpsManagedContract(contractAddress, gasPrice, chainId)
- , setOpsOptions = {
- returnType: returnTypes.transactionReceipt(),
- tag: ''
- }
- ;
- var setOpsResult = await opsManaged.setOpsAddress(deployerAddress,
- deployerPassphrase,
- opsAddress,
- setOpsOptions
- );
+ const SetOpsObject = new SetOpsKlass({
+ contract_address: contractAddress,
+ gas_price: gasPrice,
+ chain_id: chainId,
+ deployer_address: deployerAddress,
+ deployer_passphrase: deployerPassphrase,
+ ops_address: opsAddress,
+ options: setOpsOptions
+ });
+ var setOpsResult = await SetOpsObject.perform();
logger.debug(setOpsResult);
- var contractOpsAddress = await opsManaged.getOpsAddress();
+
+ const GetOpsObject = new GetOpsKlass({
+ contract_address: contractAddress,
+ gas_price: gasPrice,
+ chain_id: chainId
+ });
+ const getOpsResult = await GetOpsObject.perform();
+ const contractOpsAddress = getOpsResult.data.opsAddress;
logger.debug("Ops Address Set to: " + contractOpsAddress);
} else {
logger.error("Error deploying contract");
logger.error(deployResult);
}
-
+ process.exit(0);
}
// node tools/deploy/airdrop.js brandedTokenContractAddress baseCurrency workerContractAddress airdropBudgetHolder gasPrice chainId
diff --git a/tools/deploy/helper.js b/tools/deploy/helper.js
index 06d0da7..fa9f67c 100644
--- a/tools/deploy/helper.js
+++ b/tools/deploy/helper.js
@@ -39,7 +39,7 @@ const _private = {
clearInterval(txSetInterval);
onResolve(response);
} else {
- console.log('Waiting for ' + transactionHash + ' to be included in block.');
+ logger.debug('Waiting for ' + transactionHash + ' to be included in block.');
}
};
@@ -108,7 +108,7 @@ const deployHelper = {
options
);
// this is needed since the contract object
- contract.setProvider(web3Provider.currentProvider);
+ //contract.setProvider(web3Provider.currentProvider);
const deploy = function () {
const encodeABI = contract.deploy(options).encodeABI();
@@ -121,14 +121,14 @@ const deployHelper = {
});
};
- console.log("Unlocking address: " + deployerAddr);
- console.log("Unlocking!!!");
+ logger.debug("Unlocking address: " + deployerAddr);
+ logger.debug("Unlocking!!!");
- console.log("deployerAddr: "+deployerAddr);
+ logger.debug("deployerAddr: "+deployerAddr);
await web3Provider.eth.personal.unlockAccount(deployerAddr, deployerAddrPassphrase);
- console.log("Deploying contract " + contractName);
+ logger.debug("Deploying contract " + contractName);
var deployFailedReason = null;
const transactionReceipt = await deploy().then(
@@ -137,7 +137,7 @@ const deployHelper = {
}
).catch(reason => {
deployFailedReason = reason;
- console.log( deployFailedReason );
+ logger.debug( deployFailedReason );
return null;
});
@@ -145,7 +145,7 @@ const deployHelper = {
return Promise.reject( deployFailedReason );
}
- console.log("deploy transactionReceipt ::", transactionReceipt);
+ logger.debug("deploy transactionReceipt ::", transactionReceipt);
const contractAddress = transactionReceipt.contractAddress;
@@ -156,8 +156,8 @@ const deployHelper = {
}
// Print summary
- console.log("Contract Address: " + contractAddress);
- console.log("Gas used: " + transactionReceipt.gasUsed);
+ logger.debug("Contract Address: " + contractAddress);
+ logger.debug("Gas used: " + transactionReceipt.gasUsed);
return Promise.resolve({
receipt: transactionReceipt,
@@ -206,6 +206,7 @@ const deployHelper = {
writeContractAddressToFile: function(fileName, contractAddress) {
// Write contract address to file
if ( fileName !== '') {
+ logger.debug("Writing to file: ", fileName, "contract address: ", contractAddress);
fs.writeFileSync(Path.join(__dirname, '/' + fileName), contractAddress);
}
}
diff --git a/tools/deploy/pricer.js b/tools/deploy/pricer.js
index 1407d34..2c3bcb1 100644
--- a/tools/deploy/pricer.js
+++ b/tools/deploy/pricer.js
@@ -15,16 +15,20 @@
* @module tools/deploy/pricer
*/
-const readline = require('readline');
-const rootPrefix = '../..';
-const web3Provider = require(rootPrefix + '/lib/web3/providers/rpc');
-const prompts = readline.createInterface(process.stdin, process.stdout);
-const logger = require(rootPrefix + '/helpers/custom_console_logger');
-const OpsManagedContract = require(rootPrefix + "/lib/contract_interact/ops_managed_contract");
-const Deployer = require(rootPrefix + '/lib/deployer');
-const coreAddresses = require(rootPrefix + '/config/core_addresses');
-const coreConstants = require(rootPrefix + '/config/core_constants');
-const returnTypes = require(rootPrefix + "/lib/global_constant/return_types");
+const readline = require('readline')
+ , rootPrefix = '../..'
+ , web3Provider = require(rootPrefix + '/lib/web3/providers/ws')
+ , prompts = readline.createInterface(process.stdin, process.stdout)
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , Deployer = require(rootPrefix + '/services/deploy/deployer')
+ , coreAddresses = require(rootPrefix + '/config/core_addresses')
+ , returnTypes = require(rootPrefix + "/lib/global_constant/return_types")
+ , helper = require(rootPrefix + "/tools/deploy/helper")
+ , openstPayment = require(rootPrefix + '/index')
+ , SetOpsKlass = openstPayment.services.opsManaged.setOps
+ , GetOpsKlass = openstPayment.services.opsManaged.getOps
+ , gasLimitGlobalConstant = require(rootPrefix + '/lib/global_constant/gas_limit')
+;
// Different addresses used for deployment
const deployerName = "deployer"
@@ -125,38 +129,50 @@ async function performer(argv) {
];
const contractName = 'pricer'
- , deployerInstance = new Deployer()
, deployOptions = {returnType: returnTypes.transactionReceipt()};
;
- const deployResult = await deployerInstance.deploy(
- contractName,
- constructorArgs,
- gasPrice,
- deployOptions);
+ const deployerInstance = new Deployer({
+ contract_name: contractName,
+ constructor_args: constructorArgs,
+ gas_price: gasPrice,
+ gas_limit: gasLimitGlobalConstant.default(),
+ options: deployOptions
+ });
+ const deployResult = await deployerInstance.perform();
if (deployResult.isSuccess()) {
const contractAddress = deployResult.data.transaction_receipt.contractAddress;
logger.win("contractAddress: " + contractAddress);
if (fileForContractAddress !== '') {
- deployerInstance.writeContractAddressToFile(fileForContractAddress, contractAddress);
+ helper.writeContractAddressToFile(fileForContractAddress, contractAddress);
}
- logger.debug("Setting Ops Address to: " + opsAddress);
const setOpsOptions = {
- returnType: returnTypes.transactionReceipt(),
- tag: ''
- }
- , opsManaged = new OpsManagedContract(contractAddress, gasPrice, chainId)
- ;
- var setOpsResult = await opsManaged.setOpsAddress(
- deployerAddress,
- deployerPassphrase,
- opsAddress,
- setOpsOptions);
+ returnType: returnTypes.transactionReceipt(),
+ tag: ''
+ }
+ logger.debug("Setting Ops Address to: " + opsAddress);
+ const SetOpsObject = new SetOpsKlass({
+ contract_address: contractAddress,
+ gas_price: gasPrice,
+ chain_id: chainId,
+ deployer_address: deployerAddress,
+ deployer_passphrase: deployerPassphrase,
+ ops_address: opsAddress,
+ options: setOpsOptions
+ });
+ var setOpsResult = await SetOpsObject.perform();
logger.debug(setOpsResult);
- const contractOpsAddress = await opsManaged.getOpsAddress();
+
+ const GetOpsObject = new GetOpsKlass({
+ contract_address: contractAddress,
+ gas_price: gasPrice,
+ chain_id: chainId
+ });
+ const getOpsResult = await GetOpsObject.perform();
+ const contractOpsAddress = getOpsResult.data.opsAddress;
logger.debug("Ops Address Set to: " + contractOpsAddress);
} else {
@@ -164,6 +180,7 @@ async function performer(argv) {
logger.error(deployResult);
}
+ process.exit(0);
}
performer(process.argv);
diff --git a/tools/deploy/workers.js b/tools/deploy/workers.js
index dd3444d..4f714f8 100644
--- a/tools/deploy/workers.js
+++ b/tools/deploy/workers.js
@@ -1,3 +1,5 @@
+"use strict";
+
/**
* This is script for deploying Workers contract on any chain.
*
@@ -15,14 +17,14 @@
* @module tools/deploy/workers
*/
-const readline = require('readline');
-const rootPrefix = '../..';
-const prompts = readline.createInterface(process.stdin, process.stdout);
-const logger = require(rootPrefix + '/helpers/custom_console_logger');
-const Deployer = require(rootPrefix + '/lib/deployer');
-const SetWorkerAndOpsKlass = require(rootPrefix + '/lib/set_worker_and_ops')
- , setWorkerOps = new SetWorkerAndOpsKlass();
-
+const readline = require('readline')
+ , rootPrefix = '../..'
+ , prompts = readline.createInterface(process.stdin, process.stdout)
+ , logger = require(rootPrefix + '/helpers/custom_console_logger')
+ , helper = require(rootPrefix + "/tools/deploy/helper")
+ , SetWorkerAndOpsKlass = require(rootPrefix + '/lib/set_worker_and_ops')
+ , setWorkerOps = new SetWorkerAndOpsKlass()
+;
/**
* It is the main performer method of this deployment script
@@ -80,13 +82,12 @@ async function performer(argv) {
var response = await setWorkerOps.perform({gasPrice: gasPrice, chainId: chainId});
logger.debug("**** Deployment Response", response);
if (response.isSuccess() && fileForContractAddress !== '') {
- var deployerInstance = new Deployer();
- deployerInstance.writeContractAddressToFile(fileForContractAddress, response.data.workerContractAddress);
+ helper.writeContractAddressToFile(fileForContractAddress, response.data.workerContractAddress);
}
process.exit(0);
}
-// node tools/deploy/worker.js gasPrice chainId
+// node tools/deploy/workers.js gasPrice chainId
performer(process.argv);