# thirdweb ile mint etme

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

NFT basma durumunda, thirdweb denetlenmiş sözleşmeleri ve geniş SDK'larıyla birlikte kullanıma hazır bir kontrol paneli ve IPFS yükleme sunar.

## Tek bir NFT'yi manuel olarak basma

Sadece tek bir görsel yükleyip basmak istiyorsanız, thirdweb tıklamayla dağıtım arayüzü sunar.

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

Oradan iki yol arasında seçim yapabilirsiniz:

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

Her birini bu sayfada hızlıca inceleyelim.\
The [thirdweb Developer Portal](https://portal.thirdweb.com/) ihtiyacınız olursa size daha fazla bilgi verecektir.

### TokenERC721 sayfasını kullanma

1. şuraya gidin: [TokenERC721](https://thirdweb.com/thirdweb.eth/TokenERC721) sayfa. Bu, bir NFT Koleksiyonu oluşturmak için onların sözleşmesine dayanır.
2. Sözleşme dağıtım sayfasına erişmek için "Deploy Now" tıklayın.

<figure><img src="https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FiOBJ9vEjTgrGDXLvTc1H%2Fimage.png?alt=media&#x26;token=813cbc07-bb5c-4264-bebf-855d6eb6df04" alt=""><figcaption></figcaption></figure>

3. "Contract metadata" bölümünü doldurun:
   1. NFT koleksiyonunuzu temsil etmesini istediğiniz görseli (veya sadece basmak istediğiniz görseli) yükleyin.
   2. Koleksiyonunuza benzersiz bir ad ve bir sembol/ticker verin.
   3. Bir açıklama verin.
4. thirdweb, "Primary Sales" ve "Royalties" için alıcı adreslerini otomatik doldurur; Web3 adreslerinin gerçekten sizin cüzdanınıza ait olduğundan emin olun.
5. "Deploy Options" içinde Chiliz Chain'i seçin (ya da sadece testse Chiliz Spicy Testnet'i) ve "Deploy Now" tuşuna tıklayın:

<figure><img src="https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2F5pwRre3hAs9tnenpIpOo%2Fimage.png?alt=media&#x26;token=97754b66-957f-427e-8ecc-d82d65c0740a" alt=""><figcaption></figcaption></figure>

6. thirdweb sözleşmeyi dağıtmaya başlayacak ve Web3 cüzdanınızdan bir onay modalı tetikleyecektir. Dağıtımı bitirmek için onaylayın.\
   ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FZA5AENlXHNJ4t958GMwB%2Fimage.png?alt=media\&token=02d4ed98-a898-4e98-9bff-0d2894d6ed1e)
7. İşlem tamamlandığında "View Contract" butonuna tıklayın. thirdweb kontrol panelinizde sözleşmenin sayfasına yönlendirileceksiniz; burada bir kontrol listesi/ilerleme çubuğu göreceksiniz:\
   ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FJzTrC2bhoCIvPQC5C1bc%2Fimage.png?alt=media\&token=fbddb609-467d-41d5-aa4e-db89756e9fcc)
8. Kontrol listesinden görüldüğü gibi, şimdilik yaptığınız tek şey bir sözleşme dağıtmak; NFT'yi gerçekten basmanız hâlâ gerekiyor. Sol sütunda, yeni bir sayfa açmak için "NFTs" menü öğesine tıklayın; şimdilik bu sayfa boştur:\
   ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FN8snuMGiNGQ95LpBVYVd%2Fimage.png?alt=media\&token=23637f39-e3a2-4927-8e85-2618b496aa34)
9. "Mint" düğmesine tıklayın; bir yan panel açılacak ve NFT'nizin her özniteliği için alanlar gösterecektir. Burada NFT'nizin metadata'sını oluşturursunuz:\
   ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FMHxWQopIf0X3yvrMYQEw%2Fimage.png?alt=media\&token=d6847f12-d9cc-4b0d-820b-703b80727f93)
10. Çeşitli alanları doldurun. "Artist\_name" veya "Type\_of\_work" gibi NFT koleksiyonunuza özgü alanlar oluşturabilirsiniz ve gelişmiş seçenekleri keşfedebilirsiniz; ancak bu test için minimumda tutabilirsiniz: isim, medya dosyası, açıklama.&#x20;
11. Yan panelin altındaki "Mint NFT" düğmesine tıklayın ve cüzdanınızdan işlemi onaylayın. \
    ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FOHQ6CYuKlTU095csZbVm%2Fimage.png?alt=media\&token=c3b9070c-0e0d-4258-a3ab-f4d1e7882405)
12. thirdweb daha sonra "NFTs" sayfasını gösterecek; NFT'niz artık görünür olacak ve NFT sözleşmenize bağlı olacaktır.&#x20;

TAMAM! NFT'nizi bastınız!

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

<figure><img src="https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FMIE0awyJCp6V2R7cT5ug%2Fimage.png?alt=media&#x26;token=0a2555c5-1d3b-46dd-9c80-7179d3003598" alt=""><figcaption></figcaption></figure>

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

### "Create Token" düğmesini kullanma

Aslında bu, yukarıdakinden daha doğrudan bir yoldur ve thirdweb'e yeni eklenmiş bir özelliktir.

1. thirdweb kontrol panelinizde herhangi bir proje klasöründen, sol kenar çubuğunda "Tokens" seçeneğine tıklayın:\
   ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2Ffhhm3V6WJUMusyKa48hB%2Fimage.png?alt=media\&token=52ee0435-3521-489f-987a-35548593dbf6)
2. Açılan "Tokens" sayfasında sağ taraftaki "Create Token" düğmesine tıklayın. Bir modal pencere açılır ve 2 seçenek gösterir; "Create NFT Collection" seçeneğini seçin.\
   ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FPaabgWRx5ip9785p9ohj%2Fimage.png?alt=media\&token=9c2649a6-53b9-4da8-aa69-902062beeba4)
3. Bu sizi adım adım bir sürüme götürecektir: [TokenERC721](https://thirdweb.com/thirdweb.eth/TokenERC721) dağıtım sayfasının (aslında bir ERC-721 Drop sözleşmesi dağıtacaktır). Bu sözleşme için gerekli tüm alanları doldurun, sonra "Next" düğmesine basın.
4. Sonraki ekran NFT'nin kendisi hakkındadır: görseli yükleyin ve görseli tanımlayan alanları doldurun, sonra "Next" düğmesine basın.
5. thirdweb şimdi başlatmak üzere olduğunuz NFT koleksiyonunun bir özetini gösterir. Her şeyin doğru olduğunu kontrol edin ve ardından "Launch NFT Collection" düğmesine tıklayın.
6. thirdweb, sözleşmeyi dağıtma, NFT'yi basma ve koşulları ayarlama işlerini tek seferde üstlenir. Web3 cüzdanınız üzerinden üç işlemi onaylamanız gerekecek.\
   ![](https://2155691341-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4L7rBH2rmyoBTn93MSdx%2Fuploads%2FcGZUd5TQPujpphUVGXCe%2Fimage.png?alt=media\&token=d634d62d-6022-499f-8ffd-1879effd60aa)
7. Bu işlem tamamlandığında "View NFT" düğmesine tıklayın; thirdweb kontrol panelinize geri yönlendirileceksiniz ve bu sözleşmeye özel sayfa — ve ona bağlı NFT'ler — gösterilecektir.

Oradan, gerçekten zincirde olduğunu bir blok gezgini aracılığıyla kontrol edebilir veya NFT'nizi bir pazar yeri üzerinden satmaya başlayabilirsiniz.

## Tek bir NFT'yi programatik olarak basma

İşte [thirdweb v5 SDK](https://portal.thirdweb.com/references/typescript/v5)kullanan bir kod örneği, bu örnek medya dosyasını IPFS'e yükler, `metadata.json` dosyasını oluşturur, sonra onu da IPFS'e yükler.

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

* Chiliz Chain üzerinde zaten dağıtılmış bir ERC-721 sözleşmesi. Bu durumda bunu thirdweb kullanarak yapmalısınız, başka bir araçla değil.
* thirdweb tarafından dağıttığınız ERC-721 sözleşmesine bağlı bir thirdweb API anahtarı. Bunu akıllı sözleşmenin proje sayfasında "Client ID" adı altında bulabilirsiniz.
* Yerel bir thirdweb SDK kurulumu. Bunu kullanarak yapabilirsiniz: `npm`:

```bash
npm install thirdweb dotenv
```

Buradaki `dotenv` parametresi bir `.env` dosyası oluşturur; bu özel değerleri saklamak için gereklidir:

```
THIRDWEB_SECRET_KEY=YOUR_TW_SECRET_KEY # thirdweb proje sayfanızdan.
PRIVATE_KEY=0xabc...                   # İşlemi gönderecek Web3 cüzdanı.
CONTRACT_ADDRESS=0xYour721Address      # Dağıttığınız TokenERC721 sözleşmeniz.
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" %}
Asla `PRIVATE_KEY` veya `THIRDWEB_SECRET_KEY` istemci tarafı kodunda açığa çıkarmayın! \
Bu dosyayı güvenli bir sunucu/CI üzerinde tutun ve herkese açık bir depoya yüklemeyin
{% endhint %}

Şimdi her şey hazır olduğuna göre, bu betikten ilham alabilirsiniz; bu betik şunları yapacaktır:

1. Medya dosyasını IPFS'e yükleyecek
2. oluşturacak ve yükleyecek `metadata.json` dosyasını
3. Sözleşmenin mintTo metodunu kullanarak NFT'yi basacak.
4. Ortaya çıkan `tokenId` ve `tokenUrl` gibi bilgileri size gösterecek.

{% hint style="success" %}
Bu sadece bir örnek koddur; kendi proje kodunuza uyarlamanız gerekecek!
{% 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ükle
  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öner 
  // console.log("imageUri:", imageUri);

  // IPFS imageUri'ye referans veren metadata.json 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 kullanılarak mintTo işlemi hazırla ve gönder
  // mintTo, tokenURI olarak doğrudan kullanılacak bir string 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 göstermek 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 almanız gereken önemli kısımlar şunlardır:

* `upload` dosyaları (ve JSON'u) IPFS'e depolar ve `ipfs://…` URI'leri döndürür.
* `mintTo` doğrudan kullanılmak üzere bir string (kabul eder) `tokenURI`.
* Standart ERC-721 `Transfer` olayını ayrıştırarak basılanı okuyoruz `tokenId`.

## Programatik olarak bir NFT koleksiyonu basma

Bir NFT koleksiyonu basmak, tek bir NFT basmaktan çok farklı değildir. En belirgin fark, sizin `.env` dosyanızın tüm görselleri içeren klasöre `IMAGE_DIR`işaret etmesi, tek bir görsele işaret eden `IMAGE_PATH`.

```dotenv
THIRDWEB_SECRET_KEY=YOUR_TW_SECRET_KEY # thirdweb proje sayfanızdan.
PRIVATE_KEY=0xabc...                   # İşlemi gönderecek Web3 cüzdanı.
CONTRACT_ADDRESS=0xYour721Address      # Dağıttığınız TokenERC721 sözleşmeniz.
CHAIN_ID=88882                         # 88888=Mainnet, 88882=Spicy
yerine
IMAGE_PATH=./art                       # Medya dosyalarınızın yerel yolu.
DESCRIPTION=Minted on Chiliz Chain
```

NAME\_PREFIX=My Chiliz NFT              # Bu şuna dönüşecek: "My Chiliz NFT \<n>"

{% 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";
}

Burada sunduğumuz örnek kod bu durumu dikkate alır:
// 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()))
}

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}`,
  });

  .map((f) => path.join(dir, f));
  // Bir klasördeki medya dosyalarını IPFS'e yükle
  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öner

  //console.log("Uploaded images to IPFS:", imageUris.length, "files");
  // Her imageUri'ye referans veren metadata.json oluştur ve yükle
  // NAME ve DESCRIPTION çevresel değişkenlerini kullanır; isimler "<NAME> #<index>" olur
  const namePrefix = process.env.NAME!;

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

  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 tx = mintTo({
      contract,
      to: account.address,
      nft: metadataUri, // TokenURI
    });

    const { transactionHash } = await sendTransaction({ transaction: tx, account });
    const metadataUri = metadataUris[i];

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

    console.log(`[${i + 1}/${metadataUris.length}] tx:`, transactionHash);
    const events = parseEventLogs({ logs: receipt.logs, events: [transferEvent()] });
    // Bu mint için tokenId'yi almak üzere Transfer olayını ayrıştır
      const minted = events.find(
    );
    const tokenId = minted ? (minted.args.tokenId as bigint) : undefined;

    (e) => e.eventName === "Transfer" && typeof e.args.from === "string" && e.args.from.toLowerCase() === ZERO
    if (tokenId !== undefined) {
      const nft = await getNFT({ contract, tokenId });
      // console.log(`[${i + 1}/${metadataUris.length}] tokenId:`, tokenId?.toString() ?? "(not found)");
    }
  }
}

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

```

{% endcode %}

// console.log(\`\[${i + 1}/${metadataUris.length}] tokenURI (read back):\`, nft.tokenURI);

* `Detaylı değişiklikler şunlardır:` IMAGES\_DIR `IMAGE_PATH`.
* ile değiştirildi `Eklenen` listMediaFiles
* birden çok girdiyi toplamak için. `upload` Görüntüler ve metadata için toplu işlemler (sıralamayı korur).
* Her `mintTo` metadataUri üzerinde döngü `, her bir`olayı kendi `Transfer` için ayrıştırma. `tokenId`.
* İsimler otomatik numaralandırılır: `NAME #1`, `NAME #2`, … mevcut `NAME`/`DESCRIPTION`.

Yine, lütfen bunu kendi kodunuz için bir ilham kaynağı olarak kullanın, aynen kopyalamayın!

Not: Lazy minting yapmak isterseniz, thirdweb'ün ERC-721 sözleşmesi [şuna sahip `lazyMint` metodu](https://portal.thirdweb.com/references/typescript/v5/erc721/lazyMint).
