kamiweb3-sdk
Version:
TypeScript SDK for KAMI721-C, KAMI721-AC, and KAMI1155-C smart contracts
351 lines • 15.8 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ERC1155CWrapper = void 0;
const ethers_1 = require("ethers");
const types_1 = require("../types");
const KAMI1155C_json_1 = __importDefault(require("../abis/KAMI1155C.json"));
/**
* Wraps an instance of the KAMI1155C contract (standard or upgradeable proxy) to provide typed methods.
*/
class ERC1155CWrapper {
/**
* Creates an instance of ERC1155CWrapper.
* @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 KAMI1155C ABI. Provide the KAMI1155CUpgradeable ABI when attaching to a proxy.
*/
constructor(address, signerOrProvider, contractAbi) {
// Use provided ABI or default to standard KAMI1155C ABI
this.abi = contractAbi || KAMI1155C_json_1.default.abi;
if (!this.abi || this.abi.length === 0) {
if (!contractAbi && (!KAMI1155C_json_1.default || !KAMI1155C_json_1.default.abi)) {
throw new Error('Default KAMI1155C 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 ERC1155 Functions ===
/**
* Gets the balance of a specific token ID for an account.
* @param account The address of the account.
* @param id The ID of the token.
* @returns A promise that resolves to the balance.
*/
async balanceOf(account, id) {
return this.contract.getFunction('balanceOf')(account, id);
}
/**
* Gets the balances of multiple token IDs for multiple accounts.
* @param accounts An array of account addresses.
* @param ids An array of token IDs.
* @returns A promise that resolves to an array of balances.
*/
async balanceOfBatch(accounts, ids) {
if (accounts.length !== ids.length) {
throw new Error('accounts and ids arrays must have the same length');
}
return this.contract.getFunction('balanceOfBatch')(accounts, ids);
}
/**
* Safely transfers tokens from one address to another.
* Requires the caller to be the owner, approved, or the approved operator.
* @param from The address to transfer from.
* @param to The address to transfer to.
* @param id The ID of the token to transfer.
* @param amount The amount of tokens to transfer.
* @param data Additional data with no specified format.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async safeTransferFrom(from, to, id, amount, data, overrides = {}) {
this.requireSigner();
const tx = await this.contract.getFunction('safeTransferFrom')(from, to, id, amount, data, overrides);
return tx;
}
/**
* Safely transfers multiple token types from one address to another.
* Requires the caller to be the owner, approved, or the approved operator.
* @param from The address to transfer from.
* @param to The address to transfer to.
* @param ids An array of token IDs to transfer.
* @param amounts An array of amounts corresponding to each token ID.
* @param data Additional data with no specified format.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async safeBatchTransferFrom(from, to, ids, amounts, data, overrides = {}) {
this.requireSigner();
if (ids.length !== amounts.length) {
throw new Error('ids and amounts arrays must have the same length');
}
const tx = await this.contract.getFunction('safeBatchTransferFrom')(from, to, ids, amounts, data, overrides);
return tx;
}
/**
* Enables or disables approval for a third party ("operator") to manage all of the caller's tokens.
* @param operator Address to add to the set of authorized operators.
* @param approved True if the operator is approved, false to revoke approval.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async setApprovalForAll(operator, approved, overrides = {}) {
this.requireSigner();
const tx = await this.contract.getFunction('setApprovalForAll')(operator, approved, overrides);
return tx;
}
/**
* Queries the approval status of an operator for a given owner.
* @param owner The owner of the tokens.
* @param operator The address of the operator.
* @returns True if the operator is approved, false otherwise.
*/
async isApprovedForAll(owner, operator) {
return this.contract.getFunction('isApprovedForAll')(owner, operator);
}
/**
* Returns the URI for a given token ID.
* @param id The ID of the token.
* @returns A promise that resolves to the URI string.
*/
async uri(id) {
return this.contract.getFunction('uri')(id);
}
async supportsInterface(interfaceId) {
return this.contract.getFunction('supportsInterface')(interfaceId);
}
// === KAMI Specific Functions ===
/**
* Mints new tokens of a specific ID to a specified address.
* Requires MINTER_ROLE.
* Requires the platform to have approved the contract for the total USDC cost if applicable (verify fee logic).
* @param to The address to mint to.
* @param id The ID of the token to mint.
* @param amount The amount of tokens to mint.
* @param data Optional data field.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async mint(to, id, amount, data = '0x', overrides = {}) {
this.requireSigner();
return this.contract.getFunction('mint')(to, id, amount, data, overrides);
}
/**
* Mints batches of tokens to a specified address.
* Requires MINTER_ROLE.
* @param to The address to mint to.
* @param ids Array of token IDs to mint.
* @param amounts Array of amounts corresponding to IDs.
* @param data Optional data field.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async mintBatch(to, ids, amounts, data = '0x', overrides = {}) {
this.requireSigner();
if (ids.length !== amounts.length) {
throw new Error('ids and amounts arrays must have the same length');
}
return this.contract.getFunction('mintBatch')(to, ids, amounts, data, overrides);
}
/**
* Sells tokens from the owner to a buyer.
* Requires the seller (signer) to own or be approved for the tokens.
* Requires the buyer to have approved the contract to spend the salePrice in USDC.
* @param to The address of the buyer.
* @param id The ID of the token being sold.
* @param amount The amount of tokens being sold.
* @param salePrice The total price for the amount in the smallest unit of USDC.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async sellToken(to, id, amount, salePrice, overrides = {}) {
this.requireSigner();
return this.contract.getFunction('sellToken')(to, id, amount, salePrice, overrides);
}
// === Rental Functions ===
/**
* Rents tokens for a specified duration.
* Requires the renter (signer) to approve the contract to spend the rentalPrice in USDC.
* @param id The ID of the token to rent.
* @param duration The rental duration in seconds.
* @param rentalPrice The price in the smallest unit of USDC.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async rentToken(id, duration, rentalPrice, overrides = {}) {
this.requireSigner();
return this.contract.getFunction('rentToken')(id, duration, rentalPrice, overrides);
}
/**
* Ends a rental period early.
* @param id The ID of the token whose rental is ending.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async endRental(id, overrides = {}) {
this.requireSigner();
return this.contract.getFunction('endRental')(id, overrides);
}
/**
* Extends an existing rental.
* Requires the renter (signer) to approve the additional payment.
* @param id The ID of the token being extended.
* @param additionalDuration Additional duration in seconds.
* @param additionalPayment Additional payment in smallest USDC unit.
* @param overrides Optional transaction overrides.
* @returns A promise that resolves to the transaction response.
*/
async extendRental(id, additionalDuration, additionalPayment, overrides = {}) {
this.requireSigner();
return this.contract.getFunction('extendRental')(id, additionalDuration, additionalPayment, overrides);
}
/**
* Gets the rental details for a specific token ID.
* @param id The token ID.
* @returns A promise resolving to the rental details.
*/
async getRentalDetails(id) {
const result = await this.contract.getFunction('getRentalDetails')(id);
return {
renter: result.renter,
rentalEndTime: result.rentalEndTime,
};
}
// === Royalty Management ===
async setMintRoyalties(royalties, overrides = {}) {
this.requireSigner();
this.requireRole(types_1.OWNER_ROLE); // Assuming OWNER_ROLE manages royalties
return this.contract.getFunction('setMintRoyalties')(royalties, overrides);
}
async setTransferRoyalties(royalties, overrides = {}) {
this.requireSigner();
this.requireRole(types_1.OWNER_ROLE);
return this.contract.getFunction('setTransferRoyalties')(royalties, overrides);
}
async setTokenMintRoyalties(id, royalties, overrides = {}) {
this.requireSigner();
this.requireRole(types_1.OWNER_ROLE);
return this.contract.getFunction('setTokenMintRoyalties')(id, royalties, overrides);
}
async setTokenTransferRoyalties(id, royalties, overrides = {}) {
this.requireSigner();
this.requireRole(types_1.OWNER_ROLE);
return this.contract.getFunction('setTokenTransferRoyalties')(id, royalties, overrides);
}
async getMintRoyaltyReceivers(id) {
return this.contract.getFunction('getMintRoyaltyReceivers')(id);
}
async getTransferRoyaltyReceivers(id) {
return this.contract.getFunction('getTransferRoyaltyReceivers')(id);
}
// === Configuration ===
async setMintPrice(newMintPrice, overrides = {}) {
this.requireSigner();
this.requireRole(types_1.OWNER_ROLE);
return this.contract.getFunction('setMintPrice')(newMintPrice, overrides);
}
async getMintPrice() {
return this.contract.getFunction('getMintPrice')();
}
async setPlatformCommission(newPercentage, newPlatformAddress, overrides = {}) {
this.requireSigner();
this.requireRole(types_1.OWNER_ROLE);
return this.contract.getFunction('setPlatformCommission')(newPercentage, newPlatformAddress, overrides);
}
async getPlatformAddress() {
return this.contract.getFunction('getPlatformAddress')();
}
async getPlatformCommissionPercentage() {
return this.contract.getFunction('getPlatformCommissionPercentage')();
}
async setBaseURI(baseURI, overrides = {}) {
this.requireSigner();
this.requireRole(types_1.OWNER_ROLE);
return this.contract.getFunction('setBaseURI')(baseURI, overrides);
}
async getBaseURI() {
return this.contract.getFunction('getBaseURI')();
}
// === Administrative ===
async pause(overrides = {}) {
this.requireSigner();
this.requireRole(types_1.PAUSER_ROLE);
return this.contract.getFunction('pause')(...[], overrides);
}
async paused() {
return this.contract.getFunction('paused')();
}
async unpause(overrides = {}) {
this.requireSigner();
this.requireRole(types_1.PAUSER_ROLE);
return this.contract.getFunction('unpause')(...[], overrides);
}
// === Access Control ===
async hasRole(role, account) {
return this.contract.getFunction('hasRole')(role, account);
}
async getRoleAdmin(role) {
return this.contract.getFunction('getRoleAdmin')(role);
}
async grantRole(role, account, overrides = {}) {
this.requireSigner();
// Requires caller to have the admin role for the role being granted
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);
}
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);
}
async renounceRole(role, account, overrides = {}) {
this.requireSigner();
// The account renouncing must be the caller
const signerAddress = await this.contract.runner.getAddress();
if (signerAddress.toLowerCase() !== account.toString().toLowerCase()) {
throw new Error('Cannot renounce role for another account.');
}
return this.contract.getFunction('renounceRole')(role, account, 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; // Cast is safe due to the check above
}
/**
* Helper to check if the current signer has a specific role.
* Throws an error if the signer is missing or lacks the role.
* @param role The role keccak256 hash (e.g., OWNER_ROLE).
* @param errorMessage Optional custom error message.
*/
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 ERC1155CWrapper instance connected with the new signer/provider.
*/
connect(signerOrProvider) {
// Pass the existing ABI to the new instance
return new ERC1155CWrapper(this.address, signerOrProvider, this.abi);
}
}
exports.ERC1155CWrapper = ERC1155CWrapper;
//# sourceMappingURL=ERC1155CWrapper.js.map