Add preliminary pricing for t0 and maker bond. Add reverse on_delete Cascade Orders -> Htlcs

This commit is contained in:
Reckless_Satoshi 2022-01-06 08:20:04 -08:00
parent 5505476ea4
commit 805b12de65
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
3 changed files with 41 additions and 13 deletions

View File

@ -24,7 +24,7 @@ class EUserAdmin(UserAdmin):
@admin.register(Order) @admin.register(Order)
class OrderAdmin(AdminChangeLinksMixin, admin.ModelAdmin): 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') list_display_links = ('id','type')
change_links = ('maker','taker','buyer_invoice','maker_bond','taker_invoice','taker_bond','trade_escrow') change_links = ('maker','taker','buyer_invoice','maker_bond','taker_invoice','taker_bond','trade_escrow')

View File

@ -9,6 +9,7 @@ from datetime import timedelta
from django.utils import timezone from django.utils import timezone
from pathlib import Path from pathlib import Path
import requests
from .lightning import LNNode from .lightning import LNNode
@ -21,6 +22,8 @@ MAX_TRADE = 500*1000
FEE = 0.002 # Trade fee in % FEE = 0.002 # Trade fee in %
BOND_SIZE = 0.01 # Bond in % BOND_SIZE = 0.01 # Bond in %
ESCROW_USERNAME = 'admin' ESCROW_USERNAME = 'admin'
MARKET_PRICE_API = 'https://blockchain.info/ticker'
class LNPayment(models.Model): class LNPayment(models.Model):
@ -133,6 +136,16 @@ class Order(models.Model):
# buyer payment LN invoice # buyer payment LN invoice
buyer_invoice = models.ForeignKey(LNPayment, related_name='buyer_invoice', on_delete=models.SET_NULL, null=True, default=None, blank=True) 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): class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE) user = models.OneToOneField(User,on_delete=models.CASCADE)
@ -207,11 +220,17 @@ class Logics():
def satoshis_now(order): def satoshis_now(order):
''' checks trade amount in sats ''' ''' checks trade amount in sats '''
# TODO if order.is_explicit:
# order.last_satoshis = satoshis_now = order.satoshis
# order.save() 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): def order_expires(order):
order.status = Order.Status.EXP 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.'} return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'}
if order.maker_bond: if order.maker_bond:
return order.maker_bond.invoice return True, {'invoice':order.maker_bond.invoice,'bond_satoshis':order.maker_bond.num_satoshis}
bond_amount = cls.satoshis_now(order) 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!' 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( order.maker_bond = LNPayment.objects.create(
concept = LNPayment.Concepts.MAKEBOND, concept = LNPayment.Concepts.MAKEBOND,
@ -269,12 +289,13 @@ class Logics():
receiver = User.objects.get(username=ESCROW_USERNAME), receiver = User.objects.get(username=ESCROW_USERNAME),
invoice = invoice, invoice = invoice,
status = LNPayment.Status.INVGEN, status = LNPayment.Status.INVGEN,
num_satoshis = bond_amount, num_satoshis = bond_satoshis,
description = description, description = description,
payment_hash = payment_hash, payment_hash = payment_hash,
expires_at = expires_at, expires_at = expires_at,
) )
order.save() order.save()
return invoice
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}

View File

@ -58,8 +58,11 @@ class OrderMakerView(CreateAPIView):
premium=premium, premium=premium,
satoshis=satoshis, satoshis=satoshis,
is_explicit=is_explicit, is_explicit=is_explicit,
expires_at= timezone.now()+timedelta(minutes=EXPIRATION_MAKE), expires_at=timezone.now()+timedelta(minutes=EXPIRATION_MAKE),
maker=request.user) 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() order.save()
if not serializer.is_valid(): 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 status is 'waiting for maker bond', reply with a hodl invoice too.
if order.status == Order.Status.WFB and data['is_maker']: 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) return Response(data, status=status.HTTP_200_OK)