-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OCT-1895: basic holonym integration #393
base: develop
Are you sure you want to change the base?
Changes from all commits
8a46387
e979378
028af08
7c08a71
31ecfff
01ca3df
da3622b
045a659
108d356
a33a0fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,14 @@ class GPStamps(BaseModel): | |
stamps = Column(db.String, nullable=False) | ||
|
||
|
||
class HolonymSBT(BaseModel): | ||
__tablename__ = "holonym_sbts" | ||
id = Column(db.Integer, primary_key=True) | ||
user_id = Column(db.Integer, db.ForeignKey("users.id"), nullable=False) | ||
has_sbt = Column(db.Boolean, nullable=False, default=False) | ||
sbt_details = Column(db.String, nullable=False, default="[]") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we set a default param as [] or just "" since it's a string and it'd make the future validations a bit easier? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This field is processed as json. Both [] and "" are not a valid JSON string. |
||
|
||
|
||
class PatronModeEvent(BaseModel): | ||
__tablename__ = "patron_events" | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import requests | ||
from typing import Tuple, List, Union | ||
from enum import StrEnum | ||
from eth_utils.address import to_checksum_address | ||
|
||
ACTION_ID = "123456789" # Default, holonym-wide ActionID. | ||
paulperegud marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# Use different ActionID to prevent tracking between protocols consuming Holonym. | ||
# https://docs.holonym.id/for-developers/custom-sybil-resistance#how-to-set-an-actionid | ||
|
||
|
||
class CredentialType(StrEnum): | ||
paulperegud marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
CredentialType specifies different methods used by Holonym. | ||
|
||
PHONE_NUMBER_VERIFICATION - phone number verification, code is sent also through e2e messengers | ||
GOV_ID_KYC_WITH_ZK - KYC with zk barrier between provider and address | ||
E_PASSPORT_ON_DEVICE_WITH_ZK - the most private, on-device only, currently android only | ||
""" | ||
|
||
PHONE_NUMBER_VERIFICATION = "phone" | ||
GOV_ID_KYC_WITH_ZK = "gov-id" | ||
E_PASSPORT_ON_DEVICE_WITH_ZK = "epassport" | ||
|
||
|
||
def check( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i'm not sure if it shouldn't be directly in the service since it's something more about the functional logic, not the API itself but just raising up the case, it's up to you There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All it does is iterate through credential type, enhancing API a bit. I wouldn't call that logic. Just presenting data in a bit more useful manner. |
||
address: str, cred: Union[CredentialType, None] = None | ||
) -> Tuple[bool, List[str]]: | ||
""" | ||
Check if address has a holonym's SBT. | ||
|
||
Specify credential type. If unspecified, function will query for | ||
all credential types. | ||
|
||
Returns a tuple. First element is True if address has at least one SBT. | ||
Second element contains a list credential types for which active SBT was found. | ||
""" | ||
address = to_checksum_address(address) | ||
if cred is None: | ||
paulperegud marked this conversation as resolved.
Show resolved
Hide resolved
|
||
creds = list(CredentialType) | ||
else: | ||
creds = [cred] | ||
|
||
results = {} | ||
for cred in creds: | ||
results[cred] = _call(address, cred) | ||
|
||
has_sbt = any(results.values()) | ||
sbt_type = [k for k, v in results.items() if v] | ||
return has_sbt, sbt_type | ||
|
||
|
||
def _call(address: str, cred: str) -> bool: | ||
dict = requests.get( | ||
f"https://api.holonym.io/sybil-resistance/{cred}/optimism?user={address}&action-id={ACTION_ID}" | ||
).json() | ||
return dict["result"] |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,5 @@ | ||||||
from datetime import datetime | ||||||
from decimal import Decimal | ||||||
from typing import Protocol, Optional, Tuple, runtime_checkable | ||||||
from typing import Protocol, Optional, runtime_checkable | ||||||
|
||||||
from app.context.manager import Context | ||||||
from app.infrastructure.database.uniqueness_quotient import ( | ||||||
|
@@ -9,13 +8,23 @@ | |||||
) | ||||||
from app.modules.uq.core import calculate_uq | ||||||
from app.pydantic import Model | ||||||
from app.modules.user.antisybil.service.holonym import HolonymAntisybilDTO | ||||||
from app.modules.user.antisybil.service.passport import GitcoinAntisybilDTO | ||||||
|
||||||
|
||||||
@runtime_checkable | ||||||
class Antisybil(Protocol): | ||||||
class Passport(Protocol): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately one of proposed names clashes with some other name. I'll leave both as they are. |
||||||
def get_antisybil_status( | ||||||
self, _: Context, user_address: str | ||||||
) -> Optional[Tuple[float, datetime]]: | ||||||
) -> Optional[GitcoinAntisybilDTO]: | ||||||
... | ||||||
|
||||||
|
||||||
@runtime_checkable | ||||||
class Holonym(Protocol): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately one of proposed names clashes with some other name. I'll leave both as they are. |
||||||
def get_sbt_status( | ||||||
self, _: Context, user_address: str | ||||||
) -> Optional[HolonymAntisybilDTO]: | ||||||
... | ||||||
|
||||||
|
||||||
|
@@ -26,7 +35,8 @@ def get_budget(self, context: Context, user_address: str) -> int: | |||||
|
||||||
|
||||||
class PreliminaryUQ(Model): | ||||||
antisybil: Antisybil | ||||||
passport: Passport | ||||||
holonym: Holonym | ||||||
budgets: UserBudgets | ||||||
uq_threshold: int | ||||||
|
||||||
|
@@ -56,7 +66,7 @@ def calculate(self, context: Context, user_address: str) -> Decimal: | |||||
return calculate_uq(gp_score, self.uq_threshold) | ||||||
|
||||||
def _get_gp_score(self, context: Context, address: str) -> float: | ||||||
antisybil_status = self.antisybil.get_antisybil_status(context, address) | ||||||
if antisybil_status is None: | ||||||
passport_status = self.passport.get_antisybil_status(context, address) | ||||||
if passport_status is None: | ||||||
return 0.0 | ||||||
return antisybil_status[0] | ||||||
return passport_status[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i also started thinking if we shouldn't match HolonymSBT with a specific epoch that it corresponds to? it'll help to distinguish between these tokens that are valid and expired ones (since we want to verify it for every epoch specifically, right?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Holonym's API doesn't return information about expiration. We should refresh SBT status when user allocates.