1 # network.py - Accessing the dogepartyd json-rpc api.
2 # Copyright (C) 2014 Rob Myers rob@robmyers.org
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 ################################################################################
19 ################################################################################
26 ################################################################################
27 # Dogeparty API access
28 ################################################################################
30 headers = {'content-type': 'application/json'}
32 class DogepartyApi(object):
33 """Connect to and call the Dogeparty API"""
35 def __init__(self, user, password, host='localhost', port='5000'):
36 """Configure the API connection"""
37 self.host = 'http://{}:{}@{}:{}'.format(user,
42 def call_api(self, method, params):
43 """Call dogepartyd via the json-rpc interface"""
50 response = requests.post(self.host, data=json.dumps(payload), headers=headers)
52 return response.json()['result']
54 print(response.json())
57 def send_token(self, from_address, to_address, token, amount, fee):
58 """Send the given amount of tokens"""
60 params = {'source': from_address,
61 'destination': to_address,
63 'quantity': int(amount),
65 'encoding': 'opreturn'}
66 tx_hash = self.call_api("do_send", params)
71 def __new_address_for_code(self):
72 """Return a new address to receive the tokens representing the program"""
75 def __get_account_token_amount(self, address, token):
76 """Return the amount of token address has, 0 for none"""
79 def address_has_no_code_tokens(self, address):
80 """Check that address has no code tokens"""
82 for token in translation.TOKENS:
83 count = self.get_account_token_amount(address, token)
89 def address_has_sufficient_tokens(self, address, token_pairs, warning_level=10):
90 """Check that address has sufficient tokens to send to express the program
91 encoded in token_pairs, warning if sending would reduce the amount of
94 for pair in token_pairs:
95 totals[pair[0]] = totals.get(pair[0], 0) + pair[1]
97 for token, count in totals.items():
98 available = get_account_token_amount(address, token)
99 if (available - count) < warning_level:
100 print("This program requires {} {} tokens. Address {} currently has {} . After this program it will only have {} .".format(count, token, address, available, available - count))
101 if available < count:
102 print("Account {} has insufficient {} tokens ({})to send the {} needed to represent this program.".format(address, token, available, count))
107 def __address_has_sufficient_fees(self, address, token_pairs, fee, warning_level=100):
108 """Check that the account has sufficient Dogecoins to pay the fees for all
109 the token transactions"""
110 total_required = len(token_pairs) * fee
114 def __upload_code(from_address, to_address, token_pairs, fee):
115 """Check that from_address has sufficient tokens and that to_address has
116 none, then create transactions to transfer the token amounts expressed
117 in token pairs from from_address to to_address"""
118 if self.address_has_sufficient_tokens(from_address, token_pairs) and \
119 self.address_has_no_code_tokens(to_address):
123 def token_transactions_for_address(self, receiver):
124 """Get the token transactions (and any doge transfers) sent to the adress.
125 This is insecure for fetching programs without further filtering."""
126 params = {'filters': {'field':'destination',
129 'order_by':'tx_index',
131 sends = self.call_api('get_sends', params)
135 def token_transactions_for_address_from_sender(self, receiver, sender):
136 """Get the token transactions (and any doge transfers) sent to the adress from the sender"""
137 params = {'filters': [{'field':'destination',
143 'order_by':'tx_index',
145 sends = self.call_api('get_sends', params)