UNPKG

six-caver-js

Version:

caver-js is a JavaScript API library that allows developers to interact with a Klaytn node

543 lines (479 loc) 23.2 kB
/* Copyright 2020 The caver-js Authors This file is part of the caver-js library. The caver-js library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The caver-js library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the caver-js. If not, see <http://www.gnu.org/licenses/>. */ const _ = require('lodash') const BigNumber = require('bignumber.js') const Contract = require('../../caver-contract') const { validateDeployParameterForKIP7, determineSendParams, kip7JsonInterface, kip7ByteCode, formatParamForUint256, interfaceIds, } = require('./kctHelper') const { isAddress, toBuffer, isHexStrict, toHex } = require('../../caver-utils') const KIP13 = require('../src/kip13') class KIP7 extends Contract { /** * deploy deploys a KIP-7 token contract to Klaytn network. * `const deployedContract = await caver.kct.kip7.deploy({ * name: 'TokenName', * symbol: 'TKN', * decimals: 18, * initialSupply: new BigNumber(1000000000000000000), * }, '0x{address in hex}')` * * @method deploy * @param {Object} tokenInfo The object that defines the name, symbol, decimals, and initialSupply of the token to deploy. * @param {Object|String} sendOptions The address of the account to deploy the KIP-7 token contract or an object holding parameters that are required for sending a transaction. * @return {Object} */ static deploy(tokenInfo, sendOptions) { validateDeployParameterForKIP7(tokenInfo) const { name, symbol, decimals, initialSupply } = tokenInfo const kip7 = new KIP7() // If sendOptions is string type, sendOptions means deployer's address if (_.isString(sendOptions)) sendOptions = { from: sendOptions, gas: 4000000, value: 0 } sendOptions.gas = sendOptions.gas !== undefined ? sendOptions.gas : 4000000 return kip7 .deploy({ data: kip7ByteCode, arguments: [name, symbol, decimals, initialSupply], }) .send(sendOptions) } /** * detectInterface detects which interface the KIP-7 token contract supports. * * @method detectInterface * @param {string} contractAddress The address of the KIP-7 token contract to detect. * @return {object} */ static detectInterface(contractAddress) { const kip7 = new KIP7(contractAddress) return kip7.detectInterface() } /** * KIP7 class represents the KIP-7 token contract. * * @constructor * @param {string} tokenAddress - The KIP-7 token contract address. * @param {Array} [abi] - The Contract Application Binary Interface (ABI) of the KIP-7. */ constructor(tokenAddress, abi = kip7JsonInterface) { if (tokenAddress) { if (_.isString(tokenAddress)) { if (!isAddress(tokenAddress)) throw new Error(`Invalid token address ${tokenAddress}`) } else { abi = tokenAddress tokenAddress = undefined } } super(abi, tokenAddress) } /** * clone copies a KIP7 instance with the new address parameter set to the target contract address. * * @method clone * @param {String} tokenAddress The address of the token contract. * @return {Object} */ clone(tokenAddress = this.options.address) { const cloned = new this.constructor(tokenAddress, this.options.jsonInterface) cloned.setWallet(this._wallet) return cloned } /** * detectInterface detects which interface the KIP-7 token contract supports. * * @method detectInterface * @return {object} */ async detectInterface() { const detected = { IKIP7: false, IKIP7Metadata: false, IKIP7Mintable: false, IKIP7Burnable: false, IKIP7Pausable: false, } const notSupportedMsg = `This contract does not support KIP-13.` const contractAddress = this._address try { const isSupported = await KIP13.isImplementedKIP13Interface(contractAddress) if (isSupported !== true) throw new Error(notSupportedMsg) // Since there is an extension that has the same interface id even though it is a different KCT, // it must be checked first whether the contract is a KIP-7 contract. detected.IKIP7 = await this.supportsInterface(interfaceIds.kip7.IKIP7) if (detected.IKIP7 === false) return detected await Promise.all( Object.keys(interfaceIds.kip7).map(async interfaceName => { if (interfaceIds.kip7[interfaceName] !== interfaceIds.kip7.IKIP7) detected[interfaceName] = await this.supportsInterface(interfaceIds.kip7[interfaceName]) }) ) return detected } catch (e) { throw new Error(notSupportedMsg) } } /** * supportsInterface checks whether interface is supported or not. * * @method supportsInterface * @param {string} interfaceId The interface id to check. * @return {boolean} */ async supportsInterface(interfaceId) { const supported = await this.methods.supportsInterface(interfaceId).call() return supported } /** * name returns the name of the token. * * @method name * @return {String} */ async name() { const name = await this.methods.name().call() return name } /** * symbol returns the symbol of the token. * * @method symbol * @return {String} */ async symbol() { const symbol = await this.methods.symbol().call() return symbol } /** * decimals returns the decimals of the token. * * @method symbol * @return {Number} */ async decimals() { const decimals = await this.methods.decimals().call() return Number(decimals) } /** * totalSupply returns the total supply of the token. * * @method totalSupply * @return {BigNumber} */ async totalSupply() { const totalSupply = await this.methods.totalSupply().call() return new BigNumber(totalSupply) } /** * balanceOf returns the balance of the account. * * @method balanceOf * @param {String} account The address of the account for which you want to see balance. * @return {BigNumber} */ async balanceOf(account) { const balance = await this.methods.balanceOf(account).call() return new BigNumber(balance) } /** * allowance returns the amount the spender is allowed to use on behalf of the owner. * * @method allowance * @param {String} owner The address of the account that set the spender to use the money on behalf of the owner. * @param {String} spender The address of the account that received the approve amount that can be used on behalf of the owner. * @return {BigNumber} */ async allowance(owner, spender) { const allowance = await this.methods.allowance(owner, spender).call() return new BigNumber(allowance) } /** * isMinter returns whether the account is minter or not. * * @method isMinter * @param {String} account The address of the account you want to check minter or not. * @return {Boolean} */ async isMinter(account) { const isMinter = await this.methods.isMinter(account).call() return isMinter } /** * isPauser returns whether the account is pauser or not. * * @method isPauser * @param {String} account The address of the account you want to check pauser or not. * @return {Boolean} */ async isPauser(account) { const isPauser = await this.methods.isPauser(account).call() return isPauser } /** * paused returns whether or not the token contract's transaction is paused. * * @method paused * @return {Boolean} */ async paused() { const isPaused = await this.methods.paused().call() return isPaused } /** * approve sets amount as the allowance of spender over the caller’s tokens. * * @method approve * @param {String} spender The address of the account to use on behalf of owner for the amount to be set in allowance. * @param {BigNumber|String|Number} amount The amount of tokens the spender allows to use on behalf of the owner. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async approve(spender, amount, sendParam = {}) { const executableObj = this.methods.approve(spender, formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * transfer moves amount tokens from the caller’s account to recipient. * * @method transfer * @param {String} recipient The address of the account to receive the token. * @param {BigNumber|String|Number} amount The amount of tokens you want to transfer. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async transfer(recipient, amount, sendParam = {}) { const executableObj = this.methods.transfer(recipient, formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * transferFrom moves amount tokens from sender to recipient using the allowance mechanism. * amount is then deducted from the caller’s allowance. * * @method transferFrom * @param {String} sender The address of the account that owns the token to be sent with allowance mechanism. * @param {String} recipient The address of the account to receive the token. * @param {BigNumber|String|Number} amount The amount of tokens you want to transfer. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async transferFrom(sender, recipient, amount, sendParam = {}) { const executableObj = this.methods.transferFrom(sender, recipient, formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * safeTransfer safely transfers tokens to another address. * * @method safeTransfer * @param {String} recipient The address of the account to receive the token. * @param {BigNumber|String|Number} amount The amount of tokens you want to transfer. * @param {Buffer|String|Number} [data] The optional data to send along with the call. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async safeTransfer(recipient, amount, data, sendParam = {}) { if (data && _.isObject(data)) { if (data.gas !== undefined || data.from !== undefined) { if (Object.keys(sendParam).length > 0) throw new Error(`Invalid parameters`) sendParam = data data = undefined } } if (data && !_.isBuffer(data)) { if (_.isString(data) && !isHexStrict(data)) data = toHex(data) data = toBuffer(data) } const executableObj = data ? this.methods.safeTransfer(recipient, formatParamForUint256(amount), data) : this.methods.safeTransfer(recipient, formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * safeTransferFrom safely transfers tokens to another address. * * @method safeTransferFrom * @param {String} sender The address of the account that owns the token to be sent with allowance mechanism. * @param {String} recipient The address of the account to receive the token. * @param {BigNumber|String|Number} amount The amount of tokens you want to transfer. * @param {Buffer|String|Number} data The optional data to send along with the call. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async safeTransferFrom(sender, recipient, amount, data, sendParam = {}) { if (data && _.isObject(data)) { if (data.gas !== undefined || data.from !== undefined) { if (Object.keys(sendParam).length > 0) throw new Error(`Invalid parameters`) sendParam = data data = undefined } } if (data && !_.isBuffer(data)) { if (_.isString(data) && !isHexStrict(data)) data = toHex(data) data = toBuffer(data) } const executableObj = data ? this.methods.safeTransferFrom(sender, recipient, formatParamForUint256(amount), data) : this.methods.safeTransferFrom(sender, recipient, formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * mint creates amount tokens and assigns them to account, increasing the total supply. * The account sending transaction to execute the addMinter must be a Minter with a MinterRole. * * @method mint * @param {String} account The address of the account to which the minted token will be allocated. * @param {BigNumber|String|Number} amount The amount of tokens to mint. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async mint(account, amount, sendParam = {}) { const executableObj = this.methods.mint(account, formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * addMinter adds an account as a minter that has the permission of MinterRole and can mint. * The account sending transaction to execute the addMinter must be a Minter with a MinterRole. * * @method addMinter * @param {String} account The address of account to add as minter. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async addMinter(account, sendParam = {}) { const executableObj = this.methods.addMinter(account) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * renounceMinter renounces privilege of MinterRole. * The account sending transaction to execute the renounceMinter must be a Minter with a MinterRole. * * @method renounceMinter * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async renounceMinter(sendParam = {}) { const executableObj = this.methods.renounceMinter() sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * burn destroys amount tokens from the caller. * * @method burn * @param {BigNumber|String|Number} amount The amount of tokens to destroy. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async burn(amount, sendParam = {}) { const executableObj = this.methods.burn(formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * burnFrom destroys amount tokens from account is then deducted from the caller’s allowance. * * @method burnFrom * @param {String} account The address of the account that owns the token to be burned with allowance mechanism. * @param {BigNumber|String|Number} amount The amount of tokens to destroy. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async burnFrom(account, amount, sendParam = {}) { const executableObj = this.methods.burnFrom(account, formatParamForUint256(amount)) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * addPauser adds an account as a pauser that has the permission of PauserRole and can pause. * The account sending transaction to execute the addPauser must be a Pauser with a PauserRole. * * @method addPauser * @param {String} account The address of account to add as pauser. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async addPauser(account, sendParam = {}) { const executableObj = this.methods.addPauser(account) sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * pause triggers stopped state that stops sending tokens in emergency situation. * The account sending transaction to execute the pause must be a Pauser with a PauserRole. * * @method pause * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async pause(sendParam = {}) { const executableObj = this.methods.pause() sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * unpause sets amount as the allowance of spender over the caller’s tokens. * The account sending transaction to execute the unpause must be a Pauser with a PauserRole. * * @method unpause * @param {String} spender The address of the account to use on behalf of owner for the amount to be set in allowance. * @param {BigNumber|String|Number} amount The amount of tokens the spender allows to use on behalf of the owner. * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async unpause(sendParam = {}) { const executableObj = this.methods.unpause() sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } /** * renouncePauser renounces privilege of PauserRole. * The account sending transaction to execute the renouncePauser must be a Pauser with a PauserRole. * * @method renouncePauser * @param {Object} sendParam An object with defined parameters for sending a transaction. * @return {Object} A receipt containing the execution result of the transaction for executing the KIP-7 token contract. * In this receipt, instead of the logs property, there is an events property parsed by KIP-7 abi. */ async renouncePauser(sendParam = {}) { const executableObj = this.methods.renouncePauser() sendParam = await determineSendParams(executableObj, sendParam, this.options) return executableObj.send(sendParam) } } KIP7.byteCode = kip7ByteCode module.exports = KIP7