> For the complete documentation index, see [llms.txt](https://docs.chiliz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chiliz.com/tr/gelistir/gelismis/nft-ile-calisma/thirdweb-ile-minting.md).

# thirdweb ile Minting

[thirdweb](https://thirdweb.com/), birden fazla blockchain ağında merkeziyetsiz uygulamalar oluşturmak için araçlar ve altyapı sunan bir platformdur. SDK'lar, API'ler ve önceden oluşturulmuş bileşenlerle blockchain entegrasyonunu basitleştirir.

NFT basımı söz konusu olduğunda, thirdweb; denetlenmiş sözleşmeleri ve kapsamlı SDK'larıyla birlikte kullanışlı bir pano ve IPFS yükleme olanağı sunar.

## Manuel Olarak Tek NFT Basımı

Yalnızca tek bir görüntü yükleyip basmak istiyorsanız, thirdweb tıklayarak deploy etme arayüzü sunar.

Önce Web3 cüzdanınızı sahip olarak kullanarak bir thirdweb hesabı oluşturun. Bu size thirdweb panonuza erişim sağlar.

Oradan iki yol arasında seçim yapabilirsiniz:

* [TokenERC721](https://thirdweb.com/thirdweb.eth/TokenERC721) sayfasını ve "Deploy Now" düğmesini kullanın.
* Veya panonun "Create Token" arayüzünü kullanın.

Bu sayfada her birini kısaca inceleyelim.\
Daha fazla bilgiye ihtiyaç duyduğunuzda [thirdweb Geliştirici Portalı](https://portal.thirdweb.com/) size yardımcı olacaktır.

### TokenERC721 Sayfasını Kullanma

1. [TokenERC721](https://thirdweb.com/thirdweb.eth/TokenERC721) sayfasına gidin. Bu, NFT Koleksiyonu oluşturmak için sözleşmelerine dayanmaktadır.
2. Sözleşme deploy sayfasına erişmek için "Deploy Now"a tıklayın.
3. "Contract metadata" bölümünü doldurun:
   1. NFT koleksiyonunuzu (veya basmak istediğiniz görüntüyü) temsil edecek görüntüyü yükleyin.
   2. Koleksiyonunuza benzersiz bir ad ve sembol/ticker verin.
   3. Bir açıklama ekleyin.
4. thirdweb, "Primary Sales" ve "Royalties" için alıcı adreslerini otomatik olarak doldurur; Web3 adreslerinin gerçekten cüzdanınıza ait olduğunu kontrol edin.
5. "Deploy Options" bölümünde Chiliz Chain'i (veya bu bir test ise Chiliz Spicy Testnet'i) seçin ve "Deploy Now"a tıklayın:
6. thirdweb, Web3 cüzdanınızdan bir onay modalı tetikleyerek sözleşmeyi deploy etmeye başlar. Deploy işlemini tamamlamak için onaylayın.<br>
7. Tamamlandıktan sonra "View Contract" düğmesine tıklayın. Bir kontrol listesi/ilerleme çubuğuyla thirdweb panonuzdaki sözleşmenin sayfasına yönlendirileceksiniz:<br>
8. Kontrol listesinden de görebileceğiniz gibi, şimdiye kadar yalnızca bir sözleşme deploy ettiniz; NFT'yi aslında hâlâ basmanız gerekiyor. Sol sütunda "NFTs" menü öğesine tıklayarak şu an boş olan yeni bir sayfayı açın:<br>
9. "Mint" düğmesine tıklayın; NFT'nizin her özelliği için alan içeren bir yan panel açılır. NFT'nizin meta verilerini burada oluşturursunuz:<br>
10. Çeşitli alanları doldurun. "Artist\_name" veya "Type\_of\_work" gibi NFT koleksiyonunuza özgü alanlar oluşturabilir ve gelişmiş seçenekleri keşfedebilirsiniz; ancak bu test için minimal tutabilirsiniz: ad, medya dosyası, açıklama.
11. Yan panelininin altındaki "Mint NFT" düğmesine tıklayın ve işlemi cüzdanınızdan onaylayın.<br>
12. thirdweb ardından NFT'nizin sözleşmenize eklenmiş olarak görünür olduğu "NFTs" sayfasını gösterir.

TAMAMLANDI! NFT'nizi başarıyla bastınız!

Gerçekten Chiliz Chain'de olduğunu doğrulamak için [Chiliscan](https://www.chiliscan.com/)'ı (veya Spicy Testnet kullanıyorsanız [testnet varyantını](https://testnet.chiliscan.com/)) açın ve NFT'nin hash'ini arama alanına yapıştırın. Sözleşmenizin zincirde olduğunu hemen doğrulamalı ve "Inventory" sekmesi NFT'nizi sizin (ya da en azından cüzdanınızın ID'si) sahip olarak listelemelidir.

NFT'nizi Chiliz Chain Mainnet'te bastıysanız, [Rarible](https://rarible.com/) veya [OKX](https://www.okx.com/) gibi pazaryerlerindeki hesabınızda görünmesi gerekir ve oradan satışa başlayabilirsiniz!

### "Create Token" Düğmesini Kullanma

Bu aslında yukarıdakinden daha doğrudan bir yoldur ve thirdweb'e yakın zamanda eklenen bir özelliktir.

1. thirdweb panonuzdaki herhangi bir proje klasöründen sol kenar çubuğundaki "Tokens" seçeneğine tıklayın:<br>
2. Açılan "Tokens" sayfasında sağ taraftaki "Create Token" düğmesine tıklayın. 2 seçenekli bir modal pencere açılır; "Create NFT Collection"ı seçin.<br>
3. Bu sizi [TokenERC721](https://thirdweb.com/thirdweb.eth/TokenERC721) deploy sayfasının adım adım sürümüne götürür (aslında bir ERC-721 Drop sözleşmesi deploy edecektir). Bu sözleşme için gerekli tüm alanları doldurun, ardından "Next" düğmesine basın.
4. Sonraki ekran NFT'nin kendisiyle ilgilidir: görüntüyü yükleyin ve görüntünüzü tanımlayan alanları doldurun, ardından "Next" düğmesine basın.
5. thirdweb artık başlatmak üzere olduğunuz NFT koleksiyonunun özetini gösterir. Her şeyin doğru olduğunu kontrol edin, ardından "Launch NFT Collection" düğmesine tıklayın.
6. thirdweb, sözleşmeyi deploy etmeyi, NFT'yi basmayı ve koşulları belirlemeyi tek seferde üstlenir. Web3 cüzdanınız üzerinden üç işlemi onaylamanız gerekecektir.<br>
7. Bu işlem tamamlandıktan sonra "View NFT" düğmesine tıklayın ve thirdweb panosu, NFT koleksiyonunuza ve ekli NFT'lerinize özgü sayfaya yönlendirileceksiniz.

Oradan bir blok gezgini aracılığıyla gerçekten zincirde olduğunu kontrol edebilir veya NFT'nizi bir pazaryeri üzerinden satışa başlayabilirsiniz.

## Programatik Olarak Tek NFT Basımı

Aşağıda, medya dosyasını IPFS'e yükleyen, `metadata.json` dosyasını oluşturan ve ardından onu da IPFS'e yükleyen [thirdweb v5 SDK'sını](https://portal.thirdweb.com/references/typescript/v5) kullanan bir kod örneği verilmiştir.

Bunun için şunlara ihtiyacınız olacak:

* Chiliz Chain'de önceden deploy edilmiş bir ERC-721 sözleşmesi. Bu durumda başka bir araç yerine thirdweb kullanarak deploy etmeniz gerekir.
* thirdweb üzerinden deploy ettiğiniz ERC-721 sözleşmesine bağlı bir thirdweb API anahtarı. Bunu, akıllı sözleşmenizin proje sayfasında "Client ID" adı altında bulabilirsiniz.
* thirdweb SDK'nın yerel kurulumu. `npm` kullanarak yapabilirsiniz:

```bash
npm install thirdweb dotenv
```

`dotenv` parametresi, özel değerleri depolamak için gerekli olan `.env` dosyasını oluşturur:

```
THIRDWEB_SECRET_KEY=YOUR_TW_SECRET_KEY # thirdweb proje sayfanızdan.
PRIVATE_KEY=0xabc...                   # İşlemi gönderecek Web3 cüzdanı.
CONTRACT_ADDRESS=0xYour721Address      # Deploy ettiğiniz TokenERC721 sözleşmesi.
CHAIN_ID=88882                         # 88888=Mainnet, 88882=Spicy
IMAGE_PATH=./art/image.png             # Medya dosyanızın yerel yolu.
NAME=My Chiliz NFT
DESCRIPTION=Minted on Chiliz Chain
```

{% hint style="danger" %}
`PRIVATE_KEY` veya `THIRDWEB_SECRET_KEY`'i istemci taraflı kodda asla açığa çıkarmayın!\
Bu dosyayı güvenli bir sunucuda/CI'da tutun ve genel bir depoya yüklemeyin.
{% endhint %}

Her şey hazır olduğunda şu işlemleri gerçekleştirecek bu komut dosyasından ilham alabilirsiniz:

1. Medya dosyasını IPFS'e yükleme
2. `metadata.json` dosyasını oluşturma ve yükleme
3. Sözleşmenin mintTo yöntemi kullanılarak NFT basımı.
4. Elde edilen `tokenId` ve `tokenUrl`'yi görüntüleme.

{% hint style="success" %}
Bu yalnızca örnek bir koddur; kendi proje kodunuza uyarlamanız gerekecektir!
{% endhint %}

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```typescript
import 'dotenv/config';
import fs from 'fs';
import path from 'path';

import { createThirdwebClient, getContract, sendTransaction, waitForReceipt, parseEventLogs } from "thirdweb";
import { defineChain } from "thirdweb/chains";
import { privateKeyToAccount } from "thirdweb/wallets";
import { mintTo, transferEvent, getNFT } from "thirdweb/extensions/erc721";
import { upload } from "thirdweb/storage";

function guessMime(p: string) {
  const ext = path.extname(p).toLowerCase();
  if (ext === ".png") return "image/png";
  if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
  if (ext === ".webp") return "image/webp";
  if (ext === ".gif") return "image/gif";
  if (ext === ".mp4") return "video/mp4";
  if (ext === ".webm") return "video/webm";
  return "application/octet-stream";
}

async function main() {
  const client = createThirdwebClient({ secretKey: process.env.THIRDWEB_SECRET_KEY! });
  const chain = defineChain(Number(process.env.CHAIN_ID)); // 88888 veya 88882
  const account = privateKeyToAccount({ client, privateKey: process.env.PRIVATE_KEY! });

  const contract = getContract({
    client,
    chain,
    address: process.env.CONTRACT_ADDRESS as `0x${string}`,
  });

  // Medya dosyasını IPFS'e yükleme
  const filePath = process.env.IMAGE_PATH!;
  const buffer = fs.readFileSync(filePath);
  const file = new File([buffer], path.basename(filePath), { type: guessMime(filePath) });

  const [imageUri] = await upload({ client, files: [file] }); // ipfs://... döndürür
  // console.log("imageUri:", imageUri);

  // IPFS imageUri'yi referans alan metadata.json dosyasını oluştur ve yükle
  const metadata = {
    name: process.env.NAME!,
    description: process.env.DESCRIPTION!,
    image: imageUri
  };
  const metaBlob = new Blob([JSON.stringify(metadata, null, 2)], { type: "application/json" });
  const metaFile = new File([metaBlob], "metadata.json", { type: "application/json" });

  const [metadataUri] = await upload({ client, files: [metaFile] });
  // console.log("metadataUri:", metadataUri);

  // metadata URI'yi kullanarak mintTo işlemini hazırla ve gönder
  // mintTo, doğrudan tokenURI olarak kullanmak için bir dize kabul eder.
  const tx = mintTo({
    contract,
    to: account.address,
    nft: metadataUri, // tokenURI
  });

  const { transactionHash } = await sendTransaction({ transaction: tx, account });
  //console.log("tx:", transactionHash);

  const receipt = await waitForReceipt({ client, chain, transactionHash });

  // tokenId'yi almak için Transfer olayını ayrıştır
  const events = parseEventLogs({ logs: receipt.logs, events: [transferEvent()] });
  const minted = events.find(e => e.eventName === "Transfer" && e.args.from === "0x0000000000000000000000000000000000000000");
  const tokenId = minted ? (minted.args.tokenId as bigint) : undefined;
  //console.log("tokenId:", tokenId?.toString() ?? "(not found)");

  if (tokenId !== undefined) {
    const nft = await getNFT({ contract, tokenId });
    //console.log("tokenURI (read back):", nft.tokenURI);
  }
}

main().catch((err) => (console.error(err), process.exit(1)));
```

{% endcode %}

İlham almak için kritik kısımlar şunlardır:

* `upload`, dosyaları (ve JSON'u) IPFS'e depolar ve `ipfs://…` URI'leri döndürür.
* `mintTo`, doğrudan `tokenURI` olarak kullanmak için bir dize kabul eder.
* Basılan `tokenId`'yi okumak için standart ERC-721 `Transfer` olayını ayrıştırıyoruz.

## Programatik Olarak NFT Koleksiyonu Basımı

NFT koleksiyonu basmak, tek NFT basmaktan çok farklı değildir. En belirgin fark, `.env` dosyanızın `IMAGE_PATH` ile tek bir görüntüye değil, `IMAGE_DIR` ile tüm görüntüleri içeren klasöre işaret etmesidir.

```dotenv
THIRDWEB_SECRET_KEY=YOUR_TW_SECRET_KEY # thirdweb proje sayfanızdan.
PRIVATE_KEY=0xabc...                   # İşlemi gönderecek Web3 cüzdanı.
CONTRACT_ADDRESS=0xYour721Address      # Deploy ettiğiniz TokenERC721 sözleşmesi.
CHAIN_ID=88882                         # 88888=Mainnet, 88882=Spicy
IMAGE_PATH=./art                       # Medya dosyalarınızın yerel yolu.
NAME_PREFIX=My Chiliz NFT              # Şu olacak: "My Chiliz NFT <n>"
DESCRIPTION=Minted on Chiliz Chain
```

Burada sunduğumuz örnek kod bunu göz önünde bulundurmaktadır:

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```typescript
import 'dotenv/config';
import fs from 'fs';
import path from 'path';

import { createThirdwebClient, getContract, sendTransaction, waitForReceipt, parseEventLogs } from "thirdweb";
import { defineChain } from "thirdweb/chains";
import { privateKeyToAccount } from "thirdweb/wallets";
import { mintTo, transferEvent, getNFT } from "thirdweb/extensions/erc721";
import { upload } from "thirdweb/storage";

function guessMime(p: string) {
  const ext = path.extname(p).toLowerCase();
  if (ext === ".png") return "image/png";
  if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
  if (ext === ".webp") return "image/webp";
  if (ext === ".gif") return "image/gif";
  if (ext === ".mp4") return "video/mp4";
  if (ext === ".webm") return "video/webm";
  return "application/octet-stream";
}

// Tüm dosyaları toplamanın bir yolu
function listMediaFiles(dir: string) {
  const allow = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif", ".mp4", ".webm", ".svg"]);
  return fs
    .readdirSync(dir)
    .filter((f) => allow.has(path.extname(f).toLowerCase()))
    .map((f) => path.join(dir, f));
}

async function main() {
  const client = createThirdwebClient({ secretKey: process.env.THIRDWEB_SECRET_KEY! });
  const chain = defineChain(Number(process.env.CHAIN_ID)); // 88888 veya 88882
  const account = privateKeyToAccount({ client, privateKey: process.env.PRIVATE_KEY! }); 

  const contract = getContract({
    client,
    chain,
    address: process.env.CONTRACT_ADDRESS as `0x${string}`,
  });

  // Bir klasördeki medya dosyalarını IPFS'e yükleme
  const dirPath = process.env.IMAGES_DIR!;
  const filePaths = listMediaFiles(dirPath);
  if (!filePaths.length) {
    throw new Error(`No media files found in ${dirPath}`);
  }

  const fileObjs = filePaths.map((p) => {
    const buffer = fs.readFileSync(p);
    return new File([buffer], path.basename(p), { type: guessMime(p) });
  });

  const imageUris = await upload({ client, files: fileObjs }); // ["ipfs://...", ...] döndürür
  //console.log("Uploaded images to IPFS:", imageUris.length, "files");

  // Her imageUri'yi referans alan metadata.json dosyalarını oluştur ve yükle
  // NAME ve DESCRIPTION env değişkenlerini kullanır; adlar "<NAME> #<index>" olur
  const namePrefix = process.env.NAME!;
  const description = process.env.DESCRIPTION!;

  // Meta veri JSON'ları için File nesneleri dizisi oluşturma
  const metaFiles = imageUris.map((imageUri, i) => {
    const metadata = {
      name: `${namePrefix} #${i + 1}`,
      description,
      image: imageUri
    };
    const metaBlob = new Blob([JSON.stringify(metadata, null, 2)], { type: "application/json" });
    return new File([metaBlob], `metadata-${i + 1}.json`, { type: "application/json" });
  });

  const metadataUris = await upload({ client, files: metaFiles }); // ["ipfs://.../metadata-1.json", ...]
  //console.log("Uploaded metadata files to IPFS:", metadataUris.length);

  // metadata URI'lerini kullanarak mintTo işlemlerini hazırla ve gönder (sıralı)
  const ZERO = "0x0000000000000000000000000000000000000000";

  for (let i = 0; i < metadataUris.length; i++) {
    const metadataUri = metadataUris[i];

    const tx = mintTo({
      contract,
      to: account.address,
      nft: metadataUri, // tokenURI
    });

    const { transactionHash } = await sendTransaction({ transaction: tx, account });
    console.log(`[${i + 1}/${metadataUris.length}] tx:`, transactionHash);

    const receipt = await waitForReceipt({ client, chain, transactionHash });

    // Bu basım için tokenId'yi almak amacıyla Transfer olayını ayrıştır
    const events = parseEventLogs({ logs: receipt.logs, events: [transferEvent()] });
    const minted = events.find(
      (e) => e.eventName === "Transfer" && typeof e.args.from === "string" && e.args.from.toLowerCase() === ZERO
    );
    const tokenId = minted ? (minted.args.tokenId as bigint) : undefined;

    // console.log(`[${i + 1}/${metadataUris.length}] tokenId:`, tokenId?.toString() ?? "(not found)");
    if (tokenId !== undefined) {
      const nft = await getNFT({ contract, tokenId });
      // console.log(`[${i + 1}/${metadataUris.length}] tokenURI (read back):`, nft.tokenURI);
    }
  }
}

main().catch((err) => (console.error(err), process.exit(1)));

```

{% endcode %}

Detaylı değişiklikler şunlardır:

* `IMAGES_DIR`, `IMAGE_PATH`'in yerini alır.
* Birden fazla girdi toplamak için `listMediaFiles` eklendi.
* Görüntüler ve meta veriler için toplu `upload` kullanımı (sırayı korur).
* Her `metadataUri` için `mintTo` döngüsü; her `Transfer` olayından `tokenId` ayrıştırılır.
* Adlar otomatik numaralandırılır: mevcut `NAME`/`DESCRIPTION` değerlerinizi kullanarak `NAME #1`, `NAME #2`, …

Lütfen bunu kendi kodunuz için bir ilham kaynağı olarak kullanın, olduğu gibi kullanmayın!

Not: Tembel basımı tercih ederseniz, thirdweb'in ERC-721 sözleşmesinde [bir `lazyMint` yöntemi](https://portal.thirdweb.com/references/typescript/v5/erc721/lazyMint) bulunmaktadır.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.chiliz.com/tr/gelistir/gelismis/nft-ile-calisma/thirdweb-ile-minting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
