diff --git a/brightIDfaucet/celery.py b/brightIDfaucet/celery.py index c5f9c812..19ce2d2e 100644 --- a/brightIDfaucet/celery.py +++ b/brightIDfaucet/celery.py @@ -45,6 +45,10 @@ 'update-donation-receipt-status': { "task": "faucet.tasks.update_donation_receipt_pending_status", "schedule": 60, + }, + "draw-prizetap-raffles": { + "task": "prizetap.tasks.draw_the_expired_raffles", + "schedule": 60 } } diff --git a/core/helpers.py b/core/helpers.py new file mode 100644 index 00000000..492ce996 --- /dev/null +++ b/core/helpers.py @@ -0,0 +1,20 @@ +import time +from contextlib import contextmanager +from django.core.cache import cache + +@contextmanager +def memcache_lock(lock_id, oid, lock_expire=60): + timeout_at = time.monotonic() + lock_expire + # cache.add fails if the key already exists + status = cache.add(lock_id, oid, lock_expire) + try: + yield status + finally: + # memcache delete is very slow, but we have to use it to take + # advantage of using add() for atomic locking + if time.monotonic() < timeout_at and status: + # don't release the lock if we exceeded the timeout + # to lessen the chance of releasing an expired lock + # owned by someone else + # also don't release the lock if we didn't acquire it + cache.delete(lock_id) \ No newline at end of file diff --git a/core/utils.py b/core/utils.py index f91c44d3..b61ed481 100644 --- a/core/utils.py +++ b/core/utils.py @@ -2,6 +2,7 @@ import pytz from time import time from web3 import Web3 +from web3.middleware import geth_poa_middleware from web3.contract.contract import Contract, ContractFunction from web3.types import Type, TxParams from django.utils import timezone @@ -50,11 +51,12 @@ def get_first_day_of_the_month(): class Web3Utils: - def __init__(self, rpc_url) -> None: + def __init__(self, rpc_url, poa = False) -> None: self._rpc_url = rpc_url self._w3 = None self._account = None self._contract = None + self._poa = poa @property def w3(self) -> Web3: @@ -62,11 +64,17 @@ def w3(self) -> Web3: return self._w3 self._w3 = Web3(Web3.HTTPProvider(self._rpc_url)) + if self.poa: + self._w3.middleware_onion.inject(geth_poa_middleware, layer=0) if self._w3.is_connected(): return self._w3 raise Exception(f"RPC provider is not connected ({self._rpc_url})") + + @property + def poa(self): + return self._poa @property def account(self): @@ -83,7 +91,7 @@ def set_contract(self, address, abi): self._contract = self.w3.eth.contract(address=address, abi=abi) def contract_txn(self, func: Type[ContractFunction]): - signed_tx = self.build_contract_call(func) + signed_tx = self.build_contract_txn(func) txn_hash = self.send_raw_tx(signed_tx) return txn_hash.hex() @@ -92,8 +100,10 @@ def contract_call(self, func: Type[ContractFunction], from_address=None): return func.call({"from": from_address}) return func.call() - def build_contract_call(self, func: Type[ContractFunction]): - tx_data = func.build_transaction({"from": self.account.address}) + def build_contract_txn(self, func: Type[ContractFunction]): + nonce = self.w3.eth.get_transaction_count(self.account.address) + tx_data = func.build_transaction( + {"from": self.account.address, "nonce": nonce}) return self.sign_tx(tx_data) def sign_tx(self, tx_data: TxParams): diff --git a/prizetap/constants.py b/prizetap/constants.py index 48489d48..00a95553 100644 --- a/prizetap/constants.py +++ b/prizetap/constants.py @@ -1,557 +1,2204 @@ PRIZETAP_ERC20_ABI = [ - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "error" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - } + { + "inputs": [ + { + "internalType": "address", + "name": "_chainlinkVRFCoordinator", + "type": "address" + }, + { + "internalType": "uint64", + "name": "_chainlinkVRFSubscriptionId", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "_chainlinkKeyHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_muonAppId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "parity", + "type": "uint8" + } + ], + "internalType": "struct IMuonClient.PublicKey", + "name": "_muonPublicKey", + "type": "tuple" + }, + { + "internalType": "address", + "name": "_muon", + "type": "address" + }, + { + "internalType": "address", + "name": "_muonValidGateway", + "type": "address" + }, + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "have", + "type": "address" + }, + { + "internalType": "address", + "name": "want", + "type": "address" + } + ], + "name": "OnlyCoordinatorCanFulfill", + "type": "error" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": False, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": False, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "Participate", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "winner", + "type": "address" + } + ], + "name": "PrizeClaimed", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "PrizeRefunded", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": False, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "RaffleCreated", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "organizer", + "type": "address" + } + ], + "name": "RaffleHeld", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "rejector", + "type": "address" + } + ], + "name": "RaffleRejected", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": True, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": True, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "indexed": False, + "internalType": "uint256[]", + "name": "randomWords", + "type": "uint256[]" + } + ], + "name": "VRFRequestFulfilled", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + } + ], + "name": "VRFRequestSent", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "winner", + "type": "address" + } + ], + "name": "WinnerSpecified", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPERATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "claimPrize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "currency", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxParticipants", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "requirementsHash", + "type": "bytes32" + } + ], + "name": "createRaffle", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "getParticipants", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "heldRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "isParticipated", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRaffleId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muon", + "outputs": [ + { + "internalType": "contract IMuonClient", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muonAppId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muonPublicKey", + "outputs": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "parity", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muonValidGateway", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "reqId", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "signature", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "nonce", + "type": "address" + } + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "signature", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "gatewaySignature", + "type": "bytes" + } + ], + "name": "participateInRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "raffles", + "outputs": [ + { + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "internalType": "uint256", + "name": "prizeAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "currency", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxParticipants", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "participantsCount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "winner", + "type": "address" + }, + { + "internalType": "bool", + "name": "exists", + "type": "bool" + }, + { + "internalType": "enum AbstractPrizetapRaffle.Status", + "name": "status", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "requirementsHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "randomWords", + "type": "uint256[]" + } + ], + "name": "rawFulfillRandomWords", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "refundPrize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "rejectRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "gaslimit", + "type": "uint32" + } + ], + "name": "setCallbackGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_muonAddress", + "type": "address" + } + ], + "name": "setMuonAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_muonAppId", + "type": "uint256" + } + ], + "name": "setMuonAppId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gatewayAddress", + "type": "address" + } + ], + "name": "setMuonGateway", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "parity", + "type": "uint8" + } + ], + "internalType": "struct IMuonClient.PublicKey", + "name": "_muonPublicKey", + "type": "tuple" + } + ], + "name": "setMuonPublicKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "periodSeconds", + "type": "uint256" + } + ], + "name": "setValidationPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "keyHash", + "type": "bytes32" + } + ], + "name": "setVrfKeyHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "count", + "type": "uint16" + } + ], + "name": "setVrfRequestConfirmations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + } + ], + "name": "setVrfSubscriptionId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "validationPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "reqId", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "signature", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "nonce", + "type": "address" + } + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "sign", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "gatewaySignature", + "type": "bytes" + } + ], + "name": "verifyTSSAndGateway", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "vrfRequests", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } ] PRIZETAP_ERC721_ABI = [ - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "error" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "", - "type": "event" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "", - "stateMutability": "view", - "type": "function" - }, - { - "inputs": "[object Object],[object Object],[object Object],[object Object],[object Object]", - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": "[object Object]", - "stateMutability": "view", - "type": "function" - } + { + "inputs": [ + { + "internalType": "address", + "name": "_chainlinkVRFCoordinator", + "type": "address" + }, + { + "internalType": "uint64", + "name": "_chainlinkVRFSubscriptionId", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "_chainlinkKeyHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_muonAppId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "parity", + "type": "uint8" + } + ], + "internalType": "struct IMuonClient.PublicKey", + "name": "_muonPublicKey", + "type": "tuple" + }, + { + "internalType": "address", + "name": "_muon", + "type": "address" + }, + { + "internalType": "address", + "name": "_muonValidGateway", + "type": "address" + }, + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "have", + "type": "address" + }, + { + "internalType": "address", + "name": "want", + "type": "address" + } + ], + "name": "OnlyCoordinatorCanFulfill", + "type": "error" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": False, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": False, + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "name": "Participate", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "winner", + "type": "address" + } + ], + "name": "PrizeClaimed", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "PrizeRefunded", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "indexed": False, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "RaffleCreated", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "organizer", + "type": "address" + } + ], + "name": "RaffleHeld", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "rejector", + "type": "address" + } + ], + "name": "RaffleRejected", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": True, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": True, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": True, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "indexed": False, + "internalType": "uint256[]", + "name": "randomWords", + "type": "uint256[]" + } + ], + "name": "VRFRequestFulfilled", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": False, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + } + ], + "name": "VRFRequestSent", + "type": "event" + }, + { + "anonymous": False, + "inputs": [ + { + "indexed": True, + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "indexed": True, + "internalType": "address", + "name": "winner", + "type": "address" + } + ], + "name": "WinnerSpecified", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "OPERATOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_ERC721_RECEIVED", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "claimPrize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "collection", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxParticipants", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "requirementsHash", + "type": "bytes32" + } + ], + "name": "createRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "getParticipants", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "heldRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "isParticipated", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastRaffleId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muon", + "outputs": [ + { + "internalType": "contract IMuonClient", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muonAppId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muonPublicKey", + "outputs": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "parity", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "muonValidGateway", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "reqId", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "signature", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "nonce", + "type": "address" + } + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "signature", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "gatewaySignature", + "type": "bytes" + } + ], + "name": "participateInRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "raffles", + "outputs": [ + { + "internalType": "address", + "name": "initiator", + "type": "address" + }, + { + "internalType": "address", + "name": "collection", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxParticipants", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maxMultiplier", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "startTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "participantsCount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "winner", + "type": "address" + }, + { + "internalType": "bool", + "name": "exists", + "type": "bool" + }, + { + "internalType": "enum AbstractPrizetapRaffle.Status", + "name": "status", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "requirementsHash", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "internalType": "uint256[]", + "name": "randomWords", + "type": "uint256[]" + } + ], + "name": "rawFulfillRandomWords", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "refundPrize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + } + ], + "name": "rejectRaffle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "gaslimit", + "type": "uint32" + } + ], + "name": "setCallbackGasLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_muonAddress", + "type": "address" + } + ], + "name": "setMuonAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_muonAppId", + "type": "uint256" + } + ], + "name": "setMuonAppId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_gatewayAddress", + "type": "address" + } + ], + "name": "setMuonGateway", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "parity", + "type": "uint8" + } + ], + "internalType": "struct IMuonClient.PublicKey", + "name": "_muonPublicKey", + "type": "tuple" + } + ], + "name": "setMuonPublicKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "periodSeconds", + "type": "uint256" + } + ], + "name": "setValidationPeriod", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "keyHash", + "type": "bytes32" + } + ], + "name": "setVrfKeyHash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "count", + "type": "uint16" + } + ], + "name": "setVrfRequestConfirmations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "id", + "type": "uint64" + } + ], + "name": "setVrfSubscriptionId", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "validationPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "raffleId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "reqId", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "signature", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "nonce", + "type": "address" + } + ], + "internalType": "struct IMuonClient.SchnorrSign", + "name": "sign", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "gatewaySignature", + "type": "bytes" + } + ], + "name": "verifyTSSAndGateway", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "vrfRequests", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } ] UNITAP_PASS_ABI = [ diff --git a/prizetap/migrations/0026_alter_raffle_nft_id.py b/prizetap/migrations/0026_alter_raffle_nft_id.py new file mode 100644 index 00000000..33c3c7b4 --- /dev/null +++ b/prizetap/migrations/0026_alter_raffle_nft_id.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.4 on 2023-09-17 09:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('prizetap', '0025_alter_raffle_nft_id'), + ] + + operations = [ + migrations.AlterField( + model_name='raffle', + name='nft_id', + field=models.CharField(blank=True, max_length=256, null=True), + ), + ] diff --git a/prizetap/models.py b/prizetap/models.py index 30460993..c7742dbb 100644 --- a/prizetap/models.py +++ b/prizetap/models.py @@ -36,7 +36,7 @@ class Meta: decimals = models.IntegerField(default=18) is_prize_nft = models.BooleanField(default=False) - nft_id = BigNumField(null=True, blank=True) + nft_id = models.CharField(max_length=256, null=True, blank=True) token_uri = models.TextField(null=True, blank=True) chain = models.ForeignKey(Chain, on_delete=models.CASCADE, related_name="raffles") diff --git a/prizetap/serializers.py b/prizetap/serializers.py index d53e58a7..887cafb9 100644 --- a/prizetap/serializers.py +++ b/prizetap/serializers.py @@ -3,12 +3,17 @@ from authentication.serializers import SimpleProfilerSerializer from faucet.serializers import SmallChainSerializer from .models import * +from .constants import * class ConstraintSerializer(UserConstraintBaseSerializer, serializers.ModelSerializer): class Meta(UserConstraintBaseSerializer.Meta): ref_name = "RaffleConstraint" model = Constraint + def get_params(self, constraint: UserConstraint): + c_class: ConstraintVerification = eval(constraint.name) + return [p.value for p in c_class.param_keys()] + class SimpleRaffleSerializer(serializers.ModelSerializer): class Meta: model = Raffle diff --git a/prizetap/tasks.py b/prizetap/tasks.py new file mode 100644 index 00000000..475875ed --- /dev/null +++ b/prizetap/tasks.py @@ -0,0 +1,30 @@ +from celery import shared_task +from django.utils import timezone +from core.helpers import memcache_lock +from .models import Raffle +from .utils import PrizetapContractClient + + +@shared_task(bind=True) +def draw_the_expired_raffles(self): + + id = f"{self.name}-LOCK" + + with memcache_lock(id, self.app.oid) as acquired: + if not acquired: + print(f"Could not acquire process lock at {self.name}") + return + + raffles_queryset = ( + Raffle.objects + .filter(deadline__lt=timezone.now()) + .filter(is_active=True) + ) + if raffles_queryset.count() > 0: + for raffle in raffles_queryset: + if raffle.number_of_onchain_entries > 0 and not raffle.winner_entry: + print(f"Drawing the raffle {raffle.name}") + raffle_client = PrizetapContractClient(raffle) + if raffle_client.draw_raffle(): + raffle.is_active = False + raffle.save() diff --git a/prizetap/utils.py b/prizetap/utils.py index 9503d540..0c3227fb 100644 --- a/prizetap/utils.py +++ b/prizetap/utils.py @@ -16,13 +16,13 @@ def __init__(self, raffle) -> None: self.set_account(self.raffle.chain.wallet.private_key) def draw_raffle(self): - func = self.contract.functions.heldRaffle(self.raffle.raffle_id) + func = self.contract.functions.heldRaffle(self.raffle.raffleId) return self.contract_txn(func) class UnitapPassClient(Web3Utils): def __init__(self, chain: Chain) -> None: - super().__init__(chain.rpc_url_private) + super().__init__(chain.rpc_url_private, chain.poa) self.set_contract( "0x23826Fd930916718a98A21FF170088FBb4C30803", UNITAP_PASS_ABI)