def getaddress(ctx): '''Resends the user's current account address''' # Author is a Member id = ctx.message.author.id if not is_registered(id): yield from bot.say( 'You are not registered. Use ?register to create an account.') return dconn = Bitcoind('~/.dashcore/dash.conf', rpcport=19998) # testnet, 9998 is realnet addr = dconn.getaccountaddress(id) dconn.setaccount(addr, id) # Generate and save a QR code with the address im = qrcode.make(addr) filename = '/tmp/' + addr + '.png' im.save(filename, 'png') yield from bot.say('Your tip wallet address is %s.' % (addr)) yield from bot.send_file(ctx.message.channel, filename) # Clean up the image file os.remove(filename)
class HaikuberuCoin(object): """ Coin class for cointip bot """ conn = None conf = None def __init__(self, _conf=None): """ Initialize CtbCoin with given parameters. _conf is a coin config dictionary defined in conf/coins.yml """ # verify _conf is a config dictionary if not _conf or not hasattr(_conf, 'name') or not hasattr( _conf, 'config_file') or not hasattr(_conf, 'txfee'): raise Exception("CtbCoin::__init__(): _conf is empty or invalid") self.conf = _conf # connect to coin daemon try: lg.debug("CtbCoin::__init__(): connecting to %s...", self.conf.name) self.conn = Bitcoind(self.conf.config_file, rpcserver=self.conf.config_rpcserver) except BitcoindException as e: lg.error( "CtbCoin::__init__(): error connecting to %s using %s: %s", self.conf.name, self.conf.config_file, e) raise lg.info("CtbCoin::__init__():: connected to %s", self.conf.name) time.sleep(0.5) # set transaction fee lg.info("Setting tx fee of %f", self.conf.txfee) self.conn.settxfee(self.conf.txfee) def getbalance(self, _user=None, _minconf=None): """ Get user's tip or withdraw balance. _minconf is number of confirmations to use. Returns (float) balance """ lg.debug("CtbCoin::getbalance(%s, %s)", _user, _minconf) user = self.verify_user(_user=_user) minconf = self.verify_minconf(_minconf=_minconf) balance = Decimal(0) try: balance = self.conn.getbalance(user, minconf) except BitcoindException as e: lg.error( "CtbCoin.getbalance(): error getting %s (minconf=%s) balance for %s: %s", self.conf.name, minconf, user, e) raise time.sleep(0.5) return Decimal(balance) def getinfo(self): try: info = self.conn.getinfo() except BitcoindException as e: raise time.sleep(0.5) return info def sendtouser(self, _userfrom=None, _userto=None, _amount=None, _minconf=1): """ Transfer (move) coins to user Returns (bool) """ lg.debug("CtbCoin::sendtouser(%s, %s, %s)", _userfrom, _userto, _amount) #time.sleep(0.5) return True def sendtoaddr(self, _userfrom=None, _addrto=None, _amount=None): """ Send coins to address Returns (string) txid """ lg.debug("CtbCoin::sendtoaddr(%s, %s, %s)", _userfrom, _addrto, _amount) userfrom = self.verify_user(_user=_userfrom) addrto = self.verify_addr(_addr=_addrto) amount = float(self.verify_amount(_amount=_amount)) minconf = self.verify_minconf(_minconf=self.conf.minconf.withdraw) txid = "" self.conn.settxfee(self.conf.txfee) # send request to coin daemon try: lg.info("CtbCoin::sendtoaddr(): sending %s %s from %s to %s", amount, self.conf.name, userfrom, addrto) # Unlock wallet, if applicable if hasattr(self.conf, 'walletpassphrase'): lg.debug("CtbCoin::sendtoaddr(): unlocking wallet...") self.conn.walletpassphrase(self.conf.walletpassphrase, 1) # Perform transaction lg.debug("CtbCoin::sendtoaddr(): calling sendfrom()...") txid = self.conn.sendtoaddress(addrto, amount) # Lock wallet, if applicable if hasattr(self.conf, 'walletpassphrase'): lg.debug("CtbCoin::sendtoaddr(): locking wallet...") self.conn.walletlock() except Exception as e: lg.error( "CtbCoin::sendtoaddr(): error sending %s %s from %s to %s: %s", amount, self.conf.name, userfrom, addrto, e) raise time.sleep(0.5) return str(txid) def validateaddr(self, _addr=None): """ Verify that _addr is a valid coin address Returns (bool) """ lg.debug("CtbCoin::validateaddr(%s)", _addr) addr = self.verify_addr(_addr=_addr) addr_valid = self.conn.validateaddress(addr) time.sleep(0.5) if not addr_valid.has_key('isvalid') or not addr_valid['isvalid']: lg.debug("CtbCoin::validateaddr(%s): not valid", addr) return False else: lg.debug("CtbCoin::validateaddr(%s): valid", addr) return True def get_account_addr(self, _user=None): """ Verify that _user has a coin address returns (string) address """ addr = None addr = self.conn.getaccountaddress(_user) time.sleep(0.5) return addr def getnewaddr(self, _user=None): """ Generate a new address for _user Returns (string) address """ user = self.verify_user(_user=_user) addr = "" counter = 0 while True: try: # Unlock wallet for keypoolrefill if hasattr(self.conf, 'walletpassphrase'): self.conn.walletpassphrase(self.conf.walletpassphrase, 1) # Generate new address addr = self.conn.getnewaddress(user) # Lock wallet if hasattr(self.conf, 'walletpassphrase'): self.conn.walletlock() if not addr: raise Exception("CtbCoin::getnewaddr(%s): empty addr", user) time.sleep(0.1) return str(addr) except BitcoindException as e: lg.error("CtbCoin::getnewaddr(%s): BitcoindException: %s", user, e) raise except CannotSendRequest as e: if counter < 3: lg.warning( "CtbCoin::getnewaddr(%s): CannotSendRequest, retrying") counter += 1 time.sleep(10) continue else: raise except Exception as e: if str(e) == "timed out" and counter < 3: lg.warning("CtbCoin::getnewaddr(%s): timed out, retrying") counter += 1 time.sleep(10) continue else: lg.error("CtbCoin::getnewaddr(%s): Exception: %s", user, e) raise def verify_user(self, _user=None): """ Verify and return a username """ if not _user or not type(_user) in [str, unicode]: raise Exception( "CtbCoin::verify_user(): _user wrong type (%s) or empty (%s)", type(_user), _user) return str(_user.lower()) def verify_addr(self, _addr=None): """ Verify and return coin address """ if not _addr or not type(_addr) in [str, unicode]: raise Exception( "CtbCoin::verify_addr(): _addr wrong type (%s) or empty (%s)", type(_addr), _addr) return re.escape(str(_addr)) def verify_amount(self, _amount=None): """ Verify and return amount """ if not _amount or not type(_amount) in [Decimal, int, float ] or not _amount > 0: raise Exception( "CtbCoin::verify_amount(): _amount wrong type (%s), empty, or negative (%s)", type(_amount), _amount) return _amount def verify_minconf(self, _minconf=None): """ Verify and return minimum number of confirmations """ if not _minconf or not type(_minconf) == int or not _minconf >= 0: raise Exception( "CtbCoin::verify_minconf(): _minconf wrong type (%s), empty, or negative (%s)", type(_minconf), _minconf) return _minconf