kamiweb3-sdk
Version:
TypeScript SDK for KAMI721-C, KAMI721-AC, and KAMI1155-C smart contracts
173 lines • 9.98 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ERC721CFactory = void 0;
const ethers_1 = require("ethers");
// Import the wrapper class
const ERC721CWrapper_1 = require("../contracts/ERC721CWrapper");
// Import the standard implementation artifact
const KAMI721C_json_1 = __importDefault(require("../abis/KAMI721C.json"));
// Import the upgradeable implementation artifact
const KAMI721CUpgradeable_json_1 = __importDefault(require("../abis/KAMI721CUpgradeable.json"));
// --- Assume OpenZeppelin Artifacts are available ---
// You need to place these JSON files (with abi and bytecode) in the specified path
const ProxyAdmin_json_1 = __importDefault(require("../abis/openzeppelin/ProxyAdmin.json"));
const TransparentUpgradeableProxy_json_1 = __importDefault(require("../abis/openzeppelin/TransparentUpgradeableProxy.json"));
class ERC721CFactory {
/**
* Attaches to an existing standard ERC721C contract.
* @param address The address of the deployed ERC721C contract.
* @param signerOrProvider A Signer (for transactions) or Provider (for read-only).
* @returns An ERC721CWrapper instance using the standard ABI.
*/
static attach(address, signerOrProvider) {
// Call constructor without specific ABI to use the default (standard)
return new ERC721CWrapper_1.ERC721CWrapper(address, signerOrProvider);
}
/**
* Attaches to an existing upgradeable ERC721C contract (proxy).
* @param proxyAddress The address of the deployed proxy contract.
* @param signerOrProvider A Signer (for transactions) or Provider (for read-only).
* @returns An ERC721CWrapper instance using the upgradeable ABI.
*/
static attachUpgradeable(proxyAddress, signerOrProvider) {
// Pass the Upgradeable ABI explicitly to the constructor
const upgradeableAbi = KAMI721CUpgradeable_json_1.default.abi;
if (!upgradeableAbi)
throw new Error('Upgradeable ABI not found');
return new ERC721CWrapper_1.ERC721CWrapper(proxyAddress, signerOrProvider, upgradeableAbi);
}
/**
* Deploys a new standard (non-upgradeable) ERC721C contract.
* @param args The deployment arguments based on the contract constructor.
* @param signer The signer to use for deployment.
* @returns A Promise resolving to an ERC721CWrapper instance of the deployed contract.
*/
static async deploy(args, signer) {
if (!signer) {
throw new Error('Signer is required for deployment.');
}
// Extract ABI and bytecode from the standard artifact
const abi = KAMI721C_json_1.default.abi;
const bytecode = KAMI721C_json_1.default.bytecode;
if (!abi || abi.length === 0) {
throw new Error('ABI not found in KAMI721C artifact.');
}
if (!bytecode || bytecode === '0x' || bytecode === '') {
throw new Error('Bytecode not found or is invalid in KAMI721C artifact.');
}
const factory = new ethers_1.ContractFactory(abi, bytecode, signer);
console.log('Deploying KAMI721C (standard) with arguments:', {
usdcAddress: args.usdcAddress,
name: args.name,
symbol: args.symbol,
baseURI: args.baseURI,
initialMintPrice: args.initialMintPrice.toString(),
platformAddress: args.platformAddress,
platformCommissionPercentage: args.platformCommissionPercentage.toString(),
});
try {
const contract = await factory.deploy(args.usdcAddress, args.name, args.symbol, args.baseURI, args.initialMintPrice, args.platformAddress, args.platformCommissionPercentage);
await contract.waitForDeployment();
const deployedAddress = await contract.getAddress();
console.log(`KAMI721C (standard) deployed to: ${deployedAddress}`);
// Return wrapper using the standard ABI
return new ERC721CWrapper_1.ERC721CWrapper(deployedAddress, signer, KAMI721C_json_1.default.abi);
}
catch (error) {
console.error('KAMI721C (standard) deployment failed:', error);
if (error instanceof Error) {
throw new Error(`KAMI721C (standard) deployment failed: ${error.message}`);
}
throw new Error('KAMI721C (standard) deployment failed with an unknown error.');
}
}
/**
* Deploys a new upgradeable ERC721C contract using the Transparent Proxy pattern.
* @param initArgs The arguments for the initializer function.
* @param signer The signer to use for deployment.
* @param proxyAdminOwner (Optional) The address that will own the ProxyAdmin. Defaults to the signer.
* @returns A Promise resolving to an ERC721CWrapper instance attached to the proxy address.
*/
static async deployUpgradeable(initArgs, signer, proxyAdminOwner) {
if (!signer) {
throw new Error('Signer is required for deployment.');
}
const signerAddress = await signer.getAddress();
const adminOwner = proxyAdminOwner ? proxyAdminOwner.toString() : signerAddress;
// 1. Deploy Implementation Contract
const implFactory = new ethers_1.ContractFactory(KAMI721CUpgradeable_json_1.default.abi, KAMI721CUpgradeable_json_1.default.bytecode, signer);
console.log('Deploying KAMI721CUpgradeable implementation...');
const implementation = await implFactory.deploy();
await implementation.waitForDeployment();
const implementationAddress = await implementation.getAddress();
console.log(`Implementation deployed to: ${implementationAddress}`);
// 2. Deploy ProxyAdmin Contract
const proxyAdminFactory = new ethers_1.ContractFactory(ProxyAdmin_json_1.default.abi, ProxyAdmin_json_1.default.bytecode, signer);
console.log(`Deploying ProxyAdmin (owner: ${adminOwner})...`);
const proxyAdminContract = await proxyAdminFactory.deploy();
await proxyAdminContract.waitForDeployment();
const proxyAdminAddress = await proxyAdminContract.getAddress();
// Ensure the contract instance is typed correctly for the transferOwnership call
const proxyAdmin = new ethers_1.Contract(proxyAdminAddress, ProxyAdmin_json_1.default.abi, signer);
// Transfer ownership if a different owner was specified
if (adminOwner.toLowerCase() !== signerAddress.toLowerCase()) {
console.log(`Transferring ProxyAdmin ownership to ${adminOwner}...`);
const tx = await proxyAdmin.transferOwnership(adminOwner);
await tx.wait();
console.log('ProxyAdmin ownership transferred.');
}
console.log(`ProxyAdmin deployed to: ${proxyAdminAddress}`);
// 3. Encode Initializer Data
const implementationInterface = new ethers_1.Interface(KAMI721CUpgradeable_json_1.default.abi);
const initializeData = implementationInterface.encodeFunctionData('initialize', [
initArgs.usdcAddress,
initArgs.name,
initArgs.symbol,
initArgs.baseURI,
initArgs.initialMintPrice,
initArgs.platformAddress,
initArgs.platformCommissionPercentage,
]);
console.log('Encoded initialize data:', initializeData);
// 4. Deploy TransparentUpgradeableProxy Contract
const proxyFactory = new ethers_1.ContractFactory(TransparentUpgradeableProxy_json_1.default.abi, TransparentUpgradeableProxy_json_1.default.bytecode, signer);
console.log('Deploying TransparentUpgradeableProxy...');
const proxy = await proxyFactory.deploy(implementationAddress, proxyAdminAddress, initializeData);
await proxy.waitForDeployment();
const proxyAddress = await proxy.getAddress();
console.log(`TransparentUpgradeableProxy deployed to: ${proxyAddress}`);
// 5. Return Wrapper attached to Proxy using Implementation ABI
console.log('Attaching wrapper to proxy...');
// Use the correct Upgradeable ABI for the wrapper when interacting via proxy
return new ERC721CWrapper_1.ERC721CWrapper(proxyAddress, signer, KAMI721CUpgradeable_json_1.default.abi);
}
/**
* Initiates an upgrade of a transparent proxy to a new implementation contract.
* Note: This only deploys the new implementation. The actual upgrade call must be made
* via the ProxyAdmin contract, typically by the ProxyAdmin owner.
* @param proxyAddress The address of the proxy contract to upgrade.
* @param signer The signer to deploy the new implementation.
* @returns The address of the newly deployed implementation contract.
*/
static async deployNewImplementation(signer) {
if (!signer) {
throw new Error('Signer is required for deployment.');
}
// Deploy the new implementation
const implFactory = new ethers_1.ContractFactory(KAMI721CUpgradeable_json_1.default.abi, KAMI721CUpgradeable_json_1.default.bytecode, signer);
console.log('Deploying new KAMI721CUpgradeable implementation...');
const newImplementation = await implFactory.deploy();
await newImplementation.waitForDeployment();
const newImplementationAddress = await newImplementation.getAddress();
console.log(`New implementation deployed to: ${newImplementationAddress}`);
console.warn(`IMPORTANT: New implementation deployed to ${newImplementationAddress}. ` +
`To complete the upgrade, the ProxyAdmin owner must call 'upgrade(proxyAddress, newImplementationAddress)' ` +
`on the ProxyAdmin contract.`);
return newImplementationAddress;
}
}
exports.ERC721CFactory = ERC721CFactory;
//# sourceMappingURL=ERC721CFactory.js.map