UNPKG

@paulstinchcombe/kami721c-sdk

Version:

SDK for interacting with KAMI721C NFT contracts

179 lines (178 loc) 10.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ethers_1 = require("ethers"); const KAMI721CFactory_1 = require("../factories/KAMI721CFactory"); const console_colors_1 = require("../utils/console-colors"); const dotenv_1 = __importDefault(require("dotenv")); dotenv_1.default.config(); // === Configuration === const RPC_URL = process.env.RPC_URL; const PRIVATE_KEY = process.env.PRIVATE_KEY; const USDC_ADDRESS = process.env.USDC_ADDRESS; const RECEIVER_1 = process.env.ROYALTY_RECEIVER_1; const RECEIVER_2 = process.env.ROYALTY_RECEIVER_2; const RECEIVER_3 = process.env.ROYALTY_RECEIVER_3; const BASE_RENTAL_PRICE = process.env.BASE_RENTAL_PRICE_PER_DAY ? BigInt(process.env.BASE_RENTAL_PRICE_PER_DAY) : 2000000n; // Default 2 USDC // Minimal ABI for USDC interactions const USDC_ABI = [ 'function approve(address spender, uint256 amount) external returns (bool)', 'function allowance(address owner, address spender) external view returns (uint256)', 'function decimals() external view returns (uint8)', ]; // --- 1. Deploy Contract Function --- async function deployContract(wallet) { console_colors_1.colorLog.section('1. Deploying Contract'); if (!USDC_ADDRESS) throw new Error('USDC_ADDRESS environment variable is required.'); const factory = new KAMI721CFactory_1.KAMI721CFactory(wallet); const platformAddress = process.env.PLATFORM_ADDRESS || wallet.address; const platformCommission = process.env.PLATFORM_COMMISSION_PERCENTAGE ? parseInt(process.env.PLATFORM_COMMISSION_PERCENTAGE) : 500; // 5% const initialMintPrice = process.env.MINT_PRICE ? BigInt(process.env.MINT_PRICE) : 1000000n; // 1 USDC const name = process.env.CONTRACT_NAME || 'KAMI Setup Example'; const symbol = process.env.CONTRACT_SYMBOL || 'KSE'; const baseURI = process.env.BASE_URI || 'https://api.example.com/setup/'; console.log('Deploying upgradeable contract via proxy with parameters:'); console.log((0, console_colors_1.formatKeyValue)('USDC Address', USDC_ADDRESS)); console.log((0, console_colors_1.formatKeyValue)('Name', name)); console.log((0, console_colors_1.formatKeyValue)('Symbol', symbol)); console.log((0, console_colors_1.formatKeyValue)('Base URI', baseURI)); console.log((0, console_colors_1.formatKeyValue)('Initial Mint Price', `${ethers_1.ethers.formatUnits(initialMintPrice, 6)} USDC`)); console.log((0, console_colors_1.formatKeyValue)('Platform Address', platformAddress)); console.log((0, console_colors_1.formatKeyValue)('Platform Commission', `${platformCommission / 100}%`)); console.log((0, console_colors_1.formatKeyValue)('Initial Owner', wallet.address)); const nftContract = await factory.deployUpgradeable(USDC_ADDRESS, name, symbol, baseURI, initialMintPrice, platformAddress, platformCommission, wallet.address); const proxyAddress = nftContract.getAddress(); console_colors_1.colorLog.success(`Contract deployed successfully at proxy address: ${console_colors_1.logStyles.address(proxyAddress)}`); return nftContract; } // --- 2. Set Royalties Function --- async function setRoyalties(nftContract, receivers) { console_colors_1.colorLog.section('2. Setting Royalties'); if (receivers.length !== 3) { throw new Error('This function expects exactly 3 receiver addresses.'); } // Assuming equal split (3333 basis points each, summing to 9999) const royaltyData = [ { receiver: receivers[0], feeNumerator: 3333n }, { receiver: receivers[1], feeNumerator: 3333n }, { receiver: receivers[2], feeNumerator: 3333n }, ]; const transferRoyaltyPercentage = 1000; // 10% for transfers console.log(`Setting mint royalties for 3 receivers: ${receivers.join(', ')}`); const mintTx = await nftContract.setMintRoyalties(royaltyData); console.log('Mint royalties transaction sent:', mintTx.hash); await mintTx.wait(); console_colors_1.colorLog.success('Mint royalties set successfully.'); console.log(`Setting transfer royalties for 3 receivers: ${receivers.join(', ')}`); const transferTx = await nftContract.setTransferRoyalties(royaltyData); console.log('Transfer royalties transaction sent:', transferTx.hash); await transferTx.wait(); console_colors_1.colorLog.success('Transfer royalties set successfully.'); console.log(`Setting transfer royalty percentage to ${transferRoyaltyPercentage / 100}%...`); const percentageTx = await nftContract.setRoyaltyPercentage(transferRoyaltyPercentage); console.log('Royalty percentage transaction sent:', percentageTx.hash); await percentageTx.wait(); console_colors_1.colorLog.success('Transfer royalty percentage set successfully.'); } // --- 3. Mint Token Function --- async function mintToken(nftContract, wallet) { console_colors_1.colorLog.section('3. Minting Token'); if (!USDC_ADDRESS) throw new Error('USDC_ADDRESS needed for minting.'); const mintPrice = await nftContract.mintPrice(); console.log(`Mint price: ${ethers_1.ethers.formatUnits(mintPrice, 6)} USDC`); const usdcContract = new ethers_1.Contract(USDC_ADDRESS, USDC_ABI, wallet); const decimals = await usdcContract.decimals(); // Check allowance const allowance = await usdcContract.allowance(wallet.address, nftContract.getAddress()); console.log(`Current USDC allowance: ${ethers_1.ethers.formatUnits(allowance, decimals)} USDC`); if (allowance < mintPrice) { console.log('Approving USDC spend...'); const approveTx = await usdcContract.approve(nftContract.getAddress(), mintPrice); console.log('Approval transaction sent:', approveTx.hash); await approveTx.wait(); console_colors_1.colorLog.success('USDC Approved'); } else { console.log('Sufficient USDC allowance already set.'); } // Mint console.log('Sending mint transaction...'); const mintTx = await nftContract.mint(); console.log('Mint transaction sent:', mintTx.hash); const receipt = await mintTx.wait(); console_colors_1.colorLog.success(`Token minted successfully in block ${receipt?.blockNumber}`); // Determine token ID (simplistic approach) const totalSupply = await nftContract.totalSupply(); const tokenId = totalSupply > 0n ? totalSupply - 1n : 0n; console.log(`Minted token ID (estimated): ${tokenId}`); return tokenId; } // --- 4. Prepare for Sale Function --- async function prepareForSale(nftContract, tokenId) { console_colors_1.colorLog.section('4. Preparing Token for Sale'); console.log(`Approving contract ${nftContract.getAddress()} to manage token ID ${tokenId}...`); // The owner calls approve, allowing the contract to transfer the token during sellToken const approveTx = await nftContract.approve(nftContract.getAddress(), tokenId); console.log('Approval transaction sent:', approveTx.hash); await approveTx.wait(); console_colors_1.colorLog.success(`Token ${tokenId} approved for sale via contract.`); console.log('(Note: Actual sale price is set when calling sellToken)'); } // --- 5. Log Rental Parameters Function --- async function logRentalParameters(nftContract, basePricePerDay) { console_colors_1.colorLog.section('5. Logging Rental Parameters'); const platformCommPercentage = await nftContract.getPlatformCommissionPercentage(); const commissionAmount = (basePricePerDay * platformCommPercentage) / 10000n; const totalRentalPricePerDay = basePricePerDay + commissionAmount; console.log('Example Rental Parameters (for 1 day):'); console.log((0, console_colors_1.formatKeyValue)('Base Rental Price', `${ethers_1.ethers.formatUnits(basePricePerDay, 6)} USDC`)); console.log((0, console_colors_1.formatKeyValue)('Platform Commission', `${Number(platformCommPercentage) / 100}%`)); console.log((0, console_colors_1.formatKeyValue)('Commission Amount', `${ethers_1.ethers.formatUnits(commissionAmount, 6)} USDC`)); console.log((0, console_colors_1.formatKeyValue)('Total Price (Renter Pays)', `${ethers_1.ethers.formatUnits(totalRentalPricePerDay, 6)} USDC`)); console.log('(Note: Actual rental is initiated by calling rentToken with duration and total price)'); } // --- Main Orchestration Function --- async function main() { console.log('Starting KAMI721C Deployment and Setup Script...'); if (!RPC_URL || !PRIVATE_KEY) { throw new Error('RPC_URL and PRIVATE_KEY environment variables are required.'); } if (!RECEIVER_1 || !RECEIVER_2 || !RECEIVER_3) { throw new Error('ROYALTY_RECEIVER_1, ROYALTY_RECEIVER_2, and ROYALTY_RECEIVER_3 environment variables are required.'); } const provider = new ethers_1.ethers.JsonRpcProvider(RPC_URL); const wallet = new ethers_1.ethers.Wallet(PRIVATE_KEY, provider); console_colors_1.colorLog.info(`Using wallet: ${console_colors_1.logStyles.address(wallet.address)} on network ${(await provider.getNetwork()).name}`); try { // 1. Deploy const nftContract = await deployContract(wallet); // Wait a moment for chain/indexer await new Promise((resolve) => setTimeout(resolve, 3000)); // 2. Set Royalties const royaltyReceivers = [RECEIVER_1, RECEIVER_2, RECEIVER_3]; await setRoyalties(nftContract, royaltyReceivers); // 3. Mint Token const mintedTokenId = await mintToken(nftContract, wallet); // 4. Prepare for Sale await prepareForSale(nftContract, mintedTokenId); // 5. Log Rental Parameters await logRentalParameters(nftContract, BASE_RENTAL_PRICE); console_colors_1.colorLog.section('Setup Complete!'); console.log(`Contract Address: ${nftContract.getAddress()}`); console.log(`Minted Token ID: ${mintedTokenId}`); } catch (error) { console_colors_1.colorLog.error('Script failed:'); console.error(error.message); if (error.reason) console.error('Reason:', error.reason); if (error.data) console.error('Data:', error.data); process.exit(1); } } main();