From 2b1b254338934f15aefbb7ba41b926ebd379cd8d Mon Sep 17 00:00:00 2001 From: ciaranightingale Date: Wed, 31 May 2023 23:03:16 +0100 Subject: [PATCH 1/3] wip --- thirdweb/contracts/maps.py | 4 ++ thirdweb/contracts/token_drop.py | 80 ++++++++++++++++++++++ thirdweb/core/classes/contract_deployer.py | 8 +++ thirdweb/types/contract.py | 8 ++- thirdweb/types/settings/metadata.py | 13 ++++ 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 thirdweb/contracts/token_drop.py diff --git a/thirdweb/contracts/maps.py b/thirdweb/contracts/maps.py index a1aec67..1c82452 100644 --- a/thirdweb/contracts/maps.py +++ b/thirdweb/contracts/maps.py @@ -11,6 +11,7 @@ Marketplace, NFTDrop, EditionDrop, + TokenDrop, Multiwrap, ) @@ -22,6 +23,7 @@ Marketplace.contract_type: Marketplace, # type: ignore NFTDrop.contract_type: NFTDrop, # type: ignore EditionDrop.contract_type: EditionDrop, # type: ignore + TokenDrop.contract_type: TokenDrop, # type: ignore Multiwrap.contract_type: Multiwrap, # type: ignore } @@ -32,6 +34,7 @@ Marketplace.contract_type: "Marketplace", NFTDrop.contract_type: "DropERC721", EditionDrop.contract_type: "DropERC1155", + TokenDrop.contract_type: "DropERC20", Multiwrap.contract_type: "Multiwrap", } @@ -42,5 +45,6 @@ "Marketplace": Marketplace.contract_type, "DropERC721": NFTDrop.contract_type, "DropERC1155": EditionDrop.contract_type, + "DropERC20": TokenDrop.contract_type, "Multiwrap": Multiwrap.contract_type, } diff --git a/thirdweb/contracts/token_drop.py b/thirdweb/contracts/token_drop.py new file mode 100644 index 0000000..36ae658 --- /dev/null +++ b/thirdweb/contracts/token_drop.py @@ -0,0 +1,80 @@ +from typing import Any, Final, List, Optional +from thirdweb.abi import DropERC20 +from thirdweb.abi.drop_erc20 import IDropAllowlistProof +from thirdweb.constants.role import Role +from thirdweb.core.classes.contract_events import ContractEvents +from thirdweb.core.classes.contract_metadata import ContractMetadata +from thirdweb.core.classes.contract_platform_fee import ContractPlatformFee +from thirdweb.core.classes.contract_roles import ContractRoles +from thirdweb.core.classes.contract_sales import ContractPrimarySale +from thirdweb.core.classes.contract_wrapper import ContractWrapper +from thirdweb.core.classes.drop_claim_conditions import DropClaimConditions +from thirdweb.core.classes.erc_20_standard import ERC20Standard +from thirdweb.core.classes.ipfs_storage import IpfsStorage +from thirdweb.types.contract import ContractType +from thirdweb.types.currency import CurrencyValue, Price, TokenAmount +from thirdweb.types.sdk import SDKOptions +from thirdweb.types.settings.metadata import TokenDropContractMetadata +from eth_account.account import LocalAccount +from web3 import Web3 + +from thirdweb.types.tx import TxResultWithId + + +class TokenDrop(ERC20Standard[DropERC20]): + """ + Setup Tokens that are minted as users claim them. + + ```python + from thirdweb import ThirdwebSDK + + # You can customize this to a supported network or your own RPC URL + network = "mumbai" + + # Now we can create a new instance of the SDK + sdk = ThirdwebSDK(network) + + # If you want to send transactions, you can instantiate the SDK with a private key instead: + # sdk = ThirdwebSDK.from_private_key(PRIVATE_KEY, network) + + contract = sdk.get_token_drop("{{contract_address}}") + ``` + """ + + _abi_type = DropERC20 + + contract_type: Final[ContractType] = ContractType.TOKEN_DROP + contract_roles: Final[List[Role]] = [Role.ADMIN, Role.MINTER, Role.TRANSFER] + + metadata: ContractMetadata[DropERC20, TokenDropContractMetadata] + roles: ContractRoles + primary_sale: ContractPrimarySale[DropERC20] + platform_fee: ContractPlatformFee[DropERC20] + claim_conditions: DropClaimConditions + events: ContractEvents[DropERC20] + + def __init__( + self, + provider: Web3, + address: str, + storage: IpfsStorage, + signer: Optional[LocalAccount] = None, + options: SDKOptions = SDKOptions(), + ): + abi = DropERC20(provider, address) + contract_wrapper = ContractWrapper(abi, provider, signer, options) + super().__init__(contract_wrapper, storage) + + self.metadata = ContractMetadata( + contract_wrapper, storage, TokenDropContractMetadata + ) + self.roles = ContractRoles(contract_wrapper, self.contract_roles) + self.primary_sale = ContractPrimarySale(contract_wrapper) + self.platform_fee = ContractPlatformFee(contract_wrapper) + self.claim_conditions = DropClaimConditions( + self._contract_wrapper, self.metadata, self._storage + ) + self.events = ContractEvents(contract_wrapper) + + def call(self, fn: str, *args) -> Any: + return self._contract_wrapper.call(fn, *args) \ No newline at end of file diff --git a/thirdweb/core/classes/contract_deployer.py b/thirdweb/core/classes/contract_deployer.py index c5ad0f4..24f584d 100644 --- a/thirdweb/core/classes/contract_deployer.py +++ b/thirdweb/core/classes/contract_deployer.py @@ -18,6 +18,7 @@ MarketplaceContractMetadata, NFTCollectionContractMetadata, TokenContractMetadata, + TokenDropContractMetadata, ) @@ -78,6 +79,13 @@ def deploy_edition_drop(self, metadata: EditionDropContractMetadata) -> str: """ return self._deploy_contract(ContractType.EDITION_DROP, metadata.to_json()) + + def deploy_token_drop(self, metadata: TokenDropContractMetadata) -> str: + """ + Deploy a Token Drop contract + """ + + return self._deploy_contract(ContractType.TOKEN_DROP, metadata.to_json()) def deploy_multiwrap(self, metadata: MultiwrapContractMetadata) -> str: """ diff --git a/thirdweb/types/contract.py b/thirdweb/types/contract.py index 24dca54..e8a2e24 100644 --- a/thirdweb/types/contract.py +++ b/thirdweb/types/contract.py @@ -12,6 +12,7 @@ IERC1155, DropERC721, DropERC1155, + DropERC20, Multiwrap, ) from thirdweb.abi.i_mintable_erc20 import IMintableERC20 @@ -31,6 +32,7 @@ TWFactory, DropERC721, DropERC1155, + DropERC20, Multiwrap, IMintableERC20 ], @@ -41,13 +43,13 @@ TPrimarySaleABI = TypeVar( "TPrimarySaleABI", - bound=Union[TokenERC721, TokenERC1155, TokenERC20, DropERC721, DropERC1155], + bound=Union[TokenERC721, TokenERC1155, TokenERC20, DropERC721, DropERC1155, DropERC20], ) TPlatformFeeABI = TypeVar( "TPlatformFeeABI", bound=Union[ - TokenERC721, TokenERC1155, TokenERC20, Marketplace, DropERC721, DropERC1155 + TokenERC721, TokenERC1155, TokenERC20, Marketplace, DropERC721, DropERC1155, DropERC20 ], ) @@ -65,6 +67,7 @@ Marketplace, DropERC721, DropERC1155, + DropERC20, Multiwrap, ], ) @@ -75,6 +78,7 @@ class ContractType(Enum): NFT_COLLECTION = "nft-collection" EDITION = "edition" TOKEN = "token" + TOKEN_DROP = "token-drop" MARKETPLACE = "marketplace" NFT_DROP = "nft-drop" EDITION_DROP = "edition-drop" diff --git a/thirdweb/types/settings/metadata.py b/thirdweb/types/settings/metadata.py index d4ee1e9..28731b1 100644 --- a/thirdweb/types/settings/metadata.py +++ b/thirdweb/types/settings/metadata.py @@ -95,6 +95,19 @@ class TokenContractMetadata( @staticmethod def from_json(json: Dict[str, Any]) -> "TokenContractMetadata": return from_dict(TokenContractMetadata, json) + +@dataclass +class TokenDropContractMetadata( + ContractMetadataSchema, + ContractSymbolSchema, + ContractPrimarySaleSchema, + ContractTrustedForwarderSchema, + ContractPlatformFeeSchema, + MerkleSchema, +): + @staticmethod + def from_json(json: Dict[str, Any]) -> "TokenDropContractMetadata": + return from_dict(TokenDropContractMetadata, json) @dataclass From 4cfbcf8c886609aa2df83ca02a3b4af561180b50 Mon Sep 17 00:00:00 2001 From: ciaranightingale Date: Wed, 31 May 2023 23:09:15 +0100 Subject: [PATCH 2/3] initial test file --- tests/test_token_drop.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/test_token_drop.py diff --git a/tests/test_token_drop.py b/tests/test_token_drop.py new file mode 100644 index 0000000..accafea --- /dev/null +++ b/tests/test_token_drop.py @@ -0,0 +1,24 @@ +from tkinter.tix import IMAGE +from eth_account.account import LocalAccount +from thirdweb.constants.currency import ZERO_ADDRESS +from thirdweb.core.sdk import ThirdwebSDK +from thirdweb.contracts import TokenDrop +from brownie import accounts +import pytest + +from thirdweb.types.settings.metadata import TokenContractMetadata + + +@pytest.mark.usefixtures("sdk", "primary_account") +@pytest.fixture(scope="function") +def token_drop(sdk: ThirdwebSDK, primary_account) -> TokenDrop: + sdk.update_signer(primary_account) + return sdk.get_token( + sdk.deployer.deploy_token_drop( + TokenContractMetadata( + name="SDK Token", + symbol="SDK", + primary_sale_recipient=ZERO_ADDRESS, + ) + ) + ) \ No newline at end of file From a88774191c83961ef4a2aa900872065d7a3ef76f Mon Sep 17 00:00:00 2001 From: ciaranightingale Date: Wed, 31 May 2023 23:11:00 +0100 Subject: [PATCH 3/3] add import --- thirdweb/contracts/__init__.py | 1 + thirdweb/contracts/token_drop.py | 6 ------ 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/thirdweb/contracts/__init__.py b/thirdweb/contracts/__init__.py index f32ff12..5a66e4a 100644 --- a/thirdweb/contracts/__init__.py +++ b/thirdweb/contracts/__init__.py @@ -4,5 +4,6 @@ from .marketplace import Marketplace from .nft_drop import NFTDrop from .edition_drop import EditionDrop +from .token_drop import TokenDrop from .multiwrap import Multiwrap from .maps import * diff --git a/thirdweb/contracts/token_drop.py b/thirdweb/contracts/token_drop.py index 36ae658..36e7923 100644 --- a/thirdweb/contracts/token_drop.py +++ b/thirdweb/contracts/token_drop.py @@ -1,6 +1,5 @@ from typing import Any, Final, List, Optional from thirdweb.abi import DropERC20 -from thirdweb.abi.drop_erc20 import IDropAllowlistProof from thirdweb.constants.role import Role from thirdweb.core.classes.contract_events import ContractEvents from thirdweb.core.classes.contract_metadata import ContractMetadata @@ -12,15 +11,10 @@ from thirdweb.core.classes.erc_20_standard import ERC20Standard from thirdweb.core.classes.ipfs_storage import IpfsStorage from thirdweb.types.contract import ContractType -from thirdweb.types.currency import CurrencyValue, Price, TokenAmount from thirdweb.types.sdk import SDKOptions from thirdweb.types.settings.metadata import TokenDropContractMetadata from eth_account.account import LocalAccount from web3 import Web3 - -from thirdweb.types.tx import TxResultWithId - - class TokenDrop(ERC20Standard[DropERC20]): """ Setup Tokens that are minted as users claim them.