@paulstinchcombe/kami721c-sdk
Version:
SDK for interacting with KAMI721C NFT contracts
232 lines (231 loc) • 11.8 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.KAMI721CFactory = void 0;
const ethers_1 = require("ethers");
// import KAMI721CABI from '../abis/KAMI721C.json';
const KAMI721C_1 = require("../contracts/KAMI721C");
// Import ABIs for implementation and proxy
const KAMI721CUpgradeable_json_1 = __importDefault(require("../abis/KAMI721CUpgradeable/KAMI721CUpgradeable.json"));
const KAMITransparentUpgradeableProxy_json_1 = __importDefault(require("../abis/TransparentUpgradeableProxy/KAMITransparentUpgradeableProxy.json"));
/**
* Factory class for deploying KAMI721C contracts (Standard and Upgradeable via Proxy)
*/
class KAMI721CFactory {
/**
* Creates a new instance of the KAMI721C factory
* @param runner A signer or provider with deployment permissions
*/
constructor(runner) {
this.runner = runner;
// Create factory for the implementation contract
this.implementationFactory = new ethers_1.ContractFactory(KAMI721CUpgradeable_json_1.default.abi, KAMI721CUpgradeable_json_1.default.bytecode, runner);
// Create factory for the proxy contract
this.proxyFactory = new ethers_1.ContractFactory(KAMITransparentUpgradeableProxy_json_1.default.abi, KAMITransparentUpgradeableProxy_json_1.default.bytecode, runner);
}
/**
* Deploy a new KAMI721C contract (Upgradeable via Transparent Proxy)
* @param usdcAddress The address of the USDC token contract
* @param name The name of the NFT collection
* @param symbol The symbol of the NFT collection
* @param baseURI The base URI for token metadata
* @param initialMintPrice The initial mint price in USDC (with 6 decimals)
* @param platformAddress The address that will receive platform commissions (also becomes proxy admin)
* @param platformCommissionPercentage The platform commission percentage in basis points (e.g., 500 = 5%)
* @param ownerAddress The address to grant the OWNER_ROLE to initially
* @returns The deployed contract instance, interacting with the proxy
*/
async deployUpgradeable(usdcAddress, name, symbol, baseURI, initialMintPrice = 1000000n, // Default 1 USDC (6 decimals)
platformAddress, platformCommissionPercentage = 500, // Default 5%
ownerAddress) {
let finalPlatformAddress = platformAddress;
let finalOwnerAddress = ownerAddress;
// Determine deployer address if needed
let deployerAddress;
if (this.runner && 'getAddress' in this.runner) {
deployerAddress = await this.runner.getAddress();
}
else {
// If runner is not a signer, addresses must be provided
if (!finalPlatformAddress || !finalOwnerAddress) {
throw new Error('platformAddress and ownerAddress are required when using a provider');
}
}
// If addresses not provided, use the deployer's address
if (!finalPlatformAddress && deployerAddress) {
finalPlatformAddress = deployerAddress;
console.log(`Using deployer address ${deployerAddress} as platform address and proxy admin.`);
}
if (!finalOwnerAddress && deployerAddress) {
finalOwnerAddress = deployerAddress;
console.log(`Using deployer address ${deployerAddress} as initial owner.`);
}
// Ensure addresses are set
if (!finalPlatformAddress || !finalOwnerAddress) {
throw new Error('Could not determine platformAddress or ownerAddress.');
}
console.log('Deploying KAMI721CUpgradeable implementation...');
try {
const implementationContract = await this.implementationFactory.deploy({ gasLimit: 5000000 });
await implementationContract.waitForDeployment();
const implementationAddress = await implementationContract.getAddress();
console.log('Implementation contract deployed at:', implementationAddress);
// Verify deployment
const provider = this.runner.provider;
if (!provider) {
throw new Error('Runner does not have a provider.');
}
const code = await provider.getCode(implementationAddress);
if (!code || code === '0x') {
throw new Error('Implementation deployment failed - no code at address');
}
// Prepare initialization calldata
const implementationInterface = new ethers_1.Interface(KAMI721CUpgradeable_json_1.default.abi);
const initializeData = implementationInterface.encodeFunctionData('initialize', [
usdcAddress,
name,
symbol,
baseURI,
initialMintPrice,
finalPlatformAddress,
platformCommissionPercentage,
finalOwnerAddress,
]);
console.log('Prepared initialization calldata.');
// Deploy the proxy contract
console.log('Deploying KAMITransparentUpgradeableProxy...');
const proxyContract = await this.proxyFactory.deploy(implementationAddress, finalPlatformAddress, // Use platformAddress as proxy admin
initializeData, { gasLimit: 2000000 } // Gas limit for proxy deployment
);
await proxyContract.waitForDeployment();
const proxyAddress = await proxyContract.getAddress();
console.log('Proxy contract deployed at:', proxyAddress);
// Verify proxy deployment
const proxyCode = await provider.getCode(proxyAddress);
if (!proxyCode || proxyCode === '0x') {
throw new Error('Proxy deployment failed - no code at address');
}
// Return a contract instance attached to the proxy address, using the implementation ABI
console.log(`Returning contract instance attached to proxy address ${proxyAddress}`);
return new KAMI721C_1.KAMI721C(this.runner, proxyAddress, KAMI721CUpgradeable_json_1.default.abi);
}
catch (error) {
console.error('Deployment failed:', {
error: error.message,
reason: error.reason,
code: error.code,
data: error.data,
transaction: error.transaction,
});
throw error;
}
}
// Keep the old deploy method for standard (non-upgradeable) deployment if needed,
// or remove/deprecate it.
/**
* Deploy a new KAMI721C contract (Standard Non-Upgradeable Version)
* @deprecated Use deployUpgradeable instead for the proxy-based version.
* @param usdcAddress The address of the USDC token contract
* @param name The name of the NFT collection
* @param symbol The symbol of the NFT collection
* @param baseURI The base URI for token metadata
* @param initialMintPrice The initial mint price in USDC (with 6 decimals)
* @param platformAddress The address that will receive platform commissions
* @param platformCommissionPercentage The platform commission percentage in basis points (e.g., 500 = 5%)
* @returns The deployed contract instance
*/
async deployStandard(usdcAddress, name, symbol, baseURI, initialMintPrice = 1000000n, // Default 1 USDC (6 decimals)
platformAddress, platformCommissionPercentage = 500 // Default 5%
) {
console.warn('Deploying standard non-upgradeable KAMI721C. Use deployUpgradeable for proxy deployment.');
let finalPlatformAddress = platformAddress;
// If platform address not provided, use the deployer's address
if (!finalPlatformAddress) {
if (this.runner && 'getAddress' in this.runner) {
finalPlatformAddress = await this.runner.getAddress();
}
else {
throw new Error('Platform address is required when deployer address cannot be determined');
}
}
console.log('Deploying standard contract with parameters:', {
usdcAddress,
name,
symbol,
baseURI,
initialMintPrice,
finalPlatformAddress,
platformCommissionPercentage,
});
// Use the original KAMI721C ABI/Bytecode for standard deployment
// Assuming the old ABI is still needed and available
const standardCompiledContract = await Promise.resolve().then(() => __importStar(require('../abis/KAMI721C/KAMI721C.json')));
const standardFactory = new ethers_1.ContractFactory(standardCompiledContract.abi, standardCompiledContract.bytecode, this.runner);
try {
console.log('Creating standard deployment transaction...');
const contract = (await standardFactory.deploy(usdcAddress, name, symbol, baseURI, initialMintPrice, finalPlatformAddress, platformCommissionPercentage, { gasLimit: 5000000 }));
console.log('Waiting for standard deployment transaction to be mined...');
await contract.waitForDeployment();
const address = await contract.getAddress();
console.log('Standard contract deployed at address:', address);
// Verify the contract was deployed successfully
console.log('Verifying standard contract deployment...');
const provider = this.runner.provider;
if (!provider) {
throw new Error('Runner does not have a provider.');
}
const code = await provider.getCode(address);
if (!code || code === '0x') {
throw new Error('Standard contract deployment failed - no code at contract address');
}
console.log('Standard contract code verified successfully');
return new KAMI721C_1.KAMI721C(this.runner, address, standardCompiledContract.abi);
}
catch (error) {
console.error('Standard deployment failed:', {
error: error.message,
reason: error.reason,
code: error.code,
data: error.data,
transaction: error.transaction,
});
throw error;
}
}
}
exports.KAMI721CFactory = KAMI721CFactory;