import requests import six import json import operator from decimal import Decimal from app import config class WalletRPC(object): def __init__(self, rpc_endpoint, username='', password=''): self.endpoint = f'{rpc_endpoint}/json_rpc' self.auth = requests.auth.HTTPDigestAuth( username, password ) def make_wallet_rpc(self, method, params={}): r = requests.get( self.endpoint, data=json.dumps({'method': method, 'params': params}), auth=self.auth ) if 'error' in r.json(): return r.json()['error'] else: return r.json()['result'] def height(self): return self.make_wallet_rpc('get_height', {}) def addresses(self, account=0, addr_indices=None): qdata = {'account_index': account} if addr_indices: qdata['address_index'] = addr_indices _addresses = self.make_wallet_rpc('get_address', qdata) addresses = [None] * (max(map(operator.itemgetter('address_index'), _addresses['addresses'])) + 1) for _addr in _addresses['addresses']: addresses[_addr['address_index']] = _addr['address'] return addresses def new_address(self, account=0, label=None): data = {'account_index': account, 'label': label} _address = self.make_wallet_rpc('create_address', data) return (_address['address_index'], _address['address']) def balances(self, account=0): data = {'account_index': account} _balance = self.make_wallet_rpc('get_balance', data) return (_balance['balance'], _balance['unlocked_balance']) def transfer(self, address, amount): data = { 'account_index': 0, 'destinations': [{'address': address, 'amount': amount}], 'priority': 1, 'unlock_time': 0, 'get_tx_key': True, 'get_tx_hex': False, 'new_algorithm': True, 'do_not_relay': False, } transfer = self.make_wallet_rpc('transfer', data) return transfer def incoming_transfers(self, subaddress_index): data = { 'subaddr_indices': [subaddress_index], 'transfer_type': 'all' } return self.make_wallet_rpc('incoming_transfers', data) def get_transfers(self, subaddress_index=None): if subaddress_index: indices = [subaddress_index] else: indices = None data = { 'in': True, 'out': True, 'subaddr_indices': indices } return self.make_wallet_rpc('get_transfers', data) def get_balance(self, subaddress_index): data = { 'address_indices': [subaddress_index] } _balance = self.make_wallet_rpc('get_balance', data) res = _balance['per_subaddress'][0] return (res['balance'], res['unlocked_balance']) class CoinUtils(object): def __init__(self): pass def to_atomic(self, amount): if not isinstance(amount, (Decimal, float) + six.integer_types): raise ValueError("Amount '{}' doesn't have numeric type. Only Decimal, int, long and " "float (not recommended) are accepted as amounts.") return int(amount * 10**self.decimal_points) def from_atomic(self, amount): return (Decimal(amount) * self.full_notation).quantize(self.full_notation) def as_real(self, amount): real = Decimal(amount).quantize(self.full_notation) return float(real) class Wownero(CoinUtils): def __init__(self): self.decimal_points = 11 self.full_notation = Decimal('0.00000000001') class Monero(CoinUtils): def __init__(self): self.decimal_points = 12 self.full_notation = Decimal('0.000000000001') wow_wallet = WalletRPC( config.WOW_WALLET_RPC_ENDPOINT, config.WOW_WALLET_RPC_USER, config.WOW_WALLET_RPC_PASS ) xmr_wallet = WalletRPC( config.XMR_WALLET_RPC_ENDPOINT, config.XMR_WALLET_RPC_USER, config.XMR_WALLET_RPC_PASS ) wownero = Wownero() monero = Monero()