Implement referral attributes and logics

This commit is contained in:
Reckless_Satoshi 2022-03-05 10:43:15 -08:00
parent dea2b665fb
commit 4ee6778e11
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
9 changed files with 60 additions and 19 deletions

View File

@ -90,5 +90,8 @@ PROPORTIONAL_ROUTING_FEE_LIMIT = 0.0002
# Base flat limit fee for routing in Sats (used only when proportional is lower than this)
MIN_FLAT_ROUTING_FEE_LIMIT = 10
# Reward tip. Reward for every finished trade in the referral program (Satoshis)
REWARD_TIP = 100
# Username for HTLCs escrows
ESCROW_USERNAME = 'admin'

View File

@ -103,6 +103,7 @@ class UserProfileAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
"avatar_tag",
"id",
"user_link",
"is_referred",
"telegram_enabled",
"total_contracts",
"platform_rating",

View File

@ -1029,12 +1029,19 @@ class Logics:
cls.return_bond(order.taker_bond)
cls.return_bond(order.maker_bond)
##### !!! KEY LINE - PAYS THE BUYER INVOICE !!!
##### Backgroun process "follow_invoices" will try to pay this invoice until success
##### Background process "follow_invoices" will try to pay this invoice until success
order.status = Order.Status.PAY
order.payout.status = LNPayment.Status.FLIGHT
order.payout.save()
order.save()
send_message.delay(order.id,'trade_successful')
# Add referral rewards (safe)
try:
Logics.add_rewards(order)
except:
pass
return True, None
else:
@ -1082,3 +1089,17 @@ class Logics:
user.profile.save()
return True, None
@classmethod
def add_rewards(cls, order):
'''
This order is called after a trade is finished.
If order participants were referred, we add the reward to the referees.
'''
if order.maker.profile.is_referred:
order.maker.profile.referred_by.pending_rewards += int(config('REWARD_TIP'))
if order.taker.profile.is_referred:
order.taker.profile.referred_by.pending_rewards += int(config('REWARD_TIP'))
return

View File

@ -411,6 +411,14 @@ class Profile(models.Model):
default=False,
null=False
)
referred_by = models.ForeignKey(
'self',
related_name="referee",
on_delete=models.SET_NULL,
null=True,
default=None,
blank=True,
)
referral_code = models.CharField(
max_length=15,
null=True,
@ -421,7 +429,7 @@ class Profile(models.Model):
# Claimable rewards
earned_rewards = models.PositiveIntegerField(null=False, default=0)
# Total claimed rewards
claimed_rewarded = models.PositiveIntegerField(null=False, default=0)
claimed_rewards = models.PositiveIntegerField(null=False, default=0)
# Disputes
num_disputes = models.PositiveIntegerField(null=False, default=0)

View File

@ -17,9 +17,11 @@ def users_cleansing():
queryset = User.objects.filter(~Q(last_login__range=active_time_range))
queryset = queryset.filter(is_staff=False) # Do not delete staff users
# And do not have an active trade or any past contract.
# And do not have an active trade, any past contract or any reward.
deleted_users = []
for user in queryset:
if user.profile.pending_rewards > 0 or user.profile.earned_rewards > 0 or user.profile.claimed_rewards > 0:
continue
if not user.profile.total_contracts == 0:
continue
valid, _, _ = Logics.validate_already_maker_or_taker(user)
@ -45,6 +47,7 @@ def follow_send_payment(lnpayment):
from api.lightning.node import LNNode, MACAROON
from api.models import LNPayment, Order
from api.logics import Logics
fee_limit_sat = int(
max(

View File

@ -3,9 +3,7 @@ from .views import MakerView, OrderView, UserView, BookView, InfoView
urlpatterns = [
path("make/", MakerView.as_view()),
path(
"order/",
OrderView.as_view({
path("order/",OrderView.as_view({
"get": "get",
"post": "take_update_confirm_dispute_cancel"
}),

View File

@ -10,7 +10,7 @@ from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from api.serializers import ListOrderSerializer, MakeOrderSerializer, UpdateOrderSerializer
from api.models import LNPayment, MarketTick, Order, Currency
from api.models import LNPayment, MarketTick, Order, Currency, Profile
from api.logics import Logics
from api.messages import Telegram
from secrets import token_urlsafe
@ -446,7 +446,6 @@ class OrderView(viewsets.ViewSet):
class UserView(APIView):
lookup_url_kwarg = "token"
NickGen = NickGenerator(lang="English",
use_adv=False,
use_adj=True,
@ -476,12 +475,8 @@ class UserView(APIView):
"bad_request"] = f"You are already logged in as {request.user} and have an active order"
return Response(context, status.HTTP_400_BAD_REQUEST)
# Does not allow this 'mistake' if the last login was sometime ago (5 minutes)
# if request.user.last_login < timezone.now() - timedelta(minutes=5):
# context['bad_request'] = f'You are already logged in as {request.user}'
# return Response(context, status.HTTP_400_BAD_REQUEST)
token = request.GET.get(self.lookup_url_kwarg)
token = request.GET.get("token")
ref_code = request.GET.get("ref_code")
# Compute token entropy
value, counts = np.unique(list(token), return_counts=True)
@ -515,15 +510,26 @@ class UserView(APIView):
with open(image_path, "wb") as f:
rh.img.save(f, format="png")
# Create new credentials and login if nickname is new
if len(User.objects.filter(username=nickname)) == 0:
User.objects.create_user(username=nickname,
password=token,
is_staff=False)
user = authenticate(request, username=nickname, password=token)
user.profile.avatar = "static/assets/avatars/" + nickname + ".png"
#user.profile.referral_code = token_urlsafe(8)
login(request, user)
context['referral_code'] = token_urlsafe(8)
user.profile.referral_code = context['referral_code']
user.profile.avatar = "static/assets/avatars/" + nickname + ".png"
# If the ref_code is not none this is a new referred robot
if ref_code != None and ref_code !='undefined':
user.profile.is_referred = True
user.profile.referred_by = Profile.objects.get(referral_code=ref_code)
user.profile.save()
return Response(context, status=status.HTTP_201_CREATED)
else:
@ -686,6 +692,8 @@ class InfoView(ListAPIView):
if request.user.is_authenticated:
context["nickname"] = request.user.username
context["referral_link"] = str(config('HOST_NAME'))+'/ref/'+str(request.user.profile.referral_code)
context["earned_rewards"] = request.user.profile.earned_rewards
has_no_active_order, _, order = Logics.validate_already_maker_or_taker(
request.user)
if not has_no_active_order:

View File

@ -56,7 +56,6 @@ export default class UserGenPage extends Component {
// sort of cryptographically strong function to generate Base62 token client-side
genBase62Token(length)
{
console.log(this.refCode)
return window.btoa(Array.from(
window.crypto.getRandomValues(
new Uint8Array(length * 2)))
@ -66,7 +65,7 @@ export default class UserGenPage extends Component {
}
getGeneratedUser=(token)=>{
fetch('/api/user' + '?token=' + token)
fetch('/api/user' + '?token=' + token + '&ref_code=' + this.refCode)
.then((response) => response.json())
.then((data) => {
this.setState({

File diff suppressed because one or more lines are too long