mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-18 12:11:35 +00:00
Implement public API non-KYC BTC prices
This commit is contained in:
parent
408516241d
commit
f383d20c37
@ -312,30 +312,25 @@ class Order(models.Model):
|
||||
taker_platform_rated = models.BooleanField(default=False, null=False)
|
||||
|
||||
t_to_expire = {
|
||||
0: int(config("EXP_MAKER_BOND_INVOICE")), # 'Waiting for maker bond'
|
||||
0: int(config("EXP_MAKER_BOND_INVOICE")), # 'Waiting for maker bond'
|
||||
1: 60 * 60 * int(config("PUBLIC_ORDER_DURATION")), # 'Public'
|
||||
2: 0, # 'Deleted'
|
||||
3: int(config("EXP_TAKER_BOND_INVOICE")), # 'Waiting for taker bond'
|
||||
4: 0, # 'Cancelled'
|
||||
5: 0, # 'Expired'
|
||||
6: 60 * int(config("INVOICE_AND_ESCROW_DURATION")
|
||||
), # 'Waiting for trade collateral and buyer invoice'
|
||||
7: 60 * int(config("INVOICE_AND_ESCROW_DURATION")
|
||||
), # 'Waiting only for seller trade collateral'
|
||||
8: 60 * int(config("INVOICE_AND_ESCROW_DURATION")
|
||||
), # 'Waiting only for buyer invoice'
|
||||
9: 60 * 60 *
|
||||
int(config("FIAT_EXCHANGE_DURATION")), # 'Sending fiat - In chatroom'
|
||||
10: 60 * 60 *
|
||||
int(config("FIAT_EXCHANGE_DURATION")), # 'Fiat sent - In chatroom'
|
||||
11: 1 * 24 * 60 * 60, # 'In dispute'
|
||||
12: 0, # 'Collaboratively cancelled'
|
||||
13: 24 * 60 * 60, # 'Sending satoshis to buyer'
|
||||
14: 24 * 60 * 60, # 'Sucessful trade'
|
||||
15: 24 * 60 * 60, # 'Failed lightning network routing'
|
||||
16: 10 * 24 * 60 * 60, # 'Wait for dispute resolution'
|
||||
17: 24 * 60 * 60, # 'Maker lost dispute'
|
||||
18: 24 * 60 * 60, # 'Taker lost dispute'
|
||||
2: 0, # 'Deleted'
|
||||
3: int(config("EXP_TAKER_BOND_INVOICE")), # 'Waiting for taker bond'
|
||||
4: 0, # 'Cancelled'
|
||||
5: 0, # 'Expired'
|
||||
6: 60 * int(config("INVOICE_AND_ESCROW_DURATION")), # 'Waiting for trade collateral and buyer invoice'
|
||||
7: 60 * int(config("INVOICE_AND_ESCROW_DURATION")), # 'Waiting only for seller trade collateral'
|
||||
8: 60 * int(config("INVOICE_AND_ESCROW_DURATION")), # 'Waiting only for buyer invoice'
|
||||
9: 60 * 60 * int(config("FIAT_EXCHANGE_DURATION")), # 'Sending fiat - In chatroom'
|
||||
10: 60 * 60 * int(config("FIAT_EXCHANGE_DURATION")),# 'Fiat sent - In chatroom'
|
||||
11: 1 * 24 * 60 * 60, # 'In dispute'
|
||||
12: 0, # 'Collaboratively cancelled'
|
||||
13: 24 * 60 * 60, # 'Sending satoshis to buyer'
|
||||
14: 24 * 60 * 60, # 'Sucessful trade'
|
||||
15: 24 * 60 * 60, # 'Failed lightning network routing'
|
||||
16: 10 * 24 * 60 * 60, # 'Wait for dispute resolution'
|
||||
17: 24 * 60 * 60, # 'Maker lost dispute'
|
||||
18: 24 * 60 * 60, # 'Taker lost dispute'
|
||||
}
|
||||
|
||||
def __str__(self):
|
||||
|
@ -71,4 +71,7 @@ class ClaimRewardSerializer(serializers.Serializer):
|
||||
invoice = serializers.CharField(max_length=2000,
|
||||
allow_null=True,
|
||||
allow_blank=True,
|
||||
default=None)
|
||||
default=None)
|
||||
|
||||
class PriceSerializer(serializers.Serializer):
|
||||
pass
|
@ -1,5 +1,5 @@
|
||||
from django.urls import path
|
||||
from .views import MakerView, OrderView, UserView, BookView, InfoView, RewardView
|
||||
from .views import MakerView, OrderView, UserView, BookView, InfoView, RewardView, PriceView
|
||||
|
||||
urlpatterns = [
|
||||
path("make/", MakerView.as_view()),
|
||||
@ -12,5 +12,6 @@ urlpatterns = [
|
||||
path("book/", BookView.as_view()),
|
||||
# path('robot/') # Profile Info
|
||||
path("info/", InfoView.as_view()),
|
||||
path("price/", PriceView.as_view()),
|
||||
path("reward/", RewardView.as_view()),
|
||||
]
|
||||
|
15
api/utils.py
15
api/utils.py
@ -108,4 +108,17 @@ def compute_premium_percentile(order):
|
||||
float(similar_order.last_satoshis) / float(similar_order.amount))
|
||||
|
||||
rates = np.array(rates)
|
||||
return round(np.sum(rates < order_rate) / len(rates), 2)
|
||||
return round(np.sum(rates < order_rate) / len(rates), 2)
|
||||
|
||||
|
||||
def compute_avg_premium(queryset):
|
||||
weighted_premiums = []
|
||||
volumes = []
|
||||
for tick in queryset:
|
||||
weighted_premiums.append(tick.premium * tick.volume)
|
||||
volumes.append(tick.volume)
|
||||
|
||||
total_volume = sum(volumes)
|
||||
# Avg_premium is the weighted average of the premiums by volume
|
||||
avg_premium = sum(weighted_premiums) / total_volume
|
||||
return avg_premium, total_volume
|
50
api/views.py
50
api/views.py
@ -9,12 +9,12 @@ from rest_framework.response import Response
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from api.serializers import ListOrderSerializer, MakeOrderSerializer, UpdateOrderSerializer, ClaimRewardSerializer
|
||||
from api.serializers import ListOrderSerializer, MakeOrderSerializer, UpdateOrderSerializer, ClaimRewardSerializer, PriceSerializer
|
||||
from api.models import LNPayment, MarketTick, Order, Currency, Profile
|
||||
from api.logics import Logics
|
||||
from api.messages import Telegram
|
||||
from secrets import token_urlsafe
|
||||
from api.utils import get_lnd_version, get_commit_robosats, compute_premium_percentile
|
||||
from api.utils import get_lnd_version, get_commit_robosats, compute_premium_percentile, compute_avg_premium
|
||||
|
||||
from .nick_generator.nick_generator import NickGenerator
|
||||
from robohash import Robohash
|
||||
@ -655,18 +655,11 @@ class InfoView(ListAPIView):
|
||||
# Compute average premium and volume of today
|
||||
queryset = MarketTick.objects.filter(timestamp__day=today.day)
|
||||
if not len(queryset) == 0:
|
||||
weighted_premiums = []
|
||||
volumes = []
|
||||
for tick in queryset:
|
||||
weighted_premiums.append(tick.premium * tick.volume)
|
||||
volumes.append(tick.volume)
|
||||
|
||||
total_volume = sum(volumes)
|
||||
# Avg_premium is the weighted average of the premiums by volume
|
||||
avg_premium = sum(weighted_premiums) / total_volume
|
||||
avg_premium, total_volume = compute_avg_premium(queryset)
|
||||
# If no contracts, fallback to lifetime avg premium
|
||||
else:
|
||||
avg_premium = 0
|
||||
total_volume = 0
|
||||
queryset = MarketTick.objects.all()
|
||||
avg_premium, total_volume = compute_avg_premium(queryset)
|
||||
|
||||
queryset = MarketTick.objects.all()
|
||||
if not len(queryset) == 0:
|
||||
@ -729,6 +722,33 @@ class RewardView(CreateAPIView):
|
||||
context['successful_withdrawal'] = False
|
||||
return Response(context, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
|
||||
return Response({"successful_withdrawal": True}, status.HTTP_200_OK)
|
||||
|
||||
class PriceView(CreateAPIView):
|
||||
|
||||
serializer_class = PriceSerializer
|
||||
|
||||
def get(self, request):
|
||||
|
||||
# Compute average premium and volume of last 24 h
|
||||
start_datetime = timezone.now() - timedelta(days=1)
|
||||
queryset = MarketTick.objects.filter(timestamp__gt=start_datetime)
|
||||
if not len(queryset) == 0:
|
||||
avg_premium, _ = compute_avg_premium(queryset)
|
||||
|
||||
# If no contracts exists in the last 24 h, fallback to lifetime average premium.
|
||||
else:
|
||||
queryset = MarketTick.objects.all()
|
||||
avg_premium, _ = compute_avg_premium(queryset)
|
||||
|
||||
payload = {}
|
||||
queryset = Currency.objects.all().order_by('currency')
|
||||
for currency in queryset:
|
||||
code = Currency.currency_dict[str(currency.currency)]
|
||||
payload[code] = {'price': currency.exchange_rate * (1 + avg_premium / 100),
|
||||
'premium': avg_premium}
|
||||
|
||||
# A hack here. BTC swaps have usually no premium (at least, they are totally different)
|
||||
payload['BTC'] = {'price': 1, 'premium': 0}
|
||||
|
||||
return Response(payload, status.HTTP_200_OK)
|
@ -315,11 +315,11 @@ export default class BottomBar extends Component {
|
||||
<ListItemIcon>
|
||||
<PasswordIcon/>
|
||||
</ListItemIcon>
|
||||
<ListItemText secondary="It will not remain here">
|
||||
<ListItemText secondary="Your token (will not remain here)">
|
||||
{this.props.token ?
|
||||
<TextField
|
||||
disabled
|
||||
label='Your Token, back it up!'
|
||||
label='Back it up!'
|
||||
value={this.props.token }
|
||||
variant='filled'
|
||||
size='small'
|
||||
|
@ -367,6 +367,17 @@ export default class OrderPage extends Component {
|
||||
)
|
||||
}
|
||||
|
||||
BackButton = () => {
|
||||
// If order has expired, show back button.
|
||||
if (this.state.status == 5){
|
||||
return(
|
||||
<Grid item xs={12} align="center">
|
||||
<Button variant='contained' color='secondary' onClick={this.props.history.goBack}>Back</Button>
|
||||
</Grid>
|
||||
)}
|
||||
return(null)
|
||||
}
|
||||
|
||||
CancelButton = () => {
|
||||
|
||||
// If maker and Waiting for Bond. Or if taker and Waiting for bond.
|
||||
@ -560,8 +571,11 @@ export default class OrderPage extends Component {
|
||||
|
||||
<Grid item xs={12} align="center">
|
||||
{/* Participants can see the "Cancel" Button, but cannot see the "Back" or "Take Order" buttons */}
|
||||
{this.state.is_participant ?
|
||||
<this.CancelButton/>
|
||||
{this.state.is_participant ?
|
||||
<>
|
||||
<this.CancelButton/>
|
||||
<this.BackButton/>
|
||||
</>
|
||||
:
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12} align="center">
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user