Skip to content

Instantly share code, notes, and snippets.

@miladmostavi
Created August 24, 2016 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save miladmostavi/508f1628e543d10b314d901b8fd9097d to your computer and use it in GitHub Desktop.
Save miladmostavi/508f1628e543d10b314d901b8fd9097d to your computer and use it in GitHub Desktop.
SingularDTV crowdsale javascript code.
var SingularDTVCrowdfunding_abi = [{"inputs": [], "constant": true, "type": "function", "name": "startDate", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "CROWDFUNDING_PERIOD", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "emergencyCall", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": "singularDTVFundAddress"}, {"type": "address", "name": "singularDTVTokenAddress"}], "constant": false, "type": "function", "name": "setup", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "withdrawFunding", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "fundBalance", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVFund", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "baseValue", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "TOKEN_TARGET", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVToken", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "owner", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [{"type": "uint256", "name": "valueInWei"}], "constant": false, "type": "function", "name": "changeBaseValue", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": ""}], "constant": true, "type": "function", "name": "investments", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "fund", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "stage", "outputs": [{"type": "uint8", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "updateStage", "outputs": [{"type": "uint8", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "valuePerShare", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "TOKEN_LOCKING_PERIOD", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "campaignEndedSuccessfully", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "workshopWaited2Years", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "CAP", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "withdrawForWorkshop", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "type": "constructor"}];
var SingularDTVFund_abi = [{"inputs": [{"type": "address", "name": "singularDTVCrowdfundingAddress"}, {"type": "address", "name": "singularDTVTokenAddress"}], "constant": false, "type": "function", "name": "setup", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "depositRevenue", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": false, "type": "function", "name": "withdrawRevenue", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [{"type": "address", "name": "forAddress"}], "constant": false, "type": "function", "name": "softWithdrawRevenueFor", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "workshop", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [{"type": "address", "name": ""}], "constant": true, "type": "function", "name": "revenueAtTimeOfWithdraw", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVToken", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "owner", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "singularDTVCrowdfunding", "outputs": [{"type": "address", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "totalRevenue", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [{"type": "address", "name": ""}], "constant": true, "type": "function", "name": "owed", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [], "type": "constructor"}];
var SingularDTVToken_abi = [{"inputs": [], "constant": true, "type": "function", "name": "name", "outputs": [{"type": "string", "name": ""}]}, {"inputs": [{"type": "address", "name": "_spender"}, {"type": "uint256", "name": "_value"}], "constant": false, "type": "function", "name": "approve", "outputs": [{"type": "bool", "name": "success"}]}, {"inputs": [], "constant": true, "type": "function", "name": "totalSupply", "outputs": [{"type": "uint256", "name": ""}]}, {"inputs": [{"type": "address", "name": "from"}, {"type": "address", "name": "to"}, {"type": "uint256", "name": "value"}], "constant": false, "type": "function", "name": "transferFrom", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [], "constant": true, "type": "function", "name": "decimals", "outputs": [{"type": "uint8", "name": ""}]}, {"inputs": [{"type": "address", "name": "_for"}, {"type": "uint256", "name": "tokenCount"}], "constant": false, "type": "function", "name": "issueTokens", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": "_owner"}], "constant": true, "type": "function", "name": "balanceOf", "outputs": [{"type": "uint256", "name": "balance"}]}, {"inputs": [], "constant": true, "type": "function", "name": "symbol", "outputs": [{"type": "string", "name": ""}]}, {"inputs": [{"type": "address", "name": "to"}, {"type": "uint256", "name": "value"}], "constant": false, "type": "function", "name": "transfer", "outputs": [{"type": "bool", "name": ""}]}, {"inputs": [{"type": "address", "name": "_owner"}, {"type": "address", "name": "_spender"}], "constant": true, "type": "function", "name": "allowance", "outputs": [{"type": "uint256", "name": "remaining"}]}, {"inputs": [], "type": "constructor"}, {"inputs": [{"indexed": true, "type": "address", "name": "from"}, {"indexed": true, "type": "address", "name": "to"}, {"indexed": false, "type": "uint256", "name": "value"}], "type": "event", "name": "Transfer", "anonymous": false}, {"inputs": [{"indexed": true, "type": "address", "name": "owner"}, {"indexed": true, "type": "address", "name": "spender"}, {"indexed": false, "type": "uint256", "name": "value"}], "type": "event", "name": "Approval", "anonymous": false}];
'use strict';
/* Filters */
angular.module('singularFilters', [])
.filter('bigNumber', function() {
return function(big_number) {
if(big_number) {
var string_split = String(big_number.toString(10)).split('.');
var new_string = "";
var places = string_split[0].length - 1;
for (var i=places; i>=0; i--) {
new_string = string_split[0][i] + new_string;
if (i > 0 && (places - i + 1) % 3 == 0) {
new_string = ',' + new_string;
}
}
if (string_split.length == 2) {
new_string += '.' + string_split[1].substring(0, 2);
}
return new_string;
}
return null;
};
})
.filter('dateFormat', function() {
return function(date_input) {
if(date_input != 0) {
return moment(date_input).format('YYYY-MM-DD HH:mm:ss');
}
return '-';
};
})
.filter('dateFormatFromNow', function() {
function filter(date_input) {
if(date_input != 0) {
return moment(new Date(date_input)).fromNow();
}
return '-';
};
filter.$stateful = true;
return filter;
})
.filter('feeToPercentage', function() {
return function(fee) {
if (fee) {
return fee.dividedBy(1000).toString(10);
}
return "";
};
});
var app = angular.module('crowdfunding', [
'LocalStorageModule',
'singularServices',
'singularFilters',
'ui-notification',
'angular-clipboard',
'singularTestTools'
]);
app.controller('StatusCtrl', function($scope, walletService, EthereumService, stateService, Notification, clipboard, $timeout) {
$scope.crowdsale_enabled = window.crowdsale_config.enabled;
$scope.$watch(function() {
return walletService.exists() && ! stateService.isWalletCreating;
}, function(newVal) {
if (!newVal) {
$scope.is_shown = 0;
} else {
$scope.address = walletService.getAddress();
$scope.is_shown = 1;
}
});
$scope.$watch(function() {
return stateService.blocknumber + stateService.updates;
}, function(newVal) {
$scope.tokens = walletService.balances.sngls ? walletService.balances.sngls.toFixed(0) : '...';
$scope.eth_balance = walletService.balances.wei ? web3.fromWei(walletService.balances.wei, 'ether').toFixed(4) : '...';
$scope.transactions = getTransactions();
$scope.sngls_price = stateService.snglsPrice;
$scope.stage = stateService.stage;
if($scope.stage == stateService.stages.CrowdfundingEndedAndGoalReached) {
EthereumService.getRevenueShare().then(function(revenue_share_wei) {
$scope.revenue_share = web3.fromWei(revenue_share_wei).toNumber();
});
}
if($scope.stage == stateService.stages.CrowdfundingEndedAndGoalNotReached || crowdsale_config.show_withdraw_investment) {
EthereumService.getInvestmentShare().then(function(investment_wei) {
$scope.investment_share = web3.fromWei(investment_wei).toNumber();
});
}
});
$scope.isBuyShown = function() {
return $scope.is_shown && ($scope.stage == stateService.stages.CrowdfundingGoingAndGoalNotReached || $scope.stage == stateService.stages.CrowdfundingGoingAndGoalReached);
};
$scope.isWithdrawRevenueShown = function() {
return $scope.is_shown && $scope.stage == stateService.stages.CrowdfundingEndedAndGoalReached;
};
function getTransactions() {
return _.sortBy(EthereumService.transactions , function(o) {
return new Date(o.date).getTime();
}).reverse();
}
$scope.show_deposit = 0;
$scope.show_withdraw = 0;
$scope.show_tx_history = 0;
$scope.cancelWalletAction = function() {
$scope.show_deposit = 0;
$scope.show_withdraw = 0;
$scope.show_tx_history = 0;
$timeout(function() {
$('html, body').animate({
scrollTop: $("#wallet").offset().top
}, 400);
});
};
$scope.showDeposit = function() {
$scope.show_deposit = 1;
$scope.show_withdraw = 0;
$scope.show_tx_history = 0;
$timeout(function() {
$('html, body').animate({
scrollTop: $("#wallet-deposit").offset().top
}, 400);
});
}
$scope.showWithdraw = function() {
$scope.show_deposit = 0;
$scope.show_withdraw = 1;
$scope.show_tx_history = 0;
$scope.withdraw_amount = null;
$timeout(function() {
$('html, body').animate({
scrollTop: $("#wallet-withdraw").offset().top
}, 400);
});
}
$scope.showTxHistory = function() {
$scope.show_deposit = 0;
$scope.show_withdraw = 0;
$scope.show_tx_history = 1;
$scope.withdraw_amount = null;
$scope.transactions = getTransactions();
$timeout(function() {
$('html, body').animate({
scrollTop: $("#wallet-txhistory").offset().top
}, 400);
});
}
$scope.copyAddressToClipboard = function() {
if (!clipboard.supported) {
Notification.error('Sorry, copy to clipboard is not supported on your device');
return false;
}
clipboard.copyText(walletService.getAddress());
Notification.info('Address copied to clipboard');
};
$scope.openShapeshiftPopup = function($event) {
$event.preventDefault();
var link = $event.target.href;
window.open(link,'1418115287605','width=700,height=500,toolbar=0,menubar=0,location=0,status=1,scrollbars=1,resizable=0,left=0,top=0');
};
$scope.logout = function() {
walletService.destroy();
EthereumService.logout();
loadCrowdFundingPhase1(1);
window.location.reload();
};
$scope.withdraw = function() {
$scope.withdraw_error = {};
if($scope.withdraw_token == 'ETH') {
if(walletService.balances.wei.equals(0)) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = "You don't have any ETH in your wallet";
return false;
}
try {
var value = web3.toWei($scope.withdraw_amount);
var gas_cost = new BigNumber(web3.eth.gasPrice * 21000);
var gas_cost_eth = web3.fromWei(gas_cost);
var max_value = web3.fromWei(new BigNumber(walletService.balances.wei).minus(gas_cost));
var total_cost = new BigNumber(value).plus(gas_cost);
if(total_cost.greaterThan(walletService.balances.wei)) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = 'Not enough funds. Gas cost is: ' + gas_cost_eth + ' ETH; The maximum amount you can withdraw is: ' + max_value + ' ETH';
return false;
}
} catch(e) {
console.log(e);
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = 'Amount must be a valid number';
return false;
}
if(! web3.isAddress($scope.withdraw_to)) {
$scope.withdraw_error.to = true;
$scope.withdraw_error.message = 'Invalid Ethereum address';
return false;
}
$scope.withdrawing = true;
stateService.EthereumService.withdraw($scope.withdraw_to, value).then(function(tx_hash) {
Notification.info('Your withdrawal transaction was sent, it may take up to 20 seconds. Awaiting confirmation...');
stateService.EthereumService.waitForTransactionReceipt(tx_hash).then(function() {
Notification.success('Withdrawal transaction confirmed.');
});
$scope.closeWithdraw();
}).catch(function(err) {
Notification.error('Transaction error: ' + err);
}).finally(function() {
$scope.withdrawing = false;
});
}
if($scope.withdraw_token == 'SNGLS') {
if(walletService.balances.sngls.equals(0)) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = "You don't have any SGNLS in your wallet";
return false;
}
var gas_cost = new BigNumber(web3.eth.gasPrice * stateService.EthereumService.DEFAULT_GAS);
var gas_cost_eth = web3.fromWei(gas_cost);
if(gas_cost.greaterThan(walletService.balances.wei)) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = 'Not enough ETH funds for gas cost. Please deposit at least ' + gas_cost_eth + ' ETH in your account first';
return false;
}
try {
var tokens = $scope.withdraw_amount;
var tokens_bn = new BigNumber(tokens);
if(tokens_bn.greaterThan(walletService.balances.sngls)) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = 'You can transfer a maximum of ' + walletService.balances.sngls + ' SNGLS.';
return false;
}
} catch(e) {
console.log(e);
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = 'Amount must be a valid number';
return false;
}
if(! tokens_bn.isInteger()) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = 'Amount must be an integer. SNGLS do not have sub units.';
return false;
}
if(! web3.isAddress($scope.withdraw_to)) {
$scope.withdraw_error.to = true;
$scope.withdraw_error.message = 'Invalid Ethereum address';
return false;
}
$scope.withdrawing = true;
stateService.EthereumService.transferSngls($scope.withdraw_to, tokens).then(function(tx_hash) {
Notification.info('Your withdrawal transaction was sent, it may take up to 20 seconds. Awaiting confirmation...');
stateService.EthereumService.waitForTransactionReceipt(tx_hash).then(function() {
Notification.success('Withdrawal transaction confirmed.');
});
$scope.closeWithdraw();
}).catch(function(err) {
Notification.error('Transaction error: ' + err);
}).finally(function() {
$scope.withdrawing = false;
});
}
};
var skip_buy_form_recalc = false;
$scope.$watch(function() {
return $scope.buy_sngls_amount;
}, function(newVal, oldValue) {
if(skip_buy_form_recalc) {
skip_buy_form_recalc = false;
return;
}
if(! newVal) {
$scope.buy_sngls_amount = null;
$scope.buy_eth_amount = null;
$scope.buy_eth_amount_bn = null;
return;
}
try {
skip_buy_form_recalc = true;
var sngls = new BigNumber($scope.buy_sngls_amount).floor();
$scope.buy_sngls_amount = sngls.toFixed(0);
$scope.buy_eth_amount_bn = new BigNumber(web3.fromWei(sngls.times($scope.sngls_price), 'ether'));
$scope.buy_eth_amount = $scope.buy_eth_amount_bn.toNumber();
} catch(e) {
console.error(e);
$scope.buy_sngls_amount = oldValue;
}
});
$scope.$watch(function() {
return $scope.buy_eth_amount;
}, function(newVal, oldValue) {
if(skip_buy_form_recalc) {
skip_buy_form_recalc = false;
return;
}
if(! newVal) {
$scope.buy_sngls_amount = null;
$scope.buy_eth_amount = null;
$scope.buy_eth_amount_bn = null;
return;
}
try {
skip_buy_form_recalc = true;
$scope.buy_eth_amount_bn = new BigNumber(newVal);
$scope.buy_sngls_amount = $scope.buy_eth_amount_bn.div(web3.fromWei($scope.sngls_price)).floor();
} catch(e) {
console.error(e);
$scope.buy_eth_amount = oldValue;
}
});
$scope.buySngls = function() {
$scope.buy_error = {};
if(walletService.balances.wei.equals(0)) {
$scope.buy_error.amount = true;
$scope.buy_error.message = "You don't have any ETH in your wallet";
return false;
}
try {
var value = web3.toWei($scope.buy_eth_amount_bn);
var gas_cost = new BigNumber(web3.eth.gasPrice * stateService.EthereumService.DEFAULT_GAS);
var gas_cost_eth = web3.fromWei(gas_cost);
if(gas_cost.greaterThan(walletService.balances.wei)) {
$scope.buy_error.amount = true;
$scope.buy_error.message = 'Not enough ETH funds for gas cost. Please deposit at least ' + gas_cost_eth + ' ETH in your account first';
return false;
}
var gas_cost = new BigNumber(web3.eth.gasPrice * stateService.EthereumService.DEFAULT_GAS);
var gas_cost_eth = web3.fromWei(gas_cost);
var max_value = web3.fromWei(new BigNumber(walletService.balances.wei).minus(gas_cost));
var total_cost = new BigNumber(value).plus(gas_cost);
if(total_cost.greaterThan(walletService.balances.wei)) {
$scope.buy_error.amount = true;
$scope.buy_error.message = 'Not enough funds. Gas cost is: ' + gas_cost_eth + ' ETH; The maximum amount you can buy with is: ' + max_value + ' ETH';
return false;
}
} catch(e) {
console.log(e);
$scope.buy_error.amount = true;
$scope.buy_error.message = 'Amount must be a valid number';
return false;
}
if(value <= 0) {
$scope.buy_error.amount = true;
$scope.buy_error.message = 'SNGLS amount is requiured';
return false;
}
$scope.buying = true;
stateService.EthereumService.buySngls(value).then(function(tx_hash) {
Notification.info('Your buy transaction was sent, it may take up to 20 seconds. Awaiting confirmation...');
sendGaEvent('crowdsale', 'buy', 'sngls', $scope.buy_sngls_amount);
stateService.EthereumService.waitForTransactionReceipt(tx_hash).then(function() {
Notification.success('Buy transaction confirmed.');
$scope.buying = false;
$scope.buy_sngls_amount = null;
EthereumService.updateStatsWidgets();
});
}).catch(function(err) {
Notification.error('Transaction error: ' + err);
$scope.buying = false;
}).finally(function() {
//
});
};
$scope.closeWithdraw = function() {
$scope.withdraw_amount = null;
$scope.withdraw_to = null;
$scope.withdraw_error = {};
$scope.cancelWalletAction();
};
$scope.withdrawRevenueShare = function() {
$scope.withdraw_revenue = {};
var gas_cost = new BigNumber(web3.eth.gasPrice * stateService.EthereumService.DEFAULT_GAS);
var gas_cost_eth = web3.fromWei(gas_cost);
if(gas_cost.greaterThan(walletService.balances.wei)) {
$scope.withdraw_revenue.message = 'Not enough ETH funds for gas cost. Please deposit at least ' + gas_cost_eth + ' ETH in your account first';
return false;
}
$scope.withdrawing_revenue_share = true;
stateService.EthereumService.withdrawRevenueShare().then(function(tx_hash) {
Notification.info('Your withdrawRevenueShare transaction was sent, it may take up to 20 seconds. Awaiting confirmation...');
stateService.EthereumService.waitForTransactionReceipt(tx_hash).then(function() {
Notification.success('withdrawRevenueShare transaction confirmed.');
$scope.withdrawing_revenue_share = false;
});
}).catch(function(err) {
Notification.error('Transaction error: ' + err);
$scope.withdrawing_revenue_share = false;
}).finally(function() {
//
});
};
$scope.isWithdrawInvestmentShown = function() {
return stateService.stage == stateService.stages.CrowdfundingEndedAndGoalNotReached;
};
$scope.withdrawInvestmentShare = function() {
$scope.withdraw_investment = {};
var gas_cost = new BigNumber(web3.eth.gasPrice * stateService.EthereumService.DEFAULT_GAS);
var gas_cost_eth = web3.fromWei(gas_cost);
if(gas_cost.greaterThan(walletService.balances.wei)) {
$scope.withdraw_investment.message = 'Not enough ETH funds for gas cost. Please deposit at least ' + gas_cost_eth + ' ETH in your account first';
return false;
}
$scope.withdrawing_investment_share = true;
stateService.EthereumService.withdrawInvestmentShare().then(function(tx_hash) {
Notification.info('Your withdrawinvestmentShare transaction was sent, it may take up to 20 seconds. Awaiting confirmation...');
stateService.EthereumService.waitForTransactionReceipt(tx_hash).then(function() {
Notification.success('withdrawinvestmentShare transaction confirmed.');
$scope.withdrawing_investment_share = false;
});
}).catch(function(err) {
Notification.error('Transaction error: ' + err);
$scope.withdrawing_investment_share = false;
}).finally(function() {
//
});
};
});
app.controller('LightWalletCtrl', function($scope, walletService, $http, stateService) {
$scope.$watch(function() {
return walletService.exists()
}, function(newVal) {
if (newVal) {
if (!$scope.is_creating) {
loadCrowdFundingPhase2(5);
}
} else {
loadCrowdFundingPhase1(1);
}
});
$scope.recovery_seed = null;
$scope.recovery_seed_form_error = 0;
$scope.setRecoveringWallet = function(val) {
$scope.recovering_wallet = val;
};
$scope.endRecovery = function() {
$scope.recovering_wallet = 0;
$scope.recovering_wallet_seed = 0;
$scope.recovery_seed = null;
$scope.recovery_seed_form_error = 0;
};
$scope.uploadWallet = function(element) {
walletService.upload(element, $scope.endRecovery);
angular.element(element).val(null);
return walletService;
};
$scope.recoverBySeed = function() {
$scope.recovery_seed_form_error = 0;
if (!lightwallet.keystore.isSeedValid($scope.recovery_seed)) {
$scope.recovery_seed_form_error = 1;
return false;
}
loadCrowdFundingStep3($scope.recovery_seed, true);
$scope.endRecovery();
$scope.is_creating = 1;
stateService.set({
isWalletCreating: true
});
};
$scope.setCreatingWallet = function(val) {
$scope.creating_wallet = val;
$scope.$digest();
};
$scope.sendWalletToEmail = function() {
$scope.sending_wallet_to_email = 1;
$http.post('/crowdsale/send', {
address: walletService.getAddress(),
keystore: walletService.keystore.serialize(),
})
.success(function(response, status, headers, config) {
if (response.success) {
$('#cfn-step4-continue').data('allowed', 1).slideDown();
} else {
alert('Our mail server seems to be down. Please try to download the wallet instead.');
}
})
.error(function(data, status, headers, config) {
alert('Our mail server seems to be down. Please try to download the wallet instead.');
}).finally(function() {
$scope.sending_wallet_to_email = 0;
});
};
window.crowdfunding_LightWalletCtrlScope = $scope;
});
app.controller('PasswordPromptCtrl', function($scope, stateService) {
$scope.$watch(function() {
return stateService.show_password_prompt;
}, function(newVal) {
if (!newVal) {
$scope.is_shown = 0;
} else {
$scope.is_shown = 1;
}
});
$scope.unlockWallet = function() {
$scope.deriving_key = true;
$scope.wallet_password_error = false;
if(! $scope.wallet_password) {
$scope.deriving_key = false;
$scope.wallet_password_error = true;
return false;
}
var keystore = stateService.walletService.keystore;
lightwallet.keystore.deriveKeyFromPassword($scope.wallet_password, function(err, pwDerivedKey) {
$scope.deriving_key = false;
if(! err && keystore.isDerivedKeyCorrect(pwDerivedKey)) {
stateService.password_prompt_cb(null, $scope.wallet_password);
stateService.password_prompt_cb = null;
$scope.wallet_password = null;
$scope.wallet_password_error = false;
stateService.hidePasswordPrompt();
} else {
$scope.wallet_password_error = true;
$scope.$digest();
}
});
};
$scope.close = function() {
stateService.hidePasswordPrompt();
};
});
app.config(function($httpProvider) {
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
$httpProvider.defaults.transformRequest = function(data) {
if (data === undefined) {
return data;
}
return $.param(data);
}
});
app.filter('nl2br', function() {
return function(msg) {
var breakTag = '<br>';
var msg = (msg + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2');
return msg;
}
});
app.directive('laddaLoading', function($filter, $timeout) {
return {
scope: true,
link: function(scope, element, attrs) {
var $element = $(element);
scope.$watch(attrs.laddaLoading, function(newVal) {
if (newVal) {
if (!$element.hasClass('ladda-button')) {
$element.addClass('ladda-button');
$element.attr('data-style', 'zoom-in');
}
scope.ladda_object = Ladda.create($element.get(0));
scope.ladda_object.start();
} else if (scope.ladda_object) {
scope.ladda_object.stop()
}
});
}
};
});
app.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.focusMe, function(value) {
if (value === 1) {
$timeout(function() {
element[0].focus();
});
}
});
}
};
});
function loadCrowdFundingStep(step, data) {
// Make other steps inactive
$('.cfn-step').removeClass('cfn-active-step');
switch (step) {
case 1:
loadCrowdFundingStep1();
break;
case 2:
loadCrowdFundingStep2();
break;
case 3:
loadCrowdFundingStep3(data);
break;
case 4:
loadCrowdFundingStep4();
break;
case 5:
loadCrowdFundingStep5();
break;
case 6:
loadCrowdFundingStep6(data);
break;
default:
loadCrowdFundingStep1();
}
}
function loadCrowdFundingPhase1(step) {
var $phase = $('#cfn-phase1');
$('.cfn-phase').removeClass('cfn-active-phase');
$('#cfn-password-form').find('[type=password]').val('');
// Make the phase active
$phase.addClass('cfn-active-phase');
// Initiate the step with the first one
step = step || 1;
// Load the step
loadCrowdFundingStep(step);
//loadCrowdFundingStep(3, "taste rule grid clog surprise finger world thank someone learn pause dentist");
}
function loadCrowdFundingStep1() {
crowdfunding_LightWalletCtrlScope.is_creating = 0;
var $step1 = $('#cfn-step1');
// Make active
$step1.addClass('cfn-active-step');
// We've got two actions: Generate & Open Wallet. Generate should get you to next step
$('#cfn-generate-btn').unbind('click').click(function(e) {
e.preventDefault();
loadCrowdFundingStep(2);
});
}
function loadCrowdFundingStep2() {
var $step2 = $('#cfn-step2');
var $progressBody = $step2.find('.cfn-progress-body');
var $progressBar = $step2.find('.cfn-progress-fill');
var $progressIndicator = $step2.find('.cfn-progress-indicator');
var entropy_limit = 5000;
var seed = null;
var percentage = 0;
var progress = 0;
crowdfunding_LightWalletCtrlScope.is_creating = 1;
window.state_service.set({
isWalletCreating: true
}, true);
// Make active
$step2.addClass('cfn-active-step');
// Set the default for the progress bar
$progressBar.css('width', percentage + '%');
$progressIndicator.text(percentage);
// Generate the seed
EntropyCollector.start();
var interval_timer = window.setInterval(function() {
if (EntropyCollector.estimatedEntropy > entropy_limit) {
$progressBody.addClass('cfn-progress-end');
$progressIndicator.text(100);
seed = lightwallet.keystore.generateRandomSeed(String.fromCharCode.apply(null, new Uint16Array(EntropyCollector.buffer)));
EntropyCollector.stop();
$(document).unbind('mousemove touchmove');
loadCrowdFundingStep(3, seed);
clearInterval(interval_timer);
} else {
percentage = parseInt(EntropyCollector.estimatedEntropy / entropy_limit * 100);
if (percentage > progress) {
$progressBar.css('width', percentage + '%');
$progressIndicator.text(percentage);
progress = percentage;
}
}
}, 1000 / 30);
}
function loadCrowdFundingStep3(seed, isRecovery) {
var $step1 = $('#cfn-step1');
var $step3 = $('#cfn-step3');
var keystore = null;
var address = null;
// Make active
$step1.removeClass('cfn-active-step');
$step3.addClass('cfn-active-step');
if (isRecovery) {
$('#cfn-step3-warning').hide();
} else {
$('#cfn-step3-warning').show();
}
// Update seed value
$('#cfn-seed').text(seed);
$('#cfn-password-form').unbind('submit').submit(function(e) {
e.preventDefault();
var $form = $(this);
var $responseContainer = $('#cfn-password-form-response');
var $passField = $form.find('input[name=password]');
var $passVerifyField = $form.find('input[name=verify-password]');
var password = $passField.val();
var verify_password = $passVerifyField.val();
$responseContainer.hide();
$responseContainer.empty();
$form.find('input').removeClass('input-error');
crowdfunding_LightWalletCtrlScope.setCreatingWallet(1);
$.post($form.attr('action'), $form.serialize(), function(response) {
if (response.success == 1) {
registerWallet();
} else {
$(response.errors).each(function(index, item) {
$form.find('input[name=' + item.name + ']').addClass('input-error');
$responseContainer.append('<div class="alert-fail">' + item.message[0] + '</div>');
});
$responseContainer.slideDown();
crowdfunding_LightWalletCtrlScope.setCreatingWallet(0);
}
}, 'json');
function registerWallet() {
lightwallet.keystore.deriveKeyFromPassword(password, function(err, pwDerivedKey) {
var ks = new lightwallet.keystore(seed, pwDerivedKey);
ks.generateNewAddress(pwDerivedKey, 1);
var address = "0x" + ks.getAddresses()[0];
$form.find('input').val('');
Wallet.keystore = ks;
Wallet.save();
loadCrowdFundingStep(4);
crowdfunding_LightWalletCtrlScope.setCreatingWallet(0);
sendGaEvent('lightwallet', 'generated');
});
}
});
}
function loadCrowdFundingStep4() {
var $step4 = $('#cfn-step4');
var $sendForm = $('#cfn-send-wallet-form');
// Make active
$step4.addClass('cfn-active-step');
$('#cfn-download-wallet-btn').unbind('click').click(function(e) {
e.preventDefault();
Wallet.download();
$step4.find('.cfn-continue').data('allowed', 1);
$step4.find('.cfn-continue').slideDown();
$sendForm.hide();
// Remove focus from button
$(this).blur();
});
$('#cfn-open-send-form-btn').unbind('click').click(function(e) {
e.preventDefault();
$sendForm.fadeIn();
// Remove focus from button
$(this).blur();
});
$sendForm.unbind('submit').submit(function() {
var $button = $sendForm.find('button[type=submit]');
var $email = $sendForm.find('input[name=email]');
var $keystore = $sendForm.find('input[name=keystore]');
var $containerResponse = $('#cfn-send-wallet-form-response');
clearTimeout($sendForm.data('resetTimeout'));
if (!$button.hasClass('ladda-button')) {
$button.addClass('ladda-button');
$button.attr('data-style', 'zoom-in');
}
$button.each(function() {
var ladda = Ladda.create(this);
ladda.start();
$(this).data('ladda-object', ladda);
});
// Adds the keystore to the form
$keystore.val(Wallet.keystore.serialize());
var input = $("<input>").attr("type", "hidden").attr('id', 'dynamic-address-input').attr('name', 'address').val(Wallet.getAddress());
$sendForm.find('#dynamic-address-input').remove();
$sendForm.append($(input));
// Resets errors
$containerResponse.hide();
$containerResponse.empty();
$email.removeClass('input-error');
$.ajax({
type: "POST",
url: $sendForm.attr('action'),
jsonp: "c",
dataType: "json",
data: $sendForm.serialize(),
complete: function(answer) {
var response = JSON.parse(answer.responseText);
var output = "";
$button.each(function() {
try {
$(this).data('ladda-object').stop();
} catch (e) {
}
});
var resetTimeout = setTimeout(function() {
$button.removeClass('ladda-button');
}, 1000);
$sendForm.data('resetTimeout', resetTimeout);
if (response.success == 1) {
output += '<div>Your message has been successfully sent. Thank you!</div>';
$email.val('');
$keystore.val('');
$sendForm.hide();
$step4.find('.cfn-continue').data('allowed', 1);
$step4.find('.cfn-continue').slideDown();
} else {
$.each(response.messages, function(i, e) {
if (i === 'email') {
$email.addClass('input-error');
}
output += '<div class="alert-fail">' + e + '</div>';
});
}
$containerResponse.append(output);
$containerResponse.slideDown();
}
});
return false;
});
$step4.find('.cfn-continue').unbind('click').click(function(e) {
e.preventDefault();
if ($(this).data('allowed') == 1) {
window.state_service.set({
isWalletCreating: false
}, true);
loadCrowdFundingPhase2(5);
}
});
}
function loadCrowdFundingPhase2()
{
var $phase = $('#cfn-phase2');
$('.cfn-phase').removeClass('cfn-active-phase');
// Make the phase active
$phase.addClass('cfn-active-phase');
}
'use strict';
/* Services */
var singularServices = angular.module('singularServices', []);
singularServices.factory('stateService', function($rootScope, EthereumService, $timeout, $q) {
var state = {
isWalletCreating: false,
EthereumService: EthereumService,
walletService: EthereumService.walletService,
updates: 0,
blocknumber: 0,
sharesIssued: true,
snglsPrice: null,
stage: null,
};
state.stages = {
CrowdfundingGoingAndGoalNotReached: 0,
CrowdfundingEndedAndGoalNotReached: 1,
CrowdfundingGoingAndGoalReached: 2,
CrowdfundingEndedAndGoalReached: 3,
};
state.set = function(newState, isExternalCall) {
state = Object.assign(state, newState);
if(isExternalCall) {
$rootScope.$digest();
}
};
state.showPasswordPrompt = function(cb) {
state.show_password_prompt = 1;
state.password_prompt_cb = cb;
state.last_main_zindex = $('#main').css('z-index');
$('#main').css('z-index', 5000);
try {
$rootScope.$digest();
} catch(e) {}
};
state.hidePasswordPrompt = function() {
state.show_password_prompt = 0;
if(state.password_prompt_cb && state.EthereumService.transaction_awaiting_pw_deferred) {
state.EthereumService.transaction_awaiting_pw_deferred.reject('Wallet password was not provided');
state.EthereumService.transaction_awaiting_pw_deferred = null;
}
state.password_prompt_cb = null;
$timeout(function() {
$('#main').css('z-index', state.last_main_zindex);
});
};
state.update = function(skip_increment) {
$q.all([
EthereumService.updateBalance(),
EthereumService.getSnglsPrice(),
getCurrentStage(),
]).then(function(results) {
EthereumService.walletService.balances = EthereumService.balances;
EthereumService.walletService.eth_balance = web3.fromWei(EthereumService.balances.wei);
state.snglsPrice = results[1];
state.updates++;
try {
$rootScope.$digest();
} catch(e) {}
});
};
function getCurrentStage() {
var deferred = $q.defer();
crowdfunding_contract.updateStage.call(function(err, stage) {
if (!err) {
state.stage = stage.toNumber();
deferred.resolve(stage.toNumber());
} else {
console.error(err);
}
});
return deferred.promise;
}
state.updateBlocknumber = function() {
EthereumService.getBlocknumber().then(function(blocknumber) {
if(state.blocknumber != blocknumber) {
state.blocknumber = blocknumber;
state.update();
EthereumService.checkPendingTransactions();
EthereumService.updateTransactions();
}
}).finally(function() {
$timeout(function() {
state.updateBlocknumber();
}, 5000);
});
};
state.updateBlocknumber();
//circular reference
EthereumService.stateService = state;
window.state_service = state;
return state;
});
singularServices.service('walletService', function($rootScope, localStorageService, $http) {
var wallet = this;
wallet.keystore = null;
wallet.EthereumService = null;
wallet.balances = {
sngls: null,
wei: null,
};
wallet.exists = function() {
return localStorageService.get('keystore') ? true : false;
};
wallet.save = function() {
localStorageService.set('keystore', this.keystore.serialize());
this.connect(wallet.EthereumService);
setTimeout(function() {
$rootScope.$digest();
}, 1);
return this;
};
wallet.upload = function(element, cb) {
var reader = new FileReader();
reader.onload = function() {
var text = reader.result;
try {
localStorageService.set('keystore', text);
if(wallet.restore(wallet.EthereumService)) {
if(cb) { cb(); }
}
$rootScope.$digest();
} catch (err) {}
};
reader.readAsText(element.files[0]);
};
wallet.download = function() {
if (!wallet.exists()) {
alert("No wallet exists!");
return;
}
var blob = new Blob([localStorageService.get('keystore')], {
type: "text/plain;charset=utf-8"
});
saveAs(blob, "sngular_wallet.txt");
};
wallet.restore = function(EthereumService) {
try {
this.keystore = lightwallet.keystore.deserialize(localStorageService.get('keystore'));
wallet.connect(EthereumService);
return true;
} catch (e) {
console.error(e);
this.destroy();
alert('We could not restore your wallet. Make sure you are using a compatible format.');
return false;
}
};
wallet.getAddress = function() {
return "0x" + this.keystore.getAddresses()[0];
};
wallet.destroy = function() {
localStorageService.remove('keystore');
this.keystore = null;
wallet.balances = {
sngls: null,
wei: null,
};
return this;
};
wallet.connect = function(EthereumService) {
this.keystore.passwordProvider = function (callback) {
wallet.EthereumService.stateService.showPasswordPrompt(callback);
};
EthereumService.connectProvider();
if(EthereumService.stateService) {
EthereumService.stateService.update();
}
};
window.Wallet = this;
});
singularServices.factory('EthereumService', ['$interval', '$timeout', '$http', '$rootScope', 'localStorageService', 'walletService', '$q',
function($interval, $timeout, $http, $rootScope, localStorageService, walletService, $q) {
window.web3 = new Web3();
/* service config */
var BLOCK_TIME = 15; // in seconds
var UPDATE_BLOCKCHAIN = BLOCK_TIME * 1000; // every 15 seconds
/* default setting values */
var DEFAULT_GAS = 150000;
var DEFAULT_ETHEREUM_NODE = window.crowdsale_config.default_node;
var DEFAULT_CONTRACT_ADDRESS = window.crowdsale_config.fund_address;
var factory = {};
factory.DEFAULT_GAS = DEFAULT_GAS;
factory.walletService = walletService;
factory.balances = {
wei: null,
sngls: null,
};
factory.transactions = [];
/* add and persists transaction in local storage */
function addTransaction(transaction) {
factory.transactions.push(transaction);
//trigger UI update
factory.stateService.updates++;
localStorageService.set('transactions', angular.toJson(factory.transactions));
}
factory.addTransaction = addTransaction;
/* update information about pending transactions */
function updateTransactions() {
var pending_transactions = factory.transactions.filter(function(tx) {if(!tx.receipt) return tx});
for (var i=0; i<pending_transactions.length; i++) {
web3.eth.getTransactionReceipt(pending_transactions[i].hash, function(err, receipt) {
if(!err) {
for (var j=0; j<factory.transactions.length; j++) {
if(receipt && factory.transactions[j].hash == receipt.transactionHash) {
factory.transactions[j].receipt = receipt;
localStorageService.set('transactions', angular.toJson(factory.transactions));
}
}
}
else {
logError(err);
}
});
}
}
factory.updateTransactions = updateTransactions;
factory.getEthereumNode = function() {
return localStorageService.get('ethereum_node') || DEFAULT_ETHEREUM_NODE;
};
factory.setContractAddress = function(contract_address) {
if (web3.isAddress(contract_address)) {
localStorageService.set('contract_address', angular.toJson(contract_address));
}
};
factory.setEthereumNode = function(ethereum_node) {
if (angular.isDefined(ethereum_node)) {
localStorageService.set('ethereum_node', ethereum_node);
}
};
factory.resetSettings = function() {
localStorageService.set('contract_address', "");
localStorageService.set('ethereum_node', "");
};
factory.getBlocknumber = function() {
var deferred = $q.defer();
web3.eth.getBlockNumber(function(err, current_block) {
if(!err) {
deferred.resolve(current_block);
}
else {
deferred.reject(err);
}
});
return deferred.promise;
}
factory.logout = function () {
factory.balances = {
wei: null,
sngls: null,
};
factory.transactions = [];
factory.shares = {};
localStorageService.set('transactions', '');
};
factory.withdraw = function(receiver_address, value) {
var deferred = $q.defer();
web3.eth.sendTransaction({
from: walletService.getAddress(),
to: receiver_address,
value: value,
gas: 21000,
gasPrice: web3.eth.gasPrice
},
function(err, tx_hash) {
if (!err) {
addTransaction({
'hash': tx_hash,
'subject': 'withdraw',
'token': 'ETH',
'value': web3.fromWei(value),
'receipt': null,
'from': walletService.getAddress(),
'to': receiver_address,
'date': new Date()
});
deferred.resolve(tx_hash);
} else {
deferred.reject(err);
console.error(err);
}
}
);
factory.transaction_awaiting_pw_deferred = deferred;
return deferred.promise;
};
/* initializes web3 library and interface contract*/
var CrowdfundingContract = web3.eth.contract(SingularDTVCrowdfunding_abi);
window.crowdfunding_contract = CrowdfundingContract.at(crowdsale_config.crowdfunding_address);
var FundContract = web3.eth.contract(SingularDTVFund_abi);
window.fund_contract = FundContract.at(crowdsale_config.fund_address);
var TokenContract = web3.eth.contract(SingularDTVToken_abi);
window.token_contract = TokenContract.at(crowdsale_config.token_address);
/* connect provider with keystore */
factory.connectProvider = function() {
window.provider = new HookedWeb3Provider({
host: factory.getEthereumNode(),
transaction_signer: walletService.keystore
});
web3.setProvider(provider);
is_connected = true;
try {
factory.transactions = angular.fromJson(localStorageService.get('transactions')) || [];
updateTransactions();
} catch(e) {
}
};
/* update balance info */
factory.updateBalance = function() {
var deferred_eth = $q.defer();
var deferred_sngls = $q.defer();
web3.eth.getBalance(walletService.getAddress(), function(err, balance) {
if (!err) {
factory.balances.wei = balance;
deferred_eth.resolve(balance);
} else {
console.error(err);
}
});
token_contract.balanceOf.call(walletService.getAddress(), function(err, balance) {
if (!err) {
factory.balances.sngls = balance;
deferred_sngls.resolve(balance)
} else {
console.error(err);
}
});
return $q.all([
deferred_eth.promise,
deferred_sngls.promise,
]);
};
factory.transferSngls = function(receiver_address, value) {
var deferred = $q.defer();
token_contract.transfer.sendTransaction(
receiver_address,
value,
{from: walletService.getAddress(), value: 0, gas: DEFAULT_GAS, gasPrice: web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'withdraw',
'token': 'SNGLS',
'value': value,
'receipt': null,
'from': walletService.getAddress(),
'to': receiver_address,
'date': new Date()
});
deferred.resolve(tx_hash);
}
else {
deferred.reject(err);
console.error(err);
}
}
);
factory.transaction_awaiting_pw_deferred = deferred;
return deferred.promise;
};
factory.buySngls = function(value) {
var deferred = $q.defer();
var value_bn = new BigNumber(value);
var sngls_price = factory.stateService.snglsPrice;
var sngls = value_bn.dividedBy(sngls_price).floor();
crowdfunding_contract.fund.sendTransaction(
{from: walletService.getAddress(), value: value, gas: DEFAULT_GAS, gasPrice: web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'buy',
'token': 'SNGLS',
'value': sngls.toFixed(0),
'receipt': null,
'from': walletService.getAddress(),
'to': crowdsale_config.crowdfunding_address,
'date': new Date()
});
deferred.resolve(tx_hash);
}
else {
deferred.reject(err);
console.error(err);
}
}
);
factory.transaction_awaiting_pw_deferred = deferred;
return deferred.promise;
};
factory.depositRevenue = function(value) {
var deferred = $q.defer();
fund_contract.depositRevenue.sendTransaction(
{from: walletService.getAddress(), value: value, gas: DEFAULT_GAS, gasPrice: web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'addRevenue',
'token': 'ETH',
'value': web3.fromWei(value),
'receipt': null,
'from': walletService.getAddress(),
'to': crowdsale_config.fund_address,
'date': new Date()
});
deferred.resolve(tx_hash);
}
else {
deferred.reject(err);
console.error(err);
}
}
);
factory.transaction_awaiting_pw_deferred = deferred;
return deferred.promise;
};
factory.withdrawForWorkshop = function() {
var deferred = $q.defer();
crowdfunding_contract.withdrawForWorkshop.sendTransaction(
{from: walletService.getAddress(), value: 0, gas: DEFAULT_GAS, gasPrice: web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'withdrawForWorkshop',
'token': 'ETH',
'value': 0,
'receipt': null,
'from': walletService.getAddress(),
'to': crowdsale_config.crowdfunding_address,
'date': new Date()
});
deferred.resolve(tx_hash);
}
else {
deferred.reject(err);
console.error(err);
}
}
);
factory.transaction_awaiting_pw_deferred = deferred;
return deferred.promise;
};
factory.pending_transactions = {};
factory.waitForTransactionReceipt = function(tx_hash) {
var deferred = $q.defer();
factory.pending_transactions[tx_hash] = {
callback: deferred.resolve,
};
return deferred.promise;
};
factory.checkPendingTransactions = function() {
for(var tx_hash in factory.pending_transactions) {
web3.eth.getTransactionReceipt(tx_hash, function(err, receipt) {
if(!err && receipt) {
for (var j=0; j<factory.transactions.length; j++) {
if(receipt && factory.transactions[j].hash == receipt.transactionHash) {
factory.transactions[j].receipt = receipt;
localStorageService.set('transactions', angular.toJson(factory.transactions));
}
}
factory.pending_transactions[tx_hash].callback();
delete factory.pending_transactions[tx_hash];
}
});
}
};
factory.getSnglsPrice = function() {
var deferred = $q.defer();
crowdfunding_contract.valuePerShare.call(function(err, wei_per_share) {
if (!err) {
deferred.resolve(wei_per_share)
} else {
console.error(err);
}
});
return deferred.promise;
};
factory.getCrowdfundBalance = function() {
var deferred = $q.defer();
crowdfunding_contract.fundBalance.call(function(err, total_wei_balance) {
if (!err) {
deferred.resolve(total_wei_balance);
} else {
console.error(err);
}
});
return deferred.promise;
};
factory.getTotalSupply = function() {
var deferred = $q.defer();
token_contract.totalSupply.call(function(err, totalSupply) {
if (!err) {
deferred.resolve(totalSupply);
} else {
console.error(err);
}
});
return deferred.promise;
};
factory.getRevenueShare = function() {
var deferred = $q.defer();
fund_contract.withdrawRevenue.call(
{from: walletService.getAddress()},
function(err, revenue_share) {
if (!err) {
deferred.resolve(revenue_share);
} else {
console.error(err);
}
}
);
return deferred.promise;
};
factory.withdrawRevenueShare = function() {
var deferred = $q.defer();
fund_contract.withdrawRevenue.sendTransaction(
walletService.getAddress(),
{from: walletService.getAddress(), value: 0, gas: DEFAULT_GAS, gasPrice: web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'withdrawRevenueShare',
'token': 'ETH',
'value': 0,
'receipt': null,
'from': walletService.getAddress(),
'to': crowdsale_config.fund_address,
'date': new Date()
});
deferred.resolve(tx_hash);
}
else {
deferred.reject(err);
console.error(err);
}
}
);
factory.transaction_awaiting_pw_deferred = deferred;
return deferred.promise;
};
factory.getInvestmentShare = function() {
var deferred = $q.defer();
crowdfunding_contract.investments.call(walletService.getAddress(), function(err, investment_share) {
if (!err) {
deferred.resolve(investment_share);
} else {
console.error(err);
}
});
return deferred.promise;
};
factory.withdrawInvestmentShare = function() {
var deferred = $q.defer();
crowdfunding_contract.withdrawFunding.sendTransaction(
{from: walletService.getAddress(), value: 0, gas: DEFAULT_GAS, gasPrice: web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'withdrawFunding',
'token': 'ETH',
'value': 0,
'receipt': null,
'from': walletService.getAddress(),
'to': crowdsale_config.crowdfunding_address,
'date': new Date()
});
deferred.resolve(tx_hash);
}
else {
deferred.reject(err);
console.error(err);
}
}
);
factory.transaction_awaiting_pw_deferred = deferred;
return deferred.promise;
};
factory.updateStatsWidgets = function() {
$q.all([
factory.getTotalSupply(),
factory.getCrowdfundBalance(),
]).then(function(results) {
updateState(results[0].toFixed(0), web3.fromWei(results[1]).toFixed(1));
});
};
if (walletService.exists()) {
walletService.restore(factory);
}
walletService.EthereumService = factory;
window.service = factory;
return factory;
}
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment