Skip to content

Commit

Permalink
Merge pull request #257 from UnitapApp/feature/tokentap-contribution-hub
Browse files Browse the repository at this point in the history
Token contribution hub
  • Loading branch information
ShayanShiravani authored Jan 10, 2024
2 parents 92e4484 + 44a92d0 commit 0543673
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.0.4 on 2024-01-09 19:09

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('tokenTap', '0027_merge_20240105_1916'),
]

operations = [
migrations.RenameField(
model_name='tokendistribution',
old_name='permissions',
new_name='constraints',
),
]
51 changes: 51 additions & 0 deletions tokenTap/migrations/0029_tokendistribution_email_url_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Generated by Django 4.0.4 on 2024-01-10 13:59

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('tokenTap', '0028_rename_permissions_tokendistribution_constraints'),
]

operations = [
migrations.AddField(
model_name='tokendistribution',
name='email_url',
field=models.EmailField(default='', max_length=255),
preserve_default=False,
),
migrations.AddField(
model_name='tokendistribution',
name='necessary_information',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='tokendistribution',
name='rejection_reason',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='tokendistribution',
name='start_at',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name='tokendistribution',
name='status',
field=models.CharField(choices=[('PENDING', 'Pending'), ('REJECTED', 'Rejected'), ('VERIFIED', 'Verified')], default='PENDING', max_length=10),
),
migrations.AddField(
model_name='tokendistribution',
name='telegram_url',
field=models.URLField(blank=True, max_length=255, null=True),
),
migrations.AlterField(
model_name='tokendistribution',
name='deadline',
field=models.DateTimeField(default=django.utils.timezone.now),
preserve_default=False,
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 4.0.4 on 2024-01-10 14:46

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('authentication', '0028_remove_wallet_unique_wallet_address_and_more'),
('tokenTap', '0029_tokendistribution_email_url_and_more'),
]

operations = [
migrations.AddField(
model_name='tokendistribution',
name='distributor_address',
field=models.CharField(default='', max_length=255),
preserve_default=False,
),
migrations.AddField(
model_name='tokendistribution',
name='distributor_profile',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.DO_NOTHING, related_name='token_distributions', to='authentication.userprofile'),
preserve_default=False,
),
]
23 changes: 21 additions & 2 deletions tokenTap/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.core.cache import cache
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from authentication.models import UserProfile
from core.models import Chain, UserConstraint
Expand All @@ -24,12 +25,23 @@ class Constraint(UserConstraint):


class TokenDistribution(models.Model):
class Status(models.TextChoices):
PENDING = "PENDING", _("Pending")
REJECTED = "REJECTED", _("Rejected")
VERIFIED = "VERIFIED", _("Verified")

name = models.CharField(max_length=100)

distributor = models.CharField(max_length=100, null=True, blank=True)
distributor_profile = models.ForeignKey(
UserProfile, on_delete=models.DO_NOTHING, related_name="token_distributions"
)
distributor_address = models.CharField(max_length=255)
distributor_url = models.URLField(max_length=255, null=True, blank=True)
discord_url = models.URLField(max_length=255, null=True, blank=True)
twitter_url = models.URLField(max_length=255, null=True, blank=True)
email_url = models.EmailField(max_length=255)
telegram_url = models.URLField(max_length=255, null=True, blank=True)
image_url = models.URLField(max_length=255, null=True, blank=True)
token_image_url = models.URLField(max_length=255, null=True, blank=True)

Expand All @@ -41,14 +53,21 @@ class TokenDistribution(models.Model):
)
contract = models.CharField(max_length=255, null=True, blank=True)

permissions = models.ManyToManyField(Constraint, blank=True)
constraints = models.ManyToManyField(Constraint, blank=True)

created_at = models.DateTimeField(auto_now_add=True)
deadline = models.DateTimeField(null=True, blank=True)
start_at = models.DateTimeField(default=timezone.now)
deadline = models.DateTimeField()

max_number_of_claims = models.IntegerField(null=True, blank=True)

notes = models.TextField(null=True, blank=True)
necessary_information = models.TextField(null=True, blank=True)

status = models.CharField(
max_length=10, choices=Status.choices, default=Status.PENDING
)
rejection_reason = models.TextField(null=True, blank=True)

is_active = models.BooleanField(default=True)

Expand Down
71 changes: 67 additions & 4 deletions tokenTap/serializers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import base64
import json

from rest_framework import serializers

from core.constraints import ConstraintVerification, get_constraint
Expand All @@ -9,6 +12,8 @@
UserConstraint,
)

from .constants import CONTRACT_ADDRESSES


class ConstraintSerializer(UserConstraintBaseSerializer, serializers.ModelSerializer):
class Meta(UserConstraintBaseSerializer.Meta):
Expand All @@ -32,7 +37,7 @@ def update(self, instance, validated_data):

class TokenDistributionSerializer(serializers.ModelSerializer):
chain = ChainSerializer()
permissions = ConstraintSerializer(many=True)
constraints = ConstraintSerializer(many=True)

class Meta:
model = TokenDistribution
Expand All @@ -43,20 +48,27 @@ class Meta:
"distributor_url",
"discord_url",
"twitter_url",
"email_url",
"telegram_url",
"image_url",
"token_image_url",
"token",
"token_address",
"amount",
"chain",
"contract",
"permissions",
"constraints",
"created_at",
"start_at",
"deadline",
"max_number_of_claims",
"number_of_claims",
"total_claims_since_last_round",
"notes",
"necessary_information",
"status",
"rejection_reason",
"is_active",
"is_expired",
"is_maxed_out",
"is_claimable",
Expand All @@ -65,7 +77,7 @@ class Meta:

class SmallTokenDistributionSerializer(serializers.ModelSerializer):
chain = ChainSerializer()
permissions = ConstraintSerializer(many=True)
constraints = ConstraintSerializer(many=True)

class Meta:
model = TokenDistribution
Expand All @@ -82,7 +94,7 @@ class Meta:
"amount",
"chain",
"contract",
"permissions",
"constraints",
"created_at",
"deadline",
"max_number_of_claims",
Expand Down Expand Up @@ -121,3 +133,54 @@ def get_payload(self, obj):
class TokenDistributionClaimResponseSerializer(serializers.Serializer):
detail = serializers.CharField()
signature = TokenDistributionClaimSerializer()


class CreateTokenDistributionSerializer(serializers.ModelSerializer):
class Meta:
model = TokenDistribution
fields = "__all__"

read_only_fields = [
"pk",
"distributor_profile",
"created_at",
"status",
"rejection_reason",
"is_active",
]

def validate(self, data):
constraints = data["constraints"]
constraint_params = json.loads(base64.b64decode(data["constraint_params"]))
data["constraint_params"] = base64.b64decode(data["constraint_params"]).decode(
"utf-8"
)
reversed_constraints = []
if "reversed_constraints" in data:
reversed_constraints = str(data["reversed_constraints"]).split(",")
if len(constraints) != 0:
for c in constraints:
constraint_class: ConstraintVerification = get_constraint(c.name)
try:
if len(constraint_class.param_keys()) != 0:
constraint_class.is_valid_param_keys(constraint_params[c.name])
except KeyError as e:
raise serializers.ValidationError(
{"constraint_params": [{f"{c.name}": str(e)}]}
)
valid_constraints = [str(c.pk) for c in constraints]
if len(reversed_constraints) > 0:
for c in reversed_constraints:
if c not in valid_constraints:
raise serializers.ValidationError(
{"reversed_constraints": [{f"{c}": "Invalid constraint pk"}]}
)
valid_chains = list(CONTRACT_ADDRESSES.keys())
chain_id = data["chain"].chain_id
if chain_id not in valid_chains:
raise serializers.ValidationError({"chain": "Invalid value"})
valid_contracts = list(CONTRACT_ADDRESSES[chain_id].values())
if data["contract"] not in valid_contracts:
raise serializers.ValidationError({"contract": "Invalid value"})
data["distributor_profile"] = self.context["user_profile"]
return data
Loading

0 comments on commit 0543673

Please sign in to comment.