/* cryptocoins_EDM.gs v2.2.1 License: DonationWare Eric Miller 2014-2015 ---------Just remember we did save you hours of coding!!!---------------- If you like my fork/edits - Donate any coins to my Cryptsy: 9a907c34e3bbe12cf61ab5053004f497173396d6 Fork of https://gist.githubusercontent.com/sergiocampama/7919632/raw/08ab9caae2be1a9b9b5e8551c7687b10795772f6/cryptocoins.gs - Eric Douglas Miller V2.0 [25-02-2014] - Added Bter, ypool, BTCGuild, and BitMinter support [25-02-2014] - Added a Wrapper for "getBalanceforCoin()" v2.1 [26-02-2014] - Added hmac_hash_SHA256 support [26-02-2014] - Added CEXIO support - Limited: Blalances, Rates (depriciated) [26-02-2014] - Added ErrorHandling - infinate retry on error after 1 second pause v2.2 [27-02-2014] - Code reduction and optimizations [27-02-2014] - Example SpreadsheetScreenshot Link: http://imgur.com/R78tD8Y v2.2.1 [27-02-2014] - Commenting ---Based on original source of (https://gist.githubusercontent.com/sergiocampama/7919632/raw/08ab9caae2be1a9b9b5e8551c7687b10795772f6/cryptocoins.gs): Sergio Campamá 2013 - 2014 (Donate BTC to 1kaipigF61pFduHmwUA8aFR6b81HEj17X) - http://kaipi.me - @sergiocampama License: DonationWare v1.3 [22-01-2014] - Added `getCryptsyBalanceForCoin` and `getCryptsyRateForCoin` as proposed by @cosmicdice [26-01-2014] - Added support for rates in other markets as proposed by @elmer1000 [28-01-2014] - Added `getActiveCryptsyBalances` that returns an array with active balances in Cryptsy */ /* User Data */ var cryptsy_private_key = ""; var cryptsy_public_key = ""; var bitminteruser = "" var bitminter_API = ""; var ypool_API = ""; var BTCGuild_API = "" var CEXIO_username = ""; var CEXIO_api_key = ""; var CEXIO_api_secret = ""; var openexchangerate_api_key = ""; /* Get rates */ /* Info: The `nonce` params on some functions are to invalidate the Spreadsheet's cache, just input in a cell with a random value and change it when you want to refresh. */ function getUSDtoCurrency(currency, nonce) {var rates = JSON.parse(UrlFetchApp.fetch("https://openexchangerates.org/api/latest.json?app_id=" + openexchangerate_api_key)).rates; return rates[currency];} function getBTCtoUSD(nonce) {return getBTCtoUSDInExchange("MtGox", nonce);} function getCEXIORate(market,nonce) {var rate = 0; return JSON.parse(UrlFetchApp.fetch("https://cex.io/api/ticker/"+market))["bid"];} function getBTCtoUSDInExchange(exchange_name, nonce) {if (exchange_name == "BitStamp"){return parseFloat(JSON.parse(UrlFetchApp.fetch("https://www.bitstamp.net/api/ticker/")).last);}; return parseInt(JSON.parse(UrlFetchApp.fetch("http://data.mtgox.com/api/2/BTCUSD/money/ticker_fast")).data.last_local.value_int)/1.0e5;} function getCryptsyRateForCoin(coin_code, nonce) {try {return getCryptsyRateForCoinInMarket(coin_code, "BTC", nonce);} catch(err) {Utilities.sleep(1000);return getCryptsyRateForCoin(coin_code, nonce)}} function getCryptsyRateForCoinInMarket(coin_code, market, nonce) {var markets = getCryptsyMarkets(); var coin_rate = 0; if(!!markets[market][coin_code]) {coin_rate = markets[market][coin_code];}; return coin_rate;} var getCryptsyMarkets = function() { var markets = cryptsyRequest({method: "getmarkets"}); var btc_markets = {"BTC": 1}; var ltc_markets = {}; var xpm_markets = {}; markets.forEach(function(market) {if (market.secondary_currency_code == "BTC") {btc_markets[market.primary_currency_code] = market.last_trade} else if (market.secondary_currency_code == "LTC") {ltc_markets[market.primary_currency_code] = market.last_trade;} else if (market.secondary_currency_code == "XPM") {xpm_markets[market.primary_currency_code] = market.last_trade;}}); var ltc_btc = btc_markets["LTC"]; var xpm_btc = btc_markets["XPM"]; for(var market in ltc_markets) {btc_markets[market] = ltc_btc * ltc_markets[market];}; for(var market in xpm_markets) {btc_markets[market] = xpm_btc * xpm_markets[market];}; return {"BTC": btc_markets, "LTC": ltc_markets, "XPM": xpm_markets}; } /* Get balances */ /* Info: The `nonce` params on some functions are to invalidate the Spreadsheet's cache, just input in a cell with a random value and change it when you want to refresh. */ function getBalanceforCoin(location, coin_type, nonce) { if (location.toUpperCase()=="CEX.IO") {return getCEXIOBalanceForCoin(coin_type, nonce)} if (location.toUpperCase()=="BTCGUILD.COM") {return getBTCGuildBalanceForCoin(coin_type, nonce)} if (location.toUpperCase()=="CRYPTSY.COM") {return getCryptsyBalanceForCoin(coin_type, nonce)} if (location.toUpperCase()=="YPOOL.NET") {return getypoolBalanceForCoin(coin_type, nonce)} if (location.toUpperCase()=="BITMINTER.COM") {return getbitminterBalanceForCoin(coin_type, nonce)} } function getypoolBalanceForCoin(coin_code, nonce) {var balance = 0; var response = UrlFetchApp.fetch("http://ypool.net/api/personal_stats?coinType="+coin_code+"&key=" + ypool_API); return JSON.parse(response)["balance"] + JSON.parse(response)["unconfirmedBalance"];} function getCEXIOBalanceForCoin(coin_code, nonce) {try {var balance = 0; var coin_data = JSON.parse(CEXIO_balance())[coin_code]; if (!!coin_data["available"]) {var balance = coin_data["available"];} else {var balance = coin_data["available"] + coin_data["orders"]}; return balance;} catch(err) {Utilities.sleep(1000);return getCEXIOBalanceForCoin(coin_code, nonce);}} function getBTCGuildBalanceForCoin(coin_type, nonce) {try {var balance = 0; var balances = JSON.parse(UrlFetchApp.fetch("https://www.btcguild.com/api.php?api_key=" + BTCGuild_API))["user"]; if (coin_type.toUpperCase() == "BTC") {var tag = "unpaid_rewards"} else {var tag = "unpaid_rewards_"+coin_type.toLowerCase()}; return balances[tag];} catch(err) {Utilities.sleep(1000);return getBTCGuildBalanceForCoin(coin_type, nonce);};} function getbitminterBalanceForCoin(coin_type, nonce) {var balance = 0; var balances = JSON.parse(UrlFetchApp.fetch("https://bitminter.com/api/users/" + bitminteruser + "?key=" + bitminter_API))["balances"]; return balances[coin_type];} function getBterRateForCoin(market, nonce) {try {return JSON.parse(UrlFetchApp.fetch("http://data.bter.com/api/1/ticker/"+market.toLowerCase()))["buy"];} catch(err) {Utilities.sleep(1000);return getBterRateForCoin(market, nonce)};} function getBTCBalance(address, nonce) {return JSON.parse(UrlFetchApp.fetch("https://blockchain.info/address/" + address + "?format=json")).final_balance/1.0e8;} function getCryptsyBalanceEstimated(nonce) {var balances = getCryptsyBalances(); var markets = getCryptsyMarkets()["BTC"]; var estimated_btc = 0; for(var coin in balances) {if (!!markets[coin]) {estimated_btc += markets[coin] * balances[coin];}}; return estimated_btc;} function getActiveCryptsyBalances(nonce) {var balances = getCryptsyBalances(); array_balances = []; for(var p in balances) {if (balances.hasOwnProperty(p) && balances[p] > 0) {array_balances.push([p, balances[p]]);}}; return array_balances;} function getAllCryptsyBalances(nonce) {var balances = getCryptsyBalances(); array_balances = []; for(var p in balances) {if (balances.hasOwnProperty(p) && balances[p] > -1) {array_balances.push([p, balances[p]]);}}; return array_balances;} function getCryptsyBalanceForCoin(coin_code, nonce) {var balances = getCryptsyBalances(); var coin_balance = 0; if(!!balances[coin_code]) {coin_balance = balances[coin_code];}; return coin_balance;} /* Under the hood */ /* Pay no attention to the man behind the curtain - You break it you buy it :) */ var getCryptsyBalances = function() {return cryptsyRequest({method: "getinfo"})["balances_available"];} function CEXIO_ticker(couple) {return CEXIO_api_call('ticker', new Object(), 0, couple)} function CEXIO_order_book(couple) {return CEXIO_api_call('order_book', new Object(), 0, couple)} function CEXIO_trade_history(since,couple) {param = new Object(); param.since = since; return CEXIO_api_call('trade_history', param, 0, couple)} function CEXIO_balance() {param = new Object(); return CEXIO_api_call('balance', param, 1, '')} function CEXIO_open_orders(couple) {return CEXIO_api_call('open_orders', new Object(), 1, couple);} function CEXIO_cancel_order(id) {param = new Object(); param.id = id; return CEXIO_api_call('cancel_order', param, 1, '');} function CEXIO_place_order(type, amount, price, couple) {param = new Object(); param.type = type; param.amount = amount; param.price = price; return CEXIO_api_call('place_order', param, 1, couple)} var cryptsyRequest = function (params) { var nonce = (new Date()).valueOf(); if (!params) {params = {};} params["nonce"] = nonce; var serialized_params = serialize(params); var signature = hmac_hash_SHA512(serialized_params, cryptsy_private_key); var options = {headers: {"Key": cryptsy_public_key, "Sign": signature}, payload: serialized_params, method: "post"} return JSON.parse(UrlFetchApp.fetch("https://www.cryptsy.com/api", options))["return"]; } function CEXIO_api_call(method, param, is_private, couple) { try { if (couple == undefined) {var couple = ''} else {if (couple.length > 5) {url = url + couple +'/'}} if (is_private == undefined) {var is_private = 0} else {if (is_private == 1) { var nonce = (new Date()).valueOf().toString(); var signature = createCEXIOSignature(nonce); var param = {"key": CEXIO_api_key, "signature": signature, "nonce": nonce};}} return UrlFetchApp.fetch("https://cex.io" + '/api/' + method +'/', { "method": "post", "payload" : param });} catch(err) {Utilities.sleep(1000);return CEXIO_api_call(method, param, is_private, couple);}; } function createCEXIOSignature(nonce) {return hmac_hash_SHA256(nonce + CEXIO_username + CEXIO_api_key, CEXIO_api_secret).toUpperCase();} var serialize = function(obj) {var str = []; for(var p in obj) {if (obj.hasOwnProperty(p)) {str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));}}; return str.join("&");} var hmac_hash_SHA512 = function(params, private_key) {return CryptoJS.HmacSHA512(params, private_key).toString();} var hmac_hash_SHA256 = function(params, private_key) {return CryptoJS.HmacSHA256(params, private_key).toString();} /* CryptoJS v3.1.2 -- SHA512 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ var CryptoJS=CryptoJS||function(a,j){var c={},b=c.lib={},f=function(){},l=b.Base={extend:function(a){f.prototype=this;var d=new f;a&&d.mixIn(a);d.hasOwnProperty("init")||(d.init=function(){d.$super.init.apply(this,arguments)});d.init.prototype=d;d.$super=this;return d},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var d in a)a.hasOwnProperty(d)&&(this[d]=a[d]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, u=b.WordArray=l.extend({init:function(a,d){a=this.words=a||[];this.sigBytes=d!=j?d:4*a.length},toString:function(a){return(a||m).stringify(this)},concat:function(a){var d=this.words,M=a.words,e=this.sigBytes;a=a.sigBytes;this.clamp();if(e%4)for(var b=0;b>>2]|=(M[b>>>2]>>>24-8*(b%4)&255)<<24-8*((e+b)%4);else if(65535>>2]=M[b>>>2];else d.push.apply(d,M);this.sigBytes+=a;return this},clamp:function(){var D=this.words,d=this.sigBytes;D[d>>>2]&=4294967295<< 32-8*(d%4);D.length=a.ceil(d/4)},clone:function(){var a=l.clone.call(this);a.words=this.words.slice(0);return a},random:function(D){for(var d=[],b=0;b>>2]>>>24-8*(e%4)&255;b.push((c>>>4).toString(16));b.push((c&15).toString(16))}return b.join("")},parse:function(a){for(var d=a.length,b=[],e=0;e>>3]|=parseInt(a.substr(e, 2),16)<<24-4*(e%8);return new u.init(b,d/2)}},y=k.Latin1={stringify:function(a){var b=a.words;a=a.sigBytes;for(var c=[],e=0;e>>2]>>>24-8*(e%4)&255));return c.join("")},parse:function(a){for(var b=a.length,c=[],e=0;e>>2]|=(a.charCodeAt(e)&255)<<24-8*(e%4);return new u.init(c,b)}},z=k.Utf8={stringify:function(a){try{return decodeURIComponent(escape(y.stringify(a)))}catch(b){throw Error("Malformed UTF-8 data");}},parse:function(a){return y.parse(unescape(encodeURIComponent(a)))}}, x=b.BufferedBlockAlgorithm=l.extend({reset:function(){this._data=new u.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=z.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(b){var d=this._data,c=d.words,e=d.sigBytes,l=this.blockSize,k=e/(4*l),k=b?a.ceil(k):a.max((k|0)-this._minBufferSize,0);b=k*l;e=a.min(4*b,e);if(b){for(var x=0;xm;m++)k[m]=a();b=b.SHA512=c.extend({_doReset:function(){this._hash=new l.init([new f.init(1779033703,4089235720),new f.init(3144134277,2227873595),new f.init(1013904242,4271175723),new f.init(2773480762,1595750129),new f.init(1359893119,2917565137),new f.init(2600822924,725511199),new f.init(528734635,4215389547),new f.init(1541459225,327033209)])},_doProcessBlock:function(a,b){for(var c=this._hash.words, f=c[0],j=c[1],d=c[2],l=c[3],e=c[4],m=c[5],N=c[6],c=c[7],aa=f.high,O=f.low,ba=j.high,P=j.low,ca=d.high,Q=d.low,da=l.high,R=l.low,ea=e.high,S=e.low,fa=m.high,T=m.low,ga=N.high,U=N.low,ha=c.high,V=c.low,r=aa,n=O,G=ba,E=P,H=ca,F=Q,Y=da,I=R,s=ea,p=S,W=fa,J=T,X=ga,K=U,Z=ha,L=V,t=0;80>t;t++){var A=k[t];if(16>t)var q=A.high=a[b+2*t]|0,g=A.low=a[b+2*t+1]|0;else{var q=k[t-15],g=q.high,v=q.low,q=(g>>>1|v<<31)^(g>>>8|v<<24)^g>>>7,v=(v>>>1|g<<31)^(v>>>8|g<<24)^(v>>>7|g<<25),C=k[t-2],g=C.high,h=C.low,C=(g>>>19| h<<13)^(g<<3|h>>>29)^g>>>6,h=(h>>>19|g<<13)^(h<<3|g>>>29)^(h>>>6|g<<26),g=k[t-7],$=g.high,B=k[t-16],w=B.high,B=B.low,g=v+g.low,q=q+$+(g>>>0>>0?1:0),g=g+h,q=q+C+(g>>>0>>0?1:0),g=g+B,q=q+w+(g>>>0>>0?1:0);A.high=q;A.low=g}var $=s&W^~s&X,B=p&J^~p&K,A=r&G^r&H^G&H,ka=n&E^n&F^E&F,v=(r>>>28|n<<4)^(r<<30|n>>>2)^(r<<25|n>>>7),C=(n>>>28|r<<4)^(n<<30|r>>>2)^(n<<25|r>>>7),h=u[t],la=h.high,ia=h.low,h=L+((p>>>14|s<<18)^(p>>>18|s<<14)^(p<<23|s>>>9)),w=Z+((s>>>14|p<<18)^(s>>>18|p<<14)^(s<<23|p>>>9))+(h>>> 0>>0?1:0),h=h+B,w=w+$+(h>>>0>>0?1:0),h=h+ia,w=w+la+(h>>>0>>0?1:0),h=h+g,w=w+q+(h>>>0>>0?1:0),g=C+ka,A=v+A+(g>>>0>>0?1:0),Z=X,L=K,X=W,K=J,W=s,J=p,p=I+h|0,s=Y+w+(p>>>0>>0?1:0)|0,Y=H,I=F,H=G,F=E,G=r,E=n,n=h+g|0,r=w+A+(n>>>0>>0?1:0)|0}O=f.low=O+n;f.high=aa+r+(O>>>0>>0?1:0);P=j.low=P+E;j.high=ba+G+(P>>>0>>0?1:0);Q=d.low=Q+F;d.high=ca+H+(Q>>>0>>0?1:0);R=l.low=R+I;l.high=da+Y+(R>>>0>>0?1:0);S=e.low=S+p;e.high=ea+s+(S>>>0

>>0?1:0);T=m.low=T+J;m.high=fa+W+(T>>>0>>0?1: 0);U=N.low=U+K;N.high=ga+X+(U>>>0>>0?1:0);V=c.low=V+L;c.high=ha+Z+(V>>>0>>0?1:0)},_doFinalize:function(){var a=this._data,b=a.words,c=8*this._nDataBytes,f=8*a.sigBytes;b[f>>>5]|=128<<24-f%32;b[(f+128>>>10<<5)+30]=Math.floor(c/4294967296);b[(f+128>>>10<<5)+31]=c;a.sigBytes=4*b.length;this._process();return this._hash.toX32()},clone:function(){var a=c.clone.call(this);a._hash=this._hash.clone();return a},blockSize:32});j.SHA512=c._createHelper(b);j.HmacSHA512=c._createHmacHelper(b)})(); (function(){var a=CryptoJS,j=a.enc.Utf8;a.algo.HMAC=a.lib.Base.extend({init:function(a,b){a=this._hasher=new a.init;"string"==typeof b&&(b=j.parse(b));var f=a.blockSize,l=4*f;b.sigBytes>l&&(b=a.finalize(b));b.clamp();for(var u=this._oKey=b.clone(),k=this._iKey=b.clone(),m=u.words,y=k.words,z=0;z>>2]|=(d[e>>>2]>>>24-8*(e%4)&255)<<24-8*((b+e)%4);else if(65535>>2]=d[e>>>2];else c.push.apply(c,d);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< 32-8*(c%4);a.length=h.ceil(c/4)},clone:function(){var a=m.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],d=0;d>>2]>>>24-8*(b%4)&255;d.push((e>>>4).toString(16));d.push((e&15).toString(16))}return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>3]|=parseInt(a.substr(b, 2),16)<<24-4*(b%8);return new r.init(d,c/2)}},n=l.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var d=[],b=0;b>>2]>>>24-8*(b%4)&255));return d.join("")},parse:function(a){for(var c=a.length,d=[],b=0;b>>2]|=(a.charCodeAt(b)&255)<<24-8*(b%4);return new r.init(d,c)}},j=l.Utf8={stringify:function(a){try{return decodeURIComponent(escape(n.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return n.parse(unescape(encodeURIComponent(a)))}}, u=g.BufferedBlockAlgorithm=m.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=j.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,d=c.words,b=c.sigBytes,e=this.blockSize,f=b/(4*e),f=a?h.ceil(f):h.max((f|0)-this._minBufferSize,0);a=f*e;b=h.min(4*a,b);if(a){for(var g=0;gn;){var j;a:{j=k;for(var u=h.sqrt(j),t=2;t<=u;t++)if(!(j%t)){j=!1;break a}j=!0}j&&(8>n&&(m[n]=l(h.pow(k,0.5))),r[n]=l(h.pow(k,1/3)),n++);k++}var a=[],f=f.SHA256=q.extend({_doReset:function(){this._hash=new g.init(m.slice(0))},_doProcessBlock:function(c,d){for(var b=this._hash.words,e=b[0],f=b[1],g=b[2],j=b[3],h=b[4],m=b[5],n=b[6],q=b[7],p=0;64>p;p++){if(16>p)a[p]= c[d+p]|0;else{var k=a[p-15],l=a[p-2];a[p]=((k<<25|k>>>7)^(k<<14|k>>>18)^k>>>3)+a[p-7]+((l<<15|l>>>17)^(l<<13|l>>>19)^l>>>10)+a[p-16]}k=q+((h<<26|h>>>6)^(h<<21|h>>>11)^(h<<7|h>>>25))+(h&m^~h&n)+r[p]+a[p];l=((e<<30|e>>>2)^(e<<19|e>>>13)^(e<<10|e>>>22))+(e&f^e&g^f&g);q=n;n=m;m=h;h=j+k|0;j=g;g=f;f=e;e=k+l|0}b[0]=b[0]+e|0;b[1]=b[1]+f|0;b[2]=b[2]+g|0;b[3]=b[3]+j|0;b[4]=b[4]+h|0;b[5]=b[5]+m|0;b[6]=b[6]+n|0;b[7]=b[7]+q|0},_doFinalize:function(){var a=this._data,d=a.words,b=8*this._nDataBytes,e=8*a.sigBytes; d[e>>>5]|=128<<24-e%32;d[(e+64>>>9<<4)+14]=h.floor(b/4294967296);d[(e+64>>>9<<4)+15]=b;a.sigBytes=4*d.length;this._process();return this._hash},clone:function(){var a=q.clone.call(this);a._hash=this._hash.clone();return a}});s.SHA256=q._createHelper(f);s.HmacSHA256=q._createHmacHelper(f)})(Math); (function(){var h=CryptoJS,s=h.enc.Utf8;h.algo.HMAC=h.lib.Base.extend({init:function(f,g){f=this._hasher=new f.init;"string"==typeof g&&(g=s.parse(g));var h=f.blockSize,m=4*h;g.sigBytes>m&&(g=f.finalize(g));g.clamp();for(var r=this._oKey=g.clone(),l=this._iKey=g.clone(),k=r.words,n=l.words,j=0;j