Batch Transfer

Step 1: Create Signer instance

  • Nodejs:
const provider = new ethers.providers.JsonRpcProvider("RPC_URL", 1);
const signer = new ethers.Wallet("WALLET_PRIVATE_KEY", provider);
  • Web browser:
import { initializeWagmi } from "@uniblock/wagmi"
const chainId = <CHAIN_ID>
const wagmi = await initializeWagmi(uniblock_api_key);
const { chains, provider, webSocketProvider } = wagmi.configureChains([chainId]);
const client = wagmi.createClient(
  provider,
  webSocketProvider,
  chains,
  [
    connector.METAMASK_CONNECTOR,
  ],
);
await wagmi.connectWallet(client, connector.METAMASK_CONNECTOR);
const signer = await wagmi.getSigner();

Note: To use the wagmi, install it through yarn add @uniblock/wagmi or npm install @uniblock/wagmi

Step 2: Call batch method

BatchTransferERC20

Transfer the token specified by the tokenAddress parameter from amounts to each receiver from receivers respectively at a time.

Parameter

ArgumentTypeDescrition
tokenAddressstringThe address of the ERC20 token to be transferred.
receiversstring[]The wallet addresses to receive the ERC20 tokens.
amountsstring[]The number of tokens received by each recipient.
signerSignerThe instance to represent wallet address.

Example

Before batchTransferERC20(), ensure there is allowance for erc20 transfer fee if the paymentToken of multiSend contract is an erc20 token. If not, developers can always use the following lines to ensure sufficient allowance:

// increase allowance for erc20 transfer fee token
const feeAmount = (await multiSendSdk.getFee())
const feeToken = (await multiSendSdk.getPaymentToken())
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
if(feeToken !== ZERO_ADDRESS){
    const allowance = await multiSendSdk.getAllowance(feeToken, await signer.getAddress())
    if(allowance.lt(feeAmount)){
        const feeIncrementAllowance = feeAmount.sub(allowance).toString()
        await multiSendSdk.increaseAllowance(feeToken, feeIncrementAllowance, signer)
    }
}

// increase allowance for transferred erc20 token
const transferTokenAllowance = await multiSendSdk.getAllowance(tokenAddress, await signer.getAddress());
const totalAmount = amounts.reduce((acc, curr) => (acc+curr))
if(transferTokenAllowance.lt(totalAmount)){
    const transferIncrementAllowance = totalAmount.sub(transferTokenAllowance).toString()
    await multiSendSdk.increaseAllowance(tokenAddress, transferIncrementAllowance, signer)
}

Then call batchTransferERC20


const TransactionResponse = await multiSendSdk.batchTransferERC20(tokenAddress, receivers, amounts.map(amount => amount.toString()), signer)

// TransactionResponse:
// {
//   "type": 2,
//   "chainId": 5,
//   "nonce": 20,
//   "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x59682f00" },
//   "maxFeePerGas": { "type": "BigNumber", "hex": "0xaf85d11c" },
//   "gasPrice": null,
//   "gasLimit": { "type": "BigNumber", "hex": "0x01d778" },
//   "to": "0xb6D709A2b53a6949eD127e8F5b47112A1e07580B",
//   "value": { "type": "BigNumber", "hex": "0x00" },
//   "data": "0xcce7ec13000000000000000000000000655f2166b0709cd575202630952d71e2bb0d61af0000000000000000000000000000000000000000000000000000000000000014",
//   "accessList": [],
//   "hash": "0x76af6b34a512e8267a5f5a249ae78b004116bc6855a3024f6e2fb3c909494f86",
//   "v": 1,
//   "r": "0xc6940153c7abc6f4e1cee7fb1678d3e2ae3fdf720448557ee2baeebba4e338f0",
//   "s": "0x2bd90951a91c64168075c675ad7ecb450614b863554388b91844c6456437d965",
//   "from": "0x246280fD39740213D089f6f3A09745cb52aC5eCA",
//   "confirmations": 0
// }

BatchTransferERC721

Transfer each tokenId from parameter tokenIds which are under the tokenAddress to each receiver.

Parameter

ArgumentTypeDescription
tokenAddressstringThe address of the ERC721 contract whose tokenIds are going to be transferred.
receiversstring[]The wallet addresses to receive the ERC721 tokens.
tokenIdsstring[]The tokenId that represents the assets which are going to be transferred.
signerSignerThe instance to represent wallet address.

Example

Before batchTransferERC721(), ensure there is approval of the tokenId under the ERC721 contract and allowance for erc721 transfer fee if the paymentToken of multiSend contract is an erc20 token. If not, developers can always use the following lines to ensure sufficient allowance and approval:

// increase allowance for ERC20 transfer fee
const feeAmount = (await multiSendSdk.getFee())
const feeToken = (await multiSendSdk.getPaymentToken())
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
if(feeToken !== ZERO_ADDRESS){
    const allowance = await multiSendSdk.getAllowance(feeToken, await signer.getAddress())
    if(allowance.lt(feeAmount)){
        const feeIncrementAllowance = feeAmount.sub(allowance).toString()
        await multiSendSdk.increaseAllowance(feeToken, feeIncrementAllowance, signer)
    }
}

// set approval for ERC721 token
const approve = await multiSendSdk.getApproved(tokenAddress, '1')
if(!approve)    await multiSendSdk.approve(tokenAddress, '1', signer)

Then call batchTransferERC721


const transactionResponse = await multiSendSdk.batchTransferERC721(
 erc721Token,
 [walletAddress],
 ['1'],
 signer,
 );

// transactionResponse:
// {
//   "type": 2,
//   "chainId": 5,
//   "nonce": 73,
//   "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x59682f00" },
//   "maxFeePerGas": { "type": "BigNumber", "hex": "0x253c05757c" },
//   "gasPrice": null,
//   "gasLimit": { "type": "BigNumber", "hex": "0x013b3e" },
//   "to": "0x0918AF5794b234f2eC236FE3E1075c6B021EFC69",
//   "value": { "type": "BigNumber", "hex": "0x00" },
//   "data": "0x18947bf70000000000000000000000000673ef1db29ee35a58cd6b212a13dff07c8d6626000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000cee2872ea9e72b7eb5be52ca34223264450ae9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001",
//   "accessList": [],
//   "hash": "0xe9bb1fe8c86d3d2757bf630efd0b2fd3b83b6381250ba3d52b1af0f85ea687ec",
//   "v": 1,
//   "r": "0xcb31704de3d989674c5bd970d44a335ed8697c74ef6a647e967e28943af8ebc2",
//   "s": "0x01d9ac9fb53c51dd5abdeac4404f986aec1d5a7b3389d1726fa09804b1543372",
//   "from": "0x0CEE2872EA9E72b7eb5BE52cA34223264450AE9c",
//   "confirmations": 0
// }

BatchTransferERC1155

Transfer amount of token specified by each tokenId from tokenIds which are under the ERC1155 token address to each receiver of receivers

Parameter

ArgumentTypeDescription
tokenAddressstringThe address of the ERC1155 contract whose tokenIds are going to be transferred.
receiversstring[]The wallet addresses to receive the ERC1155 tokens.
tokenIdsstring[][]The tokenIds that represents of the assets to be transferred.
amountsstring[][]The number of tokens received by each recipient.
datastring[]Additional data with no specified format.
signerSignerThe instance to represent wallet address.

Example

Before batchTransferERC1155(), ensure there is approval of the tokenId under the ERC1155 contract and allowance for erc1155 transfer fee if the paymentToken of multiSend contract is an erc20 token. If not, developers can always use the following lines to ensure sufficient allowance and approval:

// increase allowance for ERC20 transfer fee
const feeAmount = (await multiSendSdk.getFee())
const feeToken = (await multiSendSdk.getPaymentToken())
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
if(feeToken !== ZERO_ADDRESS){
    const allowance = await multiSendSdk.getAllowance(feeToken, await signer.getAddress())
    if(allowance.lt(feeAmount)){
        const feeIncrementAllowance = feeAmount.sub(allowance).toString()
        await multiSendSdk.increaseAllowance(feeToken, feeIncrementAllowance, signer)
    }
}

// set approval for ERC1155 token
const approval = await multiSendSdk.getApprovalForAll(erc1155Token, await signer.getAddress())
if(!approval)    await multiSend.setApproveForAll(erc1155Token, true)

Then call batchTransferERC1155

const transactionResponse = await multiSend.batchTransferERC1155(
    erc1155Token,
    [walletAddress],
    [['1']],
    [['1']],
    [ZERO_ADDRESS],
    signer,
);

// transactionResponse:  
// {
//    "type": 2,
//    "chainId": 5,
//    "nonce": 74,
//    "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x59682f00" },
//    "maxFeePerGas": { "type": "BigNumber", "hex": "0x200f2e3744" },
//    "gasPrice": null,
//    "gasLimit": { "type": "BigNumber", "hex": "0x0136d6" },
//    "to": "0x0918AF5794b234f2eC236FE3E1075c6B021EFC69",
//    "value": { "type": "BigNumber", "hex": "0x00" },
//    "data": "0x7da0f183...",
//    "accessList": [],
//    "hash": "0xfcb4875cfa...",
//    "v": 1,
//    "r": "0x4adc1fc4...",
//    "s": "0x12ba3c8b...",
//    "from": "0x0CEE2872EA9E72b7eb5BE52cA34223264450AE9c",
//    "confirmations": 0
// }

BatchTransferNative

Transfer each amount of native token from amounts on contract chain to each receiver from receivers

Parameter

ArgumentTypedescription
receiversstring[]The wallet addresses to receive the native tokens.
amountsstring[]The amount of native token to be transferred to each recipient.

Example

const transactionResponse = await multiSend.batchTransferNative(
    [walletAddress],
    ['5'],
    signer,
);

// transactionResponse:
// {
//   "type": 2,
//   "chainId": 5,
//   "nonce": 75,
//   "maxPriorityFeePerGas": { "type": "BigNumber", "hex": "0x59682f00" },
//   "maxFeePerGas": { "type": "BigNumber", "hex": "0x2cf21920ea" },
//   "gasPrice": null,
//   "gasLimit": { "type": "BigNumber", "hex": "0xf051" },
//   "to": "0x0918AF5794b234f2eC236FE3E1075c6B021EFC69",
//   "value": { "type": "BigNumber", "hex": "0x0a" },
//   "data": "0x66f658e90000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000cee2872ea9e72b7eb5be52ca34223264450ae9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005",
//   "accessList": [],
//   "hash": "0x789b4863646963253485f7d849f09bcfb452dcdfb5ca66945c92ebb1df01ca77",
//   "v": 1,
//   "r": "0xca8a14b2f4aecb198dbec80e6c02794234722768cf45dd88eff22f9573d30f70",
//   "s": "0x4ec4a528f02a039c4706b5d92a50a99b25aee08743615e2d586656a14d72de14",
//   "from": "0x0CEE2872EA9E72b7eb5BE52cA34223264450AE9c",
//   "confirmations": 0
// }

Step 3: Parse the Response

The response object of all batch transfer methods follows the following format:

FieldTypeDescription
typenumberThe EIP-2718 type of this transaction
chainIdnumberThe id of the network.
noncenumberThe nonce used as part of the proof-of-work to mine this block.
maxPriorityFeePerGasBigNumberThe price (in wei) per unit of gas this transaction costs.
maxFeePerGasBigNumberThe maximum price (in wei) per unit of gas this transaction will pay for the combined EIP-1559 block's base fee and this transaction's priority fee.
gasPriceBigNumberThe price (in wei) per unit of gas this transaction will pay.
gasLimitBigNumberThe maximum amount of gas that this block was permitted to use.
tostringThe address of the target.
valueBigNumberThe amount (in wei) this transaction is sending.
datastringTransaction data.
accessListAccessListThe AccessList to include; only available for EIP-2930 and EIP-1559 transactions.
hashstringThe AccessList to include; only available for EIP-2930 and EIP-1559 transactions.
vnumberValues for the transaction's signature.
rstringValues for the transaction's signature.
sstringValues for the transaction's signature.
fromstringThe sender address of the transaction.
confirmationsnumberThe number of blocks that have been mined (including the initial block) since this transaction was mined.