With Superfluid, you can batch many, many operations into a single transaction. Here's how you do it with the SDK Core
The BatchCall class allows the user to batch multiple supported operations/transactions in one operation. Similar to the other helper classes, we can create this either through the Framework or directly initialize this.
Supported Operations
Not all operations are supported by the batch call feature, below is a list of the supported operations:
ERC20_APPROVE (SuperToken only)
ERC20_TRANSFER_FROM
SUPERTOKEN_UPGRADE
SUPERTOKEN_DOWNGRADE
SUPERFLUID_CALL_AGREEMENT
CALL_APP_ACTION
Most of the token methods are self explanatory, but some additional context for the last two operations is helpful. SUPERFLUID_CALL_AGREEMENT refers to all operations related to the CFA or IDA (createFlow, updateIndex, distribute, etc.). CALL_APP_ACTION refers to an operation which is created from calling a function that exists on a super app you have created. Refer to Usage below to see how you can create a CALL_APP_ACTION operation.
Framework based initialization
import { Framework } from"@superfluid-finance/sdk-core";import { ethers } from"ethers";constprovider=newethers.providers.InfuraProvider("matic","<INFURA_API_KEY>");constsf=awaitFramework.create({ chainId:137,//chain Id for matic - change depending on current network provider});constsigner=sf.createSigner({ privateKey:"<TEST_ACCOUNT_PRIVATE_KEY>", provider });constbatchCall=sf.batchCall([<OPERATION_A>, <OPERATION_B>,...]);
import { Framework } from"@superfluid-finance/sdk-core";import { ethers } from"ethers";constprovider=newethers.providers.InfuraProvider("matic","<INFURA_API_KEY>");constsf=awaitFramework.create({ chainId:137,//matic chainId provider});//load the token you'd like to use like this //note that tokens may be loaded by symbol or by address//this is daix on rinkebyconstdaix=awaitsf.loadSuperToken("0x745861AeD1EEe363b4AaA5F1994Be40b1e05Ff90");// 0xabc is the signer on Rinkeby testnetconstsigner=sf.createSigner({ privateKey:"<TEST_ACCOUNT_PRIVATE_KEY>", provider });constfromAddress="0xabc";constpaymentAddress="0xdef";constapproveOp=daix.approve({ receiver: paymentAddress, amount:"10000" });consttransferFromOp=daix.transferFrom({ sender: fromAddress, receiver: paymentAddress, amount:"10000",});constbatchCall=sf.batchCall([approveOp, transferFromOp]);consttxn=awaitbatchCall.exec(signer);// creating an operation from a super app function with callAppAction// initialize your super app contract's interfaceconstsuperAppInterface=newethers.utils.Interface(<SUPER_APP_ABI>);// get the calldata for your transactioninthiscase we're calling a hypothetical function titled 'transferERC20'const callData = appInterface.encodeFunctionData("transferERC20", [ token, receiver, amount,"0x",]);//create the operation by using sf.host.callAppActionconsttransferOp=sf.host.callAppAction(appAddress, callData);//add the operation to a batch callconstbatchCall=sf.batchCall([transferOp]);awaitbatchCall.exec(signer);