Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add opensea metada and nftport uploader and minter #71

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@
importlib.reload(Exporter)
importlib.reload(Refactorer)
importlib.reload(get_combinations)
importlib.reload(Uploader)
else:
from .main import \
DNA_Generator, \
Batch_Sorter, \
Exporter, \
Refactorer, \
get_combinations
get_combinations, \
Uploader

# User input Property Group:
class BMNFTS_PGT_MyProperties(bpy.types.PropertyGroup):
Expand Down Expand Up @@ -96,6 +98,7 @@ class BMNFTS_PGT_MyProperties(bpy.types.PropertyGroup):
cardanoMetaDataBool: bpy.props.BoolProperty(name="Cardano Cip")
solanaMetaDataBool: bpy.props.BoolProperty(name="Solana Metaplex")
erc721MetaData: bpy.props.BoolProperty(name="ERC721")
openSeaMetaData: bpy.props.BoolProperty(name="OpenSea")

# API Panel properties:
apiKey: bpy.props.StringProperty(name="API Key", subtype='PASSWORD')
Expand Down Expand Up @@ -129,6 +132,14 @@ class BMNFTS_PGT_MyProperties(bpy.types.PropertyGroup):

# ERC721 Custom Metadata Fields
erc721_description: bpy.props.StringProperty(name="ERC721 description")

openSea_description: bpy.props.StringProperty(name="Description")

nftport_api_key: bpy.props.StringProperty(name="Nft Port API Key")

wallet_address: bpy.props.StringProperty(name="Wallet address")

contract_address: bpy.props.StringProperty(name="Contract address")


def make_directories(save_path):
Expand Down Expand Up @@ -246,10 +257,12 @@ class refactor_panel_input:
cardanoMetaDataBool = bpy.context.scene.my_tool.cardanoMetaDataBool
solanaMetaDataBool = bpy.context.scene.my_tool.solanaMetaDataBool
erc721MetaData = bpy.context.scene.my_tool.erc721MetaData
openSeaMetaData = bpy.context.scene.my_tool.openSeaMetaData

cardano_description = bpy.context.scene.my_tool.cardano_description
solana_description = bpy.context.scene.my_tool.solana_description
erc721_description = bpy.context.scene.my_tool.erc721_description
openSea_description = bpy.context.scene.my_tool.openSea_description

Blend_My_NFTs_Output, batch_json_save_path, nftBatch_save_path = make_directories(save_path)

Expand All @@ -261,6 +274,26 @@ class refactor_panel_input:
def invoke(self, context, event):
return context.window_manager.invoke_confirm(self, event)

class uploadNFTs(bpy.types.Operator):
bl_idname = 'uploader.nfts'
bl_label = 'Upload NFTs'
bl_description = 'Upload NFTs.'
bl_options = {"REGISTER", "UNDO"}

def execute(self, context):

class uploader_panel_input:
save_path = bpy.path.abspath(bpy.context.scene.my_tool.save_path)
nftport_api_key = bpy.context.scene.my_tool.nftport_api_key.strip()
contract_address = bpy.context.scene.my_tool.contract_address.strip()
wallet_address = bpy.context.scene.my_tool.wallet_address.strip()

Uploader.uploadNFTCollection(uploader_panel_input)

self.report({'INFO'}, "NFTs Uploaded")

return {"FINISHED"}

# Create Data Panel:
class BMNFTS_PT_CreateData(bpy.types.Panel):
bl_label = "Create NFT Data"
Expand Down Expand Up @@ -386,6 +419,12 @@ def draw(self, context):
row.operator("wm.url_open", text="ERC721 Metadata Documentation",
icon='URL').url = "https://docs.opensea.io/docs/metadata-standards"

row = layout.row()
row.prop(mytool, "openSeaMetaData")
if bpy.context.scene.my_tool.openSeaMetaData:
row = layout.row()
row.prop(mytool, "openSea_description")

row = layout.row()
row.prop(mytool, "enableCustomFields")
if bpy.context.scene.my_tool.enableCustomFields:
Expand All @@ -412,6 +451,33 @@ def draw(self, context):
row.operator("wm.url_open", text="Documentation",
icon='URL').url = "https://github.com/torrinworx/Blend_My_NFTs"

class BMNFTS_PT_NFTPORT_Uploader(bpy.types.Panel):
bl_label = "NFTPort Uploader"
bl_idname = "BMNFTS_PT_NFTPORT_Uploader"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = 'Blend_My_NFTs'

def draw(self, context):
layout = self.layout
scene = context.scene
mytool = scene.my_tool

row = layout.row()
row.prop(mytool, "nftport_api_key")

row = layout.row()
row.prop(mytool, "contract_address")

row = layout.row()
row.prop(mytool, "wallet_address")

row = layout.row()
self.layout.operator("uploader.nfts", icon='DISCLOSURE_TRI_RIGHT', text="Upload To IPFS & Mint")
row = layout.row()
row.operator("wm.url_open", text="Documentation",
icon='URL').url = "https://github.com/aizwellenstan/Blend_My_NFTs_Doc"

# # Materials Panel:
#
# class BMNFTS_PT_MATERIALS_Panel(bpy.types.Panel):
Expand Down Expand Up @@ -457,6 +523,7 @@ def redraw_panel():
BMNFTS_PT_GenerateNFTs,
BMNFTS_PT_Refactor,
BMNFTS_PT_Documentation,
BMNFTS_PT_NFTPORT_Uploader,

# Other panels:
# BMNFTS_PT_MATERIALS_Panel,
Expand All @@ -465,6 +532,7 @@ def redraw_panel():
createData,
exportNFTs,
refactor_Batches,
uploadNFTs
)

def register():
Expand Down
37 changes: 37 additions & 0 deletions main/Metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,45 @@ def returnErc721MetaData(name, NFT_DNA, NFT_Variants, custom_Fields_File, enable

return metaDataDictErc721

def returnOpenSeaMetaData(name, NFT_DNA, NFT_Variants, custom_Fields_File, enableCustomFields, erc721_description):
dna = NFT_DNA.replace("-", "")
metaDataDictErc721 = {
"name": name+"_"+dna,
"description": erc721_description,
"image": "",
"attributes": None,
}

metaDataDictErc721['custom_fields'] = {
'edition': int(dna)
}

attributes = []

for i in NFT_Variants:
dictionary = {
"trait_type": i,
"value": NFT_Variants[i]
}

attributes.append(dictionary)

# Custom Fields:
if enableCustomFields:
custom_Fields = json.load(open(custom_Fields_File))
for i in custom_Fields:
dictionary = {
"trait_type": i,
"value": custom_Fields[i]
}
attributes.append(dictionary)

metaDataDictErc721["attributes"] = attributes

return metaDataDictErc721

if __name__ == '__main__':
returnSolanaMetaData()
returnCardanoMetaData()
returnErc721MetaData()
returnOpenSeaMetaData()
16 changes: 16 additions & 0 deletions main/Refactorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def renameMetaData(rename_MetaData_Variables):
cardanoMetaDataPath = os.path.join(rename_MetaData_Variables.completeCollPath, "Cardano_metaData")
solanaMetaDataPath = os.path.join(rename_MetaData_Variables.completeCollPath, "Solana_metaData")
erc721MetaDataPath = os.path.join(rename_MetaData_Variables.completeCollPath, "Erc721_metaData")
openSeaMetaDataPath = os.path.join(rename_MetaData_Variables.completeCollPath, "OpenSea_metaData")

for i in metaDataListOld:
name, NFT_DNA, NFT_Variants = getMetaDataDirty(rename_MetaData_Variables.completeMetaDataPath, i)
Expand Down Expand Up @@ -103,6 +104,19 @@ def renameMetaData(rename_MetaData_Variables):
metaDataDictErc721 = Metadata.returnErc721MetaData(erc721NewName, NFT_DNA, NFT_Variants, rename_MetaData_Variables.custom_Fields_File, rename_MetaData_Variables.enableCustomFields, rename_MetaData_Variables.erc721_description)

sendMetaDataToJson(metaDataDictErc721, erc721MetaDataPath, erc721JsonNew)

if rename_MetaData_Variables.openSeaMetaData:
if not os.path.exists(openSeaMetaDataPath):
os.mkdir(openSeaMetaDataPath)

openSeaFileName =name.split("_")[0] + "_" + str(file_num)+".json"
openSeaNewName = name.split("_")[0]
if len(rename_MetaData_Variables.openSea_description) < 1:
rename_MetaData_Variables.openSea_description = openSeaNewName

metaDataDictOpenSea = Metadata.returnOpenSeaMetaData(openSeaNewName, NFT_DNA, NFT_Variants, rename_MetaData_Variables.custom_Fields_File, rename_MetaData_Variables.enableCustomFields, rename_MetaData_Variables.openSea_description)

sendMetaDataToJson(metaDataDictOpenSea, openSeaMetaDataPath, openSeaFileName)
return

def reformatNFTCollection(refactor_panel_input):
Expand Down Expand Up @@ -220,6 +234,7 @@ class rename_MetaData_Variables:
cardanoMetaDataBool = refactor_panel_input.cardanoMetaDataBool
solanaMetaDataBool = refactor_panel_input.solanaMetaDataBool
erc721MetaData = refactor_panel_input.erc721MetaData
openSeaMetaData = refactor_panel_input.openSeaMetaData

custom_Fields_File = refactor_panel_input.custom_Fields_File
enableCustomFields = refactor_panel_input.enableCustomFields
Expand All @@ -228,6 +243,7 @@ class rename_MetaData_Variables:
cardano_description = refactor_panel_input.cardano_description
solana_description = refactor_panel_input.solana_description
erc721_description = refactor_panel_input.erc721_description
openSea_description = refactor_panel_input.openSea_description


renameMetaData(rename_MetaData_Variables)
Expand Down
105 changes: 105 additions & 0 deletions main/Uploader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""
NftGenerator Using NFTPort
@author https://github.com/aizwellenstan
"""

import os
import json
import requests
from os import listdir
from os.path import isfile, join
import time

def nftPortFileUploader(apikey, file):
response = requests.post(
"https://api.nftport.xyz/v0/files",
headers={"Authorization": apikey},
files={"file": file}
)

return json.loads(response.text)

def nftPortMetaUploader(apikey, metaData):
response = requests.post(
"https://api.nftport.xyz/v0/metadata",
headers={"Authorization": apikey, "Content-Type": "appication/json"},
data=json.dumps(metaData, indent=4)
)

return json.loads(response.text)

def minter(apikey, meta, CONTRACT_ADDRESS, MINT_TO_ADDRESS):
mintInfo = {
'chain': 'polygon',
'contract_address': CONTRACT_ADDRESS,
'metadata_uri': meta['metadata_uri'],
'mint_to_address': MINT_TO_ADDRESS,
'token_id': meta['custom_fields']['edition']
}
response = requests.post(
"https://api.nftport.xyz/v0/mints/customizable",
headers={"Authorization": apikey, "Content-Type": "appication/json"},
data=json.dumps(mintInfo, indent=4)
)

return json.loads(response.text)

def uploadToNFTPort(nftport_panel_input):
glbFile = f"{nftport_panel_input.modelPath}\{nftport_panel_input.fileName}.glb"
with open(glbFile, 'rb') as modelFile:
res = nftPortFileUploader(nftport_panel_input.apikey, modelFile)
resModelUrl = f"{res['ipfs_url']}?fileName={nftport_panel_input.fileName}.glb"

pngFile = f"{nftport_panel_input.imagePath}\{nftport_panel_input.fileName}.png"
with open(pngFile, 'rb') as imageFile:
res = nftPortFileUploader(nftport_panel_input.apikey, imageFile)
resImageUrl = f"{res['ipfs_url']}"

jsonFile = f"{nftport_panel_input.metaDataPath}\{nftport_panel_input.fileName}.json"
with open(jsonFile, 'r') as inputFile:
metaData = json.load(inputFile)
metaData['animation_url'] = resModelUrl
metaData['file_url'] = resImageUrl

res = nftPortMetaUploader(nftport_panel_input.apikey, metaData)
metaData['metadata_uri'] = res['metadata_uri']
with open(jsonFile, 'w') as outputFile:
json.dump(metaData, outputFile, ensure_ascii=False, indent=4)

return metaData

def uploadNFTCollection(uploader_panel_input):
completeCollPath = os.path.join(uploader_panel_input.save_path, "Blend_My_NFTs Output", "Complete_Collection")
completeImagePath = os.path.join(completeCollPath, "Images")
completeAnimationsPath = os.path.join(completeCollPath, "Animations")
completeModelsPath = os.path.join(completeCollPath, "Models")
openSeaMetaDataPath = os.path.join(completeCollPath, "OpenSea_metaData")

class nftport_panel_input:
apikey = uploader_panel_input.nftport_api_key
modelPath = completeModelsPath
imagePath = completeImagePath
metaDataPath = openSeaMetaDataPath
fileName = ""

onlyfiles = [f for f in listdir(completeModelsPath) if isfile(join(completeModelsPath, f))]

print(onlyfiles)
allMetadata = []
for file in onlyfiles:
fileName = file.split(".")[0]
nftport_panel_input.fileName = fileName
metaData = uploadToNFTPort(nftport_panel_input)
allMetadata.append(metaData)
print(allMetadata)
for meta in allMetadata:
minted = minter(nftport_panel_input.apikey, meta, uploader_panel_input.contract_address, uploader_panel_input.wallet_address)
print(minted)
file = f"{nftport_panel_input.metaDataPath}\{meta['custom_fields']['edition']}_minted.json"
with open(file, 'w') as outputFile:
json.dump(minted, outputFile, ensure_ascii=False, indent=4)
print("All Minted")


if __name__ == '__main__':
uploadNFTCollection()