Skip to content

Instantly share code, notes, and snippets.

@miladmostavi
Created December 13, 2016 11:11
Show Gist options
  • Save miladmostavi/7111585112b93cfc41df2b62592776ef to your computer and use it in GitHub Desktop.
Save miladmostavi/7111585112b93cfc41df2b62592776ef to your computer and use it in GitHub Desktop.
Gnosis token launch javascript code.
var token_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}];
var auction_abi = [{"inputs": [], "constant": true, "name": "TOTAL_TOKENS", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "etherWallet", "payable": false, "outputs": [{"type": "address", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "MAX_TOKENS_SOLD", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": false, "name": "bid", "payable": true, "outputs": [], "type": "function"}, {"inputs": [], "constant": true, "name": "endTime", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "calcTokenPrice", "payable": false, "outputs": [{"type": "uint256", "name": "tokenPrice"}], "type": "function"}, {"inputs": [], "constant": true, "name": "FUNDING_GOAL", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": false, "name": "claimTokens", "payable": false, "outputs": [], "type": "function"}, {"inputs": [], "constant": true, "name": "startBlock", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "daoToken", "payable": false, "outputs": [{"type": "address", "name": ""}], "type": "function"}, {"inputs": [{"type": "address", "name": ""}], "constant": true, "name": "bids", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "WAITING_PERIOD", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [{"type": "address", "name": "_daoToken"}, {"type": "address", "name": "_tokenWallet"}, {"type": "address", "name": "_etherWallet"}], "constant": false, "name": "setup", "payable": false, "outputs": [], "type": "function"}, {"inputs": [], "constant": true, "name": "owner", "payable": false, "outputs": [{"type": "address", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "finalPrice", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "tokenWallet", "payable": false, "outputs": [{"type": "address", "name": ""}], "type": "function"}, {"inputs": [], "constant": true, "name": "stage", "payable": false, "outputs": [{"type": "uint8", "name": ""}], "type": "function"}, {"inputs": [], "constant": false, "name": "updateStage", "payable": false, "outputs": [{"type": "uint8", "name": "_stage"}], "type": "function"}, {"inputs": [], "constant": true, "name": "totalRaised", "payable": false, "outputs": [{"type": "uint256", "name": ""}], "type": "function"}, {"inputs": [], "constant": false, "name": "calcCurrentTokenPrice", "payable": false, "outputs": [{"type": "uint256", "name": "tokenPrice"}], "type": "function"}, {"inputs": [], "constant": true, "name": "calcStopPrice", "payable": false, "outputs": [{"type": "uint256", "name": "stopPrice"}], "type": "function"}, {"inputs": [], "constant": false, "name": "tokenLaunched", "payable": false, "outputs": [{"type": "bool", "name": "launched"}], "type": "function"}, {"inputs": [], "type": "constructor"}, {"inputs": [{"indexed": true, "type": "address", "name": "investor"}, {"indexed": false, "type": "uint256", "name": "amount"}], "type": "event", "name": "BidSubmission", "anonymous": false}];
'use strict';
/* Filters */
angular.module('tokenLaunchFilters', [])
.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 "";
};
});
'use strict';
/* Services */
var tokenLaunchServices = angular.module('tokenLaunchServices', []);
tokenLaunchServices.factory('stateService', function($rootScope, EthereumService, $timeout, $q) {
var state = {
isWalletCreating: false,
EthereumService: EthereumService,
walletService: EthereumService.walletService,
updates: 0,
blocknumber: 0,
sharesIssued: true,
tokenPrice: null,
stage: null,
funding_method: null,
bid: null,
tokens_fungible: false,
};
state.stages = {
AuctionStarted: 0,
AuctionEnded: 1,
};
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.getTokenPrice(),
EthereumService.getCurrentBid(),
getCurrentStage(),
getTokensFungibleState(),
EthereumService.getTotalRaised(),
]).then(function(results) {
EthereumService.walletService.balances = EthereumService.balances;
EthereumService.walletService.eth_balance = web3.fromWei(EthereumService.balances.wei);
state.tokenPrice = results[1];
state.bid = results[2];
state.updates++;
try {
$rootScope.$digest();
} catch(e) {}
//update stats section
updateState({
total_funds: web3.fromWei(results[5]).toString(),
token_price: web3.fromWei(state.tokenPrice).toString(),
current_block: state.blocknumber,
});
});
};
function getCurrentStage() {
var deferred = $q.defer();
auction_contract.updateStage.call(function(err, stage) {
if (!err) {
state.stage = stage.toNumber();
deferred.resolve(stage.toNumber());
} else {
console.error(err);
}
});
return deferred.promise;
}
function getTokensFungibleState() {
var deferred = $q.defer();
auction_contract.tokenLaunched.call(function(err, tokenLaunched) {
if (!err) {
state.tokens_fungible = tokenLaunched;
deferred.resolve(tokenLaunched);
} 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;
});
tokenLaunchServices.service('walletService', function($rootScope, localStorageService, $http, $window) {
var wallet = this;
wallet.keystore = null;
wallet.EthereumService = null;
wallet.balances = {
tokens: null,
wei: null,
};
wallet.shouldRestore = function(value) {
localStorageService.set('wallet_should_restore', value);
};
wallet.useMetamask = function(value) {
localStorageService.set('use_metamask', value);
};
wallet.isUsingMetamask = function(value) {
return localStorageService.get('use_metamask') ? wallet.isMetamaskProviderSetCorrect() : false;
};
wallet.getMetamaskSelectedAddress = function() {
return angular.fromJson($window.localStorage.getItem('MetaMask-Config')).selectedAddress;
};
wallet.isMetamaskProviderSetCorrect = function() {
var provider_type = angular.fromJson($window.localStorage.getItem('MetaMask-Config')).provider.type;
if(tokenlaunch_config.metamask_provider_type != 'rpc' && tokenlaunch_config.metamask_provider_type == provider_type) {
return true;
} else if (tokenlaunch_config.metamask_provider_type == 'rpc') {
var rpc_target = angular.fromJson($window.localStorage.getItem('MetaMask-Config')).provider.rpcTarget;
if(! rpc_target) {
return false;
}
if(rpc_target == tokenlaunch_config.default_node) {
return true;
}
}
return false;
};
wallet.exists = function() {
if(window.metamask_web3 && wallet.isUsingMetamask()) {
return true;
}
if(localStorageService.get('wallet_should_restore')) {
return false;
}
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.isUsingMetamask()) {
alert('Action not allowed when using metamask');
return false;
}
if (!localStorageService.get('keystore')) {
alert("No wallet exists!");
return;
}
var blob = new Blob([localStorageService.get('keystore')], {
type: "text/plain;charset=utf-8"
});
saveAs(blob, "gnosis_wallet_" + wallet.getAddress() + ".txt");
};
wallet.restore = function(EthereumService) {
if(wallet.isUsingMetamask()) {
wallet.connect(EthereumService);
return true;
}
try {
this.keystore = lightwallet.keystore.deserialize(localStorageService.get('keystore'));
wallet.connect(EthereumService);
wallet.shouldRestore(false);
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() {
if(wallet.isUsingMetamask()) {
return wallet.getMetamaskSelectedAddress();
}
return "0x" + this.keystore.getAddresses()[0];
};
wallet.destroy = function() {
if(wallet.isUsingMetamask()) {
wallet.useMetamask(false);
}
localStorageService.remove('keystore');
this.keystore = null;
wallet.balances = {
tokens: null,
wei: null,
};
return this;
};
wallet.connect = function(EthereumService) {
if(wallet.isUsingMetamask()) {
EthereumService.connectToMetamask();
ga('set', 'dimension1', 'Metamask');
} else {
this.keystore.passwordProvider = function (callback) {
wallet.EthereumService.stateService.showPasswordPrompt(callback);
};
EthereumService.connectProvider();
ga('set', 'dimension1', 'Http provider');
}
if(EthereumService.stateService) {
EthereumService.stateService.update();
}
};
window.Wallet = this;
});
tokenLaunchServices.factory('EthereumService', ['$interval', '$timeout', '$http', '$rootScope', 'localStorageService', 'walletService', '$q', '$window',
function($interval, $timeout, $http, $rootScope, localStorageService, walletService, $q, $window) {
if($window.web3 && $window.web3.currentProvider.constructor.name == "MetamaskInpageProvider") {
$window.metamask_web3 = $window.web3;
}
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.tokenlaunch_config.default_node;
var DEFAULT_CONTRACT_ADDRESS = window.tokenlaunch_config.fund_address;
var factory = {};
factory.DEFAULT_GAS = DEFAULT_GAS;
factory.walletService = walletService;
factory.balances = {
wei: null,
tokens: 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,
tokens: 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: 23000,
gasPrice: rpc_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 AuctionContract = web3.eth.contract(auction_abi);
window.auction_contract = AuctionContract.at(tokenlaunch_config.auction_address);
var TokenContract = web3.eth.contract(token_abi);
window.token_contract = TokenContract.at(tokenlaunch_config.token_address);
/* connect provider with keystore */
factory.connectProvider = function() {
window.provider = new HookedWeb3Provider({
host: factory.getEthereumNode(),
transaction_signer: walletService.keystore
});
web3.setProvider(provider);
factory.connectRpcProvider();
window.is_connected = true;
try {
factory.transactions = angular.fromJson(localStorageService.get('transactions')) || [];
updateTransactions();
} catch(e) {
}
};
/* use metamask */
factory.connectToMetamask = function() {
web3.setProvider($window.metamask_web3.currentProvider);
factory.connectRpcProvider();
window.is_connected = true;
try {
factory.transactions = angular.fromJson(localStorageService.get('transactions')) || [];
updateTransactions();
} catch(e) {
}
};
factory.connectRpcProvider = function() {
window.rpc_provider = new HookedWeb3Provider({
host: factory.getEthereumNode()
});
window.rpc_web3 = new Web3();
window.rpc_web3.setProvider(rpc_provider);
};
/* update balance info */
factory.updateBalance = function() {
var deferred_eth = $q.defer();
var deferred_tokens = $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.tokens = balance;
deferred_tokens.resolve(balance)
} else {
console.error(err);
}
});
return $q.all([
deferred_eth.promise,
deferred_tokens.promise,
]);
};
factory.transferTokens = function(receiver_address, value) {
var deferred = $q.defer();
token_contract.transfer.sendTransaction(
receiver_address,
value,
{from: walletService.getAddress(), value: 0, gas: DEFAULT_GAS, gasPrice: rpc_web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'withdraw',
'token': 'GNO',
'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;
};
factory.buyTokens = function(value) {
var deferred = $q.defer();
var value_bn = new BigNumber(value);
var token_price = factory.stateService.tokenPrice;
var human_readable_tokens_count = value_bn.div(token_price).toNumber();;
auction_contract.bid.sendTransaction(
{from: walletService.getAddress(), value: value, gas: DEFAULT_GAS, gasPrice: rpc_web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'bid',
'token': 'ETH',
'value': web3.fromWei(value_bn),
'receipt': null,
'from': walletService.getAddress(),
'to': tokenlaunch_config.auction_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: rpc_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': tokenlaunch_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();
auction_contract.withdrawForWorkshop.sendTransaction(
{from: walletService.getAddress(), value: 0, gas: DEFAULT_GAS, gasPrice: rpc_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': tokenlaunch_config.auction_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.getTokenPrice = function() {
var deferred = $q.defer();
auction_contract.calcCurrentTokenPrice.call(function(err, wei_per_share) {
if (!err) {
deferred.resolve(wei_per_share)
} else {
console.error(err);
}
});
return deferred.promise;
};
factory.getCurrentBid = function() {
var deferred = $q.defer();
auction_contract.bids.call(walletService.getAddress(), function(err, bid) {
if (!err) {
deferred.resolve(bid)
} 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.getTotalRaised = function() {
var deferred = $q.defer();
auction_contract.totalRaised.call(function(err, totalRaised) {
if (!err) {
deferred.resolve(totalRaised);
} 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.claimTokens = function() {
var deferred = $q.defer();
auction_contract.claimTokens.sendTransaction(
{from: walletService.getAddress(), value: 0, gas: DEFAULT_GAS, gasPrice: rpc_web3.eth.gasPrice},
function (err, tx_hash) {
if(!err) {
addTransaction({
'hash': tx_hash,
'subject': 'claimTokens',
'token': 'ETH',
'value': 0,
'receipt': null,
'from': walletService.getAddress(),
'to': tokenlaunch_config.auction_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.getTotalRaised(),
factory.getTokenPrice(),
factory.getBlocknumber(),
]).then(function(results) {
updateState({
total_funds: web3.fromWei(results[0]).toString(),
token_price: web3.fromWei(results[1]).toString(),
current_block: results[2],
}, true);
});
};
if (walletService.exists()) {
walletService.restore(factory);
}
walletService.EthereumService = factory;
window.service = factory;
return factory;
}
]);
var app = angular.module('token_launch', [
'LocalStorageModule',
'tokenLaunchServices',
'tokenLaunchFilters',
'ui-notification',
'angular-clipboard',
'tokenLaunchTestTools'
]);
app.controller('StatusCtrl', function($scope, walletService, EthereumService, stateService, Notification, clipboard, $timeout) {
$scope.tokenlaunch_enabled = window.tokenlaunch_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.tokens ? new BigNumber(web3.fromWei(walletService.balances.tokens, 'ether').toFixed(4)).toFormat() : '...';
$scope.eth_balance = walletService.balances.wei ? new BigNumber(web3.fromWei(walletService.balances.wei, 'ether').toFixed(4)).toFormat() : '...';
$scope.commited_eth_balance = 0;
$scope.total_potential_tokens = 0;
$scope.transactions = getTransactions();
$scope.token_price = stateService.tokenPrice;
$scope.stage = stateService.stage;
if(stateService.bid) {
$scope.current_bid = new BigNumber(web3.fromWei(stateService.bid, 'ether').toFixed(4)).toFormat();
$scope.current_tokens = stateService.bid.greaterThan(0) ? new BigNumber(stateService.bid.div(stateService.tokenPrice).toFixed(6)).toFormat() : 0;
}
});
$scope.isBuyShown = function() {
return $scope.is_shown && $scope.stage == stateService.stages.AuctionStarted;
};
$scope.isClaimTokensShown = function() {
return $scope.is_shown && $scope.stage == stateService.stages.AuctionEnded && $scope.current_tokens;
};
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-status").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;
}
if(tokenlaunch_config.testnet) {
Notification.warning('Warning: you are on the ' + tokenlaunch_config.testnet + '. Be careful not to transfer real funds to this account.');
}
clipboard.copyText(walletService.getAddress());
Notification.info('Address copied to clipboard');
};
$scope.openShapeshiftPopup = function($event) {
$event.preventDefault();
if(tokenlaunch_config.testnet) {
alert("Warning: THIS IS A TEST. If you use shapeshift, the resulting funds (ETH) will be available on the live Ethereum network, NOT ON THIS Morden Test-Net!!!\n\nMake sure your lightwallet is backed up before continuing. In the case real ETH is sent to your Test-Net Wallet you can recover your real ETH from the lightwallet here: https://singulardtv.com/lightwallet");
}
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();
stateService.funding_method = null;
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(rpc_web3.eth.gasPrice * 23000);
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;
}
if($scope.withdraw_to == walletService.getAddress()) {
$scope.withdraw_error.to = true;
$scope.withdraw_error.message = 'Destination address should be different than yours';
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 was not sent.');
console.log(err);
}).finally(function() {
$scope.withdrawing = false;
});
}
if($scope.withdraw_token == 'GNO') {
if(walletService.balances.tokens.equals(0)) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = "You don't have any GNO tokens in your wallet";
return false;
}
if(! stateService.tokens_fungible) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = "GNO tokens are not transferable just yet. 1 week should pass from the auction closing date.";
return false;
}
var gas_cost = new BigNumber(rpc_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 = web3.toWei($scope.withdraw_amount);
var tokens_bn = new BigNumber(tokens);
if(tokens_bn.greaterThan(walletService.balances.tokens)) {
$scope.withdraw_error.amount = true;
$scope.withdraw_error.message = 'You can transfer a maximum of ' + web3.fromWei(walletService.balances.tokens) + ' GNO tokens.';
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;
}
if($scope.withdraw_to == walletService.getAddress()) {
$scope.withdraw_error.to = true;
$scope.withdraw_error.message = 'Destination address should be different than yours';
return false;
}
if($scope.withdraw_to == tokenlaunch_config.token_address) {
$scope.withdraw_error.to = true;
$scope.withdraw_error.message = 'Destination address should be different than GNO token contract address';
return false;
}
if($scope.withdraw_to == tokenlaunch_config.auction_address) {
$scope.withdraw_error.to = true;
$scope.withdraw_error.message = 'Destination address should be different than Gnosis Auction contract address';
return false;
}
$scope.withdrawing = true;
stateService.EthereumService.transferTokens($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 was not sent.');
console.log(err);
}).finally(function() {
$scope.withdrawing = false;
});
}
};
var skip_buy_form_recalc = false;
$scope.$watch(function() {
return $scope.buy_eth_amount;
}, function(newVal, oldValue) {
if(! newVal) {
$scope.potential_tokens = null;
$scope.buy_eth_amount = null;
$scope.buy_eth_amount_bn = null;
return;
}
try {
$scope.buy_eth_amount_bn = new BigNumber(newVal);
$scope.potential_tokens = new BigNumber(web3.toWei($scope.buy_eth_amount_bn)).div(stateService.tokenPrice).toNumber();
} catch(e) {
console.error(e);
$scope.buy_eth_amount = oldValue;
}
});
$scope.buyTokens = 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(rpc_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(rpc_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 = 'ETH amount is required';
return false;
}
$scope.buying = true;
stateService.EthereumService.buyTokens(value).then(function(tx_hash) {
Notification.info('Your buy transaction was sent, it may take up to 20 seconds. Awaiting confirmation...');
sendGaEvent('tokenlaunch', 'buy', 'sngls', $scope.buy_sngls_amount);
stateService.EthereumService.waitForTransactionReceipt(tx_hash).then(function() {
Notification.success('Buy transaction confirmed.');
$scope.buying = false;
$scope.buy_eth_amount = null;
EthereumService.updateStatsWidgets();
});
}).catch(function(err) {
Notification.error('Transaction was not sent.');
console.log(err);
$scope.buying = false;
}).finally(function() {
//
});
};
$scope.closeWithdraw = function() {
$scope.withdraw_amount = null;
$scope.withdraw_to = null;
$scope.withdraw_error = {};
$scope.cancelWalletAction();
};
$scope.claimTokens = function() {
$scope.claim_tokens = {};
var gas_cost = new BigNumber(rpc_web3.eth.gasPrice * stateService.EthereumService.DEFAULT_GAS);
var gas_cost_eth = web3.fromWei(gas_cost);
if(gas_cost.greaterThan(walletService.balances.wei)) {
$scope.claim_tokens.message = 'Not enough ETH funds for gas cost. Please deposit at least ' + gas_cost_eth + ' ETH in your account first';
return false;
}
$scope.claim_tokens.loading = true;
stateService.EthereumService.claimTokens().then(function(tx_hash) {
Notification.info('Your claimTokens transaction was sent, it may take up to 20 seconds. Awaiting confirmation...');
stateService.EthereumService.waitForTransactionReceipt(tx_hash).then(function() {
Notification.success('claimTokens transaction confirmed.');
$scope.claim_tokens.loading = false;
});
}).catch(function(err) {
Notification.error('Transaction was not sent.');
console.log(err);
$scope.claim_tokens.loading = false;
}).finally(function() {
//
});
};
$scope.isUsingMetamask = function() {
return walletService.isUsingMetamask();
};
});
app.controller('FundMethodCtrl', function($scope, stateService, walletService, $window, EthereumService, Notification) {
$scope.show_continue = false;
$scope.fund_method = null;
$scope.$watch(function() {
return stateService.funding_method;
}, function(newVal) {
if (!newVal) {
$scope.is_shown = !walletService.exists();
} else {
$scope.is_shown = 0;
}
});
$scope.fundMethodChange = function() {
$scope.show_continue = true;
};
$scope.goToNextStep = function() {
if($scope.fund_method == 'Metamask') {
if(! $window.metamask_web3) {
Notification.error('You need to install Metamask first.');
return false;
}
if(! walletService.isMetamaskProviderSetCorrect()) {
Notification.error($scope.getMetamaskNetworkInstructions());
return false;
}
walletService.useMetamask(true);
walletService.restore(EthereumService);
}
stateService.funding_method = $scope.fund_method;
$scope.fund_method = null;
$scope.show_continue = false;
};
$scope.isMetamaskInstalled = function() {
return $window.metamask_web3 != null;
}
$scope.getMetamaskNetworkInstructions = function() {
if(! $scope.isMetamaskInstalled() || walletService.isMetamaskProviderSetCorrect()) {
return null;
}
var instructions = null;
if(tokenlaunch_config.metamask_provider_type == 'rpc') {
instructions = 'Set metamask network to custom: ' + tokenlaunch_config.default_node + ' and reload the page';
} else {
if(tokenlaunch_config.metamask_provider_type == 'mainnet') {
instructions = 'Set the Metamask netowork to Main Ethereum Network and reload the page';
}
if(tokenlaunch_config.metamask_provider_type == 'testnet') {
instructions = 'Set the Metamask netowork to Morden Test Network and reload the page';
}
}
return instructions;
}
});
app.controller('LightWalletCtrl', function($scope, walletService, $http, stateService, $interval) {
// States
$scope.is_shown = 0;
$scope.wallet_init = 0;
$scope.wallet_generate_seed = 0;
$scope.wallet_password = 0;
$scope.wallet_backup = 0;
$scope.wallet_recover = 0;
$scope.wallet_recover_seed = 0;
$scope.wallet_new_generated = 0;
// Control
$scope.should_restore = 0;
// Info
$scope.wallet_seed = null;
$scope.wallet_data = {
password: '',
password_verify: ''
};
$scope.recovery_seed = null;
$scope.recovery_seed_form_error = 0;
$scope.$watch(function() {
return stateService.funding_method === "Lightwallet" && !walletService.exists();
}, function(newVal) {
if (newVal) {
$scope.is_shown = 1;
$scope.wallet_init = 1;
} else {
$scope.is_shown = 0;
}
});
// Starts the process of lightwallet generation
$scope.initGenerateWallet = function() {
var entropy_limit = 5000;
var percentage = 0;
var interval_timer;
$scope.wallet_init = 0;
$scope.wallet_generate_seed = 1;
// When generating a new wallet, we force the user to recover it afterwards
// to make sure it's safely stored.
$scope.shouldRestore(true);
$scope.should_restore = 1;
// Mark the creation state
stateService.set({
isWalletCreating: true
});
// Style that reflects the amount the bar has filled
$scope.seed_progress = 0;
$scope.fillStyle = {
'width': $scope.seed_progress + '%'
};
// Generate the seed
EntropyCollector.start();
interval_timer = $interval(function() {
if (EntropyCollector.estimatedEntropy > entropy_limit) {
// Sets visual progress
$scope.seed_progress = 100;
$scope.fillStyle = {
'width': $scope.seed_progress + '%'
};
// Saves seed
$scope.wallet_seed = lightwallet.keystore.generateRandomSeed(String.fromCharCode.apply(null, new Uint16Array(EntropyCollector.buffer)));
EntropyCollector.stop();
// Update to next state
$scope.wallet_generate_seed = 0;
$scope.wallet_password = 1;
// Remove event listeners & cancer inverval
document.removeEventListener('mousemove', function() {});
document.removeEventListener('touchmove', function() {});
$interval.cancel(interval_timer);
} else {
percentage = parseInt(EntropyCollector.estimatedEntropy / entropy_limit * 100);
if (percentage > $scope.seed_progress) {
$scope.seed_progress = percentage;
$scope.fillStyle = {
'width': $scope.seed_progress + '%'
};
}
}
}, 1000 / 30);
};
// Validates that wallet password respects our standards
$scope.validateWalletPassword = function() {
if ($scope.wallet_data) {
// password length
if ($scope.wallet_data.password && $scope.wallet_data.password.length < 8) {
$scope.password_form.password.$setValidity('length', false);
} else {
$scope.password_form.password.$setValidity('length', true);
}
// passwords match
if ($scope.wallet_data.password_verify && $scope.wallet_data.password != $scope.wallet_data.password_verify) {
$scope.password_form.password_verify.$setValidity('match', false);
} else {
$scope.password_form.password_verify.$setValidity('match', true);
}
}
};
// Starts creation of wallet
$scope.createWallet = function() {
var action_url = '/token/validate-register-form';
if ($scope.password_form.$valid) {
$scope.creating_wallet = 1; // button spinner on
$http.post(action_url, {
password: $scope.wallet_data.password,
verifypassword: $scope.wallet_data.password_verify,
}).success(function(response, status, headers, config) {
if (response.success === 1) {
$scope.registerWallet($scope.wallet_seed, $scope.wallet_data.password);
}
}).error(function(data, status, headers, config) {
$scope.creating_wallet = 0; // button spinner off
}).finally(function() {});
}
};
$scope.registerWallet = function(seed, password) {
lightwallet.keystore.createVault({
password: password,
seedPhrase: seed
}, function(err, ks) {
ks.keyFromPassword(password, function(err, pwDerivedKey) {
if (err) throw err;
ks.generateNewAddress(pwDerivedKey, 1);
Wallet.keystore = ks;
Wallet.save();
// reset form
$scope.password_form.$setPristine();
$scope.password_form.$setUntouched();
$scope.wallet_data.password = "";
$scope.wallet_data.password_verify = "";
$scope.creating_wallet = 0; // button spinner off
// Update to next state
$scope.wallet_password = 0;
$scope.wallet_backup = 1;
sendGaEvent('lightwallet', 'generated');
});
});
};
// Download wallet
$scope.downloadWallet = function() {
$scope.wallet_backup_continue = 1;
$scope.wallet_backup_email = 0;
Wallet.download();
};
// Email wallet
$scope.emailWallet = function() {
var action_url = '/token/send';
if ($scope.email_form.$valid) {
$scope.email_wallet_submit = 1;
$http.post(action_url, {
keystore: Wallet.keystore.serialize(),
email: $scope.email_wallet.email,
address: Wallet.getAddress()
}).success(function(response, status, headers, config) {
if (response.success === 1) {
$scope.email_wallet_success = 1;
$scope.wallet_backup_continue = 1;
} else {
alert('Our mail server seems to be down. Please try to download the wallet instead.');
}
// Clear form
$scope.email_form.$setPristine();
$scope.email_form.$setUntouched();
$scope.email_wallet.email = "";
$scope.email_wallet_submit = 0;
$scope.wallet_backup_email = 0;
}).error(function(data, status, headers, config) {
alert('Our mail server seems to be down. Please try to download the wallet instead.');
}).finally(function() {});
}
};
$scope.createWalletFinish = function() {
$scope.wallet_backup = 0;
// Set backup screen defaults
$scope.wallet_backup_continue = 0;
$scope.wallet_backup_email = 0;
$scope.email_wallet_success = 0;
if ($scope.should_restore) {
$scope.should_restore = 0;
$scope.wallet_recover = 1;
$scope.wallet_new_generated = 1;
} else {
$scope.endRecovery();
walletService.shouldRestore(false);
}
// Mark finishing of wallet creation
stateService.set({
isWalletCreating: false
});
};
$scope.setRecoveringWallet = function() {
$scope.wallet_init = 0;
$scope.wallet_new_generated = 0;
$scope.wallet_recover = 1;
};
// Should restart everything
$scope.endRecovery = function() {
$scope.wallet_init = 1;
$scope.wallet_generate_seed = 0;
$scope.wallet_password = 0;
$scope.wallet_backup = 0;
$scope.wallet_recover = 0;
$scope.wallet_recover_seed = 0;
$scope.wallet_new_generated = 0;
$scope.should_restore = 0;
$scope.wallet_seed = null;
$scope.wallet_data = {
password: '',
password_verify: ''
};
$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;
}
// Marking the end of seed recovery
$scope.wallet_new_generated = 0;
$scope.wallet_recover = 0;
$scope.wallet_recover_seed = 0;
$scope.recovery_seed_form_error = 0;
// Making user go through the password step
$scope.wallet_seed = $scope.recovery_seed;
$scope.wallet_password = 1;
// Mark we are still creating the wallet
stateService.set({
isWalletCreating: true
});
// TODO: This is what makes walletService.exists() to yield true and keep the creation process w/ password going
walletService.shouldRestore(true);
};
$scope.shouldRestore = function(val) {
walletService.shouldRestore(val);
};
$scope.backToFundingMethods = function() {
stateService.funding_method = null;
};
});
app.controller('PasswordPromptCtrl', function($scope, stateService) {
$scope.$watch(function() {
return stateService.show_password_prompt;
}, function(newVal) {
if (!newVal) {
$scope.is_shown = 0;
} else {
$('html').addClass('popup-open');
$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;
keystore.keyFromPassword($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;
$('html').removeClass('popup-open');
stateService.hidePasswordPrompt();
} else {
$scope.wallet_password_error = true;
$scope.$digest();
}
});
};
$scope.close = function() {
$('html').removeClass('popup-open');
stateService.hidePasswordPrompt();
};
});
app.controller('MistCtrl', function($scope, walletService, stateService, clipboard, Notification) {
$scope.$watch(function() {
return stateService.funding_method;
}, function(newVal) {
if (newVal === "MIST") {
$scope.is_shown = 1;
} else {
$scope.is_shown = 0;
}
});
$scope.copyTokenLaunchAddressToClipboard = function() {
if (!clipboard.supported) {
Notification.error('Sorry, copy to clipboard is not supported on your device');
return false;
}
if(tokenlaunch_config.testnet) {
Notification.warning('Warning: you are on the ' + tokenlaunch_config.testnet + '. Be careful not to transfer real funds to this address.');
}
clipboard.copyText(tokenlaunch_config.crowdfunding_address);
Notification.info('Token Launch Contract Address copied to clipboard');
};
$scope.copyTokenLaunchAbiToClipboard = function() {
if (!clipboard.supported) {
Notification.error('Sorry, copy to clipboard is not supported on your device');
return false;
}
clipboard.copyText('[{"inputs":[],"constant":true,"name":"etherWallet","payable":false,"outputs":[{"type":"address","name":""}],"type":"function"},{"inputs":[],"constant":false,"name":"bid","payable":true,"outputs":[],"type":"function"},{"inputs":[],"constant":true,"name":"FUNDING_GOAL","payable":false,"outputs":[{"type":"uint256","name":""}],"type":"function"},{"inputs":[],"constant":false,"name":"claimTokens","payable":false,"outputs":[],"type":"function"},{"inputs":[],"constant":true,"name":"startBlock","payable":false,"outputs":[{"type":"uint256","name":""}],"type":"function"},{"inputs":[],"constant":true,"name":"finalPrice","payable":false,"outputs":[{"type":"uint256","name":""}],"type":"function"},{"inputs":[],"constant":true,"name":"stage","payable":false,"outputs":[{"type":"uint8","name":""}],"type":"function"},{"inputs":[],"constant":true,"name":"totalRaised","payable":false,"outputs":[{"type":"uint256","name":""}],"type":"function"},{"inputs":[],"constant":false,"name":"calcCurrentTokenPrice","payable":false,"outputs":[{"type":"uint256","name":"tokenPrice"}],"type":"function"},{"inputs":[],"constant":true,"name":"calcStopPrice","payable":false,"outputs":[{"type":"uint256","name":"stopPrice"}],"type":"function"},{"inputs":[],"constant":false,"name":"tokenLaunched","payable":false,"outputs":[{"type":"bool","name":"launched"}],"type":"function"}]');
Notification.info("Gnosis Token Launch Contract's Json Interface copied to clipboard");
};
$scope.copyTokenAddressToClipboard = function() {
if (!clipboard.supported) {
Notification.error('Sorry, copy to clipboard is not supported on your device');
return false;
}
clipboard.copyText(tokenlaunch_config.token_address);
Notification.info('Gnosis Token Contract Address copied to clipboard');
};
$scope.backToFundingMethods = function() {
stateService.funding_method = null;
};
});
app.controller('ChartCtrl', function($scope, $window)
{
var ctx = document.getElementById("myChart");
// var data_points = [];
//var initial_block = 10;
//var final_block = 1000000;
//// Valuation after first day
//for(var i = 1; i<20; i++){
// var block = (final_block - initial_block)/i;
// var valuation = 20000 * 10000000 / ( block-initial_block);
// data_points.push(
// {
// x: block,
// y: valuation
// }
// )
//}
//var customDataPoint = {
// label: 'Valuation',
// data: data_points
//};
//$window.chart = customDataPoint;
var customDataPoint = {
pointBorderColor: 'rgba(0,164,194,1)',
borderColor: 'rgba(0,164,194,1)',
borderCapStyle: 'round',
pointBackgroundColor: '#182a36',
borderWidth: 2,
pointHoverBackgroundColor: 'rgba(0,164,194,1)',
pointHoverBorderColor: '#182a36',
data: [
{
x: 0,
y: 200
},
{
x: 0.5,
// y: 69444444.44
y: 69.45
},
{
x: 1,
// y: 34722222.22
y: 34.72
},
{
x: 2,
// y: 17361111.11
y: 17.36
},
{
x: 3,
// y: 11574074.07
y: 11.57
},
{
x: 4,
// y: 8680555.556
y: 8.68
},
{
x: 5,
// y: 6944444.444
y: 6.94
},
{
x: 6,
// y: 5787037.037
y: 5.79
},
{
x: 7,
// y: 4960317.46
y: 4.96
},
{
x: 8,
// y: 4340277.778
y: 4.34
},
{
x: 9,
// y: 3858024.691
y: 3.86
},
{
x: 10,
// y: 3472222.222
y: 3.47
},
{
x: 11,
// y: 3156565.657
y: 3.16
},
{
x: 12,
// y: 2893518.519
y: 2.89
},
{
x: 13,
// y: 2670940.171
y: 2.67
},
{
x: 14,
// y: 2480158.73
y: 2.48
}
]
};
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
customDataPoint
]
},
options: {
scales: {
xAxes: [{
type: 'linear',
position: 'bottom'
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
legend: {
display: false
},
tooltips: {
backgroundColor: 'rgba(15,27,36,1)',
// X Value of the tooltip as a string
xLabel: "Day",
callbacks: {
title: function(item, data) {
return 'Day '+item[0].xLabel;
},
label: function(item, data) {
return 'Price: ' + (item.yLabel/10).toFixed(3)+' ETH';
},
afterLabel: function(item, data){
return 'Valuation: '+item.yLabel+ 'M ETH';
}
}
}
}
});
});
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();
});
}
});
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment