Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on May 3, 2024. It is now read-only.

Commit dbcb614

Browse files
committed
Making progress on mint
1 parent c3a9a19 commit dbcb614

File tree

1 file changed

+87
-56
lines changed

1 file changed

+87
-56
lines changed

thirdweb/modules/nft.py

Lines changed: 87 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
""" Interact with the NFT module of the app"""
22
import copy
3-
from typing import Dict, List
3+
from typing import Dict, List, Union
44
import json
5+
from uuid import uuid4
6+
from eth_account.messages import encode_structured_data
57

68
import web3
79
from thirdweb.abi.erc20 import ERC20
810
from thirdweb.constants import NativeAddress, ZeroAddress
911

10-
from thirdweb_web3 import Web3
12+
from web3 import Web3
13+
from zero_ex.contract_wrappers import TxParams
1114

1215
from thirdweb.types.role import Role
1316

14-
from ..abi.nft import SignatureMint721 as NFT
17+
from ..abi.nft import SignatureMint721 as NFT, ISignatureMint721MintRequest
1518
from ..types.nft import BatchGeneratedSignature, MintArg, MintRequestStructOutput, NewSignaturePayload, SignaturePayload
1619
from ..types.nft import NftMetadata as NftType
1720
from .base import BaseModule
18-
import uuid
21+
1922
import binascii
2023

2124

@@ -51,7 +54,7 @@ def mint(self, arg: MintArg) -> NftType:
5154
:param arg: the `MintArg` object
5255
:return: the metadata of the token
5356
54-
Mints a new token to the signer.
57+
Mints a new token to the signer.
5558
- Arguments passed: Note, a class is used -> MintArg(name, description, image_uri, properties)
5659
- Returns the `NftMetadata(name,description,image,properties,id,uri)`
5760
"""
@@ -70,7 +73,7 @@ def mint_to(
7073
7174
Mints a new token to an address
7275
- Arguments passed: `to_address` and a class -> `MintArg(name, description, image_uri, properties)`
73-
- Returns the `NftMetadata(name,description,image,properties,id,uri)`
76+
- Returns the `NftMetadata(name,description,image,properties,id,uri)`
7477
"""
7578
final_properties: Dict
7679
if arg.properties is None:
@@ -233,7 +236,7 @@ def balance_of(self, address: str) -> int:
233236
234237
Returns balance of the given addressss
235238
- Use-case: Use this method if you don't want to use the connected wallet, but want to check another wallet.
236-
- Dashboard: Project ➝ NFT Module ➝ Total amount of NFT's
239+
- Dashboard: Project ➝ NFT Module ➝ Total amount of NFT's
237240
"""
238241
return self.__abi_module.balance_of.call(address)
239242

@@ -299,41 +302,46 @@ def set_restricted_transfer(self, restricted: bool = True):
299302
)
300303
)
301304

302-
def __map_payload(req: SignaturePayload or NewSignaturePayload) -> MintRequestStructOutput:
303-
return MintRequestStructOutput(
305+
def __map_payload(self, req: Union[SignaturePayload, NewSignaturePayload]) -> ISignatureMint721MintRequest:
306+
return ISignatureMint721MintRequest(
304307
to=req.to,
305308
price=req.price,
306309
currency=req.currency_address,
307-
validity_end_timestamp=req.mint_end_time_epoch_seconds,
308-
validity_start_timestamp=req.mint_start_time_epoch_seconds,
310+
validityEndTimestamp=req.mint_end_time_epoch_seconds,
311+
validityStartTimestamp=req.mint_start_time_epoch_seconds,
309312
uid=req.id,
313+
uri=req.uri
310314
)
311315

312316
def __set_allowance(
313317
self,
314318
value: int,
315-
currency_address: str
319+
currency_address: str,
320+
overrides: TxParams,
316321
):
317322
params = self.get_transact_opts()
318323
if currency_address == ZeroAddress or currency_address == NativeAddress:
319-
params["value"] = value
324+
overrides.value = value
320325
else:
321326
erc20 = ERC20(self.get_client(), currency_address)
322327
owner = self.get_signer_address()
323328
spender = self.address
324-
allownace = erc20.allowance(owner, spender)
325-
if allownace < value:
329+
allowance = erc20.allowance.call(owner, spender)
330+
if allowance < value:
326331
tx = erc20.increase_allowance.build_transaction(
327-
owner, value - allownace, params)
332+
owner, value - allowance, params)
328333
self.execute_tx(tx)
329334
return params
330335

331336
def mint_with_signature(self, req: NewSignaturePayload, signature: str) -> int:
332337
message = self.__map_payload(req)
333338
overrides = self.get_transact_opts()
334-
self.__set_allowance(req.price, req.currency_address)
335-
tx = self.__abi_module.mint_with_signature.build_transaction(
336-
message, signature, overrides)
339+
340+
self.__set_allowance(req.price, req.currency_address, overrides)
341+
342+
print("Minting NFT with signature", message)
343+
344+
tx = self.__abi_module.mint_with_signature.build_transaction(message, signature, overrides)
337345
receipt = self.execute_tx(tx)
338346
logs = self.__abi_module.get_mint_with_signature_event(
339347
receipt.transactionHash.hex())
@@ -345,59 +353,82 @@ def verify(self, mint_request: SignaturePayload, signature: str) -> bool:
345353
return self.__abi_module.verify.call(message, signature)[0]
346354

347355
def generate_signature_batch(self, payloads: list) -> list:
356+
'''
357+
Generates a batch of signatures that can be used for minting a number of NFTs
358+
359+
:param payloads: The payloads to generate the signature for
360+
:return: The generated signature
361+
'''
348362
def resolve_id(mint_request: NewSignaturePayload):
349-
if not mint_request.id:
363+
if mint_request.id is None:
350364
print("mint_request.id is empty, generating uuid-v4")
351-
generated_id = uuid.uuid4().hex
352-
return generated_id
365+
generated_id = uuid4().hex
366+
return "0x" + binascii.hexlify(str.encode(generated_id)).decode()
353367
else:
354-
return binascii.hexlify(mint_request.id).decode()
368+
return "0x" + binascii.hexlify(str.encode(mint_request.id)).decode()
355369

356370
if not self.get_signer_address() in self.get_role_members(Role.minter):
357371
raise Exception("You are not a minter")
358-
storage = self.get_storage()
359372

360-
def generate_sign(payload: NewSignaturePayload):
373+
def generate_signature(payload: NewSignaturePayload) -> BatchGeneratedSignature:
361374
resolved_id = resolve_id(payload)
362-
uri = storage.upload(payload.metadata, self.address, self.get_signer_address())
375+
376+
uri = self.upload_metadata(payload.metadata)
363377
payload.id = resolved_id
364378
payload.uri = uri
365379
chain_id = self.get_client().eth.chain_id
366380
message = self.__map_payload(payload)
367381
message["uri"] = uri
368382
message["uid"] = resolved_id
369-
return BatchGeneratedSignature(payload=payload,
370-
signature=self.get_client().eth.sign_typed_data(
371-
{
372-
"name": "SignatureMint721",
373-
"version": "1",
374-
"chainId": chain_id,
375-
"verifyingContract": self.address,
376-
},
377-
{
378-
"MintRequest": [
379-
{"name": "to",
380-
"type": "address"},
381-
{"name": "uri",
382-
"type": "string"},
383-
{"name": "price",
384-
type: "uint256"},
385-
{"name": "currency",
386-
type: "address"},
387-
{"name": "validityStartTimestamp",
388-
type: "uint128"},
389-
{"name": "validityEndTimestamp",
390-
type: "uint128"},
391-
{"name": "uid",
392-
type: "bytes32"},
393-
]
394-
},
395-
message
396-
)
397-
)
398-
return [generate_sign(payload) for payload in payloads]
383+
384+
print("message", message)
385+
encode_message = {
386+
**message,
387+
"uid": str(message['uid'].encode('utf-8'))
388+
}
389+
encoded_message = encode_structured_data(text=json.dumps({
390+
"types": {
391+
"MintRequest": [
392+
{"name": "to", "type": "address"},
393+
{"name": "uri", "type": "string"},
394+
{"name": "price", "type": "uint256"},
395+
{"name": "currency", "type": "address"},
396+
{"name": "validityStartTimestamp", "type": "uint128"},
397+
{"name": "validityEndTimestamp", "type": "uint128"},
398+
{"name": "uid", "type": "string"},
399+
],
400+
"EIP712Domain": [
401+
{"name": "name", "type": "string"},
402+
{"name": "version", "type": "string"},
403+
{"name": "chainId", "type": "uint256"},
404+
{"name": "verifyingContract", "type": "address"}
405+
]
406+
},
407+
"primaryType": "MintRequest",
408+
"domain": {
409+
"name": "SignatureMint721",
410+
"version": "1",
411+
"chainId": chain_id,
412+
"verifyingContract": self.address
413+
},
414+
"message": encode_message
415+
}))
416+
print("encoded_message =", encoded_message)
417+
return BatchGeneratedSignature(
418+
payload=payload,
419+
signature=self.get_client().eth.account.sign_message(
420+
encoded_message,
421+
self.get_private_key()
422+
).signature.hex())
423+
return [generate_signature(payload) for payload in payloads]
399424

400425
def generate_signature(self, mint_request: NewSignaturePayload):
426+
'''
427+
Generates a signature that can be used for minting an NFT
428+
429+
:param mint_request: The payload to generate the signature for
430+
:return: The generated signature
431+
'''
401432
return self.generate_signature_batch([mint_request])[0]
402433

403434
def get_with_owner(self, token_id: int):

0 commit comments

Comments
 (0)