# Bulk Instant Transfer

#### Initializing the Class

To initialize an instance of the `ZebecBulkClient` class, you need to provide a signer or provider and optionally specify contract addresses for `BulkTransfer` and `Core`. Here's an example of how to initialize the class:

```typescript
import { ethers } from "ethers";
import { ZebecBulkClient } from "@zebec-protocol/zebec-bnb-sdk";

// Initialize with a signer (e.g., MetaMask)
const signer = new ethers.Wallet("your-private-key");
const bulkClient = new ZebecBulkClient(signer);
```

1. &#x20; **Initialize Bulk Instant**

```typescript
const bulkStreamName = "YourBulkStreamName";
const now = Math.floor(Date.now() / 1000);
const amounts = ["1", "2", "3"];
const tokenAddress = "0xTokenAddress";
const receivers = [receiver1.address, receiver2.address, receiver3.address];
const startTimes = [BigNumber.from(now + 100)]; // An array of start times. Length must be equal to recurring Frequency
const recurringFrequency = 1;
const overrides = {}; // Optional overrides

const bulkInstantTree = await bulkClient.getBulkInstantTransferRoot(
      tokenAddress,
      amounts,
      receivers
    );

const txnReceipt = await bulkClient.initBlulkInstantTransfer(
      bulkStreamName,
      bulkInstantTree.root,
      startTimes,
      recurringFrequency
    );
console.log(txnReceipt);
```

`initBlulkInstantTransfer` method initializes a bulk stream with a bulk tree root, start times, and other parameters.&#x20;

`getBulkInstantTransferRoot` function is designed to calculate and retrieve the Merkle tree root for a bulk instant transfer. This function is used to create a Merkle tree structure that represents a set of instant token transfers that will occur simultaneously.

2. **Update Bulk Transfer**

<pre class="language-typescript"><code class="lang-typescript">const bulkName = "Updated Bulk";
const bulkIndex = await receiver1Client.getLatestBulkCount(sender.address).toNumber(); // bulk index to update
const amounts = ["5", "7", "9"];
const tokenAddress = "0xNewTokenAddress";
const receivers = [receiver1.address, receiver2.address, receiver3.address];
const startTimes = [BigNumber.from(now + 600), BigNumber.from(now + 900)];  // An array of start times. Length must be equal to recurring Frequency
const recurringFrequency = 2;
const overrides = {}; // Optional overrides

<strong>bulkInstantTree = await bulkClient.updateBulkInstantTransferRoot(
</strong>  tokenAddress,
  amounts,
  receivers,
  withdrawBulkCount
);

const txnReceipt = await bulkClient.updateBulkTransfer(
  bulkName,
  bulkIndex,
  merkleRoot,
  startTimes,
  recurringFrequency,
  overrides
);
console.log(txnReceipt);
</code></pre>

`updateBulkInstantTransferRoot` function is used to update an existing bulk instant transfer by recalculating the Merkle tree root based on new transfer data.

`updateBulkTransfer` method updates a bulk transfer with new information such as a merkle root and start times.

3. &#x20;**Withdraw Bulk Instant Transfer By Receiver**

```typescript
const amount = "1";
const tokenAddress = "0xTokenAddress";
const sender = "0xSenderAddress";
const receiver = "0xReceiverAddress";
const proofs = ["0xProof1", "0xProof2"]; // Array of merkle proofs
const zebecWalletTransfer = false;
const overrides = {}; // Optional overrides
const bulkIndex = await receiver1Client.getLatestBulkCount(sender.address).toNumber(); // get the latest bulk index

const txnReceipt = await bulkClient.withdrawBulkInstantTransfer(
  bulkIndex,
  amount,
  tokenAddress,
  sender,
  receiver,
  proofs,
  zebecWalletTransfer,
  overrides
);
console.log(txnReceipt);
```

This method allows a user to withdraw funds from a bulk instant transfer using merkle proofs.\
\
\&#xNAN;*Note: The purpose of the `getLatestBulkCount` function is to determine the number of bulk transfers that a user has created within the Zebec protocol. Bulk transfers are collections of individual token streams, and each bulk transfer has a unique index or identifier.*

4. &#x20;**Cancel Bulk Instant Transfer**

```typescript
const bulkIndex = 1;
const overrides = {}; // Optional overrides
const txnReceipt = await bulkClient.cancelBulkInstantTransfer(bulkIndex, overrides);
console.log(txnReceipt);
```

This method cancels a bulk instant transfer.

5. &#x20;**Calculate Latest Bulk Bytes**

```typescript
const userAddress = "0xUserAddress";
const bulkBytes = await bulkClient.calculateLatestBulkBytes(userAddress);
console.log(bulkBytes);
```

The `calculateLatestBulkBytes` function in the `ZebecBulkClient` class is used to calculate the byte representation of the latest bulk transfer associated with a specific user's address. This function allows you to obtain the byte representation of the most recent bulk transfer.

6. **Get Bulk Transfer Root**

<pre class="language-typescript"><code class="lang-typescript">const bulkBytes = "0xabcdef123456..."; // Replace with the actual bulk transfer identifier
<strong>// Retrieve the Merkle root of the specified bulk transfer
</strong>const bulkTransferRoot = await bulkClient.getBulkTransferRoot(bulkTransferBytes);
console.log(`Merkle Root of Bulk Transfer: ${bulkTransferRoot}`)

</code></pre>

The `getBulkTransferRoot` function is used to retrieve the Merkle root associated with a specific bulk transfer.

7. **Verify Bulk Transfer**

```javascript
// Verify the bulk instant transfer
const verified = await bulkClient.verifyBulkInstantTransfer(
  index,
  amount,
  tokenAddress,
  sender,
  receiver,
  proofs
);

if (verified) {
  console.log("Bulk Instant Transfer is valid and verified.");
} else {
  console.log("Bulk Instant Transfer is not valid.");
}
```

The purpose of the `verifyBulkInstantTransfer` function is to perform verification checks on a bulk instant transfer to ensure that it matches the expected properties and has not been manipulated or tampered with.
