【Windows 10/python3.8/English】Generate 100,000+ unique Kanji and sell them as NFTs Part-2

# Objectives 
After generating some unique Kanji, the last step is to sell them on OpenSea. it is pain in the neck uploading thousand of images one by one. I found automation code that uploads my images to the OpenSea. I will use that code to upload my images on the OpenSea.
**If you haven't checked Part 1 yet, Go to <a href = "https://qiita.com/Shu25/items/b3a22d107381d0d2b92d">【Part1】</a>**


# Version 

    - python 3.8 
    - Pillow 8.4.0
   
# Create OpenSea Account and Connected to Your Wallet 

OpenSea is one of the largest peer-to-peer NFT marketplaces. To sign up and sell NFTs, you need...

1. Create a cryptocurrency wallet (MetaMask) and Buy cryptocurrency (ETH)
2. (Optional) Exchange ETH to polygon ← Recommended
3. Create an OpenSea account
4. Sell your image! 


### 1. Create Cryptocurrency Wallet and Buy Ethereum 

To create cryptocurrency wallet, use <a href = "https://metamask.io/">MetaMask</a>; a Chrome extension that help us on the cryptocurrency transaction. After you download MetaMask to your Chrome, a Fox icon will show up on the top right of your browser. While creating a MetaMask account, they will give you 12 words. It's like your passcode for your bank account, **DO NOT SHARE WITH ANYONE**.

![Screen Shot 2022-02-16 at 16.06.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/70615b22-8f7c-d783-b5f0-68d1dc430ca1.png)

Once click the fox and you will see this little window. Use this window to add money, or make a smart contract. On the below window, click buy or 購入. Chose how you would like to add ETH. Since buying ETH is simple, we won't go into details. 

![Screen Shot 2022-02-16 at 16.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/13565605-a3a9-4da2-d496-6f1b60610250.png)




### 2. (Optional) Exchange ETH to Polygon 
*Polygon is a decentralised Ethereum scaling platform that enables developers to build scalable user-friendly dApps with low transaction fees without ever sacrificing on security.* - <a href = "https://polygon.technology/"> Polygon </a>. In other words, Polygon is like raffle tickets that help us to pay a small gas fee on the transaction. After the transaction is done, you need to transfer Polygon to ETH. To transfer ETH to polygon, click <a href = "https://support.opensea.io/hc/en-us/articles/1500012881642-How-do-I-transfer-ETH-from-Ethereum-to-Polygon-">here</a>.  



### 3. Create OpenSea Account 

It's very simple! You can do it ! <a href="https://support.opensea.io/hc/en-us/articles/360063498313-How-do-I-create-an-NFT-">How to Create an Account</a>. Make sure you connected to your MetaMask on your Chrome. 



###4. Sell Your Image! 

You can manually upload your image on OpenSea, but it's a pain in the neck to upload 1000+ images one by one. So most NFT artists create the automation script to upload the images. Thanks to <a href="https://github.com/nftdevs/NFTs-Upload-to-OpenSea/"> Petko Aleksandrov </a>for sharing his automation code. He also uploads a <a href = "https://www.youtube.com/watch?v=dk_N53vnJiY">YouTube</a> video to explain how to run the code. I would say just follow what he has done on his video. The only thing that you need to do is to make sure the code is updated to the latest version of OpenSea image upload flow. I had to fix some code because the timing of the popup window showing up was changed on my version of OpenSea. Here is my final automation code. (2022/2/16)

```python
import tkinter
import subprocess
from tkinter import *
from tkinter import filedialog
import os
import sys
import pickle
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as ExpectedConditions
from selenium.webdriver.support.ui import Select

root = Tk()
root.geometry('500x400')
root.title("NFTs Upload to OpenSea  ")
input_save_list = ["NFTs folder :", 0, 0, 0, 0, 0, 0, 0, 0]
main_directory = os.path.join(sys.path[0])
is_polygon = BooleanVar()
is_polygon.set(False)

def open_chrome_profile():
    subprocess.Popen(
        [
            "start",
            "chrome",
            "--remote-debugging-port=8989",
            "--user-data-dir=" + main_directory + "/chrome_profile",
        ],
        shell=True,
    )

def save_file_path():
    return os.path.join(sys.path[0], "Save_file.cloud") 

# ask for directory on clicking button, changes button name.
def upload_folder_input():
    global upload_path
    upload_path = filedialog.askdirectory()
    Name_change_img_folder_button(upload_path)

def Name_change_img_folder_button(upload_folder_input):
    upload_folder_input_button["text"] = upload_folder_input

class InputField:
    def __init__(self, label, row_io, column_io, pos, master=root):
        self.master = master
        self.input_field = Entry(self.master)
        self.input_field.label = Label(master, text=label)
        self.input_field.label.grid(row=row_io, column=column_io)
        self.input_field.grid(row=row_io, column=column_io + 1)
        try:
            with open(save_file_path(), "rb") as infile:
                new_dict = pickle.load(infile)
                self.insert_text(new_dict[pos])
        except FileNotFoundError:
            pass

    def insert_text(self, text):
        self.input_field.delete(0, "end")
        self.input_field.insert(0, text)

    def save_inputs(self, pos):
        input_save_list.insert(pos, self.input_field.get())
        with open(save_file_path(), "wb") as outfile:
            pickle.dump(input_save_list, outfile)

###input objects###
collection_link_input = InputField("OpenSea Collection Link:", 2, 0, 1)
start_num_input = InputField("Start Number:", 3, 0, 2)
end_num_input = InputField("End Number:", 4, 0, 3)
price = InputField("Price:", 5, 0, 4)
title = InputField("Title:", 6, 0, 5)
description = InputField("Description:", 7, 0, 6)
file_format = InputField("NFT Image Format:", 8, 0, 7)
external_link = InputField("External link:", 9, 0, 8)


###save inputs###
def save():
    input_save_list.insert(0, upload_path)
    collection_link_input.save_inputs(1)
    start_num_input.save_inputs(2)
    end_num_input.save_inputs(3)
    price.save_inputs(4)
    title.save_inputs(5)
    description.save_inputs(6)
    file_format.save_inputs(7)
    external_link.save_inputs(8)
   

# _____MAIN_CODE_____
def main_program_loop():
    ###START###
    project_path = main_directory
    file_path = upload_path
    collection_link = collection_link_input.input_field.get()
    start_num = int(start_num_input.input_field.get())
    end_num = int(end_num_input.input_field.get())
    loop_price = float(price.input_field.get())
    loop_title = title.input_field.get()
    loop_file_format = file_format.input_field.get()
    loop_external_link = str(external_link.input_field.get())
    loop_description = description.input_field.get()

    ##chromeoptions
    opt = Options()
    opt.add_experimental_option("debuggerAddress", "localhost:8989")
    driver = webdriver.Chrome(
        executable_path=project_path + "/chromedriver.exe",
        chrome_options=opt,
    )
    wait = WebDriverWait(driver, 300)

    ###wait for methods
    def wait_css_selector(code):
        wait.until(
            ExpectedConditions.presence_of_element_located((By.CSS_SELECTOR, code))
        )
        
    def wait_css_selectorTest(code):
        wait.until(
            ExpectedConditions.elementToBeClickable((By.CSS_SELECTOR, code))
        )    

    def wait_xpath(code):
        wait.until(ExpectedConditions.presence_of_element_located((By.XPATH, code)))


    while end_num >= start_num:
        print("Start creating NFT " +  loop_title + str(start_num))
        driver.get(collection_link)
        time.sleep(3)

        wait_xpath('//*[@id="__next"]/div[1]/main/div/div/div[1]/span/a')
        additem = driver.find_element_by_xpath('//*[@id="__next"]/div[1]/main/div/div/div[1]/span/a')
        additem.click()
        time.sleep(1)

        wait_xpath('//*[@id="media"]')
        imageUpload = driver.find_element_by_xpath('//*[@id="media"]')
        imagePath = os.path.abspath(file_path + "\\" + str(start_num) + "." + loop_file_format)  # change folder here
        imageUpload.send_keys(imagePath)

        name = driver.find_element_by_xpath('//*[@id="name"]')
        name.send_keys(loop_title + str(start_num))  # +1000 for other folders #change name before "#"
        time.sleep(1)

        ext_link = driver.find_element_by_xpath('//*[@id="external_link"]')
        ext_link.send_keys(loop_external_link)
        time.sleep(1)

        desc = driver.find_element_by_xpath('//*[@id="description"]')
        desc.send_keys(loop_description)
        time.sleep(1)

        # Select Polygon blockchain if applicable
        if is_polygon.get():
            blockchain_button = driver.find_element(By.XPATH, '//*[@id="__next"]/div[1]/main/div/div/section/div/form/div[7]/div/div[2]')
            blockchain_button.click()
            # polygon_button_location = '//span[normalize-space() = "Mumbai"]'
            # polygon_button_location
            wait_css_selector("input[value='Polygon']")
            listing = driver.find_element_by_css_selector("button[value='Polygon']")
            listing.click()
            time.sleep(7)
            
        create = driver.find_element_by_xpath('//*[@id="__next"]/div[1]/main/div/div/section/div[2]/form/div/div[1]/span/button')
        driver.execute_script("arguments[0].click();", create)
        time.sleep(1)

        wait_css_selector("i[aria-label='Close']")
        cross = driver.find_element_by_css_selector("i[aria-label='Close']")
        cross.click()
        time.sleep(1)

        main_page = driver.current_window_handle
        wait_xpath('//*[@id="__next"]/div[1]/main/div/div/div[1]/div/span[2]/a')
        sell = driver.find_element_by_xpath('//*[@id="__next"]/div[1]/main/div/div/div[1]/div/span[2]/a')
        sell.click()
        time.sleep(1)

        wait_css_selector("input[placeholder='Amount']")
        amount = driver.find_element_by_css_selector("input[placeholder='Amount']")
        amount.send_keys(str(loop_price))
        time.sleep(1)

        wait_css_selector("button[type='submit']")
        listing = driver.find_element_by_css_selector("button[type='submit']")
        listing.click()
        time.sleep(1)
        
        wait_css_selector("button[class='Blockreact__Block-sc-1xf18x6-0 Buttonreact__StyledButton-sc-glfma3-0 bhqEJb fzwDgL']")
        listing = driver.find_element_by_css_selector("button[class='Blockreact__Block-sc-1xf18x6-0 Buttonreact__StyledButton-sc-glfma3-0 bhqEJb fzwDgL']")
        listing.click()
        time.sleep(3)
        

        for handle in driver.window_handles:
            if handle != main_page:
                login_page = handle
                
        # change the control to signin page
        driver.switch_to.window(login_page)
        wait_css_selector("button[data-testid='request-signature__sign']")
        sign = driver.find_element_by_css_selector("button[data-testid='request-signature__sign']")
        sign.click()

        time.sleep(5)
  
       
        driver.switch_to.window(main_page)

        start_num = start_num + 1
        print('NFT creation completed!')

#####BUTTON ZONE#######
button_save = tkinter.Button(root, width=20, text="Save Form", command=save) 
button_save.grid(row=23, column=1)
button_start = tkinter.Button(root, width=20, bg="green", fg="white", text="Start", command=main_program_loop)
button_start.grid(row=25, column=1)
isPolygon = tkinter.Checkbutton(root, text='Polygon Blockchain', var=is_polygon)
isPolygon.grid(row=20, column=0)
open_browser = tkinter.Button(root, width=20,  text="Open Chrome Browser", command=open_chrome_profile)
open_browser.grid(row=22, column=1)
upload_folder_input_button = tkinter.Button(root, width=20, text="Add NFTs Upload Folder", command=upload_folder_input)
upload_folder_input_button.grid(row=21, column=1)
try:
    with open(save_file_path(), "rb") as infile:
        new_dict = pickle.load(infile)
        global upload_path
        Name_change_img_folder_button(new_dict[0])
        upload_path = new_dict[0]
except FileNotFoundError:
    pass
#####BUTTON ZONE END#######
root.mainloop()

``` 




:::note alert
Chrome Driver Error
=> Download recent version of Chrome Driver. Or I have to change my OS from Mac to Window. I think the problem is something to do with your python does not open right Chrome with Chrome Driver. 
:::


# Conclusion 
Congratulations! Let's Get Rich! 

### References

- https://metamask.io/
- https://polygon.technology/
- https://support.opensea.io/hc/en-us/articles/1500012881642-How-do-I-transfer-ETH-from-Ethereum-to-Polygon-
- https://support.opensea.io/hc/en-us/articles/360063498313-How-do-I-create-an-NFT-
- https://github.com/nftdevs/NFTs-Upload-to-OpenSea/
- https://www.youtube.com/watch?v=dk_N53vnJiY