Skip to content

Commit

Permalink
Merge pull request #110 from UnitapApp/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Mohamad Bastin authored Sep 2, 2023
2 parents 5f2d812 + b9312ab commit 03946b2
Show file tree
Hide file tree
Showing 38 changed files with 742 additions and 280 deletions.
12 changes: 11 additions & 1 deletion authentication/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from authentication.helpers import BRIGHTID_SOULDBOUND_INTERFACE
from django.utils import timezone
from django.core.validators import RegexValidator
from django.core.cache import cache


class ProfileManager(models.Manager):
Expand Down Expand Up @@ -66,14 +67,23 @@ def is_aura_verified(self):
)

return is_verified

def save(self, *args, **kwargs):
super().save(*args, **kwargs)

if not self.username:
self.username = f"User{self.pk}"
super().save(*args, **kwargs)

@staticmethod
def user_count():
cached_user_count = cache.get("user_profile_count")
if cached_user_count:
return cached_user_count
count = UserProfile.objects.count()
cache.set("user_profile_count", count, 300)
return count


class NetworkTypes:
EVM = "EVM"
Expand Down
1 change: 1 addition & 0 deletions authentication/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

urlpatterns = [
path("user/login/", LoginView.as_view(), name="login-user"),
path("user/count/", UserProfileCountView.as_view(), name="user-count"),
path(
"user/set-username/",
SetUsernameView.as_view(),
Expand Down
6 changes: 5 additions & 1 deletion authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@
)


class UserProfileCountView(ListAPIView):
def get(self, request, *args, **kwargs):
return Response({"count": UserProfile.user_count()}, status=200)


class SponsorView(CreateAPIView):
def post(self, request, *args, **kwargs):

address = request.data.get("address", None)
if not address:
return Response({"message": "Invalid request"}, status=403)
Expand Down
8 changes: 8 additions & 0 deletions brightIDfaucet/celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@
"task": "faucet.tasks.update_tokentap_claim_for_verified_lightning_claims",
"schedule": 3,
},
'update-tokens-price': {
"task": "faucet.tasks.update_tokens_price",
"schedule": 120,
},
'update-donation-receipt-status': {
"task": "faucet.tasks.update_donation_receipt_pending_status",
"schedule": 60,
}
}

# Load task modules from all registered Django apps.
Expand Down
4 changes: 2 additions & 2 deletions brightIDfaucet/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def before_send(event, hint):
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"core.apps.CoreConfig",
"faucet.apps.FaucetConfig",
"tokenTap.apps.TokentapConfig",
"prizetap.apps.PrizetapConfig",
Expand All @@ -116,8 +117,7 @@ def before_send(event, hint):
"encrypted_model_fields",
"drf_yasg",
"corsheaders",
"django_filters",
"core"
"django_filters"
]

MIDDLEWARE = [
Expand Down
18 changes: 17 additions & 1 deletion core/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.contrib import admin
from .models import TokenPrice


class UserConstraintBaseAdmin(admin.ModelAdmin):
fields = [
Expand All @@ -12,4 +14,18 @@ class UserConstraintBaseAdmin(admin.ModelAdmin):
"pk",
"name",
"description"
]
]


class TokenPriceAdmin(admin.ModelAdmin):
list_display = [
'symbol',
'usd_price',
'price_url',
'datetime',
'last_updated'
]
list_filter = ["symbol"]


admin.site.register(TokenPrice, TokenPriceAdmin)
6 changes: 6 additions & 0 deletions core/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class CoreConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'core'
56 changes: 53 additions & 3 deletions core/constraints.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,52 @@
import copy
from enum import Enum
from abc import ABC, abstractmethod
from authentication.models import UserProfile

class ConstraintParam(Enum):
CHAIN='chain'
ADDRESS='address'
ID='id'
USERNAME='username'
FROM_DATE='from_date'
TO_DATE='to_date'

@classmethod
def choices(cls):
return [(key.value, key.name) for key in cls]

class ConstraintVerification(ABC):
def __init__(self, user_profile:UserProfile, response:str = None) -> None:
_param_keys = []
_param_values = {}
__response_text = ""

def __init__(self, user_profile:UserProfile) -> None:
self.user_profile = user_profile
self.response_text = response

@abstractmethod
def is_observed(self, *args, **kwargs) -> bool:
pass

@classmethod
def param_keys(cls) -> list:
return cls._param_keys

@classmethod
def set_param_values(cls, values: dict):
valid_keys = [key for key in cls.param_keys()]
for key in values:
if key not in valid_keys:
raise Exception(f"Invalid param key {key}")
cls._param_values = copy.deepcopy(values)

@property
def response(self) -> str:
return self.response_text or f"{self.__class__.__name__} constraint is violated"
return self.__response_text or f"{self.__class__.__name__} constraint is violated"

@response.setter
def response(self, text: str):
self.__response_text = text


class BrightIDMeetVerification(ConstraintVerification):
def is_observed(self, *args, **kwargs):
Expand All @@ -21,4 +56,19 @@ def is_observed(self, *args, **kwargs):
class BrightIDAuraVerification(ConstraintVerification):
def is_observed(self, *args, **kwargs):
return self.user_profile.is_aura_verified

class HasNFTVerification(ConstraintVerification):
_param_keys = [
ConstraintParam.CHAIN,
ConstraintParam.ADDRESS,
ConstraintParam.ID
]

def __init__(self, user_profile: UserProfile, response: str = None) -> None:
super().__init__(user_profile, response)

def is_observed(self, *args, **kwargs):
chain_id = self._param_values[ConstraintParam.CHAIN]
collection = self._param_values[ConstraintParam.ADDRESS]
nft_id = self._param_values[ConstraintParam.ID]

25 changes: 25 additions & 0 deletions core/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 4.0.4 on 2023-08-27 22:26

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='TokenPrice',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('usd_price', models.CharField(max_length=255)),
('datetime', models.DateTimeField(auto_now_add=True)),
('last_updated', models.DateTimeField(auto_now=True, null=True)),
('price_url', models.URLField(blank=True, max_length=255)),
('symbol', models.CharField(db_index=True, max_length=255, unique=True)),
],
),
]
Empty file added core/migrations/__init__.py
Empty file.
18 changes: 13 additions & 5 deletions core/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.db import models
from .constraints import *
from django.utils.translation import gettext_lazy as _
from .constraints import *


class UserConstraint(models.Model):
class Meta:
Expand All @@ -15,8 +16,7 @@ class Type(models.TextChoices):
BrightIDAuraVerification
]


name = models.CharField(max_length=255, unique=True,
name = models.CharField(max_length=255, unique=True,
choices=[(c.__name__, c.__name__) for c in constraints])
title = models.CharField(max_length=255)
type = models.CharField(
Expand All @@ -32,5 +32,13 @@ def __str__(self) -> str:

@classmethod
def create_name_field(cls, constraints):
return models.CharField(max_length=255, unique=True,
choices=[(c.__name__, c.__name__) for c in constraints])
return models.CharField(max_length=255, unique=True,
choices=[(c.__name__, c.__name__) for c in constraints])


class TokenPrice(models.Model):
usd_price = models.CharField(max_length=255, null=False)
datetime = models.DateTimeField(auto_now_add=True)
last_updated = models.DateTimeField(auto_now=True, null=True, blank=True)
price_url = models.URLField(max_length=255, blank=True, null=False)
symbol = models.CharField(max_length=255, db_index=True, unique=True, null=False, blank=False)
14 changes: 11 additions & 3 deletions core/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from rest_framework import serializers
from .constraints import *
from .models import UserConstraint

class UserConstraintBaseSerializer(serializers.Serializer):
Expand All @@ -10,6 +11,7 @@ class UserConstraintBaseSerializer(serializers.Serializer):
)
description = serializers.CharField()
response = serializers.CharField()
params = serializers.SerializerMethodField()

class Meta:
fields = [
Expand All @@ -18,13 +20,19 @@ class Meta:
"title",
"type",
"description",
"response"
"response",
"params"
]
read_only_fields = [
"pk",
"name",
"title",
"type",
"description",
"response"
]
"response",
"params"
]

def get_params(self, constraint: UserConstraint):
c_class: ConstraintVerification = eval(constraint.name)
return [p.value for p in c_class.param_keys()]
4 changes: 2 additions & 2 deletions core/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def test_meet_constraint(self, is_meet_verified_mock:PropertyMock):
is_meet_verified_mock.return_value = False
constraint = BrightIDMeetVerification(self.user_profile)
self.assertEqual(constraint.is_observed(), False)
self.assertEqual(constraint.response(), "BrightIDMeetVerification constraint is violated")
self.assertEqual(constraint.response, "BrightIDMeetVerification constraint is violated")

@patch('authentication.models.UserProfile.is_aura_verified', new_callable=PropertyMock)
def test_aura_constraint(self, is_aura_verified_mock:PropertyMock):
is_aura_verified_mock.return_value = False
constraint = BrightIDAuraVerification(self.user_profile)
self.assertEqual(constraint.is_observed(), False)
self.assertEqual(constraint.response(), "BrightIDAuraVerification constraint is violated")
self.assertEqual(constraint.response, "BrightIDAuraVerification constraint is violated")
15 changes: 14 additions & 1 deletion faucet/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,19 @@ class TransactionBatchAdmin(admin.ModelAdmin):
class LightningConfigAdmin(admin.ModelAdmin):
readonly_fields = ["claimed_amount", "current_round"]
list_display = ["pk", "period", "period_max_cap", "claimed_amount", "current_round"]
pass


class DonationReceiptAdmin(admin.ModelAdmin):
list_display = [
'tx_hash',
'user_profile',
'chain',
'value',
'total_price',
'datetime'
]
search_fields = ['tx_hash']
list_filter = ['chain', 'user_profile']


admin.site.register(WalletAccount, WalletAccountAdmin)
Expand All @@ -82,3 +94,4 @@ class LightningConfigAdmin(admin.ModelAdmin):
admin.site.register(GlobalSettings, GlobalSettingsAdmin)
admin.site.register(TransactionBatch, TransactionBatchAdmin)
admin.site.register(LightningConfig, LightningConfigAdmin)
admin.site.register(DonationReceipt, DonationReceiptAdmin)
27 changes: 16 additions & 11 deletions faucet/faucet_manager/fund_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,16 @@ def is_gas_price_too_high(self):
def account(self) -> LocalAccount:
return self.w3.eth.account.privateKeyToAccount(self.chain.wallet.main_key)

def get_checksum_address(self):
return Web3.toChecksumAddress(self.chain.fund_manager_address.lower())
@staticmethod
def to_checksum_address(address: str):
return Web3.toChecksumAddress(address.lower())

def get_fund_manager_checksum_address(self):
return self.to_checksum_address(self.chain.fund_manager_address)

@property
def contract(self):
return self.w3.eth.contract(address=self.get_checksum_address(), abi=self.abi)
return self.w3.eth.contract(address=self.get_fund_manager_checksum_address(), abi=self.abi)

def transfer(self, bright_user: BrightUser, amount: int):
tx = self.single_eth_transfer_signed_tx(amount, bright_user.address)
Expand Down Expand Up @@ -121,13 +125,14 @@ def prepare_tx_for_broadcast(self, tx_function):
return signed_tx

def is_tx_verified(self, tx_hash):
try:
receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
if receipt["status"] == 1:
return True
return False
except TimeExhausted:
raise
receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
if receipt["status"] == 1:
return True
return False

def get_tx(self, tx_hash):
tx = self.w3.eth.get_transaction(tx_hash)
return tx


class SolanaFundManager:
Expand Down Expand Up @@ -218,7 +223,7 @@ def multi_transfer(self, data):
instructions.withdraw(
{"amount": item['amount']},
{
"lock_account": self.lock_account_address,
"lock_account": self.lock_account_address,
"operator": self.operator,
"recipient": Pubkey.from_string(item["to"])
},
Expand Down
Loading

0 comments on commit 03946b2

Please sign in to comment.