From 9723285fb3090928f4f7da38003915038ba59954 Mon Sep 17 00:00:00 2001 From: Ayush Pathak <62694274+ayshptk@users.noreply.github.com> Date: Tue, 26 Oct 2021 08:27:43 +0530 Subject: [PATCH 1/2] minor fixes --- .gitignore | 2 ++ nftlabs/modules/__init__.py | 4 +-- nftlabs/modules/collection.py | 12 +++---- nftlabs/modules/currency.py | 4 +-- nftlabs/modules/market.py | 59 +++++++++++++++----------------- nftlabs/modules/market_types.py | 32 ----------------- nftlabs/modules/nft.py | 40 +++++++++++----------- nftlabs/modules/pack.py | 4 +-- nftlabs/sdk.py | 16 ++++++++- nftlabs/types/listing.py | 12 +++---- nftlabs/types/market/__init__.py | 47 +++++++++++++++++++++---- nftlabs/types/role.py | 4 +-- 12 files changed, 125 insertions(+), 111 deletions(-) delete mode 100644 nftlabs/modules/market_types.py diff --git a/.gitignore b/.gitignore index aacdcaf6..a2c2f851 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ nftlabs/.DS_Store nftlabs/modules/docs/* nftlabs/modules/.DS_Store .DS_Store +x.sh +examples/test.py diff --git a/nftlabs/modules/__init__.py b/nftlabs/modules/__init__.py index cd8ec236..27ccb3a2 100644 --- a/nftlabs/modules/__init__.py +++ b/nftlabs/modules/__init__.py @@ -1,11 +1,9 @@ """All Modules""" -from .currency import * from .nft import * from .nft_types import * -from .currency_types import * from .currency import * from .market import * from .market_types import * from .pack import * -from .pack_types import * +from .collection import * diff --git a/nftlabs/modules/collection.py b/nftlabs/modules/collection.py index 891440d9..1828bba4 100644 --- a/nftlabs/modules/collection.py +++ b/nftlabs/modules/collection.py @@ -2,7 +2,7 @@ from zero_ex.contract_wrappers import TxParams -from .base import _BaseModule +from .base import BaseModule from ..types.metadata import Metadata from ..types.nft import NftMetadata from ..errors import NoSignerException @@ -13,7 +13,7 @@ from ..types.collection import CollectionMetadata, CreateCollectionArg, MintCollectionArg -class CollectionModule(_BaseModule): +class CollectionModule(BaseModule): address: str __abi_module: NFTCollection @@ -114,11 +114,11 @@ def mint_batch(self, args: List[MintCollectionArg]): self.mint_batch_to(self.get_signer_address(), args) def mint_batch_to(self, to_address, args: List[MintCollectionArg]): - ids = [a.id for a in args] + ids = [a.token_id for a in args] amounts = [a.amount for a in args] - self.execute_tx(self.__abi_module.mint_batch.build_transaction( - to_address, ids, amounts, self.get_transact_opts() - )) + tx = self.__abi_module.mint_batch.build_transaction( + to_address, ids, amounts, self.get_transact_opts()) + self.execute_tx(tx) def burn(self, args: MintCollectionArg): self.burn_from(self.get_signer_address(), args) diff --git a/nftlabs/modules/currency.py b/nftlabs/modules/currency.py index cbbb39c7..42ea7729 100644 --- a/nftlabs/modules/currency.py +++ b/nftlabs/modules/currency.py @@ -2,7 +2,7 @@ from ..errors import NoSignerException from ..types import Role from ..abi.coin import Coin -from .base import _BaseModule +from .base import BaseModule from ..types.currency import Currency, CurrencyValue from ..abi.erc20 import ERC20 from web3 import Web3 @@ -44,7 +44,7 @@ def balance_of(self, address: str) -> int: """ return self.__abi_module.balance_of.call(address) - def balance(self): + def balance(self) -> int: """ Gets the balance of the current address """ diff --git a/nftlabs/modules/market.py b/nftlabs/modules/market.py index 06733224..71888b73 100644 --- a/nftlabs/modules/market.py +++ b/nftlabs/modules/market.py @@ -4,13 +4,13 @@ from . import BaseModule from ..types import Role from ..abi.market import Market -from ..types.market import ListArg, Filter +from ..types.market import ListArg, Filter, MarketListing from ..types.listing import Listing from ..abi.erc20 import ERC20 from ..abi.erc165 import ERC165 from ..abi.erc1155 import ERC1155 from ..abi.nft import NFT - +nulladdress = "0x0000000000000000000000000000000000000000" class MarketModule(BaseModule): """ @@ -21,8 +21,7 @@ class MarketModule(BaseModule): Address of the market contract. """ __abi_module: Market - - def __init__(self, client: Web3, address: str): + def __init__(self, address: str, client: Web3, ): """ Initialize the Market Module. """ @@ -31,7 +30,6 @@ def __init__(self, client: Web3, address: str): self.address = address self.__abi_module = Market(client, address) - #todo: return types def list(self, arg: ListArg): """ List an asset for sale. @@ -39,30 +37,23 @@ def list(self, arg: ListArg): from_address = self.get_signer_address() client = self.get_client() erc165 = ERC165(client, arg.asset_contract) - isERC721 = erc165.supports_interface( - client, interface_id=bytearray.fromhex("80ac58cd")) + isERC721 = erc165.supports_interface.call( bytearray.fromhex("80ac58cd")) if isERC721: asset = NFT(client, arg.asset_contract) - approved = asset.is_approved_for_all( - from_address, self.address) + approved = asset.is_approved_for_all.call( from_address, self.address) if not approved: - asset.is_approve_for_all(from_address, arg.asset_contract) - is_token_approved = (asset.is_approved_for_all( - arg.token_id).lower() == self.address.lower()) + is_token_approved = asset.get_approved.call(arg.token_id).lower() == self.address.lower() if not is_token_approved: - asset.set_approval_for_all(arg.asset_contract, True) + self.execute_tx(asset.set_approval_for_all.build_transaction(self.address, True, self.get_transact_opts())) + else: asset = ERC1155(client, arg.asset_contract) - approved = asset.is_approved_for_all(from_address, self.address) + approved = asset.is_approved_for_all.call(from_address, self.address) if not approved: - asset.set_approval_for_all(from_address, arg.asset_contract) - is_token_approved = (asset.get_approved( - arg.token_id).lower() == self.address.lower()) - if not is_token_approved: - asset.set_approval_for_all(self.address, True) + asset.set_approval_for_all.call(self.address, True) - tx = self.__abi_module.list.build_transaction( + tx = self.__abi_module._list.build_transaction( arg.asset_contract, arg.token_id, arg.currency_contract, @@ -100,19 +91,20 @@ def buy(self, listing_id: int, quantity: int): """ Buy a listing. """ - listing = get(listing_id) + item = self.get(listing_id) + print(item) owner = self.get_signer_address() spender = self.address - total_price = listing.price_per_token * quantity - if listing.currency_contract is not None and listing.currency_contract != "0x0000000000000000000000000000000000000000": - erc20 = ERC20(self.get_client(), listing.currency_contract) - allowance = erc20.allowance(owner, spender) + total_price = item.pricePerToken * quantity + if item.currency is not None and item.currency != nulladdress: + erc20 = ERC20(self.get_client(), item.currency) + allowance = erc20.allowance.call(owner, spender) if allowance < total_price: - erc20.increase_allowance( - spender, + tx = erc20.increase_allowance.build_transaction( spender, total_price, - self.get_transact_opts() - ) + self.get_transact_opts()) + self.execute_tx(tx) + tx = self.__abi_module.buy.build_transaction( listing_id, quantity, @@ -131,7 +123,6 @@ def set_market_fee_bps(self, amount: int): self.get_transact_opts()) self.execute_tx(tx) - def get(self, listing_id) -> List: """ Get a listing. """ @@ -142,6 +133,12 @@ def get_all_listings(self, search_filter: Filter = None) -> List[Listing]: Returns all the listings. """ return self.get_all(search_filter) + + def get(self, listing_id) -> MarketListing: + """ + Get a listing. + """ + return MarketListing(**self.__abi_module.get_listing.call(listing_id)) def set_module_metadata(metadata: str): """ @@ -183,4 +180,4 @@ def total_listings(self) -> int: """ Returns the total supply of the market. """ - self.__abi_module.total_listings.call() + return self.__abi_module.total_listings.call() diff --git a/nftlabs/modules/market_types.py b/nftlabs/modules/market_types.py deleted file mode 100644 index eb2f760d..00000000 --- a/nftlabs/modules/market_types.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Types for the Market Module.""" - -from dataclasses import dataclass -from typing import Optional - - -@dataclass.dataclass -class ListArg: - """ - Arguments for listing a new item - """ - market_type: Optional[str] = None - limit: Optional[int] = None - offset: Optional[int] = None - asset_contract: str - token_id: int - currency_contract: str - price_per_token: int - quantity: int - tokens_per_buyer: int - seconds_until_start: int - seconds_until_end: int - - -@dataclass.dataclass -class Filter: - """ - Filter for the list_all method. - """ - seller: Optional[str] = None - tokenContract: Optional[str] = None - tokenId: Optional[int] = None \ No newline at end of file diff --git a/nftlabs/modules/nft.py b/nftlabs/modules/nft.py index 71bccd47..69c8a632 100644 --- a/nftlabs/modules/nft.py +++ b/nftlabs/modules/nft.py @@ -6,7 +6,7 @@ from web3 import Web3 from zero_ex.contract_wrappers import TxParams -from .base import _BaseModule +from .base import BaseModule from typing import Dict, List from ..abi.nft import NFT @@ -14,7 +14,7 @@ from ..types.nft import MintArg, NftMetadata as NftType -class NftModule(_BaseModule): +class NftModule(BaseModule): """ NFT Methods """ @@ -56,8 +56,8 @@ def mint_to( 'properties': final_properties } - uri = storage.upload(json.dumps(meta), self.address, self.__get_signer_address()) - tx = self.__abi_module.mint_nft.build_transaction(to_address, uri, self.__get_transact_opts()) + uri = storage.upload(json.dumps(meta), self.address, self.get_signer_address()) + tx = self.__abi_module.mint_nft.build_transaction(to_address, uri, self.get_transact_opts()) receipt = self.execute_tx(tx) result = self.__abi_module.get_minted_event( tx_hash=receipt.transactionHash.hex()) @@ -107,7 +107,7 @@ def mint_batch_to(self, to_address: str, args: List[MintArg]): 'description': arg.description, 'image': arg.image_uri, 'properties': arg.properties if arg.properties is not None else {} - }), self.address, self.__get_signer_address()) for arg in args] + }), self.address, self.get_signer_address()) for arg in args] tx = self.__abi_module.mint_nft_batch.build_transaction( to_address, uris, self.get_transact_opts()) @@ -125,7 +125,7 @@ def burn(self, token_id: int): """ tx = self.__abi_module.burn.build_transaction( token_id, - self.__get_transact_opts() + self.get_transact_opts() ) self.execute_tx(tx) @@ -137,7 +137,7 @@ def transfer_from(self, from_address: str, to_address: str, token_id: int): from_address, to_address, token_id, - self.__get_transact_opts() + self.get_transact_opts() ) self.execute_tx(tx) @@ -146,10 +146,10 @@ def transfer(self, to_address: str, token_id: int): Transfers NFT from the current signers wallet to another wallet """ tx = self.__abi_module.safe_transfer_from1.build_transaction( - self.__get_signer_address(), + self.get_signer_address(), to_address, token_id, - self.__get_transact_opts() + self.get_transact_opts() ) self.execute_tx(tx) @@ -175,7 +175,7 @@ def get_owned(self, address: str = "") -> List[NftType]: if the address parameter is not supplied """ if address == "": - address = self.__get_signer_address() + address = self.get_signer_address() balance = self.__abi_module.balance_of.call(address) owned_tokens = [self.__token_of_owner_by_index( @@ -225,9 +225,9 @@ def set_approval(self, operator: str, approved: bool = True): """ Sets approval for specified operator, defaults to grant approval """ - self.execute_tx(self.__abi_module.set_approval_for_all.call( - operator, approved, self.__get_transact_opts() - )) + tx = self.__abi_module.set_approval_for_all.build_transaction(operator, approved, self.get_transact_opts() ) + self.execute_tx(tx) + def grant_role(self, role: Role, address: str): """ @@ -248,12 +248,12 @@ def revoke_role(self, role: Role, address: str): """ role_hash = role.get_hash() self.execute_tx(self.__abi_module.revoke_role.build_transaction( - role_hash, address, self.__get_transact_opts() + role_hash, address, self.get_transact_opts() )) def set_restricted_transfer(self, restricted: bool = True): self.execute_tx(self.__abi_module.set_restricted_transfer.build_transaction( - restricted, self.__get_transact_opts() + restricted, self.get_transact_opts() )) def get_with_owner(self, token_id: int, owner: str): @@ -293,7 +293,7 @@ def get_role_members(self, role: Role): """ Returns the members of the given role """ - return [self.get_role_member(role, x) for x in range(stop=self.get_role_member_count(role))] + return [self.get_role_member(role, x) for x in range(self.get_role_member_count(role))] def get_role_member(self, role: Role, index: int): """ @@ -306,8 +306,8 @@ def get_all_role_members(self): Returns all the members of all the roles """ return { - admin: [self.get_role_members(Role.admin) for admin in self.get_role_members(Role.admin)], - transfer: [self.get_role_members(Role.transfer) for transfer in self.get_role_members(Role.transfer)], - minter: [self.get_role_members(Role.minter) for minter in self.get_role_members(Role.minter)], - pauser: [self.get_role_members(Role.pauser) for pauser in self.get_role_members(Role.pauser)], + "admin": [item for item in self.get_role_members(Role.admin)], + "transfer": [item for item in self.get_role_members(Role.transfer)], + "minter": [item for item in self.get_role_members(Role.minter)], + "pauser": [item for item in self.get_role_members(Role.pauser)], } diff --git a/nftlabs/modules/pack.py b/nftlabs/modules/pack.py index 63fb9ebe..3ea7500d 100644 --- a/nftlabs/modules/pack.py +++ b/nftlabs/modules/pack.py @@ -4,13 +4,13 @@ from ..types.nft import NftMetadata from ..types.currency import Currency, CurrencyValue from ..abi.pack import Pack -from .base import _BaseModule +from .base import BaseModule from ..abi.erc20 import ERC20 from web3 import Web3 from typing import List, Dict -class PackModule(_BaseModule): +class PackModule(BaseModule): address: str __abi_module: Pack diff --git a/nftlabs/sdk.py b/nftlabs/sdk.py index b2777986..1977f34b 100644 --- a/nftlabs/sdk.py +++ b/nftlabs/sdk.py @@ -4,7 +4,11 @@ from typing import Optional from .errors import NoSignerException -from .modules import CurrencyModule, NftModule, PackModule, CollectionModule +from .modules.nft import NftModule +from .modules.pack import PackModule +from .modules.collection import CollectionModule +from .modules.currency import CurrencyModule +from .modules.market import MarketModule from .options import SdkOptions from .storage import IpfsStorage @@ -25,6 +29,7 @@ class NftlabsSdk(object): __nft_module: Optional[NftModule] __pack_module: Optional[PackModule] __collection_module: Optional[CollectionModule] + __market_module: Optional[MarketModule] """ Create instance of the NftlabsSdk @@ -37,6 +42,7 @@ def __init__(self, options: SdkOptions, url: str): self.__pack_module = None self.__collection_module = None self.__current_account = None + self.__market_module = None self.options = options if self.options.private_key != "": @@ -97,6 +103,14 @@ def get_pack_module(self, address: str) -> PackModule: self.__pack_module = module return self.__pack_module + def get_market_module(self, address: str) -> MarketModule: + if self.__market_module is not None: + return self.__market_module + + module = MarketModule(address, self.__get_client()) + self.__init_module(module) + self.__market_module = module + return self.__market_module """ Returns an instance of the collection module """ diff --git a/nftlabs/types/listing.py b/nftlabs/types/listing.py index 229b77b6..d44fd21b 100644 --- a/nftlabs/types/listing.py +++ b/nftlabs/types/listing.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Optional, Union -from ..nft import NftMetadata -from ..currency import CurrencyValue +from .nft import NftMetadata +from .currency import CurrencyValue from dataclasses_json import dataclass_json import datetime @@ -12,10 +12,10 @@ class Listing: seller: str token_contract: str token_id: str - token_metadata: Optional[NFTMetadata] = None quantity: int currency_contract: str - currency_metadata: CurrencyValue | null - price: int + price_per_token: int sale_start: datetime.datetime - sale_end: datetime.datetime \ No newline at end of file + sale_end: datetime.datetime + token_metadata: Optional[NftMetadata] = None + currency_metadata: Optional[CurrencyValue] = None diff --git a/nftlabs/types/market/__init__.py b/nftlabs/types/market/__init__.py index 0dd4d56e..a43ec3a9 100644 --- a/nftlabs/types/market/__init__.py +++ b/nftlabs/types/market/__init__.py @@ -1,14 +1,15 @@ from dataclasses import dataclass +from dataclasses_json import dataclass_json from typing import Optional +from ..nft import NftMetadata +from ..currency import CurrencyValue +import datetime -@dataclass.dataclass +@dataclass class ListArg: """ Arguments for listing a new item """ - market_type: Optional[str] = None - limit: Optional[int] = None - offset: Optional[int] = None asset_contract: str token_id: int currency_contract: str @@ -17,13 +18,47 @@ class ListArg: tokens_per_buyer: int seconds_until_start: int seconds_until_end: int + limit: Optional[int] = None + offset: Optional[int] = None + -@dataclass.dataclass +@dataclass class Filter: """ Filter for the list_all method. """ seller: Optional[str] = None tokenContract: Optional[str] = None - tokenId: Optional[int] = None \ No newline at end of file + tokenId: Optional[int] = None + + +@dataclass_json +@dataclass +class MarketListing: + listingId: int + seller: str + assetContract: str + tokenId: int + quantity: int + currency: str + pricePerToken: int + saleStart: int + saleEnd: int + tokensPerBuyer: int + tokenType: int + +@dataclass_json +@dataclass +class Listing: + id: str + seller: str + token_contract: str + token_id: str + quantity: int + currency_contract: str + price_per_token: int + sale_start: datetime.datetime + sale_end: datetime.datetime + token_metadata: Optional[NftMetadata] = None + currency_metadata: Optional[CurrencyValue] = None \ No newline at end of file diff --git a/nftlabs/types/role.py b/nftlabs/types/role.py index 3451663a..3066bda5 100644 --- a/nftlabs/types/role.py +++ b/nftlabs/types/role.py @@ -1,8 +1,8 @@ -import enum +from enum import Enum from eth_hash.auto import keccak -class Role(enum.Enum): +class Role(Enum): admin = "" minter = "MINTER_ROLE" transfer = "TRANSFER_ROLE" From 25abf34ee3fae0805d15031e3f1eea75f0fd8d6c Mon Sep 17 00:00:00 2001 From: Ayush Pathak <62694274+ayshptk@users.noreply.github.com> Date: Thu, 28 Oct 2021 10:31:50 +0530 Subject: [PATCH 2/2] removed print statements --- nftlabs/modules/market.py | 1 - nftlabs/modules/pack.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/nftlabs/modules/market.py b/nftlabs/modules/market.py index 71888b73..bd1d9ffc 100644 --- a/nftlabs/modules/market.py +++ b/nftlabs/modules/market.py @@ -92,7 +92,6 @@ def buy(self, listing_id: int, quantity: int): Buy a listing. """ item = self.get(listing_id) - print(item) owner = self.get_signer_address() spender = self.address total_price = item.pricePerToken * quantity diff --git a/nftlabs/modules/pack.py b/nftlabs/modules/pack.py index 3ea7500d..f2902bfe 100644 --- a/nftlabs/modules/pack.py +++ b/nftlabs/modules/pack.py @@ -23,9 +23,7 @@ def get(self, pack_id: int) -> PackMetadata: uri = self.__abi_module.token_uri.call(pack_id) if uri == "": raise AssetNotFoundException(pack_id) - print("uri = ", uri) metadata = self.get_storage().get(uri) - print("pack metadata -", metadata) return None def open(self, pack_id: int) -> List[NftMetadata]: