-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpinknetwork.min.js
1 lines (1 loc) · 15.6 KB
/
pinknetwork.min.js
1
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){const bankroll_management=require("./bankroll-management");module.exports=function(io,fetch){const API_ENDPOINT="https://api.pink.network/wax/bankroll/";class BankrollAPI{constructor(){this.roll_subscription=new RollSubscription;this.cycle_roll_subscriptions={}}getRollSubscription(){return this.roll_subscription}getCycleRollSubscription(roll_id){if(typeof this.cycle_roll_subscriptions[String(roll_id)]==="undefined"){this.cycle_roll_subscriptions[String(roll_id)]=new CycleRollSubscription(roll_id)}return this.cycle_roll_subscriptions[String(roll_id)]}createBetConfigByMultiplier(multiplier,rake,max_roll=1e4){let lower_bound=1;let upper_bound=Math.floor((99-rake)/(100*multiplier)*max_roll);return new BetConfig(multiplier,lower_bound,upper_bound,max_roll)}createBetConfigByRange(lower_bound,upper_bound,rake,max_roll=1e4){let odds=(upper_bound-lower_bound+1)/max_roll;let multiplier=(99-rake)/(100*odds);return new BetConfig(multiplier.toFixed(3),lower_bound,upper_bound,max_roll)}createBetConfig(multiplier,lower_bound,upper_bound,max_roll=1e4){return new BetConfig(multiplier,lower_bound,upper_bound,max_roll)}createRollTransactionMemo(amount,rake_recipient,bet_config){if(amount>this.getRollSubscription().getMaxBet(amount,bet_config)){return false}let identifier=random_hex_string(16);let client_seed=random_hex_string(16);this.getRollSubscription().subscribeIdentifier(identifier);return{quantity:parseFloat(amount).toFixed(8)+" WAX",identifier:identifier,client_seed:client_seed,memo:"#bet "+Math.floor(bet_config.getMultiplier()*1e3)+" "+bet_config.getLowerBound()+" "+bet_config.getUpperBound()+" "+rake_recipient+" "+identifier+" "+client_seed}}createCycleRollTransactionMemo(roll_id,amount,bet_config){if(amount>this.getCycleRollSubscription(roll_id).getMaxBet(amount,bet_config)){return false}let client_seed=random_hex_string(16);return{quantity:parseFloat(amount).toFixed(8)+" WAX",client_seed:client_seed,memo:"#join "+roll_id+" "+Math.floor(bet_config.getMultiplier()*1e3)+" "+bet_config.getLowerBound()+" "+bet_config.getUpperBound()+" "+client_seed}}async getRollHistory(limit=50,page=1,rake_recipient=null,bettor=null){let resp=await this.request("rolls",{limit:limit,page:page,rake_recipient:rake_recipient,bettor:bettor});if(resp["success"]){return resp["data"]}throw resp}async getRollResult(roll_id){let resp=await this.request("rolls/"+roll_id);if(resp["success"]){return resp["data"]}throw resp}async getRollRanking(rake_recipient=null,sort="wagered",time=0,limit=50,page=1){let resp=await this.request("rolls/ranking",{rake_recipient:rake_recipient,sort:sort,time:time,limit:limit,page:page});if(resp["success"]){return resp["data"]}throw resp}async getRollAccountRanking(account,rake_recipient=null,time=0){let resp=await this.request("rolls/ranking/"+account,{time:time,rake_recipient:rake_recipient});if(resp["success"]){return resp["data"]}throw resp}async getCycleRollInfo(roll_id){let resp=await this.request("cycles/info/"+roll_id);if(resp["success"]){return resp["data"]}throw resp}async getCycleRollRanking(roll_id,sort="wagered",time=0,limit=50,page=1){let resp=await this.request("cycles/ranking/"+roll_id,{sort:sort,time:time,limit:limit,page:page});if(resp["success"]){return resp["data"]}throw resp}async getCycleRollAccountRanking(roll_id,account,time=0){let resp=await this.request("cycles/ranking/"+roll_id+"/"+account,{time:time});if(resp["success"]){return resp["data"]}throw resp}async getCycleRollHistory(roll_id,limit=50,page=1,bettor=null){let resp=await this.request("cycles/"+roll_id,{limit:limit,page:page,bettor:bettor});if(resp["success"]){return resp["data"]}throw resp}async getCycleRollResult(roll_id,cycle_id){let resp=await this.request("cycles/"+roll_id+"/"+cycle_id);if(resp["success"]){return resp["data"]}throw resp}async getBankrollBalance(){let resp=await this.request("available-funds/latest");if(resp["success"]){return resp["data"]}throw resp}async getBankrollBalanceHistory(step=3600*6,time=0){let resp=await this.request("available-funds",{step:step,time:time});if(resp["success"]){return resp["data"]}throw resp}async getExchangeRate(token_1="pink",token_2="wax"){let resp=await this.request("exchange-rate/"+token_1+"-"+token_2+"/latest");if(resp["success"]){return resp["data"]}throw resp}async getExchangeRateHistory(token_1="pink",token_2="wax",step=3600*6,time=0){let resp=await this.request("exchange-rate/"+token_1+"-"+token_2,{step:step,time:time});if(resp["success"]){return resp["data"]}throw resp}async getBankrollProfit(){let resp=await this.request("profit/latest");if(resp["success"]){return resp["data"]}throw resp}async getBankrollProfitHistory(step=3600*6,time=0){let resp=await this.request("profit",{step:step,time:time});if(resp["success"]){return resp["data"]}throw resp}async request(endpoint,params={},version=1,method="GET"){let url=API_ENDPOINT+"v"+version+"/"+endpoint;let querystring="";if(method==="GET"){for(let key in params){if(params[key]===null){continue}if(querystring!==""){querystring+="&"}querystring+=key+"="+encodeURIComponent(params[key])}if(querystring.length>0){url+="?"+querystring}}try{if(method.toLowerCase()==="get"){return(await fetch(url,{mode:"cors"})).json()}else if(method.toLowerCase()==="post"){return(await fetch(url,{method:"post",mode:"cors",body:JSON.stringify(params),headers:{"Content-Type":"application/json"}})).json()}throw{code:500,message:"Internal Server Error"}}catch(e){return{success:false,data:null,code:500,message:String(e)}}}}class BetConfig{constructor(multiplier,lower_bound,upper_bound,max_roll=1e4){this.lower_bound=lower_bound;this.upper_bound=upper_bound;this.multiplier=multiplier;this.max_roll=max_roll;if(lower_bound<1||lower_bound>upper_bound||upper_bound>max_roll){throw new Error("The bet has illegal bounds")}if((upper_bound-lower_bound+1)/max_roll*multiplier>.99){throw new Error("The bet can't have an EV higher than 0.99")}}getLowerBound(){return this.lower_bound}getUpperBound(){return this.upper_bound}getMultiplier(){return this.multiplier}getMaxRoll(){return this.max_roll}}class RollSubscription{constructor(){this.socket=io(API_ENDPOINT+"v1/rolls",{path:"/wax/bankroll/socket",forceNew:true});this.bankroll=0;let self=this;this.socket.on("bankroll_update",function(data){self.bankroll=data})}subscribeRakeRecipient(wax_account){this.socket.emit("subscribe_rake_recipient",wax_account)}subscribeIdentifier(identifier){this.socket.emit("subscribe_identifier",identifier)}subscribeAll(){this.socket.emit("subscribe_all",null)}onNewRollResult(cb){this.socket.on("new_roll",cb)}onBankrollUpdate(cb){this.socket.on("bankroll_update",cb)}getMaxBet(bet_config){return.95*bankroll_management.getMaxBet([],bet_config,this.bankroll)}}class CycleRollSubscription{constructor(roll_id){this.socket=io(API_ENDPOINT+"v1/cycles/"+roll_id,{path:"/wax/bankroll/socket",forceNew:true});this.bankroll=0;this.bets=[];let self=this;this.socket.on("bankroll_update",function(data){self.bankroll=data});this.socket.on("new_roll",function(data){self.bets=[]});this.socket.on("new_bet",function(data){self.bets.push(data)});this.socket.on("bankroll_update",function(data){self.bankroll=data})}onBankrollUpdate(cb){this.socket.on("bankroll_update",cb)}onNewRollResult(cb){this.socket.on("new_roll",cb)}onNewBet(cb){this.socket.on("new_bet",cb)}onRollReduction(cb){this.socket.on("roll_reduction",cb)}getMaxBet(bet_config){return.95*bankroll_management.getMaxBet(this.bets,bet_config,this.bankroll)}}function random_hex_string(length){let result="";let characters="0123456789abcdef";let charactersLength=characters.length;for(let i=0;i<length;i++){result+=characters.charAt(Math.floor(Math.random()*charactersLength))}return result}return BankrollAPI}},{"./bankroll-management":2}],2:[function(require,module,exports){class ChainedRange{constructor(lowerBound,upperBound,payout){this.next=null;this.lower_bound=lowerBound;this.upper_bound=upperBound;this.payout=payout}insertBet(bet){if(bet.upper_bound>this.upper_bound){this.next.insertBet(bet)}if(bet.lower_bound<=this.upper_bound){if(bet.lower_bound<=this.lower_bound){if(bet.upper_bound>=this.upper_bound){this.payout+=parseFloat(bet.amount)*parseFloat(bet.multiplier)}else{const newRange=new ChainedRange(bet.upper_bound+1,this.upper_bound,this.payout);this.upper_bound=bet.upper_bound;this.insertNextRange(newRange);this.payout+=parseFloat(bet.amount)*parseFloat(bet.multiplier)}}else{if(bet.upper_bound>=this.upper_bound){const newRange=new ChainedRange(bet.lower_bound,this.upper_bound,this.payout+parseFloat(bet.amount)*parseFloat(bet.multiplier));this.upper_bound=bet.lower_bound-1;this.insertNextRange(newRange)}else{const newMiddleRange=new ChainedRange(bet.lower_bound,bet.upper_bound,this.payout+parseFloat(bet.amount)*parseFloat(bet.multiplier));const newRightRange=new ChainedRange(bet.upper_bound+1,this.upper_bound,this.payout);this.upper_bound=bet.lower_bound-1;this.insertNextRange(newMiddleRange);newMiddleRange.insertNextRange(newRightRange)}}}}insertNextRange(nextRange){nextRange.next=this.next;this.next=nextRange}}function calculateMinBankroll(chainedRangeStart,amountCollected,maxResult){let variance=0;let currentRange=chainedRangeStart;while(currentRange!==null){if(currentRange.payout>amountCollected){const odds=(currentRange.upper_bound-currentRange.lower_bound+1)/maxResult;const maxBetFactor=5/Math.sqrt(1/odds-1)-.2;const effectivePayout=currentRange.payout-amountCollected+currentRange.payout*odds;variance+=Math.pow(effectivePayout*odds/maxBetFactor,3)}currentRange=currentRange.next}return Math.cbrt(variance)*125}function simulateMinBankrollWithInsertedBet(chainedRangeStart,amountCollected,maxResult,betRanges,betAmount,betMultiplier,betEV){for(let i in betRanges){betRanges[i].payout+=betAmount*betMultiplier}const minBankroll=calculateMinBankroll(chainedRangeStart,amountCollected+betAmount*(.007+betEV),maxResult);for(let i in betRanges){betRanges[i].payout-=betAmount*betMultiplier}return minBankroll}function getMaxBet(bets,betConfig,bankroll){const firstRange=new ChainedRange(1,betConfig.max_roll,0);let totalAmountBet=0;for(let i in bets){firstRange.insertBet(bets[i]);const ev=(bets[i].upper_bound-bets[i].lower_bound+1)/betConfig.max_roll*parseFloat(bets[i].multiplier);totalAmountBet+=parseFloat(bets[i].amount)*(.007+ev)}firstRange.insertBet({lower_bound:betConfig.lower_bound,upper_bound:betConfig.upper_bound,amount:"0",multiplier:"0"});const betRanges=[];let currentRange=firstRange;while(currentRange!=null){if(currentRange.lower_bound<=betConfig.upper_bound&¤tRange.upper_bound>=betConfig.lower_bound){betRanges.push(currentRange)}currentRange=currentRange.next}const odds=(betConfig.upper_bound-betConfig.lower_bound+1)/betConfig.max_roll;const maxBetFactor=5/Math.sqrt(1/odds-1)-.2;let soloMaxBet=bankroll*maxBetFactor/125*2;const betEV=betConfig.multiplier*odds;for(let i=100;i>=0;i--){const amount=i/100*soloMaxBet;const difference=simulateMinBankrollWithInsertedBet(firstRange,totalAmountBet,betConfig.max_roll,betRanges,amount,betConfig.multiplier,betEV)-bankroll;if(difference<0){return amount*.99}}return 0}module.exports={getMaxBet:getMaxBet}},{}],3:[function(require,module,exports){pinknetwork={bankroll:require("./bankroll-core")(io,fetch),chat:require("./chat-core")(io,fetch)}},{"./bankroll-core":1,"./chat-core":4}],4:[function(require,module,exports){module.exports=function(io,fetch){const API_ENDPOINT="https://api.pink.network/wax/chat/";class ChatAPI{constructor(room){this.socket=io(API_ENDPOINT+"v1/rooms/"+room,{path:"/wax/chat/socket",forceNew:true});let self=this;this.room=room;this.nonce=null;this.authenticated=false;this.sig_sent=false;this.socket.on("login",function(){self.authenticated=true});this.socket.on("logout",function(){self._delete_cookie("chat-auth:"+self.room);self.authenticated=false});this.socket.on("authenticate",function(msg){self.authenticated=false;self.sig_sent=false;self.nonce=msg;if(self._get_cookie("chat-auth:"+self.room)){self.socket.emit("authenticate",self._get_cookie("chat-auth:"+self.room))}})}login(signature,publicKey,account){if(this.sig_sent){return}this.sig_sent=true;this.socket.emit("login",{pub:publicKey,sig:signature,account:account})}async authenticate_arbitrary(signature,publicKey,account,stay_logged_in=true){if(this.isAuthenticated()){return}let self=this;let auth_token=await this.request("authenticate",{method:"arbitrary",room:self.room,account:account,public_key:publicKey,signature:signature,nonce:self.nonce},1,"POST");if(stay_logged_in){self._set_cookie("chat-auth:"+self.room,auth_token["data"])}if(auth_token["success"]!==true){return null}this.socket.emit("authenticate",auth_token["data"]);return auth_token["data"]}async authenticate_transaction(signature,publicKey,account,permission,stay_logged_in=true){if(this.isAuthenticated()){return}let self=this;let auth_token=await this.request("authenticate",{method:"transaction",room:self.room,account:account,permission:permission,public_key:publicKey,signature:signature,nonce:self.nonce},1,"POST");if(stay_logged_in){self._set_cookie("chat-auth:"+self.room,auth_token["data"])}if(auth_token["success"]!==true){return null}this.socket.emit("authenticate",auth_token["data"]);return auth_token["data"]}async logout(){if(!this.isAuthenticated()){return}if(this._get_cookie("chat-auth:"+this.room)){await this.request("logout",{token:this._get_cookie("chat-auth:"+this.room)},1,"POST");this._delete_cookie("chat-auth:"+this.room)}this.socket.emit("logout")}isAuthenticated(){return this.authenticated}getNonce(){return this.nonce}getAuthenticationSignText(){return"chat "+this.room+" "+this.nonce}getAuthenticationTransaction(account,permission){let self=this;return{actions:[{account:"pinknetworkx",name:"chatauth",authorization:[{actor:account,permission:permission}],data:{room:self.room,nonce:self.nonce}}],expiration:"2019-06-05T12:00:00.000",ref_block_num:1,ref_block_prefix:405914617}}send(message){this.socket.emit("chat_message",message)}onError(cb){this.socket.on("error_message",cb)}onLoad(cb){this.socket.on("chat_load",cb)}onMessage(cb){this.socket.on("chat_message",cb)}onLogout(cb){this.socket.on("logout",cb)}onLogin(cb){this.socket.on("login",cb)}async request(endpoint,params={},version=1,method="GET"){let url=API_ENDPOINT+"v"+version+"/"+endpoint;let querystring="";if(method==="GET"){for(let key in params){if(params[key]===null){continue}if(querystring!==""){querystring+="&"}querystring+=key+"="+encodeURIComponent(params[key])}if(querystring.length>0){url+="?"+querystring}}try{if(method.toLowerCase()==="get"){return(await fetch(url,{mode:"cors"})).json()}else if(method.toLowerCase()==="post"){return(await fetch(url,{method:"post",mode:"cors",body:JSON.stringify(params),headers:{"Content-Type":"application/json"}})).json()}throw{code:500,message:"Internal Server Error"}}catch(e){return{success:false,data:null,code:500,message:String(e)}}}_set_cookie(name,value,days=365){if(!document.cookie){return}let expires="";if(days){let date=new Date;date.setTime(date.getTime()+days*24*60*60*1e3);expires="; expires="+date.toUTCString()}document.cookie=name+"="+(value||"")+expires+"; path=/"}_get_cookie(name){if(!document.cookie){return null}let nameEQ=name+"=";let ca=document.cookie.split(";");for(let i=0;i<ca.length;i++){let c=ca[i];while(c.charAt(0)==" "){c=c.substring(1,c.length)}if(c.indexOf(nameEQ)==0){return c.substring(nameEQ.length,c.length)}}return null}_delete_cookie(name){if(document.cookie){document.cookie=name+"=; Max-Age=-99999999;"}}}return ChatAPI}},{}]},{},[3]);