mirror of
https://github.com/RoboSats/robosats.git
synced 2024-12-14 11:26:24 +00:00
Add environmental variables to .env
This commit is contained in:
parent
805b12de65
commit
a1771ae5ea
17
.env-sample
Normal file
17
.env-sample
Normal file
@ -0,0 +1,17 @@
|
||||
# Market price public API
|
||||
MARKET_PRICE_API = 'https://blockchain.info/ticker'
|
||||
|
||||
# Trade fee in percentage %
|
||||
FEE = 0.002
|
||||
# Bond size in percentage %
|
||||
BOND_SIZE = 0.01
|
||||
|
||||
# Trade limits in satoshis
|
||||
MIN_TRADE = 10000
|
||||
MAX_TRADE = 500000
|
||||
|
||||
# Expiration time in minutes
|
||||
EXPIRATION_MAKE = 5
|
||||
|
||||
# Username for HTLCs escrows
|
||||
ESCROW_USERNAME = 'admin'
|
154
api/logics.py
Normal file
154
api/logics.py
Normal file
@ -0,0 +1,154 @@
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
import requests
|
||||
from .lightning import LNNode
|
||||
|
||||
from .models import Order, LNPayment, User
|
||||
from decouple import config
|
||||
|
||||
FEE = float(config('FEE'))
|
||||
BOND_SIZE = float(config('BOND_SIZE'))
|
||||
MARKET_PRICE_API = config('MARKET_PRICE_API')
|
||||
ESCROW_USERNAME = config('ESCROW_USERNAME')
|
||||
|
||||
|
||||
class Logics():
|
||||
|
||||
# escrow_user = User.objects.get(username=ESCROW_USERNAME)
|
||||
|
||||
def validate_already_maker_or_taker(user):
|
||||
'''Checks if the user is already partipant of an order'''
|
||||
queryset = Order.objects.filter(maker=user)
|
||||
if queryset.exists():
|
||||
return False, {'Bad Request':'You are already maker of an order'}
|
||||
queryset = Order.objects.filter(taker=user)
|
||||
if queryset.exists():
|
||||
return False, {'Bad Request':'You are already taker of an order'}
|
||||
return True, None
|
||||
|
||||
def take(order, user):
|
||||
order.taker = user
|
||||
order.status = Order.Status.TAK
|
||||
order.save()
|
||||
|
||||
def is_buyer(order, user):
|
||||
is_maker = order.maker == user
|
||||
is_taker = order.taker == user
|
||||
return (is_maker and order.type == Order.Types.BUY) or (is_taker and order.type == Order.Types.SELL)
|
||||
|
||||
def is_seller(order, user):
|
||||
is_maker = order.maker == user
|
||||
is_taker = order.taker == user
|
||||
return (is_maker and order.type == Order.Types.SELL) or (is_taker and order.type == Order.Types.BUY)
|
||||
|
||||
def satoshis_now(order):
|
||||
''' checks trade amount in sats '''
|
||||
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 satoshis_now
|
||||
|
||||
def order_expires(order):
|
||||
order.status = Order.Status.EXP
|
||||
order.maker = None
|
||||
order.taker = None
|
||||
order.save()
|
||||
|
||||
@classmethod
|
||||
def update_invoice(cls, order, user, 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
|
||||
if cls.is_buyer(order, user) and is_valid_invoice:
|
||||
order.buyer_invoice, _ = LNPayment.objects.update_or_create(
|
||||
concept = LNPayment.Concepts.PAYBUYER,
|
||||
type = LNPayment.Types.NORM,
|
||||
sender = User.objects.get(username=ESCROW_USERNAME),
|
||||
receiver= user,
|
||||
# if there is a LNPayment matching these above, it updates that with defaults below.
|
||||
defaults={
|
||||
'invoice' : invoice,
|
||||
'status' : LNPayment.Status.VALIDI,
|
||||
'num_satoshis' : num_satoshis,
|
||||
'description' : description,
|
||||
'payment_hash' : payment_hash,
|
||||
'expires_at' : expires_at}
|
||||
)
|
||||
|
||||
#If the order status was Payment Failed. Move foward to invoice Updated.
|
||||
if order.status == Order.Status.FAI:
|
||||
order.status = Order.Status.UPI
|
||||
order.save()
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def gen_maker_hodl_invoice(cls, order, user):
|
||||
|
||||
# Do not and delete if order is more than 5 minutes old
|
||||
if order.expires_at < timezone.now():
|
||||
cls.order_expires(order)
|
||||
return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'}
|
||||
|
||||
if order.maker_bond:
|
||||
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_satoshis, description=description)
|
||||
|
||||
order.maker_bond = LNPayment.objects.create(
|
||||
concept = LNPayment.Concepts.MAKEBOND,
|
||||
type = LNPayment.Types.HODL,
|
||||
sender = user,
|
||||
receiver = User.objects.get(username=ESCROW_USERNAME),
|
||||
invoice = invoice,
|
||||
status = LNPayment.Status.INVGEN,
|
||||
num_satoshis = bond_satoshis,
|
||||
description = description,
|
||||
payment_hash = payment_hash,
|
||||
expires_at = expires_at,
|
||||
)
|
||||
|
||||
order.save()
|
||||
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
|
||||
|
||||
@classmethod
|
||||
def gen_taker_buyer_hodl_invoice(cls, order, user):
|
||||
|
||||
# Do not and delete if order is more than 5 minutes old
|
||||
if order.expires_at < timezone.now():
|
||||
cls.order_expires(order)
|
||||
return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'}
|
||||
|
||||
if order.maker_bond:
|
||||
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_satoshis, description=description)
|
||||
|
||||
order.maker_bond = LNPayment.objects.create(
|
||||
concept = LNPayment.Concepts.MAKEBOND,
|
||||
type = LNPayment.Types.HODL,
|
||||
sender = user,
|
||||
receiver = User.objects.get(username=ESCROW_USERNAME),
|
||||
invoice = invoice,
|
||||
status = LNPayment.Status.INVGEN,
|
||||
num_satoshis = bond_satoshis,
|
||||
description = description,
|
||||
payment_hash = payment_hash,
|
||||
expires_at = expires_at,
|
||||
)
|
||||
|
||||
order.save()
|
||||
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
|
128
api/models.py
128
api/models.py
@ -5,24 +5,18 @@ from django.db.models.signals import post_save, pre_delete
|
||||
from django.dispatch import receiver
|
||||
from django.utils.html import mark_safe
|
||||
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
|
||||
from decouple import config
|
||||
from pathlib import Path
|
||||
import requests
|
||||
|
||||
from .lightning import LNNode
|
||||
|
||||
#############################
|
||||
# TODO
|
||||
# Load hparams from .env file
|
||||
|
||||
MIN_TRADE = 10*1000 #In sats
|
||||
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'
|
||||
MIN_TRADE = int(config('MIN_TRADE'))
|
||||
MAX_TRADE = int(config('MAX_TRADE'))
|
||||
FEE = float(config('FEE'))
|
||||
BOND_SIZE = float(config('BOND_SIZE'))
|
||||
|
||||
|
||||
|
||||
class LNPayment(models.Model):
|
||||
@ -189,113 +183,3 @@ class Profile(models.Model):
|
||||
def avatar_tag(self):
|
||||
return mark_safe('<img src="%s" width="50" height="50" />' % self.get_avatar())
|
||||
|
||||
class Logics():
|
||||
|
||||
# escrow_user = User.objects.get(username=ESCROW_USERNAME)
|
||||
|
||||
def validate_already_maker_or_taker(user):
|
||||
'''Checks if the user is already partipant of an order'''
|
||||
queryset = Order.objects.filter(maker=user)
|
||||
if queryset.exists():
|
||||
return False, {'Bad Request':'You are already maker of an order'}
|
||||
queryset = Order.objects.filter(taker=user)
|
||||
if queryset.exists():
|
||||
return False, {'Bad Request':'You are already taker of an order'}
|
||||
return True, None
|
||||
|
||||
def take(order, user):
|
||||
order.taker = user
|
||||
order.status = Order.Status.TAK
|
||||
order.save()
|
||||
|
||||
def is_buyer(order, user):
|
||||
is_maker = order.maker == user
|
||||
is_taker = order.taker == user
|
||||
return (is_maker and order.type == Order.Types.BUY) or (is_taker and order.type == Order.Types.SELL)
|
||||
|
||||
def is_seller(order, user):
|
||||
is_maker = order.maker == user
|
||||
is_taker = order.taker == user
|
||||
return (is_maker and order.type == Order.Types.SELL) or (is_taker and order.type == Order.Types.BUY)
|
||||
|
||||
def satoshis_now(order):
|
||||
''' checks trade amount in sats '''
|
||||
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 satoshis_now
|
||||
|
||||
def order_expires(order):
|
||||
order.status = Order.Status.EXP
|
||||
order.maker = None
|
||||
order.taker = None
|
||||
order.save()
|
||||
|
||||
@classmethod
|
||||
def update_invoice(cls, order, user, 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
|
||||
if cls.is_buyer(order, user) and is_valid_invoice:
|
||||
order.buyer_invoice, _ = LNPayment.objects.update_or_create(
|
||||
concept = LNPayment.Concepts.PAYBUYER,
|
||||
type = LNPayment.Types.NORM,
|
||||
sender = User.objects.get(username=ESCROW_USERNAME),
|
||||
receiver= user,
|
||||
# if there is a LNPayment matching these above, it updates that with defaults below.
|
||||
defaults={
|
||||
'invoice' : invoice,
|
||||
'status' : LNPayment.Status.VALIDI,
|
||||
'num_satoshis' : num_satoshis,
|
||||
'description' : description,
|
||||
'payment_hash' : payment_hash,
|
||||
'expires_at' : expires_at}
|
||||
)
|
||||
|
||||
#If the order status was Payment Failed. Move foward to invoice Updated.
|
||||
if order.status == Order.Status.FAI:
|
||||
order.status = Order.Status.UPI
|
||||
order.save()
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def gen_maker_hodl_invoice(cls, order, user):
|
||||
|
||||
# Do not and delete if order is more than 5 minutes old
|
||||
if order.expires_at < timezone.now():
|
||||
cls.order_expires(order)
|
||||
return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'}
|
||||
|
||||
if order.maker_bond:
|
||||
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_satoshis, description=description)
|
||||
|
||||
order.maker_bond = LNPayment.objects.create(
|
||||
concept = LNPayment.Concepts.MAKEBOND,
|
||||
type = LNPayment.Types.HODL,
|
||||
sender = user,
|
||||
receiver = User.objects.get(username=ESCROW_USERNAME),
|
||||
invoice = invoice,
|
||||
status = LNPayment.Status.INVGEN,
|
||||
num_satoshis = bond_satoshis,
|
||||
description = description,
|
||||
payment_hash = payment_hash,
|
||||
expires_at = expires_at,
|
||||
)
|
||||
|
||||
order.save()
|
||||
|
||||
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
|
||||
|
||||
|
@ -8,8 +8,8 @@ from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from .serializers import ListOrderSerializer, MakeOrderSerializer, UpdateInvoiceSerializer
|
||||
from .models import Order, LNPayment, Logics
|
||||
from .lightning import LNNode
|
||||
from .models import Order
|
||||
from .logics import Logics
|
||||
|
||||
from .nick_generator.nick_generator import NickGenerator
|
||||
from robohash import Robohash
|
||||
@ -21,8 +21,9 @@ from pathlib import Path
|
||||
from datetime import timedelta
|
||||
from django.utils import timezone
|
||||
|
||||
# .env
|
||||
EXPIRATION_MAKE = 5 # minutes
|
||||
from decouple import config
|
||||
|
||||
EXPIRATION_MAKE = config('EXPIRATION_MAKE')
|
||||
|
||||
avatar_path = Path('frontend/static/assets/avatars')
|
||||
avatar_path.mkdir(parents=True, exist_ok=True)
|
||||
|
Loading…
Reference in New Issue
Block a user