We will make an FCT, where we will wrap ETH and transfer all WETH to other recipients. This FCT will consist of 3 Plugins - Wrap ETH, ERC20 Balance Of, and ERC20 Transfer.
If you have not worked with FCT before or have not seen any other examples, we highly encourage youto start with the Simple ERC20 Transfer example, which explains everything in more detail.
Utility is a Protocol, which consists of various utility functions such as sendETH , wrapETH and unwrapETH.
Build all 3 plugins
First, we will create wrapETH plugin and add all parameters.
constwrapETH=newUtility.actions.WrapETH({ chainId:1,})wrapETH.input.set({ value:"1"+"0".repeat(18) // We are going to wrap 1 Ether})
Then we are going to create ERC20 Balance Of Plugin
constbalanceOfWETH=newERC20.getters.BalanceOf({ chainId:1,})balanceOfWETH.input.set({ to:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",// Or take the address from wrapETH plugin like this// to: wrapETH.input.to.value methodParams: { owner:"0x...",// Address which wrapped Ether tokens. In this case// that will be the vault address. }})
And then the last plugin we are going to create is ERC20 Transfer
consttransfer=newERC20.actions.Transfer({ chainId:1,})transfer.input.set({ to:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",// Or take the address from wrapETH plugin like this// to: wrapETH.input.to.value methodParams: { recipient:"0x...",// Address, which is going to receive the tokens amount:balanceOfWETH.output.balance.getOutputVariable("balanceOfWETH_id"),// "balanceOfWETH_id" is the nodeID we are going to use later on }}
Build the FCT from plugins
First, we need to construct BatchMultiSigCall class.
Once we have BatchMultiSigCall constructed, now we can add all of the plugins to BatchMultiSigCall class by calling createMultiple() function.
The order must be like it is in the example. If the order is different, FCT might not work correctly.
awaitbatchMultiSigCall.create([ { plugin: wrapETH, from:"0x...", nodeId:"wrapETH_id" }, { plugin: balanceOfWETH, from:"0x...", nodeId: "balanceOfWETH_id" // This nodeId has to match the id, that was used in the ERC20 Transfer plugin amount
}, { plugin: transfer, from:"0x...",// Here we put the vault address, from whom the transfer will happen nodeId:"transfer_id" },])
Now we have an FCT that is ready to be exported!
constFCT=awaitbatchMultiSigCall.exportFCT()
Congratulations, you have built an FCT with 3 plugins!
Full code example
import { BatchMultiSigCall } from"@kirobo/fct-core"import { ERC20, Utility } from"@kirobo/fct-plugins"constwrapETH=newUtility.actions.WrapETH({ chainId:1,})wrapETH.input.set({ value:"1"+"0".repeat(18) // We are going to wrap 1 Ether})constbalanceOfWETH=newERC20.getters.BalanceOf({ chainId:1,})balanceOfWETH.input.set({ to:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",// Or take the address from wrapETH plugin like this// to: wrapETH.input.to.value methodParams: { owner:"0x...",// Address which wrapped Ether tokens. In this case// that will be the vault address. }})consttransfer=newERC20.actions.Transfer({ chainId:1,})transfer.input.set({ to:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",// Or take the address from wrapETH plugin like this// to: wrapETH.input.to.value methodParams: { recipient:"0x...",// Address, which is going to receive the tokens amount:balanceOfWETH.output.balance.getOutputVariable("balanceOfWETH_id"),// "balanceOfWETH_id" is the nodeID we are going to use later on }})constbatchMultiSigCall=newBatchMultiSigCall({ provider:newethers.providers.JsonRpcProvider("..."), chainId:1,})awaitbatchMultiSigCall.create([ { plugin: wrapETH, from:"0x...", nodeId:"wrapETH_id" }, { plugin: balanceOfWETH, from:"0x...", nodeId: "balanceOfWETH_id" // This nodeId has to match the id, that was used in the ERC20 Transfer plugin amount
}, { plugin: transfer, from:"0x...",// Here we put the vault address, from whom the transfer will happen nodeId:"transfer_id" },])constFCT=awaitbatchMultiSigCall.exportFCT()// Use FCT.typedData to sign on to the FCT. If you are using @metamask/eth-sig-util// to sign on EIP712 transaction, this is an example of how to sign on to FCTimport { signTypedData, SignTypedDataVersion } from"@metamask/eth-sig-util";constsignature=signTypedData({ data:FCT.typedData, privateKey:Buffer.from(key,"hex"), version:SignTypedDataVersion.V4})