-
Notifications
You must be signed in to change notification settings - Fork 0
/
JuiceboxReader.py
225 lines (171 loc) · 10.2 KB
/
JuiceboxReader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
from web3 import Web3
from Contracts import Contracts
import json, datetime, urllib.request, os
from ens import ENS
from dotenv import load_dotenv
import copy
class JuiceboxReader:
def __init__(self):
load_dotenv()
self.w3 = Web3(Web3.HTTPProvider(os.environ["INFURA_URL"]))
self.ns = ENS.fromWeb3(self.w3)
### Contracts setup
self.contracts = Contracts().contracts
with open('resources/name_to_id.json') as file:
self.name_to_id = json.load(file)
def get_latest_block(self):
return self.w3.eth.blockNumber
def get_logo(self, project_id, version='v1'):
if (version == 'v1' or version == 'v1.1'):
uri = self.contracts['v1']['projects'].functions.uriOf(project_id).call()
logo = json.load(urllib.request.urlopen(f"https://ipfs.io/ipfs/{uri}"))['logoUri']
else:
logo = 'Unsupported version provided.'
return logo
def get_balance(self, project_id, version='v1'):
if version == 'v2':
return Web3.fromWei(self.contracts['v2']['payment_terminal'].functions.currentEthOverflowOf(project_id).call(), 'ether')
elif version == 'v1.1':
return Web3.fromWei(self.contracts['v1.1']['terminal'].functions.balanceOf(project_id).call(), 'ether')
else:
return Web3.fromWei(self.contracts['v1']['terminal'].functions.balanceOf(project_id).call(), 'ether')
def get_overflow(self, project_id, version='v1'):
if (version == 'v1'):
return Web3.fromWei(self.contracts['v1']['terminal'].functions.currentOverflowOf(project_id).call(), 'ether')
def get_dao_name(self, project_id, version='v1'):
if (version == 'v1' or version == 'v1.1'):
raw = self.contracts['v1']['projects'].functions.handleOf(project_id).call()
raw = str(raw)[2:].split('\\')[0]
elif (version == 'v2'):
raw = f'Project {project_id}'
else:
return "Unsupported version provided."
return raw
def get_count(self, version):
if version in ['v1', 'v1.1']:
return self.get_countv1()
elif version == 'v2':
return self.get_countv2()
def get_countv2(self):
return self.contracts['v2']['projects'].functions.count().call()
def get_countv1(self):
return self.contracts['v1']['projects'].functions.count().call()
# Funding Cycle data
def get_raw_current_FC(self, project_id, version='v1'):
return self.contracts['v1']['funding_cycles'].functions.currentOf(project_id).call()
def get_raw_queued_FC(self, project_id, version='v1'):
return self.contracts['v1']['funding_cycles'].functions.queuedOf(project_id).call()
def get_cycle_start(self, project_id, version='v1'):
raw_start = datetime.datetime.fromtimestamp(self.contracts['v1']['funding_cycles'].functions.currentOf(project_id).call()[8])
return raw_start.strftime('%Y-%m-%d at %H:%M:%S')
def get_cycle_end(self, project_id, version='v1'):
if version in ['v1', 'v1.1']:
raw_end = datetime.datetime.fromtimestamp(self.contracts['v1']['funding_cycles'].functions.queuedOf(project_id).call()[8])
return raw_end.strftime('%Y-%m-%d at %H:%M:%S')
else:
return 'Unsupported version provided.'
def get_time_left(self, project_id, version='v1'):
if version in ['v1', 'v1.1']:
raw_end = datetime.datetime.fromtimestamp(self.contracts['v1']['funding_cycles'].functions.queuedOf(project_id).call()[8])
raw_left = raw_end - datetime.datetime.now()
return raw_left
else:
return 'Unsupported version provided.'
def get_cycle_target(self, project_id, version='v1'):
return Web3.fromWei(self.contracts['v1']['funding_cycles'].functions.currentOf(project_id).call()[10], 'ether')
def get_cycle_discount(self, project_id, version='v1'):
return self.contracts['v1']['funding_cycles'].functions.currentOf(project_id).call()[13]
def get_cycle_tapped(self, project_id, version='v1'):
return Web3.fromWei(self.contracts['v1']['funding_cycles'].functions.currentOf(project_id).call()[14], 'ether')
def get_cycle_reserved(self, project_id, version='v1'):
return int(bin(self.contracts['v1']['funding_cycles'].functions.currentOf(project_id).call()[15])[-16:-9], 2)
def get_cycle_bonding(self, project_id, version='v1'):
return int(bin(self.contracts['v1']['funding_cycles'].functions.currentOf(project_id).call()[15])[-23:-17], 2)
def get_full_balance(self, project_id, version='v1'):
return self.get_balance(project_id) + self.get_cycle_tapped(project_id)
# Events handlers
def get_new_events(self, project_id, latest_block, version):
if (version == 'v2'):
return self.get_new_events_v2(project_id, latest_block)
else:
return self.get_new_events_v1(project_id, latest_block, version)
def get_new_events_v1(self, project_id, last_block_alerted, version='v1'):
start_block = last_block_alerted + 1 # Increment so we don't do the same block twice
latest_block = self.w3.eth.blockNumber
event_filter = []
# Funding cycles contract events
tap_filter = self.contracts['v1']['funding_cycles'].events.Tap.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'projectId':int(project_id)})
# TerminalV1 contract events
redeem_filter = self.contracts['v1']['terminal'].events.Redeem.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'_projectId':int(project_id)})
pay_filter = self.contracts['v1']['terminal'].events.Pay.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'projectId':int(project_id)})
# TerminalV1.1 contract events
redeem1_filter = self.contracts['v1.1']['terminal'].events.Redeem.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'_projectId':int(project_id)})
pay1_filter = self.contracts['v1.1']['terminal'].events.Pay.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'projectId':int(project_id)})
filters_t1 = [tap_filter, redeem_filter, pay_filter]
filters_t1_1 = [redeem1_filter, pay1_filter]
entries = []
for filter in filters_t1:
for event in filter.get_all_entries():
entries.append(self.v1_handler(event))
for filter in filters_t1_1:
for event in filter.get_all_entries():
entries.append(self.v1_handler(event))
return entries, latest_block
def v1_handler(self, event):
event_caller = (self.ns.name(event.args.caller) or event.args.caller)
if (event.event == 'Pay'):
eth_value = Web3.fromWei(event.args.amount, 'ether')
_note = event.args.note
info = ['pay', event_caller, eth_value, _note, 'v1']
elif(event.event == 'Redeem'):
_ticket_count = event.args.amount
eth_value = Web3.fromWei(event.args.returnAmount, 'ether')
info = ['redeem', event_caller, eth_value, _ticket_count, 'v1']
elif(event.event == 'Tap'):
eth_value = Web3.fromWei(event.args.amount, 'ether')
tapped_amount = Web3.fromWei(event.args.newTappedAmount, 'ether')
info = ['tap', event_caller, eth_value, tapped_amount, 'v1']
return info
def v11_handler(self, event):
event_caller = (self.ns.name(event.args.caller) or event.args.caller)
if (event.event == 'Pay'):
eth_value = Web3.fromWei(event.args.amount, 'ether')
_note = event.args.note
info = ['pay', event_caller, eth_value, _note, 'v11']
elif(event.event == 'Redeem'):
_ticket_count = event.args.amount
eth_value = Web3.fromWei(event.args.returnAmount, 'ether')
info = ['redeem', event_caller, eth_value, _ticket_count, 'v11']
elif(event.event == 'Tap'):
eth_value = Web3.fromWei(event.args.amount, 'ether')
tapped_amount = Web3.fromWei(event.args.newTappedAmount, 'ether')
info = ['tap', event_caller, eth_value, tapped_amount, 'v11']
return info
def get_new_events_v2(self, project_id, last_block_alerted):
start_block = last_block_alerted + 1 # Increment so we don't do the same block twice
latest_block = self.w3.eth.blockNumber
pay2_filter = self.contracts['v2']['payment_terminal'].events.Pay.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'projectId':int(project_id)})
tap2_filter = self.contracts['v2']['payment_terminal'].events.DistributePayouts.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'projectId':int(project_id)})
redeem2_filter = self.contracts['v2']['payment_terminal'].events.RedeemTokens.createFilter(fromBlock=start_block, toBlock=latest_block, argument_filters={'projectId':int(project_id)})
filters_t2 = [pay2_filter, tap2_filter, redeem2_filter]
entries = []
for filter in filters_t2:
for event in filter.get_all_entries():
print(event.args)
entries.append(self.v2_handler(event))
return entries, latest_block
def v2_handler(self, event):
event_caller = (self.ns.name(event.args.caller) or event.args.caller)
if (event.event == 'Pay'):
eth_value = Web3.fromWei(event.args.amount, 'ether')
_note = event.args.memo
info = ['pay', event_caller, eth_value, _note, 'v2']
elif(event.event == 'Redeem'):
_ticket_count = event.args.amount
eth_value = Web3.fromWei(event.args.refundedFees, 'ether')
info = ['redeem', event_caller, eth_value, _ticket_count, 'v2']
elif(event.event == 'DistributePayouts'):
eth_value = Web3.fromWei(event.args.amount, 'ether')
tapped_amount = Web3.fromWei(event.args.distributedAmount, 'ether')
info = ['tap', event_caller, eth_value, tapped_amount, 'v2']
return info