viem ile mintleme
Basım süreci üzerinde ayrıntılı kontrol isteyen geliştiriciler için, vanilla TypeScript'i kullanabilirsiniz viem, EVM tabanlı projeler için bir TypeScript arayüzü olan Ethers.js kütüphanesi de ayrıca sağlam bir yaklaşımdır.
Gitmek vanilla üçüncü taraf çerçevelere (ör. thirdweb) güvenmeye kıyasla biraz daha fazla iş yapmanızı gerektirir. Örneğin, kendi IPFS düğümünüzü çalıştırmıyorsanız, ücretli olan NFT depolama platformlarına güvenmeniz gerekecektir.
Bu örnek şunu kullanır Pinata bir IPFS sunucusu olarak. Ayrıca bir OpenZeppelin ERC-721 sözleşmesi Chiliz Chain üzerinde kendiniz dağıtmalısınız. Remix IDE bunu tarayıcı içinde yapmanızı sağlar. Bir blok gezgini kullanarak sözleşmeyi doğrulamayı unutmayın!
Şimdi, haydi kurulum yapalım viem, Pinata SDK, ve parametresi bir modülünü:
npm i viem pinata dotenvDosyanızı dosyası oluşturur; bu, gizli değerleri saklamak için gereklidir: ihtiyaçlarınıza göre yapılandırın:
# Cüzdan / sözleşme
PRIVATE_KEY=0xabc... # sadece sunucu tarafı
CONTRACT_ADDRESS=0xYourErc721Address
RECIPIENT=0xRecipientOrLeaveEmpty # isteğe bağlı; varsayılan olarak basan adres
# Pinata
PINATA_JWT=eyJhbGciOi... # Pinata panosundan alınan JWT
PINATA_GATEWAY=your-subdomain.mypinata.cloud
# Tek basım
IMAGE_PATH=./art/image.png
DESCRIPTION=Minted on Chiliz Chain
DESCRIPTION=Viem ile Chiliz üzerinde basıldı
# Toplu basım
IMAGES_DIR=./art
NAME_PREFIX=Benim Chiliz NFT'm
BATCH_DESCRIPTION=Viem ile Chiliz üzerinde toplu olarak basıldıŞimdi koda dalalım. Bundan ilham alın, olduğu gibi kullanmayın!
Tek bir NFT basımı
import path from 'path';
import { createThirdwebClient, getContract, sendTransaction, waitForReceipt, parseEventLogs } from "thirdweb";
import { defineChain } from "thirdweb/chains";
import { createWalletClient, createPublicClient, http, parseEventLogs } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import type { Address } from 'viem';
import { chiliz, spicy } from 'viem/chains';
import { PinataSDK } from 'pinata';
// Minimal ABI: safeMint(to, uri) + tokenURI + Transfer
const abi = [
{ type: 'function', name: 'safeMint', stateMutability: 'nonpayable',
inputs: [{ name: 'to', type: 'address' }, { name: 'uri', type: 'string' }], outputs: [] },
{ type: 'function', name: 'tokenURI', stateMutability: 'view',
inputs: [{ name: 'tokenId', type: 'uint256' }], outputs: [{ type: 'string' }] },
{ type: 'event', name: 'Transfer',
inputs: [
{ name: 'from', type: 'address', indexed: true },
{ name: 'to', type: 'address', indexed: true },
{ name: 'tokenId', type: 'uint256', indexed: true },
]},
] as const;
if (ext === ".png") return "image/png";
if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
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';
}
const chain = defineChain(Number(process.env.CHAIN_ID)); // 88888 veya 88882
// Ağınızı seçin: Chiliz testnet için `spicy` kullanın, Chiliz Chain Mainnet için `chiliz`'e geçin.
const chain = spicy; // Mainnet için `chiliz` ile değiştirin
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({ account, chain, transport: http() });
const publicClient = createPublicClient({ chain, transport: http() });
const address = process.env.CONTRACT_ADDRESS as Address;
const recipient = (process.env.RECIPIENT as Address) || account.address;
// IPFS yüklemesi (Pinata)
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: process.env.PINATA_GATEWAY!,
});
const file = new File([buffer], path.basename(filePath), { type: guessMime(filePath) });
const fileBlob = new Blob([fs.readFileSync(filePath)], { type: guessMime(filePath) });
const fileObj = new File([fileBlob], path.basename(filePath), { type: guessMime(filePath) });
const up = await pinata.upload.public.file(fileObj);
const imageUri = `ipfs://${up.cid}`;
const meta = await pinata.upload.public.json({
image: imageUri
const metaBlob = new Blob([JSON.stringify(metadata, null, 2)], { type: "application/json" });
image: imageUri,
});
const metadataUri = `ipfs://${meta.cid}`;
// viem aracılığıyla zincirde basım
const txHash = await walletClient.writeContract({
address,
abi,
functionName: 'safeMint',
args: [recipient, metadataUri],
});
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
const ZERO = '0x0000000000000000000000000000000000000000';
const logs = parseEventLogs({ abi, logs: receipt.logs, eventName: 'Transfer' });
const mintLog = logs.find(l => (l.args as any).from?.toLowerCase?.() === ZERO);
const tokenId = mintLog ? (mintLog.args as any).tokenId : undefined;
console.log('tx:', txHash, '| tokenId:', tokenId ?? '(not parsed)', '| tokenURI:', metadataUri);
}
main().catch(err => (console.error(err), process.exit(1)));
Bir NFT koleksiyonu mintleme
import path from 'path';
import { createThirdwebClient, getContract, sendTransaction, waitForReceipt, parseEventLogs } from "thirdweb";
import { defineChain } from "thirdweb/chains";
// import { Blob } from 'buffer'; // Node 18: Blob elde etmek için bir sonraki satırın yorumunu kaldırın.
import { createWalletClient, createPublicClient, http, parseEventLogs } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import type { Address } from 'viem';
import { chiliz, spicy } from 'viem/chains';
import { PinataSDK } from 'pinata';
// Minimal ABI: safeMint(to, uri) + tokenURI + Transfer
const abi = [
{ type: 'function', name: 'safeMint', stateMutability: 'nonpayable',
inputs: [{ name: 'to', type: 'address' }, { name: 'uri', type: 'string' }], outputs: [] },
{ type: 'function', name: 'tokenURI', stateMutability: 'view',
inputs: [{ name: 'tokenId', type: 'uint256' }], outputs: [{ type: 'string' }] },
{ type: 'event', name: 'Transfer',
inputs: [
{ name: 'from', type: 'address', indexed: true },
{ name: 'to', type: 'address', indexed: true },
{ name: 'tokenId', type: 'uint256', indexed: true },
]},
] as const;
if (ext === ".png") return "image/png";
if (ext === ".jpg" || ext === ".jpeg") return "image/jpeg";
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';
}
const chain = defineChain(Number(process.env.CHAIN_ID)); // 88888 veya 88882
// Ağınızı seçin: Chiliz testnet için `spicy` kullanın, Mainnet için `chiliz`'e geçin.
const chain = spicy; // Mainnet için `chiliz` ile değiştirin
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({ account, chain, transport: http() });
const publicClient = createPublicClient({ chain, transport: http() });
const address = process.env.CONTRACT_ADDRESS as Address;
const recipient = (process.env.RECIPIENT as Address) || account.address;
// IPFS yüklemesi (Pinata)
const pinata = new PinataSDK({
pinataJwt: process.env.PINATA_JWT!,
pinataGateway: process.env.PINATA_GATEWAY!, // isteğe bağlı; ipfs:// URI'ları için gerekli değil
});
const file = new File([buffer], path.basename(filePath), { type: guessMime(filePath) });
const fileBlob = new Blob([fs.readFileSync(filePath)], { type: guessMime(filePath) });
// Bir Blob'u doğrudan iletin
const up = await pinata.upload.public.file(fileBlob);
const imageUri = `ipfs://${up.cid}`;
const meta = await pinata.upload.public.json({
image: imageUri
const metaBlob = new Blob([JSON.stringify(metadata, null, 2)], { type: "application/json" });
image: imageUri,
});
const metadataUri = `ipfs://${meta.cid}`;
// viem aracılığıyla zincirde basım
const txHash = await walletClient.writeContract({
address,
abi,
functionName: 'safeMint',
args: [recipient, metadataUri],
});
const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
const ZERO = '0x0000000000000000000000000000000000000000';
const logs = parseEventLogs({ abi, logs: receipt.logs, eventName: 'Transfer' });
const mintLog = logs.find(l => (l.args as any).from?.toLowerCase?.() === ZERO);
const tokenId = mintLog ? (mintLog.args as any).tokenId : undefined;
console.log('tx:', txHash, '| tokenId:', tokenId ?? '(not parsed)', '| tokenURI:', metadataUri);
}
main().catch(err => (console.error(err), process.exit(1)));
Last updated
Was this helpful?