UNPKG

@superfluid-finance/sdk-core

Version:
487 lines 26.8 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 Host_1 = __importDefault(require("./Host")); const SFError_1 = require("./SFError"); const SuperfluidAgreement_1 = __importDefault(require("./SuperfluidAgreement")); const typechain_types_1 = require("./typechain-types"); const utils_1 = require("./utils"); const cfaInterface = typechain_types_1.IConstantFlowAgreementV1__factory.createInterface(); /** * Constant Flow Agreement V1 Helper Class * @description A helper class to interact with the CFAV1 contract. */ class ConstantFlowAgreementV1 extends SuperfluidAgreement_1.default { constructor(hostAddress, cfaV1Address, cfaV1ForwarderAddress) { super(); /** ### CFA Read Functions ### */ /** * Get the details of a flow. * @param superToken the superToken of the agreement * @param sender the sender of the flow * @param receiver the receiver of the flow * @param providerOrSigner a provider or signer object * @returns {Promise<IWeb3FlowInfo>} Web3 Flow info object */ this.getFlow = async (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const normalizedReceiver = (0, utils_1.normalizeAddress)(params.receiver); try { const flowData = await this.contract .connect(params.providerOrSigner) .getFlow(normalizedToken, normalizedSender, normalizedReceiver); return this._sanitizeFlowInfo(flowData); } catch (err) { throw new SFError_1.SFError({ type: "CFAV1_READ", message: "There was an error getting the flow", cause: err, }); } }; /** * Get the flow info of an account (net flow). * @param superToken the superToken of the agreement * @param account the account we're querying * @param providerOrSigner a provider or signer object * @returns {Promise<IWeb3FlowInfo>} Web3 Flow info object */ this.getAccountFlowInfo = async (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedAccount = (0, utils_1.normalizeAddress)(params.account); try { const flowData = await this.contract .connect(params.providerOrSigner) .getAccountFlowInfo(normalizedToken, normalizedAccount); return this._sanitizeFlowInfo(flowData); } catch (err) { throw new SFError_1.SFError({ type: "CFAV1_READ", message: "There was an error getting the account flow information", cause: err, }); } }; /** * Get the net flow of an account. * @param superToken the superToken of the agreement * @param account the account we're querying * @param providerOrSigner a provider or signer object * @returns {Promise<string>} Web3 Flow info object */ this.getNetFlow = async (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedAccount = (0, utils_1.normalizeAddress)(params.account); try { return (await this.contract .connect(params.providerOrSigner) .getNetFlow(normalizedToken, normalizedAccount)).toString(); } catch (err) { throw new SFError_1.SFError({ type: "CFAV1_READ", message: "There was an error getting net flow", cause: err, }); } }; /** * Get flow operator data. * @param superToken the superToken of the agreement * @param sender the sender * @param flowOperator the flowOperator * @param providerOrSigner a provider or signer object * @returns {Promise<IWeb3FlowOperatorData>} Web3 Flow info object */ this.getFlowOperatorData = async (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); try { const flowOperatorData = await this.contract .connect(params.providerOrSigner) .getFlowOperatorData(normalizedToken, normalizedSender, normalizedFlowOperator); return this._sanitizeFlowOperatorData(flowOperatorData); } catch (err) { throw new SFError_1.SFError({ type: "CFAV1_READ", message: "There was an error getting flow operator data", cause: err, }); } }; /** * Get flow operator data using the flowOperatorId. * @param superToken the superToken of the agreement * @param flowOperatorId The keccak256 hash of encoded string "flowOperator", sender and flowOperator * @param providerOrSigner a provider or signer object * @returns {Promise<IWeb3FlowOperatorData>} Web3 Flow info object */ this.getFlowOperatorDataByID = async (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); try { const flowOperatorData = await this.contract .connect(params.providerOrSigner) .getFlowOperatorDataByID(normalizedToken, params.flowOperatorId); return this._sanitizeFlowOperatorData({ ...flowOperatorData, flowOperatorId: params.flowOperatorId, }); } catch (err) { throw new SFError_1.SFError({ type: "CFAV1_READ", message: "There was an error getting flow operator data", cause: err, }); } }; /** ### CFA Write Functions ### */ /** * Create a flow. * @param flowRate The specified flow rate. * @param sender The sender of the flow * @param receiver The receiver of the flow. * @param superToken The token to be flowed. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @param shouldUseCallAgreement Whether to use callAgreement, or the CFAv1Forwarder * @returns {Operation} An instance of Operation which can be executed or batched. */ this.createFlow = (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedReceiver = (0, utils_1.normalizeAddress)(params.receiver); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const callData = cfaInterface.encodeFunctionData("createFlow", [ normalizedToken, normalizedReceiver, params.flowRate, "0x", ]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const forwarderPopulatedTxnPromise = this.forwarder.populateTransaction.createFlow(normalizedToken, normalizedSender, normalizedReceiver, params.flowRate, params.userData || "0x", params.overrides || {}); return this._getCallAgreementOperation(callAgreementOperation, forwarderPopulatedTxnPromise, params.shouldUseCallAgreement || normalizedSender === ""); }; /** * Update a flow. * @param flowRate The specified flow rate. * @param sender The sender of the flow * @param receiver The receiver of the flow. * @param superToken The token to be flowed. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ this.updateFlow = (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedReceiver = (0, utils_1.normalizeAddress)(params.receiver); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const callData = cfaInterface.encodeFunctionData("updateFlow", [ normalizedToken, normalizedReceiver, params.flowRate, "0x", ]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const forwarderPopulatedTxnPromise = this.forwarder.populateTransaction.updateFlow(normalizedToken, normalizedSender, normalizedReceiver, params.flowRate, params.userData || "0x", params.overrides || {}); return this._getCallAgreementOperation(callAgreementOperation, forwarderPopulatedTxnPromise, params.shouldUseCallAgreement || normalizedSender === ""); }; /** * Delete a flow. * @param superToken The token to be flowed. * @param sender The sender of the flow. * @param receiver The receiver of the flow. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ this.deleteFlow = (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const normalizedReceiver = (0, utils_1.normalizeAddress)(params.receiver); const callData = cfaInterface.encodeFunctionData("deleteFlow", [ normalizedToken, normalizedSender, normalizedReceiver, "0x", ]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const forwarderPopulatedTxnPromise = this.forwarder.populateTransaction.deleteFlow(normalizedToken, normalizedSender, normalizedReceiver, params.userData || "0x", params.overrides || {}); return this._getCallAgreementOperation(callAgreementOperation, forwarderPopulatedTxnPromise, params.shouldUseCallAgreement || normalizedSender === ""); }; /** * Create a flow as an operator * @param flowRate The specified flow rate. * @param sender The sender of the flow. * @param receiver The receiver of the flow. * @param superToken The token to be flowed. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ this.createFlowByOperator = (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedReceiver = (0, utils_1.normalizeAddress)(params.receiver); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const callData = cfaInterface.encodeFunctionData("createFlowByOperator", [ normalizedToken, normalizedSender, normalizedReceiver, params.flowRate, "0x", ]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const createFlowOperation = this.createFlow(params); return this._getCallAgreementOperation(callAgreementOperation, createFlowOperation.forwarderPopulatedPromise, params.shouldUseCallAgreement || normalizedSender === ""); }; /** * Update a flow as an operator. * @param flowRate The specified flow rate. * @param sender The sender of the flow. * @param receiver The receiver of the flow. * @param superToken The token to be flowed. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ this.updateFlowByOperator = (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const normalizedReceiver = (0, utils_1.normalizeAddress)(params.receiver); const callData = cfaInterface.encodeFunctionData("updateFlowByOperator", [ normalizedToken, normalizedSender, normalizedReceiver, params.flowRate, "0x", ]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const updateFlowOperation = this.updateFlow(params); return this._getCallAgreementOperation(callAgreementOperation, updateFlowOperation.forwarderPopulatedPromise, params.shouldUseCallAgreement || normalizedSender === ""); }; /** * Delete a flow as an operator. * @param sender The sender of the flow. * @param receiver The receiver of the flow. * @param superToken The token to be flowed. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ this.deleteFlowByOperator = (params) => { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedSender = (0, utils_1.normalizeAddress)(params.sender); const normalizedReceiver = (0, utils_1.normalizeAddress)(params.receiver); const callData = cfaInterface.encodeFunctionData("deleteFlowByOperator", [normalizedToken, normalizedSender, normalizedReceiver, "0x"]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const deleteFlowOperation = this.deleteFlow(params); return this._getCallAgreementOperation(callAgreementOperation, deleteFlowOperation.forwarderPopulatedPromise, params.shouldUseCallAgreement || normalizedSender === ""); }; /** ### Internal Helper Functions ### */ /** * Sanitizes flow info, converting BigNumber to string. * @param timestamp last updated timestamp of flow * @param flowRate the current flow rate * @param deposit the deposit amount * @param owedDeposit any owed deposit * @returns {IWeb3FlowInfo} sanitized web3 flow info */ this._sanitizeFlowInfo = (params) => { return { timestamp: (0, utils_1.getSanitizedTimestamp)(params.timestamp), flowRate: params.flowRate.toString(), deposit: params.deposit.toString(), owedDeposit: params.owedDeposit.toString(), }; }; /** * Sanitizes flow operator data, converting BigNumber to string. * @param flowOperatorId The keccak256 hash of encoded string "flowOperator", sender and flowOperator * @param permissions the permissions * @param flowRateAllowance the flow rate allowance granted to the flow operator * @returns {IWeb3FlowOperatorData} sanitized web3 flow info */ this._sanitizeFlowOperatorData = (params) => { return { flowOperatorId: params.flowOperatorId, permissions: params.permissions.toString(), flowRateAllowance: params.flowRateAllowance.toString(), }; }; this.host = new Host_1.default(hostAddress); this.contract = new ethers_1.ethers.Contract(cfaV1Address, typechain_types_1.IConstantFlowAgreementV1__factory.abi); this.forwarder = new ethers_1.ethers.Contract(cfaV1ForwarderAddress, typechain_types_1.CFAv1Forwarder__factory.abi); } /** ### CFA ACL Write Functions (byOperator) ### */ /** * Increase the flow rate allowance for an ACL operator. * @param superToken The token to be flowed. * @param flowOperator The operator of the flow. * @param flowRateAllowanceDelta The amount to increase the flow rate allowance by. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ increaseFlowRateAllowance(params) { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); const callData = cfaInterface.encodeFunctionData("increaseFlowRateAllowance", [ normalizedToken, normalizedFlowOperator, params.flowRateAllowanceDelta, "0x", ]); return this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); } /** * Decrease the flow rate allowance for an ACL operator. * @param superToken The token to be flowed. * @param flowOperator The operator of the flow. * @param flowRateAllowanceDelta The amount to decrease the flow rate allowance by. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ decreaseFlowRateAllowance(params) { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); const callData = cfaInterface.encodeFunctionData("decreaseFlowRateAllowance", [ normalizedToken, normalizedFlowOperator, params.flowRateAllowanceDelta, "0x", ]); return this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); } /** * Increase the flow rate allowance and sets permissions for an ACL operator. * @param superToken The token to be flowed. * @param flowOperator The operator of the flow. * @param permissionsDelta The permissions to be add for the operator. * @param flowRateAllowanceDelta The amount to increase the flow rate allowance by. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ increaseFlowRateAllowanceWithPermissions(params) { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); if (!(0, utils_1.isPermissionsClean)(params.permissionsDelta)) { throw new SFError_1.SFError({ type: "UNCLEAN_PERMISSIONS", message: "The desired permissions are unclean", }); } const callData = cfaInterface.encodeFunctionData("increaseFlowRateAllowanceWithPermissions", [ normalizedToken, normalizedFlowOperator, params.permissionsDelta, params.flowRateAllowanceDelta, "0x", ]); return this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); } /** * Decrease the flow rate allowance and sets permissions for an ACL operator. * @param superToken The token to be flowed. * @param flowOperator The operator of the flow. * @param permissionsDelta The permissions to be remove from the operator. * @param flowRateAllowanceDelta The amount to decrease the flow rate allowance by. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ decreaseFlowRateAllowanceWithPermissions(params) { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); if (!(0, utils_1.isPermissionsClean)(params.permissionsDelta)) { throw new SFError_1.SFError({ type: "UNCLEAN_PERMISSIONS", message: "The desired permissions are unclean", }); } const callData = cfaInterface.encodeFunctionData("decreaseFlowRateAllowanceWithPermissions", [ normalizedToken, normalizedFlowOperator, params.permissionsDelta, params.flowRateAllowanceDelta, "0x", ]); return this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); } /** * Update permissions for a flow operator as a sender. * @param superToken The token to be flowed. * @param flowOperator The permission grantee address * @param permission The permissions to set. * @param flowRateAllowance The flowRateAllowance granted to the flow operator. * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. * @returns {Operation} An instance of Operation which can be executed or batched. */ updateFlowOperatorPermissions(params) { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); if (!(0, utils_1.isPermissionsClean)(params.permissions)) { throw new SFError_1.SFError({ type: "UNCLEAN_PERMISSIONS", message: "The desired permissions are unclean", }); } if (Number(params.flowRateAllowance) < 0) { throw new SFError_1.SFError({ type: "NEGATIVE_FLOW_ALLOWANCE", message: "No negative flow allowance allowed", }); } const callData = cfaInterface.encodeFunctionData("updateFlowOperatorPermissions", [ normalizedToken, normalizedFlowOperator, params.permissions, params.flowRateAllowance, "0x", ]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const forwarderPopulatedTxnPromise = this.forwarder.populateTransaction.updateFlowOperatorPermissions(normalizedToken, normalizedFlowOperator, params.permissions, params.flowRateAllowance, params.overrides || {}); return this._getCallAgreementOperation(callAgreementOperation, forwarderPopulatedTxnPromise, params.shouldUseCallAgreement); } /** * Give flow operator full control - max flow rate and create/update/delete permissions. * @param superToken The token to be flowed. * @param flowOperator The permission grantee address * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. */ authorizeFlowOperatorWithFullControl(params) { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); const callData = cfaInterface.encodeFunctionData("authorizeFlowOperatorWithFullControl", [normalizedToken, normalizedFlowOperator, "0x"]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const forwarderPopulatedTxnPromise = this.forwarder.populateTransaction.grantPermissions(normalizedToken, normalizedFlowOperator, params.overrides || {}); return this._getCallAgreementOperation(callAgreementOperation, forwarderPopulatedTxnPromise, params.shouldUseCallAgreement); } /** * Revoke flow operator control - set flow rate to 0 with no permissions. * @param superToken The token to be flowed. * @param flowOperator The permission grantee address * @param userData Extra user data provided. * @param overrides ethers overrides object for more control over the transaction sent. */ revokeFlowOperatorWithFullControl(params) { const normalizedToken = (0, utils_1.normalizeAddress)(params.superToken); const normalizedFlowOperator = (0, utils_1.normalizeAddress)(params.flowOperator); const callData = cfaInterface.encodeFunctionData("revokeFlowOperatorWithFullControl", [normalizedToken, normalizedFlowOperator, "0x"]); const callAgreementOperation = this.host.callAgreement(this.contract.address, callData, params.userData, params.overrides); const forwarderPopulatedTxnPromise = this.forwarder.populateTransaction.revokePermissions(normalizedToken, normalizedFlowOperator, params.overrides || {}); return this._getCallAgreementOperation(callAgreementOperation, forwarderPopulatedTxnPromise, params.shouldUseCallAgreement); } } exports.default = ConstantFlowAgreementV1; //# sourceMappingURL=ConstantFlowAgreementV1.js.map