UNPKG

caver-js

Version:

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

295 lines (276 loc) 18.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/>. */ /* eslint-disable no-unused-vars */ const LegacyTransaction = require('./transactionTypes/legacyTransaction/legacyTransaction') const EthereumAccessList = require('./transactionTypes/ethereumTypedTransaction/ethereumAccessList') const EthereumDynamicFee = require('./transactionTypes/ethereumTypedTransaction/ethereumDynamicFee') const ValueTransfer = require('./transactionTypes/valueTransfer/valueTransfer') const FeeDelegatedValueTransfer = require('./transactionTypes/valueTransfer/feeDelegatedValueTransfer') const FeeDelegatedValueTransferWithRatio = require('./transactionTypes/valueTransfer/feeDelegatedValueTransferWithRatio') const ValueTransferMemo = require('./transactionTypes/valueTransferMemo/valueTransferMemo') const FeeDelegatedValueTransferMemo = require('./transactionTypes/valueTransferMemo/feeDelegatedValueTransferMemo') const FeeDelegatedValueTransferMemoWithRatio = require('./transactionTypes/valueTransferMemo/feeDelegatedValueTransferMemoWithRatio') const AccountUpdate = require('./transactionTypes/accountUpdate/accountUpdate') const FeeDelegatedAccountUpdate = require('./transactionTypes/accountUpdate/feeDelegatedAccountUpdate') const FeeDelegatedAccountUpdateWithRatio = require('./transactionTypes/accountUpdate/feeDelegatedAccountUpdateWithRatio') const SmartContractDeploy = require('./transactionTypes/smartContractDeploy/smartContractDeploy') const FeeDelegatedSmartContractDeploy = require('./transactionTypes/smartContractDeploy/feeDelegatedSmartContractDeploy') const FeeDelegatedSmartContractDeployWithRatio = require('./transactionTypes/smartContractDeploy/feeDelegatedSmartContractDeployWithRatio') const SmartContractExecution = require('./transactionTypes/smartContractExecution/smartContractExecution') const FeeDelegatedSmartContractExecution = require('./transactionTypes/smartContractExecution/feeDelegatedSmartContractExecution') const FeeDelegatedSmartContractExecutionWithRatio = require('./transactionTypes/smartContractExecution/feeDelegatedSmartContractExecutionWithRatio') const Cancel = require('./transactionTypes/cancel/cancel') const FeeDelegatedCancel = require('./transactionTypes/cancel/feeDelegatedCancel') const FeeDelegatedCancelWithRatio = require('./transactionTypes/cancel/feeDelegatedCancelWithRatio') const ChainDataAnchoring = require('./transactionTypes/chainDataAnchoring/chainDataAnchoring') const FeeDelegatedChainDataAnchoring = require('./transactionTypes/chainDataAnchoring/feeDelegatedChainDataAnchoring') const FeeDelegatedChainDataAnchoringWithRatio = require('./transactionTypes/chainDataAnchoring/feeDelegatedChainDataAnchoringWithRatio') const LegacyTransactionWrapper = require('./transactionTypes/wrappers/legacyTransactionWrapper') const EthereumAccessListWrapper = require('./transactionTypes/wrappers/ethereumAccessListWrapper') const EthereumDynamicFeeWrapper = require('./transactionTypes/wrappers/ethereumDynamicFeeWrapper') const ValueTransferWrapper = require('./transactionTypes/wrappers/valueTransferWrapper') const FeeDelegatedValueTransferWrapper = require('./transactionTypes/wrappers/feeDelegatedValueTransferWrapper') const FeeDelegatedValueTransferWithRatioWrapper = require('./transactionTypes/wrappers/feeDelegatedValueTransferWithRatioWrapper') const ValueTransferMemoWrapper = require('./transactionTypes/wrappers/valueTransferMemoWrapper') const FeeDelegatedValueTransferMemoWrapper = require('./transactionTypes/wrappers/feeDelegatedValueTransferMemoWrapper') const FeeDelegatedValueTransferMemoWithRatioWrapper = require('./transactionTypes/wrappers/feeDelegatedValueTransferMemoWithRatioWrapper') const AccountUpdateWrapper = require('./transactionTypes/wrappers/accountUpdateWrapper') const FeeDelegatedAccountUpdateWrapper = require('./transactionTypes/wrappers/feeDelegatedAccountUpdateWrapper') const FeeDelegatedAccountUpdateWithRatioWrapper = require('./transactionTypes/wrappers/feeDelegatedAccountUpdateWithRatioWrapper') const SmartContractDeployWrapper = require('./transactionTypes/wrappers/smartContractDeployWrapper') const FeeDelegatedSmartContractDeployWrapper = require('./transactionTypes/wrappers/feeDelegatedSmartContractDeployWrapper') const FeeDelegatedSmartContractDeployWithRatioWrapper = require('./transactionTypes/wrappers/feeDelegatedSmartContractDeployWithRatioWrapper') const SmartContractExecutionWrapper = require('./transactionTypes/wrappers/smartContractExecutionWrapper') const FeeDelegatedSmartContractExecutionWrapper = require('./transactionTypes/wrappers/feeDelegatedSmartContractExecutionWrapper') const FeeDelegatedSmartContractExecutionWithRatioWrapper = require('./transactionTypes/wrappers/feeDelegatedSmartContractExecutionWithRatioWrapper') const CancelWrapper = require('./transactionTypes/wrappers/cancelWrapper') const FeeDelegatedCancelWrapper = require('./transactionTypes/wrappers/feeDelegatedCancelWrapper') const FeeDelegatedCancelWithRatioWrapper = require('./transactionTypes/wrappers/feeDelegatedCancelWithRatioWrapper') const ChainDataAnchoringWrapper = require('./transactionTypes/wrappers/chainDataAnchoringWrapper') const FeeDelegatedChainDataAnchoringWrapper = require('./transactionTypes/wrappers/feeDelegatedChainDataAnchoringWrapper') const FeeDelegatedChainDataAnchoringWithRatioWrapper = require('./transactionTypes/wrappers/feeDelegatedChainDataAnchoringWithRatioWrapper') const TransactionDecoder = require('./transactionDecoder/transactionDecoder') const AbstractTransaction = require('./transactionTypes/abstractTransaction') const { TX_TYPE_STRING, TX_TYPE_TAG } = require('./transactionHelper/transactionHelper') const Account = require('../../caver-account') const AbstractFeeDelegatedTransaction = require('./transactionTypes/abstractFeeDelegatedTransaction') const AccessList = require('./utils/accessList') const AccessTuple = require('./utils/accessTuple') /** * @typedef {LegacyTransaction|ValueTransfer|FeeDelegatedValueTransfer|FeeDelegatedValueTransferWithRatio|ValueTransferMemo|FeeDelegatedValueTransferMemo|FeeDelegatedValueTransferMemoWithRatio|AccountUpdate|FeeDelegatedAccountUpdate|FeeDelegatedAccountUpdateWithRatio|SmartContractDeploy|FeeDelegatedSmartContractDeploy|FeeDelegatedSmartContractDeployWithRatio|SmartContractExecution|FeeDelegatedSmartContractExecution|FeeDelegatedSmartContractExecution|FeeDelegatedSmartContractExecutionWithRatio|Cancel|FeeDelegatedCancel|FeeDelegatedCancelWithRatio|ChainDataAnchoring|FeeDelegatedChainDataAnchoring|FeeDelegatedChainDataAnchoringWithRatio|EthereumAccessList|EthereumDynamicFee} module:Transaction.Transaction */ /** * @typedef {FeeDelegatedValueTransfer|FeeDelegatedValueTransferWithRatio|FeeDelegatedValueTransferMemo|FeeDelegatedValueTransferMemoWithRatio|FeeDelegatedAccountUpdate|FeeDelegatedAccountUpdateWithRatio|FeeDelegatedSmartContractDeploy|FeeDelegatedSmartContractDeployWithRatio|FeeDelegatedSmartContractExecution|FeeDelegatedSmartContractExecution|FeeDelegatedSmartContractExecutionWithRatio|FeeDelegatedCancel|FeeDelegatedCancelWithRatio|FeeDelegatedChainDataAnchoring|FeeDelegatedChainDataAnchoringWithRatio} module:Transaction.FeeDelegatedTransaction */ /** * A class that manages instances of the transaction wrapper and other functions provided by the transaction module. * @class * @hideconstructor */ class TransactionModule { /** * Creates a TransactionModule. * * @constructor * @param {object} klaytnCall - An object includes klay rpc calls. */ constructor(klaytnCall) { if (!klaytnCall) throw new Error(`Invalid constructor parameter: klaytnCall is undefined.`) this.klaytnCall = klaytnCall this.legacyTransaction = new LegacyTransactionWrapper(this.klaytnCall) this.ethereumAccessList = new EthereumAccessListWrapper(this.klaytnCall) this.ethereumDynamicFee = new EthereumDynamicFeeWrapper(this.klaytnCall) this.valueTransfer = new ValueTransferWrapper(this.klaytnCall) this.feeDelegatedValueTransfer = new FeeDelegatedValueTransferWrapper(this.klaytnCall) this.feeDelegatedValueTransferWithRatio = new FeeDelegatedValueTransferWithRatioWrapper(this.klaytnCall) this.valueTransferMemo = new ValueTransferMemoWrapper(this.klaytnCall) this.feeDelegatedValueTransferMemo = new FeeDelegatedValueTransferMemoWrapper(this.klaytnCall) this.feeDelegatedValueTransferMemoWithRatio = new FeeDelegatedValueTransferMemoWithRatioWrapper(this.klaytnCall) this.accountUpdate = new AccountUpdateWrapper(this.klaytnCall) this.feeDelegatedAccountUpdate = new FeeDelegatedAccountUpdateWrapper(this.klaytnCall) this.feeDelegatedAccountUpdateWithRatio = new FeeDelegatedAccountUpdateWithRatioWrapper(this.klaytnCall) this.smartContractDeploy = new SmartContractDeployWrapper(this.klaytnCall) this.feeDelegatedSmartContractDeploy = new FeeDelegatedSmartContractDeployWrapper(this.klaytnCall) this.feeDelegatedSmartContractDeployWithRatio = new FeeDelegatedSmartContractDeployWithRatioWrapper(this.klaytnCall) this.smartContractExecution = new SmartContractExecutionWrapper(this.klaytnCall) this.feeDelegatedSmartContractExecution = new FeeDelegatedSmartContractExecutionWrapper(this.klaytnCall) this.feeDelegatedSmartContractExecutionWithRatio = new FeeDelegatedSmartContractExecutionWithRatioWrapper(this.klaytnCall) this.cancel = new CancelWrapper(this.klaytnCall) this.feeDelegatedCancel = new FeeDelegatedCancelWrapper(this.klaytnCall) this.feeDelegatedCancelWithRatio = new FeeDelegatedCancelWithRatioWrapper(this.klaytnCall) this.chainDataAnchoring = new ChainDataAnchoringWrapper(this.klaytnCall) this.feeDelegatedChainDataAnchoring = new FeeDelegatedChainDataAnchoringWrapper(this.klaytnCall) this.feeDelegatedChainDataAnchoringWithRatio = new FeeDelegatedChainDataAnchoringWithRatioWrapper(this.klaytnCall) this.type = TX_TYPE_STRING this.tag = TX_TYPE_TAG this.utils = { accessList: AccessList, accessTuple: AccessTuple, } } /** * @type {object} */ get klaytnCall() { return this._klaytnCall } set klaytnCall(c) { this._klaytnCall = c } /** * Querys transaction from Klaytn and converts to a caver transaction instance. * If it fails to receive a transaction from Klaytn, an error is thrown. * * @example * const txObject = await caver.transaction.getTransactionByHash('0x{transaction hash}') * * @method getTransactionByHash * @param {string} transactionHash The transaction hash string to query from Klaytn. * @return {Promise<AbstractTransaction>} */ async getTransactionByHash(transactionHash) { let txObject = await this.klaytnCall.getTransactionByHash(transactionHash) if (txObject === null) throw new Error(`Failed to get transaction from Klaytn with '${transactionHash}'.`) // AccountUpdate transaction received from Klaytn defines encodedAccountKey string in `key` field. // This needs to be formatted according to the caver transaction format (`account` field). if (txObject.key) { const account = Account.createFromRLPEncoding(txObject.from, txObject.key) txObject.account = account delete txObject.key } switch (txObject.type) { case 'TxTypeLegacyTransaction': txObject = this.legacyTransaction.create(txObject, this.klaytnCall) break case 'TxTypeValueTransfer': txObject = this.valueTransfer.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedValueTransfer': txObject = this.feeDelegatedValueTransfer.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedValueTransferWithRatio': txObject = this.feeDelegatedValueTransferWithRatio.create(txObject, this.klaytnCall) break case 'TxTypeValueTransferMemo': txObject = this.valueTransferMemo.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedValueTransferMemo': txObject = this.feeDelegatedValueTransferMemo.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedValueTransferMemoWithRatio': txObject = this.feeDelegatedValueTransferMemoWithRatio.create(txObject, this.klaytnCall) break case 'TxTypeAccountUpdate': txObject = this.accountUpdate.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedAccountUpdate': txObject = this.feeDelegatedAccountUpdate.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedAccountUpdateWithRatio': txObject = this.feeDelegatedAccountUpdateWithRatio.create(txObject, this.klaytnCall) break case 'TxTypeSmartContractDeploy': txObject = this.smartContractDeploy.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedSmartContractDeploy': txObject = this.feeDelegatedSmartContractDeploy.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedSmartContractDeployWithRatio': txObject = this.feeDelegatedSmartContractDeployWithRatio.create(txObject, this.klaytnCall) break case 'TxTypeSmartContractExecution': txObject = this.smartContractExecution.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedSmartContractExecution': txObject = this.feeDelegatedSmartContractExecution.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedSmartContractExecutionWithRatio': txObject = this.feeDelegatedSmartContractExecutionWithRatio.create(txObject, this.klaytnCall) break case 'TxTypeCancel': txObject = this.cancel.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedCancel': txObject = this.feeDelegatedCancel.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedCancelWithRatio': txObject = this.feeDelegatedCancelWithRatio.create(txObject, this.klaytnCall) break case 'TxTypeChainDataAnchoring': txObject = this.chainDataAnchoring.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedChainDataAnchoring': txObject = this.feeDelegatedChainDataAnchoring.create(txObject, this.klaytnCall) break case 'TxTypeFeeDelegatedChainDataAnchoringWithRatio': txObject = this.feeDelegatedChainDataAnchoringWithRatio.create(txObject, this.klaytnCall) break case 'TxTypeEthereumAccessList': txObject = this.ethereumAccessList.create(txObject, this.klaytnCall) break case 'TxTypeEthereumDynamicFee': txObject = this.ethereumDynamicFee.create(txObject, this.klaytnCall) break } return txObject } /** * Recovers the public key strings from `signatures` field. * If you want to derive an address from public key, please use `caver.utils.publicKeyToAddress`. * * @example * const publicKey = caver.transaction.recoverPublicKeys('0x{RLP-encoded transaction string}') * * @method recoverPublicKeys * @param {string} rawTx The RLP-encoded transaction string to recover public keys from `signatures`. * @return {Array.<string>} */ recoverPublicKeys(rawTx) { const tx = TransactionDecoder.decode(rawTx) return tx.recoverPublicKeys() } /** * Recovers the public key strings from `feePayerSignatures` field. * If you want to derive an address from public key, please use `caver.utils.publicKeyToAddress`. * * @example * const publicKey = caver.transaction.recoverFeePayerPublicKeys() * * @method recoverFeePayerPublicKeys * @param {string} rawTx The RLP-encoded transaction string to recover public keys from `feePayerSignatures`. * @return {Array.<string>} */ recoverFeePayerPublicKeys(rawTx) { const tx = TransactionDecoder.decode(rawTx) if (!(tx instanceof AbstractFeeDelegatedTransaction)) throw new Error( 'The `caver.transaction.recoverFeePayerPublicKeys` function can only use with fee delegation transaction. For basic transactions, use `caver.transaction.recoverPublicKeys`.' ) return tx.recoverFeePayerPublicKeys() } /** * Decodes RLP-encoded transaction string and returns a Transaction instance. * * @example * const tx = caver.transaction.decode('0x{RLP-encoded transaction string}') * * @param {string} rlpEncoded - An RLP-encoded transaction string to decode. * @return {module:Transaction.Transaction} */ decode(encoded) { return TransactionDecoder.decode(encoded) } } module.exports = TransactionModule