Batch Calls - SDK Core

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";

const provider = new ethers.providers.InfuraProvider(
  "matic",
  "<INFURA_API_KEY>"
);

const sf = await Framework.create({
  chainId: 137, //chain Id for matic - change depending on current network
  provider
});

const signer = sf.createSigner({ privateKey: "<TEST_ACCOUNT_PRIVATE_KEY>", provider });
const batchCall = sf.batchCall([<OPERATION_A>, <OPERATION_B>, ...]);

Direct Initialization

import { SuperToken } from "@superfluid-finance/sdk-core";

const batchCall = new BatchCall({
  hostAddress: "0x3E14dC1b13c488a8d5D310918780c983bD5982E7",
  operations: [<OPERATION_A>, <OPERATION_B>, ...],
});

Usage

import { Framework } from "@superfluid-finance/sdk-core";
import { ethers } from "ethers";

const provider = new ethers.providers.InfuraProvider(
  "matic",
  "<INFURA_API_KEY>"
);

const sf = await Framework.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 rinkeby
const daix = await sf.loadSuperToken("0x745861AeD1EEe363b4AaA5F1994Be40b1e05Ff90");
 
 // 0xabc is the signer on Rinkeby testnet
const signer = sf.createSigner({ privateKey: "<TEST_ACCOUNT_PRIVATE_KEY>", provider });
const fromAddress = "0xabc";
const paymentAddress = "0xdef";
const approveOp = daix.approve({ receiver: paymentAddress, amount: "10000" });
const transferFromOp = daix.transferFrom({
  sender: fromAddress,
  receiver: paymentAddress,
  amount: "10000",
});
const batchCall = sf.batchCall([approveOp, transferFromOp]);
const txn = await batchCall.exec(signer);

// creating an operation from a super app function with callAppAction
// initialize your super app contract's interface
const superAppInterface = new ethers.utils.Interface(<SUPER_APP_ABI>);

// get the calldata for your transaction
in this case we're calling a hypothetical function titled 'transferERC20'
const callData = appInterface.encodeFunctionData("transferERC20", [
   token,
   receiver,
   amount,
   "0x",
]);

//create the operation by using sf.host.callAppAction
const transferOp = sf.host.callAppAction(appAddress, callData);

//add the operation to a batch call
const batchCall = sf.batchCall([transferOp]);
await batchCall.exec(signer);

Last updated