mirror of
https://github.com/RoboSats/robosats.git
synced 2025-02-22 05:09:01 +00:00
Work on order cancel
This commit is contained in:
parent
c0d6236dbb
commit
31b19ce18c
@ -80,13 +80,15 @@ class Logics():
|
|||||||
def update_invoice(cls, order, user, invoice):
|
def update_invoice(cls, order, user, invoice):
|
||||||
is_valid_invoice, num_satoshis, description, payment_hash, expires_at = LNNode.validate_ln_invoice(invoice)
|
is_valid_invoice, num_satoshis, description, payment_hash, expires_at = LNNode.validate_ln_invoice(invoice)
|
||||||
# only user is the buyer and a valid LN invoice
|
# only user is the buyer and a valid LN invoice
|
||||||
if cls.is_buyer(order, user) and is_valid_invoice:
|
if not (cls.is_buyer(order, user) or is_valid_invoice):
|
||||||
|
return False, {'bad_request':'Invalid Lightning Network Invoice. It starts by LNTB...'}
|
||||||
|
|
||||||
order.buyer_invoice, _ = LNPayment.objects.update_or_create(
|
order.buyer_invoice, _ = LNPayment.objects.update_or_create(
|
||||||
concept = LNPayment.Concepts.PAYBUYER,
|
concept = LNPayment.Concepts.PAYBUYER,
|
||||||
type = LNPayment.Types.NORM,
|
type = LNPayment.Types.NORM,
|
||||||
sender = User.objects.get(username=ESCROW_USERNAME),
|
sender = User.objects.get(username=ESCROW_USERNAME),
|
||||||
receiver= user,
|
receiver= user,
|
||||||
# if there is a LNPayment matching these above, it updates that with defaults below.
|
# if there is a LNPayment matching these above, it updates that one with defaults below.
|
||||||
defaults={
|
defaults={
|
||||||
'invoice' : invoice,
|
'invoice' : invoice,
|
||||||
'status' : LNPayment.Status.VALIDI,
|
'status' : LNPayment.Status.VALIDI,
|
||||||
@ -96,20 +98,39 @@ class Logics():
|
|||||||
'expires_at' : expires_at}
|
'expires_at' : expires_at}
|
||||||
)
|
)
|
||||||
|
|
||||||
#If the order status was Payment Failed. Move foward to invoice Updated.
|
# If the order status is 'Waiting for invoice'. Move forward to 'waiting for invoice'
|
||||||
|
if order.status == Order.Status.WFE: order.status = Order.Status.CHA
|
||||||
|
|
||||||
|
# If the order status is 'Waiting for both'. Move forward to 'waiting for escrow' or to 'chat'
|
||||||
|
if order.status == Order.Status.WF2:
|
||||||
|
print(order.trade_escrow)
|
||||||
|
if order.trade_escrow:
|
||||||
|
if order.trade_escrow.status == LNPayment.Status.LOCKED:
|
||||||
|
order.status = Order.Status.CHA
|
||||||
|
else:
|
||||||
|
order.status = Order.Status.WFE
|
||||||
|
|
||||||
|
# If the order status was Payment Failed. Move forward to invoice Updated.
|
||||||
if order.status == Order.Status.FAI:
|
if order.status == Order.Status.FAI:
|
||||||
order.status = Order.Status.UPI
|
order.status = Order.Status.UPI
|
||||||
|
|
||||||
order.save()
|
order.save()
|
||||||
return True, None
|
return True, None
|
||||||
|
|
||||||
return False, {'bad_request':'Invalid Lightning Network Invoice. It starts by LNTB...'}
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def cancel_order(cls, order, user, state):
|
def cancel_order(cls, order, user, state):
|
||||||
|
|
||||||
# 1) When maker cancels before bond
|
# 1) When maker cancels before bond
|
||||||
'''The order never shows up on the book and status
|
'''The order never shows up on the book and order
|
||||||
changes to cancelled. That's it.'''
|
status becomes "cancelled". That's it.'''
|
||||||
|
if order.status == Order.Status.WFB and order.maker == user:
|
||||||
|
order.maker = None
|
||||||
|
order.status = Order.Status.UCA
|
||||||
|
order.save()
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
|
||||||
# 2) When maker cancels after bond
|
# 2) When maker cancels after bond
|
||||||
'''The order dissapears from book and goes to cancelled.
|
'''The order dissapears from book and goes to cancelled.
|
||||||
@ -130,7 +151,10 @@ class Logics():
|
|||||||
When a user asks for cancel, 'order.is_pending_cancel' goes True.
|
When a user asks for cancel, 'order.is_pending_cancel' goes True.
|
||||||
When the second user asks for cancel. Order is totally cancelled.
|
When the second user asks for cancel. Order is totally cancelled.
|
||||||
Has a small cost for both parties to prevent node DDOS.'''
|
Has a small cost for both parties to prevent node DDOS.'''
|
||||||
pass
|
|
||||||
|
else:
|
||||||
|
return False, {'bad_request':'You cannot cancel this order'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -168,7 +192,7 @@ class Logics():
|
|||||||
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
|
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def gen_takerbuyer_hodl_invoice(cls, order, user):
|
def gen_taker_hodl_invoice(cls, order, user):
|
||||||
|
|
||||||
# Do not gen and cancel if a taker invoice is there and older than 2 minutes
|
# Do not gen and cancel if a taker invoice is there and older than 2 minutes
|
||||||
if order.taker_bond:
|
if order.taker_bond:
|
||||||
|
@ -77,12 +77,12 @@ class Order(models.Model):
|
|||||||
WFB = 0, 'Waiting for maker bond'
|
WFB = 0, 'Waiting for maker bond'
|
||||||
PUB = 1, 'Public'
|
PUB = 1, 'Public'
|
||||||
DEL = 2, 'Deleted'
|
DEL = 2, 'Deleted'
|
||||||
TAK = 3, 'Waiting for taker bond' # only needed when taker is a buyer
|
TAK = 3, 'Waiting for taker bond'
|
||||||
UCA = 4, 'Cancelled'
|
UCA = 4, 'Cancelled'
|
||||||
WF2 = 5, 'Waiting for trade collateral and buyer invoice'
|
WF2 = 5, 'Waiting for trade collateral and buyer invoice'
|
||||||
WTC = 6, 'Waiting only for seller trade collateral'
|
WFE = 6, 'Waiting only for seller trade collateral'
|
||||||
WBI = 7, 'Waiting only for buyer invoice'
|
WFI = 7, 'Waiting only for buyer invoice'
|
||||||
EXF = 8, 'Sending fiat - In chatroom'
|
CHA = 8, 'Sending fiat - In chatroom'
|
||||||
CCA = 9, 'Collaboratively cancelled'
|
CCA = 9, 'Collaboratively cancelled'
|
||||||
FSE = 10, 'Fiat sent - In chatroom'
|
FSE = 10, 'Fiat sent - In chatroom'
|
||||||
FCO = 11, 'Fiat confirmed'
|
FCO = 11, 'Fiat confirmed'
|
||||||
|
43
api/views.py
43
api/views.py
@ -89,6 +89,12 @@ class OrderView(viewsets.ViewSet):
|
|||||||
if order.status == Order.Status.EXP:
|
if order.status == Order.Status.EXP:
|
||||||
return Response({'bad_request':'This order has expired'},status.HTTP_400_BAD_REQUEST)
|
return Response({'bad_request':'This order has expired'},status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
# 2) If order cancelled
|
||||||
|
if order.status == Order.Status.UCA:
|
||||||
|
return Response({'bad_request':'This order has been cancelled by the maker'},status.HTTP_400_BAD_REQUEST)
|
||||||
|
if order.status == Order.Status.CCA:
|
||||||
|
return Response({'bad_request':'This order has been cancelled collaborativelly'},status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
data = ListOrderSerializer(order).data
|
data = ListOrderSerializer(order).data
|
||||||
|
|
||||||
# Add booleans if user is maker, taker, partipant, buyer or seller
|
# Add booleans if user is maker, taker, partipant, buyer or seller
|
||||||
@ -96,11 +102,11 @@ class OrderView(viewsets.ViewSet):
|
|||||||
data['is_taker'] = order.taker == request.user
|
data['is_taker'] = order.taker == request.user
|
||||||
data['is_participant'] = data['is_maker'] or data['is_taker']
|
data['is_participant'] = data['is_maker'] or data['is_taker']
|
||||||
|
|
||||||
# 2) If not a participant and order is not public, forbid.
|
# 3) If not a participant and order is not public, forbid.
|
||||||
if not data['is_participant'] and order.status != Order.Status.PUB:
|
if not data['is_participant'] and order.status != Order.Status.PUB:
|
||||||
return Response({'bad_request':'Not allowed to see this order'},status.HTTP_403_FORBIDDEN)
|
return Response({'bad_request':'Not allowed to see this order'},status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
# 3) Non participants can view details (but only if PUB)
|
# 4) Non participants can view details (but only if PUB)
|
||||||
elif not data['is_participant'] and order.status != Order.Status.PUB:
|
elif not data['is_participant'] and order.status != Order.Status.PUB:
|
||||||
return Response(data, status=status.HTTP_200_OK)
|
return Response(data, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
@ -111,7 +117,7 @@ class OrderView(viewsets.ViewSet):
|
|||||||
data['taker_nick'] = str(order.taker)
|
data['taker_nick'] = str(order.taker)
|
||||||
data['status_message'] = Order.Status(order.status).label
|
data['status_message'] = Order.Status(order.status).label
|
||||||
|
|
||||||
# 4) If status is 'waiting for maker bond', reply with a MAKER HODL invoice.
|
# 5) If status is 'waiting for maker bond' and user is MAKER, reply with a MAKER HODL invoice.
|
||||||
if order.status == Order.Status.WFB and data['is_maker']:
|
if order.status == Order.Status.WFB and data['is_maker']:
|
||||||
valid, context = Logics.gen_maker_hodl_invoice(order, request.user)
|
valid, context = Logics.gen_maker_hodl_invoice(order, request.user)
|
||||||
if valid:
|
if valid:
|
||||||
@ -119,24 +125,16 @@ class OrderView(viewsets.ViewSet):
|
|||||||
else:
|
else:
|
||||||
return Response(context, status.HTTP_400_BAD_REQUEST)
|
return Response(context, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# 5) If status is 'Taken' and user is taker/buyer, reply with a TAKER HODL invoice.
|
# 6) If status is 'waiting for taker bond' and user is TAKER, reply with a TAKER HODL invoice.
|
||||||
elif order.status == Order.Status.TAK and data['is_taker'] and data['is_buyer']:
|
elif order.status == Order.Status.TAK and data['is_taker']:
|
||||||
valid, context = Logics.gen_takerbuyer_hodl_invoice(order, request.user)
|
valid, context = Logics.gen_taker_hodl_invoice(order, request.user)
|
||||||
if valid:
|
if valid:
|
||||||
data = {**data, **context}
|
data = {**data, **context}
|
||||||
else:
|
else:
|
||||||
return Response(context, status.HTTP_400_BAD_REQUEST)
|
return Response(context, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# 6) If status is 'Public' and user is taker/seller, reply with a ESCROW HODL invoice.
|
# 7) If status is 'WF2'or'WTC' and user is Seller, reply with an ESCROW HODL invoice.
|
||||||
elif order.status == Order.Status.PUB and data['is_taker'] and data['is_seller']:
|
elif (order.status == Order.Status.WF2 or order.status == Order.Status.WFE) and data['is_seller']:
|
||||||
valid, context = Logics.gen_seller_hodl_invoice(order, request.user)
|
|
||||||
if valid:
|
|
||||||
data = {**data, **context}
|
|
||||||
else:
|
|
||||||
return Response(context, status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# 7) If status is 'WF2/WTC' and user is maker/seller, reply with an ESCROW HODL invoice.
|
|
||||||
elif (order.status == Order.Status.WF2 or order.status == Order.Status.WF2) and data['is_maker'] and data['is_seller']:
|
|
||||||
valid, context = Logics.gen_seller_hodl_invoice(order, request.user)
|
valid, context = Logics.gen_seller_hodl_invoice(order, request.user)
|
||||||
if valid:
|
if valid:
|
||||||
data = {**data, **context}
|
data = {**data, **context}
|
||||||
@ -147,6 +145,10 @@ class OrderView(viewsets.ViewSet):
|
|||||||
return Response({'Order Not Found':'Invalid Order Id'}, status.HTTP_404_NOT_FOUND)
|
return Response({'Order Not Found':'Invalid Order Id'}, status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
def take_update_confirm_dispute_cancel(self, request, format=None):
|
def take_update_confirm_dispute_cancel(self, request, format=None):
|
||||||
|
'''
|
||||||
|
Here take place all of the user updates to the order object.
|
||||||
|
That is: take, confim, cancel, dispute, update_invoice or rate.
|
||||||
|
'''
|
||||||
order_id = request.GET.get(self.lookup_url_kwarg)
|
order_id = request.GET.get(self.lookup_url_kwarg)
|
||||||
|
|
||||||
serializer = UpdateOrderSerializer(data=request.data)
|
serializer = UpdateOrderSerializer(data=request.data)
|
||||||
@ -169,13 +171,14 @@ class OrderView(viewsets.ViewSet):
|
|||||||
else: Response({'bad_request':'This order is not public anymore.'}, status.HTTP_400_BAD_REQUEST)
|
else: Response({'bad_request':'This order is not public anymore.'}, status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# 2) If action is update (invoice)
|
# 2) If action is update (invoice)
|
||||||
elif action == 'update' and invoice:
|
elif action == 'update_invoice' and invoice:
|
||||||
updated, context = Logics.update_invoice(order,request.user,invoice)
|
valid, context = Logics.update_invoice(order,request.user,invoice)
|
||||||
if not updated: return Response(context,status.HTTP_400_BAD_REQUEST)
|
if not valid: return Response(context,status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# 3) If action is cancel
|
# 3) If action is cancel
|
||||||
elif action == 'cancel':
|
elif action == 'cancel':
|
||||||
pass
|
valid, context = Logics.cancel_order(order,request.user,invoice)
|
||||||
|
if not valid: return Response(context,status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# 4) If action is confirm
|
# 4) If action is confirm
|
||||||
elif action == 'confirm':
|
elif action == 'confirm':
|
||||||
|
Loading…
Reference in New Issue
Block a user