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 a01ee37

Browse files
ayshptkatbe
andauthored
added upload support (#19)
* Update ipfs_storage.py * renamed image_uri -> image, still backwards compatible if image_uri keyword is used * Test for File Uploads - minting an nft where the metadata[“image”] is a file results in that property being replaced with the IPFS hash and the image gets uploaded - minting an nft where the metadata[“image”] is a string just uploads the metadata like normal * Update test_storage.py * Fixed environ var capture * minor changes * implemented upload metadata method * minor changes * added upload metadata to nft module * minor changes, need to fix tests * fixed minor issues, encoding error still present * Fixed file uploading for image type * Cleaned up the upload_metadata function * Updated all metadata uploading to go through the BaseModule.upload_metadata function * renamed erc20->token, 721->nft, added check for `get_approval(tokenid)` in `is_approved` fixed approve error for `create_with_erc20` and `create_with_erc721` todo: `721` method still throws `thirdweb_web3.exceptions.ContractLogicError: execution reverted` * Update test_bundle.py * Update bundle.py * Ensure all tests passing, fix constants import * Remove unused variable Co-authored-by: Ibrahim Ahmed <[email protected]>
1 parent c1e59ff commit a01ee37

File tree

16 files changed

+197
-98
lines changed

16 files changed

+197
-98
lines changed

test.png

9 KB
Loading
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
TEST_NFT_CONTRACT_ADDRESS = "0xEeD541b524Ae738c48211Be91EB81E97739A0A29"
1+
TEST_NFT_CONTRACT_ADDRESS = "0xedd431613Ae5EF32D006F2Ad1fC229d939f86C64"
22
TEST_PACK_CONTRACT_ADDRESS = "0x54ec360704b2e9E4e6499a732b78094D6d78e37B"
33
TEST_MARKET_CONTRACT_ADDRESS = "0x325a98B6081ef88C6356d63c56f48Fa1d0d2DD0D"
4-
TEST_BUNDLE_CONTRACT_ADDRESS = "0x6Da734b14e4CE604f1e18efb7E7f7ef022e96616"
4+
TEST_BUNDLE_CONTRACT_ADDRESS = "0xc5392102B97496413fCCe4c823bF1F674856B382"
55
TEST_CURRENCY_CONTRACT_ADDRESS = "0xF18FEb8b2F58691d67C98dB98B360840df340e74"
66

77
TEST_COMPANION_WALLET_ADDRESS = "0x4d36d531D9cB40b8694763123D52170FAE5e1195"

tests/test.png

76.2 KB
Loading

tests/test_bundle.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import unittest
22
from os import environ
33

4-
from dataclasses_json.api import A
5-
64
from thirdweb import SdkOptions, ThirdwebSdk
75
from thirdweb.modules.bundle import BundleModule
86
from thirdweb.modules.collection import CollectionModule
9-
from thirdweb.types.collection import CreateCollectionArg
7+
8+
from .constants import (TEST_BUNDLE_CONTRACT_ADDRESS,
9+
TEST_CURRENCY_CONTRACT_ADDRESS,
10+
TEST_NFT_CONTRACT_ADDRESS)
1011

1112

1213
class TestRoles(unittest.TestCase):
@@ -19,10 +20,9 @@ def setUpClass(self):
1920
self.sdk = ThirdwebSdk(SdkOptions(
2021
private_key=environ['PKEY']
2122
), "https://rpc-mumbai.maticvigil.com")
22-
self.module = self.sdk.get_bundle_module(
23-
"0x5CF412451f4Cef34293604048238bd18D2BD1e71")
24-
self.old_module = self.sdk.get_collection_module(
25-
"0x5CF412451f4Cef34293604048238bd18D2BD1e71")
23+
contract_address = TEST_BUNDLE_CONTRACT_ADDRESS
24+
self.module = self.sdk.get_bundle_module(contract_address)
25+
self.old_module = self.sdk.get_collection_module(contract_address)
2626

2727
def test_bundle_get_all(self):
2828
"""
@@ -40,19 +40,25 @@ def test_collection_get_all(self):
4040
self.assertGreater(
4141
len(result), 0, "There should be at least 1 token in the contract")
4242

43-
# def test_collection_mint(self):
43+
def test_bundle_create(self):
44+
"""
45+
Test that tries to instantiate the Bundle module
46+
"""
47+
result = self.module.create({"name": "test"})
48+
self.assertIsNotNone(result, "The result should not be None")
49+
50+
def test_bundle_create_with_token(self):
51+
"""
52+
Test that tries to instantiate the Bundle module
53+
"""
54+
result = self.module.create_with_token(
55+
TEST_CURRENCY_CONTRACT_ADDRESS, 20, {})
56+
57+
# def test_bundle_create_with_nft(self):
4458
# """
45-
# Test that tries to instantiate the Collection module
59+
# Test that tries to instantiate the Bundle module
4660
# """
47-
# result = self.old_module.create_and_mint(meta_with_supply=CreateCollectionArg(
48-
# metadata={"name": "Test"},
49-
# supply=10,
50-
# ))
51-
# print("Minted", result)
52-
# result = self.module.create_and_mint(meta_with_supply=CreateCollectionArg(
53-
# metadata={"name": "Test"},
54-
# supply=10,
55-
# ))
61+
# result = self.module.create_with_nft(TEST_NFT_CONTRACT_ADDRESS, 1, {})
5662

5763

5864
if __name__ == '__main__':

tests/test_import.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,37 +15,41 @@ def test_init_nft_module(self):
1515
Test that tries to instantiate the NFT module
1616
"""
1717
sdk = NftlabsSdk(SdkOptions(), "https://rpc-mumbai.maticvigil.com")
18-
nft_module = sdk.get_nft_module("0xEeD541b524Ae738c48211Be91EB81E97739A0A29")
18+
nft_module = sdk.get_nft_module(
19+
"0xEeD541b524Ae738c48211Be91EB81E97739A0A29")
1920

2021
def test_init_currency_module(self):
2122
"""
2223
Test that tries to instantiate the Currency module
2324
"""
2425
sdk = NftlabsSdk(SdkOptions(), "https://rpc-mumbai.maticvigil.com")
25-
currency_module = sdk.get_currency_module("0xF18FEb8b2F58691d67C98dB98B360840df340e74")
26+
currency_module = sdk.get_currency_module(
27+
"0xF18FEb8b2F58691d67C98dB98B360840df340e74")
2628

27-
2829
def test_init_bundle_module(self):
2930
"""
3031
Test that tries to instantiate the Bundle module
3132
"""
3233
sdk = NftlabsSdk(SdkOptions(), "https://rpc-mumbai.maticvigil.com")
33-
bundle_module = sdk.get_bundle_module("0x6Da734b14e4CE604f1e18efb7E7f7ef022e96616")
34+
bundle_module = sdk.get_bundle_module(
35+
"0x6Da734b14e4CE604f1e18efb7E7f7ef022e96616")
3436

3537
def test_init_pack_module(self):
3638
"""
3739
Test that tries to instantiate the Pack module
3840
"""
3941
sdk = NftlabsSdk(SdkOptions(), "https://rpc-mumbai.maticvigil.com")
40-
pack_module = sdk.get_pack_module("0x54ec360704b2e9E4e6499a732b78094D6d78e37B")
42+
pack_module = sdk.get_pack_module(
43+
"0x54ec360704b2e9E4e6499a732b78094D6d78e37B")
4144

4245
def test_init_marketplace_module(self):
4346
"""
4447
Test that tries to instantiate the Marketplace module
4548
"""
4649
sdk = NftlabsSdk(SdkOptions(), "https://rpc-mumbai.maticvigil.com")
47-
pack_module = sdk.get_market_module("0xD3920A1fd0fB09EA00F8ce56d0c655CF7a50428C")
50+
pack_module = sdk.get_market_module(
51+
"0xD3920A1fd0fB09EA00F8ce56d0c655CF7a50428C")
4852

4953

5054
if __name__ == '__main__':
51-
unittest.main()
55+
unittest.main()

tests/test_market.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import unittest
22

3-
from nftlabs import NftlabsSdk, SdkOptions
3+
from thirdweb import ThirdwebSdk, SdkOptions
44

5-
from test_constants import (TEST_BUNDLE_CONTRACT_ADDRESS,
6-
TEST_MARKET_CONTRACT_ADDRESS,
7-
TEST_NFT_CONTRACT_ADDRESS)
5+
from .constants import (TEST_BUNDLE_CONTRACT_ADDRESS,
6+
TEST_MARKET_CONTRACT_ADDRESS,
7+
TEST_NFT_CONTRACT_ADDRESS)
88

99

1010
class TestMarket(unittest.TestCase):
1111
def test_init_marketplace_module(self):
1212
"""
1313
Test that tries to instantiate the Marketplace module
1414
"""
15-
sdk = NftlabsSdk(SdkOptions(), "https://rpc-mumbai.maticvigil.com")
15+
sdk = ThirdwebSdk(SdkOptions(), "https://rpc-mumbai.maticvigil.com")
1616
market_module = sdk.get_market_module(TEST_MARKET_CONTRACT_ADDRESS)
1717

1818
self.assertFalse(market_module.is_erc721(

tests/test_roles.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import unittest
2-
3-
from nftlabs import NftlabsSdk, SdkOptions
4-
from nftlabs.types.role import Role
52
from os import environ
6-
from test_constants import TEST_BUNDLE_CONTRACT_ADDRESS, TEST_CURRENCY_CONTRACT_ADDRESS, TEST_MARKET_CONTRACT_ADDRESS, TEST_NFT_CONTRACT_ADDRESS, TEST_COMPANION_WALLET_ADDRESS, TEST_PACK_CONTRACT_ADDRESS
3+
4+
from thirdweb import SdkOptions, ThirdwebSdk
5+
from thirdweb.types.role import Role
6+
7+
from .constants import (TEST_BUNDLE_CONTRACT_ADDRESS,
8+
TEST_COMPANION_WALLET_ADDRESS,
9+
TEST_CURRENCY_CONTRACT_ADDRESS,
10+
TEST_MARKET_CONTRACT_ADDRESS,
11+
TEST_NFT_CONTRACT_ADDRESS, TEST_PACK_CONTRACT_ADDRESS)
712

813

914
class TestRoles(unittest.TestCase):
1015
def test_grant_and_revoke_role(self):
1116
"""
1217
Test that tries to instantiate the NFT module
1318
"""
14-
sdk = NftlabsSdk(SdkOptions(
19+
sdk = ThirdwebSdk(SdkOptions(
1520
private_key=environ['PKEY']
1621
), "https://rpc-mumbai.maticvigil.com")
1722

tests/test_storage.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import unittest
3+
4+
from thirdweb import MintArg, ThirdwebSdk, SdkOptions
5+
6+
7+
class TestStorage(unittest.TestCase):
8+
def test_storage(self):
9+
sdk = ThirdwebSdk(SdkOptions(
10+
private_key=os.environ['PKEY']
11+
), "https://rpc-mumbai.maticvigil.com")
12+
13+
nft_module = sdk.get_nft_module(
14+
"0xEeD541b524Ae738c48211Be91EB81E97739A0A29")
15+
16+
# mint by uploading a file
17+
with open(file='tests/test.png', mode='rb') as f:
18+
content = f.read()
19+
module = nft_module.mint(MintArg(name="example",
20+
description="example nft!", image=content, properties={}))
21+
self.assertTrue(module.image.startswith(
22+
"ipfs://"), "Image files are expected to be uploaded when set in the image property")
23+
24+
# mint by providing a string
25+
actual_image = "ipfs://QmYWi4mkEjsL6MYoS8z2ZWPAhyDPNjPQ2pqg8MGEM1CaeQ"
26+
module = nft_module.mint(MintArg(name="example", description="example nft!",
27+
image=actual_image, properties={}))
28+
self.assertEqual(module.image, actual_image,
29+
"String image properties should be uploaded as-is")
30+
31+
32+
if __name__ == '__main__':
33+
unittest.main()

thirdweb/errors/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from typing import Any, Optional
2-
2+
import json
33

44
class NoSignerException(Exception):
55
def __init__(self):
@@ -16,3 +16,8 @@ class UnsupportedAssetException(Exception):
1616
def __init__(self, identifier: Optional[Any] = None):
1717
super().__init__(
1818
f"Asset with address {identifier} is not compatible with this method")
19+
20+
class UploadError(Exception):
21+
def __init__(self, message: str):
22+
super().__init__(f"There was an error while uploading the image : {message}")
23+

thirdweb/modules/base.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from thirdweb_web3 import Web3
88
from thirdweb_web3.types import TxReceipt
99
from zero_ex.contract_wrappers import TxParams
10-
10+
import json
1111
from ..abi.coin import Coin
1212
from ..abi.erc165 import ERC165
1313
from ..abi.market import Market
@@ -16,6 +16,7 @@
1616
from ..abi.pack import Pack
1717
from ..constants.erc_interfaces import InterfaceIdErc721, InterfaceIdErc1155
1818
from ..errors import NoSignerException
19+
import io
1920
from ..options import SdkOptions
2021
from ..storage import IpfsStorage
2122
from ..types.role import Role
@@ -52,7 +53,7 @@ def __init__(self):
5253
self.get_options = None
5354

5455
def execute_tx(self, tx) -> TxReceipt:
55-
"""
56+
"""
5657
Execute a transaction and return the receipt.
5758
"""
5859
client = self.get_client()
@@ -68,7 +69,7 @@ def execute_tx(self, tx) -> TxReceipt:
6869
)
6970

7071
def __sign_tx(self, tx):
71-
"""
72+
"""
7273
Sign a transaction.
7374
"""
7475
signed_tx = self.get_account().sign_transaction(tx)
@@ -102,6 +103,24 @@ def grant_role(self, role: Role, address: str):
102103
)
103104
self.execute_tx(tx)
104105

106+
def upload_metadata(self, data: Union[Dict, str]) -> str:
107+
"""
108+
Uploads the metadata to IPFS and returns the uri.
109+
"""
110+
storage = self.get_storage()
111+
if isinstance(data, str) and data.startswith("ipfs://"):
112+
return data
113+
114+
if 'image_uri' in data and data["image"] == "":
115+
data["image"] = data["image_uri"]
116+
117+
if 'image' in data:
118+
if isinstance(data["image"], bytes) or isinstance(data["image"], bytearray):
119+
data["image"] = storage.upload(
120+
data["image"], self.address, self.get_signer_address())
121+
122+
return storage.upload(json.dumps(data), self.address, self.get_signer_address())
123+
105124
def revoke_role(self, role: Role, address: str):
106125
"""
107126
Revokes the given role from the given address

0 commit comments

Comments
 (0)