def submit_withdrawal(self, request): # check input if "address" not in request.data.keys( ) or "amount" not in request.data.keys(): return Response({"msg": "Must specify address and amount."}, status=status.HTTP_400_BAD_REQUEST) try: amount = float(request.data["amount"]) assert amount > 0 except: return Response({"msg": "Invalid amount."}, status=status.HTTP_400_BAD_REQUEST) address = request.data["address"] if not self.rpc.make_call("validateaddress", [address])["isvalid"]: return Response({"msg": "Invalid address."}, status=status.HTTP_400_BAD_REQUEST) # check sufficient funds balance = self.rpc.make_call('getbalance', ['*', self.cur.required_confirmations]) if balance <= amount: return Response({"msg": "Insufficient funds to transfer."}, status=status.HTTP_428_PRECONDITION_REQUIRED) # initiate withdrawal txid = self.rpc.make_call("sendtoaddress", [address, amount]) result = {"txid": txid, "created_at": utc_now().timestamp()} return Response(result, status=status.HTTP_202_ACCEPTED)
def get_deposit_address(self, request): address = self.rpc.make_call("getnewaddress") address_info = { "address": address, "created_at": utc_now().timestamp() } return Response(address_info, status=status.HTTP_201_CREATED)
def get_deposit_address(self, request): address = self.w3.personal.newAccount("") address_info = { "address": address, "created_at": utc_now().timestamp() } return Response(address_info, status=status.HTTP_201_CREATED)
def get_status(self, request): if not self.cur.withdrawal_address: self.cur.withdrawal_address = self.w3.personal.newAccount("") final_block = self._determine_final_block() block = self.w3.eth.getBlock(final_block) # cold_storage_quantity = self.w3.fromWei(self.w3.eth.getBalance(self.w3.toChecksumAddress(self.cur.cold_storage_address.address)), 'ether') status_info = { 'blocks': final_block, 'latest_block_time': block.timestamp, 'latest_block_age': (utc_now() - datetime.datetime.fromtimestamp( block.timestamp, datetime.timezone.utc)), 'fee_rate': self.w3.fromWei(self.w3.eth.generateGasPrice() * 21000, 'ether'), 'required_confirmations': self.cur.required_confirmations } balance = {} balance['hot_wallet'], balance['hot_wallet_withdrawals'], balance[ 'cold_storage'] = 0, 0, 0, accounts = self.w3.eth.accounts balance['hot_wallet'] = [ self.w3.eth.getBalance(a) for a in accounts if a != self.cur.withdrawal_address ] balance['hot_wallet_withdrawals'] = self.w3.eth.getBalance( self.cur.withdrawal_address) return Response(status_info, status=status.HTTP_200_OK)
def submit_withdrawal(self, request, format=None): recipient = request.data.get('address') amount = to_decimal(request.data.get('amount', 0)) if not recipient or not amount: return Response({"msg": "Must specify address and amount."}, status=status.HTTP_400_BAD_REQUEST) if self.w3.eth.getBalance( self.w3.toChecksumAddress(self.hot_wallet_address)) < amount: return Response({"msg": "Insufficient funds to transfer."}, status=status.HTTP_428_PRECONDITION_REQUIRED) transaction_details = { "to": self.w3.toChecksumAddress(recipient), "from": self.w3.toChecksumAddress(self.hot_wallet_address), "value": self.w3.toWei(amount, 'ether'), "gas": 21000, } transaction = self.w3.eth.sendTransaction(transaction_details) result = { "txid": transaction.hex(), "created_at": utc_now().timestamp() } return Response(result, status=status.HTTP_202_ACCEPTED)
def price(self): from lib.timetools import utc_now import requests if self.symbol not in CURRENCY_prices.keys() or ( utc_now() - CURRENCY_prices[self.symbol]["time"]).total_seconds() > 60: listings = requests.get( "https://api.coinmarketcap.com/v2/listings/").json()["data"] id_ = [ listing["id"] for listing in listings if listing["symbol"] == self.symbol ][0] price = requests.get( f"https://api.coinmarketcap.com/v2/ticker/{id_}/").json( )["data"]["quotes"]["USD"]["price"] CURRENCY_prices[self.symbol] = {"time": utc_now(), "price": price} return CURRENCY_prices[self.symbol]["price"]
def get_status(self, request): # general status blockchaininfo = self.rpc.make_call("getblockchaininfo", []) latest_hash = self.rpc.make_call("getblockhash", [blockchaininfo["blocks"]]) latest_block = self.rpc.make_call("getblock", [latest_hash]) latest_time = latest_block["time"] fee_rate = self.rpc.make_call( "estimatesmartfee", [self.cur.required_confirmations])["feerate"] * 240 / 1024 status_info = { 'blocks': blockchaininfo['blocks'], 'latest_block_time': latest_time, 'latest_block_age': (utc_now() - datetime_from_utc_timestamp(latest_time)).total_seconds(), 'fee_rate': fee_rate, 'required_confirmations': self.cur.required_confirmations } # balance balance = {} balance["hot_wallet"], balance['hot_wallet_withdrawals'], balance[ "cold_storage"] = 0, 0, 0 balance["hot_wallet"] = self.rpc.make_call( 'getbalance', ['*', self.cur.required_confirmations]) #balance["hot_wallet"]["value"] = '${:,.2f}'.format(balance["hot_wallet"]["quantity"] * self.cur.price()) unspents = self.rpc.make_call( 'listunspent', [0, 999999, [self.cur.cold_storage_address]]) balance = sum([ Decimal(unspent['amount']).quantize(DEFAULT_ZERO) for unspent in unspents ]) balance['cold_wallet'] = balance #balance["cold_storage"]["value"] = '${:,.2f}'.format(balance["cold_storage"]["quantity"] * self.cur.price()) status_info.update({"balance": balance}) return Response(status_info, status=status.HTTP_200_OK)