UNPKG

@superfluid-finance/sdk-core

Version:
135 lines 7.14 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const ethers_1 = require("ethers"); const BatchCall_1 = require("./BatchCall"); const SFError_1 = require("./SFError"); const multiplyGasLimit_1 = __importDefault(require("./multiplyGasLimit")); const typechain_types_1 = require("./typechain-types"); const utils_1 = require("./utils"); /** * Operation Helper Class * @description A helper class to create `Operation` objects which can be executed or batched. */ class Operation { constructor(txn, type, forwarderPopulatedPromise) { /** * Executes the operation via the provided signer. * @description Populates all fields of the transaction, signs it and sends it to the network. * @param signer The signer of the transaction * @param gasLimitMultiplier A multiplier to provide gasLimit buffer on top of the estimated gas limit (1.2x is the default) * @returns {ethers.providers.TransactionResponse} A TransactionResponse object which can be awaited */ this.exec = async (signer, gasLimitMultiplier = 1.2) => { const populatedTransaction = await this.getPopulatedTransactionRequest(signer, gasLimitMultiplier); return await signer.sendTransaction(populatedTransaction); }; /** * Get the populated transaction by awaiting `populateTransactionPromise`. * `providerOrSigner` is used for gas estimation if necessary. * NOTE: we use the forwarder populated promise if this exists */ this.getPopulatedTransactionRequest = async (providerOrSigner, gasLimitMultiplier = 1.2) => { const populatedTransaction = this.forwarderPopulatedPromise ? await this.forwarderPopulatedPromise : await this.populateTransactionPromise; // if gasLimit exists, an Overrides object has been passed or the user has explicitly set // a gasLimit for their transaction prior to execution and so we keep it as is else we apply // a specified or the default (1.2) multiplier on the gas limit. if (!populatedTransaction.gasLimit) { const estimatedGasLimit = await providerOrSigner.estimateGas(populatedTransaction); populatedTransaction.gasLimit = (0, multiplyGasLimit_1.default)(estimatedGasLimit, gasLimitMultiplier); } return populatedTransaction; }; /** * Signs the populated transaction via the provided signer (what you intend on sending to the network). * @param signer The signer of the transaction * @returns {Promise<string>} Fully serialized, signed transaction */ this.getSignedTransaction = async (signer, gasLimitMultiplier = 1.2) => { const populatedTransaction = await this.getPopulatedTransactionRequest(signer, gasLimitMultiplier); const signerPopulatedTransaction = await signer.populateTransaction(populatedTransaction); const signedTransaction = await signer.signTransaction(signerPopulatedTransaction); return signedTransaction; }; /** * Gets the transaction hash of the transaction. * @description Calculates this by getting the keccak256 hash of the signedTxn. * @param signer The signer of the transaction * @returns {Promise<string>} The transaction hash of the transaction */ this.getTransactionHash = async (signer) => { const signedTxn = await this.getSignedTransaction(signer); return ethers_1.ethers.utils.keccak256(signedTxn); }; /** * Gets the `OperationStruct` object. * @param operation an `Operation` object * @param index the index of the `Operation` in the batchCall * @returns {Promise<OperationStruct>} OperationStruct object for batchCall */ this.toOperationStruct = async (index) => { const batchOperationType = BatchCall_1.batchOperationTypeStringToTypeMap.get(this.type); const populatedTransaction = await this.populateTransactionPromise; if (!batchOperationType) { throw new SFError_1.SFError({ type: "UNSUPPORTED_OPERATION", message: "The operation at index " + index + " is unsupported.", }); } /* istanbul ignore next */ if (!populatedTransaction.to || !populatedTransaction.data) { throw new SFError_1.SFError({ type: "MISSING_TRANSACTION_PROPERTIES", message: "The transaction is missing the to or data property.", }); } const encoder = ethers_1.ethers.utils.defaultAbiCoder; // Handles Superfluid.callAgreement if (this.type === "SUPERFLUID_CALL_AGREEMENT") { const functionArgs = (0, BatchCall_1.getCallDataFunctionArgs)(typechain_types_1.Superfluid__factory.abi, populatedTransaction.data); const data = encoder.encode(["bytes", "bytes"], [functionArgs["callData"], functionArgs["userData"]]); return { operationType: batchOperationType, target: functionArgs["agreementClass"], data, value: populatedTransaction.value, }; } // Handles Superfluid.callAppAction if (this.type === "CALL_APP_ACTION") { const functionArgs = (0, BatchCall_1.getCallDataFunctionArgs)(typechain_types_1.Superfluid__factory.abi, populatedTransaction.data); return { operationType: batchOperationType, target: functionArgs["app"], data: functionArgs["callData"], value: populatedTransaction.value, }; } if (this.type === "SIMPLE_FORWARD_CALL" || this.type === "ERC2771_FORWARD_CALL") { return { operationType: batchOperationType, target: populatedTransaction.to, data: populatedTransaction.data, value: populatedTransaction.value, }; } // Handles remaining ERC20/ERC777/SuperToken Operations (including SIMPLE_FORWARD_CALL and ERC2771_FORWARD_CALL) return { operationType: batchOperationType, target: populatedTransaction.to, data: (0, utils_1.removeSigHashFromCallData)(populatedTransaction.data), value: populatedTransaction.value, }; }; this.populateTransactionPromise = txn; this.type = type; this.forwarderPopulatedPromise = forwarderPopulatedPromise; } } exports.default = Operation; //# sourceMappingURL=Operation.js.map