diff --git a/api/admin.py b/api/admin.py index f496caa8..5e8f2aca 100644 --- a/api/admin.py +++ b/api/admin.py @@ -24,7 +24,7 @@ class EUserAdmin(UserAdmin): @admin.register(Order) class OrderAdmin(AdminChangeLinksMixin, admin.ModelAdmin): - list_display = ('id','type','maker_link','taker_link','status','amount','currency','created_at','expires_at', 'buyer_invoice_link','maker_bond_link','taker_bond_link','trade_escrow_link') + list_display = ('id','type','maker_link','taker_link','status','amount','currency','t0_satoshis','created_at','expires_at', 'buyer_invoice_link','maker_bond_link','taker_bond_link','trade_escrow_link') list_display_links = ('id','type') change_links = ('maker','taker','buyer_invoice','maker_bond','taker_invoice','taker_bond','trade_escrow') diff --git a/api/models.py b/api/models.py index 44a2f7ab..ad6de46e 100644 --- a/api/models.py +++ b/api/models.py @@ -9,6 +9,7 @@ from datetime import timedelta from django.utils import timezone from pathlib import Path +import requests from .lightning import LNNode @@ -21,6 +22,8 @@ MAX_TRADE = 500*1000 FEE = 0.002 # Trade fee in % BOND_SIZE = 0.01 # Bond in % ESCROW_USERNAME = 'admin' +MARKET_PRICE_API = 'https://blockchain.info/ticker' + class LNPayment(models.Model): @@ -133,6 +136,16 @@ class Order(models.Model): # buyer payment LN invoice buyer_invoice = models.ForeignKey(LNPayment, related_name='buyer_invoice', on_delete=models.SET_NULL, null=True, default=None, blank=True) +@receiver(pre_delete, sender=Order) +def delelete_HTLCs_at_order_deletion(sender, instance, **kwargs): + to_delete = (instance.maker_bond, instance.buyer_invoice, instance.taker_bond, instance.trade_escrow) + + for htlc in to_delete: + try: + htlc.delete() + except: + pass + class Profile(models.Model): user = models.OneToOneField(User,on_delete=models.CASCADE) @@ -207,11 +220,17 @@ class Logics(): def satoshis_now(order): ''' checks trade amount in sats ''' - # TODO - # order.last_satoshis = - # order.save() + if order.is_explicit: + satoshis_now = order.satoshis + else: + market_prices = requests.get(MARKET_PRICE_API).json() + print(market_prices) + exchange_rate = float(market_prices[Order.Currencies(order.currency).label]['last']) + print(exchange_rate) + satoshis_now = ((float(order.amount) * 1+float(order.premium)) / exchange_rate) * 100*1000*1000 + print(satoshis_now) - return 50000 + return satoshis_now def order_expires(order): order.status = Order.Status.EXP @@ -256,11 +275,12 @@ class Logics(): return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'} if order.maker_bond: - return order.maker_bond.invoice - - bond_amount = cls.satoshis_now(order) + return True, {'invoice':order.maker_bond.invoice,'bond_satoshis':order.maker_bond.num_satoshis} + + order.satoshis_now = cls.satoshis_now(order) + bond_satoshis = order.satoshis_now * BOND_SIZE description = f'Robosats maker bond for order ID {order.id}. Will return to you if you do not cheat!' - invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(num_satoshis = bond_amount, description=description) + invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(num_satoshis = bond_satoshis, description=description) order.maker_bond = LNPayment.objects.create( concept = LNPayment.Concepts.MAKEBOND, @@ -269,12 +289,13 @@ class Logics(): receiver = User.objects.get(username=ESCROW_USERNAME), invoice = invoice, status = LNPayment.Status.INVGEN, - num_satoshis = bond_amount, + num_satoshis = bond_satoshis, description = description, payment_hash = payment_hash, expires_at = expires_at, ) order.save() - return invoice + + return True, {'invoice':invoice,'bond_satoshis':bond_satoshis} diff --git a/api/views.py b/api/views.py index 0ea88ee4..a583f52e 100644 --- a/api/views.py +++ b/api/views.py @@ -58,8 +58,11 @@ class OrderMakerView(CreateAPIView): premium=premium, satoshis=satoshis, is_explicit=is_explicit, - expires_at= timezone.now()+timedelta(minutes=EXPIRATION_MAKE), + expires_at=timezone.now()+timedelta(minutes=EXPIRATION_MAKE), maker=request.user) + + order.t0_satoshis=Logics.satoshis_now(order) # TODO reate Order class method when new instance is created! + order.last_satoshis=Logics.satoshis_now(order) order.save() if not serializer.is_valid(): @@ -112,7 +115,11 @@ class OrderView(viewsets.ViewSet): # If status is 'waiting for maker bond', reply with a hodl invoice too. if order.status == Order.Status.WFB and data['is_maker']: - data['hodl_invoice'] = Logics.gen_maker_hodl_invoice(order, request.user) + valid, context = Logics.gen_maker_hodl_invoice(order, request.user) + if valid: + data = {**data, **context} + else: + Response(context, status=status.HTTP_400_BAD_REQUEST) return Response(data, status=status.HTTP_200_OK)