-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathroutes.py
378 lines (334 loc) · 14.4 KB
/
routes.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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
"""JSON swagger API to PaKeT."""
import os
import flasgger
import flask
import paket_stellar
import util.logger
import util.conversion
import webserver.validation
import db
import swagger_specs
LOGGER = util.logger.logging.getLogger('pkt.api')
VERSION = swagger_specs.VERSION
PORT = os.environ.get('PAKET_API_PORT', 8000)
BLUEPRINT = flask.Blueprint('api', __name__)
# Input validators and fixers.
webserver.validation.KWARGS_CHECKERS_AND_FIXERS['_timestamp'] = webserver.validation.check_and_fix_natural
webserver.validation.KWARGS_CHECKERS_AND_FIXERS['_buls'] = webserver.validation.check_and_fix_natural
webserver.validation.KWARGS_CHECKERS_AND_FIXERS['_num'] = webserver.validation.check_and_fix_natural
# Wallet routes.
@BLUEPRINT.route("/v{}/submit_transaction".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.SUBMIT_TRANSACTION)
@webserver.validation.call(['transaction'])
def submit_transaction_handler(transaction):
"""
Submit a signed transaction.
This call is used to submit signed transactions.
Signed transactions can be obtained by signing unsigned
transactions returned by other calls. You can use the
[laboratory](https://www.stellar.org/laboratory/#txsigner?network=test) to
sign the transaction with your private key.
---
:param transaction:
:return:
"""
return {'status': 200, 'response': paket_stellar.submit_transaction_envelope(transaction)}
@BLUEPRINT.route("/v{}/bul_account".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.BUL_ACCOUNT)
@webserver.validation.call(['queried_pubkey'])
def bul_account_handler(queried_pubkey):
"""
Get the details of a Stellar BUL account.
---
:param queried_pubkey:
:return:
"""
account = paket_stellar.get_bul_account(queried_pubkey)
return dict(status=200, **account)
@BLUEPRINT.route("/v{}/prepare_account".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.PREPARE_ACCOUNT)
@webserver.validation.call(['from_pubkey', 'new_pubkey'])
def prepare_account_handler(from_pubkey, new_pubkey, starting_balance=50000000):
"""
Prepare a create account transaction.
---
:param from_pubkey:
:param new_pubkey:
:param starting_balance:
:return:
"""
try:
return {'status': 200, 'transaction': paket_stellar.prepare_create_account(
from_pubkey, new_pubkey, starting_balance)}
# pylint: disable=broad-except
# stellar_base throws this as a broad exception.
except Exception as exception:
LOGGER.info(str(exception))
if str(exception) == 'No sequence is present, maybe not funded?':
return {'status': 400, 'error': "{} is not a funded account".format(from_pubkey)}
raise
# pylint: enable=broad-except
@BLUEPRINT.route("/v{}/prepare_trust".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.PREPARE_TRUST)
@webserver.validation.call(['from_pubkey'])
def prepare_trust_handler(from_pubkey, limit=None):
"""
Prepare an add trust transaction.
---
:param from_pubkey:
:param limit:
:return:
"""
return {'status': 200, 'transaction': paket_stellar.prepare_trust(from_pubkey, limit)}
@BLUEPRINT.route("/v{}/prepare_send_buls".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.PREPARE_SEND_BULS)
@webserver.validation.call(['from_pubkey', 'to_pubkey', 'amount_buls'])
def prepare_send_buls_handler(from_pubkey, to_pubkey, amount_buls):
"""
Prepare a BUL transfer transaction.
---
:param from_pubkey:
:param to_pubkey:
:param amount_buls:
:return:
"""
return {'status': 200, 'transaction': paket_stellar.prepare_send_buls(from_pubkey, to_pubkey, amount_buls)}
# Package routes.
@BLUEPRINT.route("/v{}/prepare_escrow".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.PREPARE_ESCROW)
@webserver.validation.call(
['launcher_pubkey', 'recipient_pubkey', 'courier_pubkey', 'payment_buls', 'collateral_buls', 'deadline_timestamp'],
require_auth=True)
def prepare_escrow_handler(
user_pubkey, launcher_pubkey, courier_pubkey, recipient_pubkey,
payment_buls, collateral_buls, deadline_timestamp, location=None):
"""
Launch a package.
Use this call to create a new package for delivery.
---
:param user_pubkey: the escrow pubkey
:param launcher_pubkey:
:param courier_pubkey:
:param recipient_pubkey:
:param payment_buls:
:param collateral_buls:
:param deadline_timestamp:
:param location:
:return:
"""
package_details = paket_stellar.prepare_escrow(
user_pubkey, launcher_pubkey, courier_pubkey, recipient_pubkey,
payment_buls, collateral_buls, deadline_timestamp)
db.create_package(**dict(package_details, location=location))
return dict(status=201, **package_details)
@BLUEPRINT.route("/v{}/accept_package".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.ACCEPT_PACKAGE)
@webserver.validation.call(['escrow_pubkey'], require_auth=True)
def accept_package_handler(user_pubkey, escrow_pubkey, location=None):
"""
Accept a package.
If the package requires collateral, commit it.
If user is the package's recipient, release all funds from the escrow.
---
:param user_pubkey:
:param escrow_pubkey:
:param location:
:return:
"""
package = db.get_package(escrow_pubkey)
event_type = 'received' if package['recipient_pubkey'] == user_pubkey else 'couriered'
db.add_event(escrow_pubkey, user_pubkey, event_type, location)
return {'status': 200}
@BLUEPRINT.route("/v{}/my_packages".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.MY_PACKAGES)
@webserver.validation.call(require_auth=True)
def my_packages_handler(user_pubkey):
"""
Get list of packages concerning the user.
---
:param user_pubkey:
:return:
"""
packages = db.get_packages(user_pubkey)
return {'status': 200, 'packages': packages}
@BLUEPRINT.route("/v{}/package".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.PACKAGE)
@webserver.validation.call(['escrow_pubkey'])
def package_handler(escrow_pubkey):
"""
Get a full info about a single package.
---
:param escrow_pubkey:
:return:
"""
package = db.get_package(escrow_pubkey)
return {'status': 200, 'package': package}
@BLUEPRINT.route("/v{}/add_event".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.ADD_EVENT)
@webserver.validation.call(['escrow_pubkey', 'event_type', 'location'], require_auth=True)
def add_event_handler(user_pubkey, escrow_pubkey, event_type, location):
"""
---
:param user_pubkey:
:param escrow_pubkey:
:param event_type:
:param location:
:return:
"""
db.add_event(escrow_pubkey, user_pubkey, event_type, location)
return {'status': 200}
@BLUEPRINT.route("/v{}/changed_location".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.CHANGED_LOCATION)
@webserver.validation.call(['escrow_pubkey', 'location'], require_auth=True)
def changed_location_handler(user_pubkey, escrow_pubkey, location):
"""
Add new `changed_location` event for package.
---
:param user_pubkey:
:param escrow_pubkey:
:param location:
:return:
"""
db.add_event(escrow_pubkey, user_pubkey, 'changed location', location)
return {'status': 200}
# Debug routes.
@BLUEPRINT.route("/v{}/debug/fund".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.FUND_FROM_ISSUER)
@webserver.validation.call(['funded_pubkey'])
def fund_handler(funded_pubkey, funded_buls=1000000000):
"""
Give BULs to an account - for debug only.
---
:return:
"""
return {'status': 200, 'response': paket_stellar.fund_from_issuer(funded_pubkey, funded_buls)}
@BLUEPRINT.route("/v{}/debug/create_mock_package".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.CREATE_MOCK_PACKAGE)
@webserver.validation.call(
['escrow_pubkey', 'launcher_pubkey', 'recipient_pubkey', 'payment_buls', 'collateral_buls', 'deadline_timestamp'])
def create_mock_package_handler(
escrow_pubkey, launcher_pubkey, recipient_pubkey,
payment_buls, collateral_buls, deadline_timestamp):
"""
Create a mock package - for debug only.
---
:return:
"""
return {'status': 201, 'package': db.create_package(
escrow_pubkey, launcher_pubkey, recipient_pubkey, payment_buls, collateral_buls, deadline_timestamp,
'mock_setopts', 'mock_refund', 'mock merge', 'mock payment')}
@BLUEPRINT.route("/v{}/debug/packages".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.PACKAGES)
@webserver.validation.call
def packages_handler():
"""
Get list of packages - for debug only.
---
:return:
"""
return {'status': 200, 'packages': db.get_packages()}
@BLUEPRINT.route("/v{}/events".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.EVENTS)
@webserver.validation.call
def events_handler(max_events_num=100, mock=None):
"""
Get all events.
---
:param max_events_num:
:param mock:
:return:
"""
if not bool(mock):
events = db.get_events(max_events_num)
# Mock data. Temporary.
else:
events = {
'packages_events': [{
'timestamp': '2018-08-03 14:29:18.116482',
'escrow_pubkey': 'GB5SUIN2OEJXG2GDYG6EGB544DQLUVZX35SJJVLHWCEZ4FYWRWW236FB',
'user_pubkey': 'GBUPZ63WK2ZLOCXPCUOMM7XRUGXOVJC3RIBL7KBTUSHLKFRKVHUB757L',
'event_type': 'launched', 'location': '51.4983407,-0.173709'
}, {
'timestamp': '2018-08-03 14:35:05.958315',
'escrow_pubkey': 'GB5SUIN2OEJXG2GDYG6EGB544DQLUVZX35SJJVLHWCEZ4FYWRWW236FB',
'user_pubkey': 'GCBKJ3QLHCBK5WBF4UZ5K2LOVDI63WG2SKLIWIMREPRLCTIHD6B5QR65',
'event_type': 'couriered', 'location': '51.4983407,-0.173709'
}, {
'timestamp': '2018-08-04 17:02:55.138572',
'escrow_pubkey': 'GB5SUIN2OEJXG2GDYG6EGB544DQLUVZX35SJJVLHWCEZ4FYWRWW236FB',
'user_pubkey': 'GDRGF2BU7CV4QU4E54B72BJEL4CWFMTTVSVJMKWESK32HLTYD4ZEWJOR',
'event_type': 'received', 'location': '53.3979468,-2.932953'
}, {
'timestamp': '2018-08-03 06:35:17.169421',
'escrow_pubkey': 'GBMU5SWBUNBCDRUMIZNCDOTMIRGLBFY5DEPIE4OTBAUOFK4V3HOENAGT',
'user_pubkey': 'GANEU37FIEBICW6352CVIUD7GYOV5H7W5YUE5ECDH5PJNF7R5ISYJR3K',
'event_type': 'launched', 'location': '31.2373787,34.7889161'
}, {
'timestamp': '2018-08-03 07:01:17.192375',
'escrow_pubkey': 'GBMU5SWBUNBCDRUMIZNCDOTMIRGLBFY5DEPIE4OTBAUOFK4V3HOENAGT',
'user_pubkey': 'GBL4FZ6HCA6SQATD5UYHQYMVWASBEZCKGL2P7PEU6VNLONVFZY6DPV3R',
'event_type': 'couriered', 'location': '31.2373787,34.7889161'
}, {
'timestamp': '2018-08-05 22:05:53.162485',
'escrow_pubkey': 'GBMU5SWBUNBCDRUMIZNCDOTMIRGLBFY5DEPIE4OTBAUOFK4V3HOENAGT',
'user_pubkey': 'GBYYI24HZ75OYBAHZOUVAAQNS5YHMN32VLCDBZFXHAAJKRRSCZICBIDJ',
'event_type': 'received', 'location': '32.8266712,34.9774087'
}, {
'timestamp': '2018-08-07 05:55:15.168276',
'escrow_pubkey': 'GALIFYZ6GDHXWDH2QZLRJY2XS77A6WXILDFSRH6ZZM3IYOIH2XEK3TAK',
'user_pubkey': 'GAZ2UUQUEYY2LHAQMP4M737DXXX3TM7L6BE5JT7LYWS5GYL6VXQ6HASR',
'event_type': 'launched', 'location': '12.926039,77.5056131'
}, {
'timestamp': '2018-08-07 09:14:18.137124',
'escrow_pubkey': 'GALIFYZ6GDHXWDH2QZLRJY2XS77A6WXILDFSRH6ZZM3IYOIH2XEK3TAK',
'user_pubkey': 'GBQR3QGZOS2K4MQPPJDKRMJ6MIEACCG4BRO23UE33TDFRZOM57VL5O5J',
'event_type': 'couriered', 'location': '12.926039,77.5056131'
}, {
'timestamp': '2018-08-09 14:27:16.143762',
'escrow_pubkey': 'GALIFYZ6GDHXWDH2QZLRJY2XS77A6WXILDFSRH6ZZM3IYOIH2XEK3TAK',
'user_pubkey': 'GAYOZB7SZBD7O4UPLLQNXFN5ZZCQJSXBKERNIY4MIWL7DVXF7DBF7OU6',
'event_type': 'received', 'location': '28.7050581,77.1419526'}],
'user_events': [{
'timestamp': '2018-08-01 17:46:18.169723',
'escrow_pubkey': None,
'user_pubkey': 'GBUPZ63WK2ZLOCXPCUOMM7XRUGXOVJC3RIBL7KBTUSHLKFRKVHUB757L',
'event_type': 'installed app', 'location': '51.5482912,-0.3048464'
}, {
'timestamp': '2018-07-22 19:36:18.123142',
'escrow_pubkey': None,
'user_pubkey': 'GCCYNSN3WETV2FBASFVXKAJ54OX4NUTP4ZUJFGXTX47A2GRQYQ52QQBK',
'event_type': 'installed app', 'location': '50.2443519,28.6989147'
}, {
'timestamp': '2018-07-22 19:58:38.164237',
'escrow_pubkey': None,
'user_pubkey': 'GCCYNSN3WETV2FBASFVXKAJ54OX4NUTP4ZUJFGXTX47A2GRQYQ52QQBK',
'event_type': 'passed kyc', 'location': '50.2443519,28.6989147'
}, {
'timestamp': '2018-07-28 05:34:21.134562',
'escrow_pubkey': None,
'user_pubkey': 'GBOTDKM6ZJNV54QLXKTU5WSYFXJZDZZSGKTYHDNWDDVAEVB73DPLSP4H',
'event_type': 'funded account', 'location': '22.9272893,113.3443182'
}, {
'timestamp': '2018-07-30 22:12:21.136421',
'escrow_pubkey': None,
'user_pubkey': 'GAUHIJXEV2D46G375FJNCUBGVUKXRF7C3VC7U3HUPCBIZUYHJKP4N6XA',
'event_type': 'funded account', 'location': '-16.2658233,-47.9159335'
}, {
'timestamp': '2018-08-03 17:35:14.136415',
'escrow_pubkey': None,
'user_pubkey': 'GAL54ATIHYBWMKYUNQSM3QAGZGCUBJGF6KEFFSQTEV7JOOA72UEJP4UL',
'event_type': 'funded account', 'location': '51.0465554,-114.0752757'}]}
return {'status': 200, 'events': events}
@BLUEPRINT.route("/v{}/debug/log".format(VERSION), methods=['POST'])
@flasgger.swag_from(swagger_specs.LOG)
@webserver.validation.call
def view_log_handler(lines_num=10):
"""
Get last lines of log - for debug only.
Specify lines_num to get the x last lines.
---
:param lines_num:
:return:
"""
with open(os.path.join(util.logger.LOG_DIR_NAME, util.logger.LOG_FILE_NAME)) as logfile:
return {'status': 200, 'log': logfile.readlines()[:-1 - lines_num:-1]}