UNPKG

kamiweb3-sdk

Version:

TypeScript SDK for KAMI721-C, KAMI721-AC, and KAMI1155-C smart contracts

398 lines 17.9 kB
"use strict"; 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.ERC721ACWrapper = void 0; const ethers_1 = require("ethers"); const types_1 = require("../types"); const KAMI721AC_json_1 = __importDefault(require("../abis/KAMI721AC.json")); const ethers = __importStar(require("ethers")); /** * Wraps an instance of the KAMI721AC contract (standard or upgradeable proxy) to provide typed methods. */ class ERC721ACWrapper { /** * Creates an instance of ERC721ACWrapper. * @param address The address of the standard contract or the proxy contract. * @param signerOrProvider A Signer (for transactions) or Provider (for read-only). * @param contractAbi (Optional) The ABI to use. Defaults to the standard KAMI721AC ABI. Provide the KAMI721ACUpgradeable ABI when attaching to a proxy. */ constructor(address, signerOrProvider, contractAbi) { // Use provided ABI or default to standard KAMI721AC ABI this.abi = contractAbi || KAMI721AC_json_1.default.abi; if (!this.abi || this.abi.length === 0) { if (!contractAbi && (!KAMI721AC_json_1.default || !KAMI721AC_json_1.default.abi)) { throw new Error('Default KAMI721AC ABI not found or invalid.'); } else { throw new Error('Provided ABI is invalid or ABI not found.'); } } this.contract = new ethers_1.Contract(address.toString(), this.abi, signerOrProvider); this.address = address.toString(); } // === Core ERC721 Functions (including ERC721A overrides) === /** * Returns the number of tokens in `owner`'s account. * @throws {Error} If owner is the zero address. */ async balanceOf(owner) { if (owner === ethers_1.ZeroAddress) throw new Error('ERC721: balance query for the zero address'); return this.contract.getFunction('balanceOf')(owner); } /** * Returns the owner of the `tokenId` token. * @throws {Error} If the token does not exist. */ async ownerOf(tokenId) { return this.contract.getFunction('ownerOf')(tokenId); } /** * Safely transfers `tokenId` token from `from` to `to`. * @throws {Error} If caller is not owner nor approved, or if `to` is zero address. */ async safeTransferFrom(from, to, tokenId, data = '0x', overrides = {}) { this.requireSigner(); if (to === ethers_1.ZeroAddress) throw new Error('ERC721: transfer to the zero address'); // ERC721A uses the same signatures for safeTransferFrom if (data && data !== '0x' && ethers.getBytes(data).length > 0) { return this.contract.getFunction('safeTransferFrom(address,address,uint256,bytes)')(from, to, tokenId, data, overrides); } else { return this.contract.getFunction('safeTransferFrom(address,address,uint256)')(from, to, tokenId, overrides); } } /** * Transfers `tokenId` token from `from` to `to`. * Note: Usage of this method is discouraged, use `safeTransferFrom` whenever possible. * @throws {Error} If caller is not owner nor approved, or if `to` is zero address. */ async transferFrom(from, to, tokenId, overrides = {}) { this.requireSigner(); if (to === ethers_1.ZeroAddress) throw new Error('ERC721: transfer to the zero address'); return this.contract.getFunction('transferFrom')(from, to, tokenId, overrides); } /** * Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * @throws {Error} If `to` is the zero address. */ async approve(to, tokenId, overrides = {}) { this.requireSigner(); if (to === ethers_1.ZeroAddress) throw new Error('ERC721: approve to the zero address'); return this.contract.getFunction('approve')(to, tokenId, overrides); } /** * Returns the account approved for `tokenId` token. * @throws {Error} If the token does not exist. */ async getApproved(tokenId) { return this.contract.getFunction('getApproved')(tokenId); } /** * Approve or remove `operator` as an operator for the caller. Operators can call transferFrom or safeTransferFrom for any token owned by the caller. */ async setApprovalForAll(operator, approved, overrides = {}) { this.requireSigner(); return this.contract.getFunction('setApprovalForAll')(operator, approved, overrides); } /** * Returns if the `operator` is allowed to manage all of the assets of `owner`. */ async isApprovedForAll(owner, operator) { return this.contract.getFunction('isApprovedForAll')(owner, operator); } /** * Returns the token collection name. */ async name() { return this.contract.getFunction('name')(); } /** * Returns the token collection symbol. */ async symbol() { return this.contract.getFunction('symbol')(); } /** * Returns the Uniform Resource Identifier (URI) for `tokenId` token. * @throws {Error} If the token does not exist. */ async tokenURI(tokenId) { return this.contract.getFunction('tokenURI')(tokenId); } /** * Returns the total amount of tokens minted in the contract. * (ERC721A provides this) */ async totalSupply() { return this.contract.getFunction('totalSupply')(); } /** * Returns the next token ID to be minted. * (Available in ERC721A-based contracts like KAMI721AC) */ async nextTokenId() { return this.contract.getFunction('nextTokenId')(); } // Note: ERC721A does not include tokenOfOwnerByIndex or tokenByIndex // It might include view functions like _numberMinted(address), _numberBurned(address), startTokenId() // Add them here if needed based on detailed ABI review or usage requirements. // Example: // async numberMinted(owner: AddressLike): Promise<bigint> { // return this.contract.getFunction('_numberMinted')(owner); // } // === ERC2981 Royalty Standard === /** * Returns the royalty information for a given token ID and sale price. * @throws {Error} If token does not exist. */ async royaltyInfo(tokenId, salePrice) { const [receiver, royaltyAmount] = await this.contract.getFunction('royaltyInfo')(tokenId, salePrice); return { receiver, royaltyAmount }; } // === KAMI Core Functions === /** * Mints one or more new NFTs to the caller's address. * Requires the sender to have approved the contract for the total USDC cost. * @param quantity The number of NFTs to mint (must be > 0). * @param overrides Optional transaction overrides. * @returns A promise that resolves to the transaction response. */ async mint(quantity, overrides = {}) { this.requireSigner(); const quant = BigInt(quantity.toString()); if (quant <= 0) throw new Error('Quantity must be greater than zero'); // KAMI721AC ABI confirms mint(uint256 quantity) return this.contract.getFunction('mint')(quant, overrides); } /** * Allows users to claim tokens (e.g., airdrop) to the caller's address. * Requires the sender to have approved the contract for the total USDC cost. * Assumes claim conditions are handled internally or off-chain. * @param quantity The number of tokens to claim (must be > 0). * @param overrides Optional transaction overrides. * @returns A promise that resolves to the transaction response. */ async claim(quantity, overrides = {}) { this.requireSigner(); const quant = BigInt(quantity.toString()); if (quant <= 0) throw new Error('Quantity must be greater than zero'); // KAMI721AC ABI confirms claim(uint256 quantity) return this.contract.getFunction('claim')(quant, overrides); } /** * Sells an NFT from the owner (or approved operator) to a buyer. * Requires seller approval and buyer USDC allowance. * @throws {Error} If `to` is the zero address. * @param to The address of the buyer. * @param tokenId The ID of the token being sold. * @param salePrice The price in the smallest unit of USDC. * @param overrides Optional transaction overrides. * @returns A promise that resolves to the transaction response. */ async sellToken(to, tokenId, salePrice, overrides = {}) { this.requireSigner(); if (to === ethers_1.ZeroAddress) throw new Error('Cannot sell token to the zero address'); return this.contract.getFunction('sellToken')(to, tokenId, salePrice, overrides); } // === KAMI Royalty Management === /** Sets default mint royalties. Requires OWNER_ROLE. */ async setMintRoyalties(royalties, overrides = {}) { this.requireSigner(); await this.requireRole(types_1.OWNER_ROLE); return this.contract.getFunction('setMintRoyalties')(royalties, overrides); } /** Sets default transfer royalties. Requires OWNER_ROLE. */ async setTransferRoyalties(royalties, overrides = {}) { this.requireSigner(); await this.requireRole(types_1.OWNER_ROLE); return this.contract.getFunction('setTransferRoyalties')(royalties, overrides); } /** Sets token-specific mint royalties. Requires OWNER_ROLE. */ async setTokenMintRoyalties(tokenId, royalties, overrides = {}) { this.requireSigner(); await this.requireRole(types_1.OWNER_ROLE); return this.contract.getFunction('setTokenMintRoyalties')(tokenId, royalties, overrides); } /** Sets token-specific transfer royalties. Requires OWNER_ROLE. */ async setTokenTransferRoyalties(tokenId, royalties, overrides = {}) { this.requireSigner(); await this.requireRole(types_1.OWNER_ROLE); return this.contract.getFunction('setTokenTransferRoyalties')(tokenId, royalties, overrides); } /** Gets mint royalty receivers for a token. */ async getMintRoyaltyReceivers(tokenId) { // Consider adding ownerOf check if needed before calling return this.contract.getFunction('getMintRoyaltyReceivers')(tokenId); } /** Gets transfer royalty receivers for a token. */ async getTransferRoyaltyReceivers(tokenId) { return this.contract.getFunction('getTransferRoyaltyReceivers')(tokenId); } // === KAMI Configuration === /** Sets the mint price. Requires OWNER_ROLE. */ async setMintPrice(newMintPrice, overrides = {}) { this.requireSigner(); await this.requireRole(types_1.OWNER_ROLE); return this.contract.getFunction('setMintPrice')(newMintPrice, overrides); } /** Gets the current mint price. */ async getMintPrice() { return this.contract.getFunction('getMintPrice')(); } /** Sets the platform commission percentage and address. Requires OWNER_ROLE. */ async setPlatformCommission(newPercentage, newPlatformAddress, overrides = {}) { this.requireSigner(); await this.requireRole(types_1.OWNER_ROLE); if (newPlatformAddress === ethers_1.ZeroAddress) throw new Error('Platform address cannot be the zero address'); return this.contract.getFunction('setPlatformCommission')(newPercentage, newPlatformAddress, overrides); } /** Gets the current platform address for commissions. */ async getPlatformAddress() { return this.contract.getFunction('getPlatformAddress')(); } /** Gets the current platform commission percentage (basis points). */ async getPlatformCommissionPercentage() { return this.contract.getFunction('getPlatformCommissionPercentage')(); } /** Sets the base URI for metadata. Requires OWNER_ROLE. */ async setBaseURI(baseURI, overrides = {}) { this.requireSigner(); await this.requireRole(types_1.OWNER_ROLE); return this.contract.getFunction('setBaseURI')(baseURI, overrides); } /** Gets the current base URI for metadata. */ async getBaseURI() { return this.contract.getFunction('getBaseURI')(); } /** Gets the address of the USDC contract used. */ async usdc() { return this.contract.getFunction('usdc')(); } // === KAMI Administrative === /** Pauses the contract. Requires PAUSER_ROLE. */ async pause(overrides = {}) { this.requireSigner(); await this.requireRole(types_1.PAUSER_ROLE); return this.contract.getFunction('pause')(...[], overrides); } /** Returns true if the contract is paused. */ async paused() { return this.contract.getFunction('paused')(); } /** Unpauses the contract. Requires PAUSER_ROLE. */ async unpause(overrides = {}) { this.requireSigner(); await this.requireRole(types_1.PAUSER_ROLE); return this.contract.getFunction('unpause')(...[], overrides); } /** Burns (destroys) a specific token. Requires caller to be owner or approved. */ async burn(tokenId, overrides = {}) { this.requireSigner(); // KAMI721AC ABI uses burn(tokenId), not burn(quantity) // Contract internally checks ownership/approval return this.contract.getFunction('burn')(tokenId, overrides); } // === Access Control === /** Checks if an account has a specific role. */ async hasRole(role, account) { return this.contract.getFunction('hasRole')(role, account); } /** Gets the admin role for a specific role. */ async getRoleAdmin(role) { return this.contract.getFunction('getRoleAdmin')(role); } /** Grants a role to an account. Requires caller to have the admin role for the role being granted. */ async grantRole(role, account, overrides = {}) { this.requireSigner(); const adminRole = await this.getRoleAdmin(role); await this.requireRole(adminRole, `Caller must have admin role (${adminRole}) to grant role ${role}`); return this.contract.getFunction('grantRole')(role, account, overrides); } /** Revokes a role from an account. Requires caller to have the admin role for the role being revoked. */ async revokeRole(role, account, overrides = {}) { this.requireSigner(); const adminRole = await this.getRoleAdmin(role); await this.requireRole(adminRole, `Caller must have admin role (${adminRole}) to revoke role ${role}`); return this.contract.getFunction('revokeRole')(role, account, overrides); } /** Renounces a role for the caller's own account. */ async renounceRole(role, overrides = {}) { // Note: The ABI has renounceRole(bytes32 role, address account), // but OZ's standard implementation prevents renouncing for others. // We get the caller's address to pass as the account argument. const signer = this.requireSigner(); const callerAddress = await signer.getAddress(); return this.contract.getFunction('renounceRole')(role, callerAddress, overrides); } // === Helper Methods === requireSigner() { const runner = this.contract.runner; if (!runner || runner.provider === null) { throw new Error('A signer is required for this operation.'); } return runner; } async requireRole(role, errorMessage) { const signer = this.requireSigner(); const address = await signer.getAddress(); if (!(await this.hasRole(role, address))) { throw new Error(errorMessage || `Caller does not have required role: ${role}`); } } /** * Connects a different signer or provider to the contract wrapper. * Preserves the ABI used when the original wrapper was created. * @param signerOrProvider The new signer or provider. * @returns A new ERC721ACWrapper instance connected with the new signer/provider. */ connect(signerOrProvider) { // Pass the existing ABI to the new instance return new ERC721ACWrapper(this.address, signerOrProvider, this.abi); } } exports.ERC721ACWrapper = ERC721ACWrapper; //# sourceMappingURL=ERC721ACWrapper.js.map