# eth\_sendBundle

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_sendBundle",
  "params": [
    {
      txs,                   // Array[String], A list of signed transactions to execute in an atomic bundle, list can be empty for bundle cancellations
      blockNumber,           // (Optional) String, a hex-encoded block number for which this bundle is valid. Default, current block number
      revertingTxHashes,     // (Optional) Array[String], A list of tx hashes that are allowed to revert or be discarded
      droppingTxHashes,      // (Optional) Array[String], A list of tx hashes that are allowed to be discarded, but may not revert
      replacementUuid,       // (Optional) String, any arbitrary string that can be used to replace or cancel this bundle
      refundPercent,         // (Optional) Number, the percentage (from 0 to 99) of the  ETH reward of the last transaction, or the transaction specified by refundIndex, that should be refunded back to the ‘refundRecipient’
      refundRecipient,       // (Optional) Address, the address that will receive the ETH refund. Default, sender of the first transaction in the bundle
      replacementSeqNumber,  // (Optional) Number, monotonically increasing sequence for bundles sharing the same replacementUuid. Later bundles must have a higher sequence or they are dropped. If 0 or omitted, ordering falls back to builder receive time
      minTimestamp,          // (Optional) Number, the minimum slot timestamp for which this bundle is valid, in seconds since the unix epoch 
    }
  ]
}
```

**N.B.:** If the `refundPercent` field is set, the builder will construct a refund transaction automatically. However, if the refund amount does not cover the cost of the transaction (i.e., `gas_used * base_fee`), the bundle will be discarded.\
‍

### **Refund Example**

**Consider the following Bundle:**

* TXN 1 - User swap (Base fee: 50 Gwei, Piority fee 3 Gwei, Gas: 280k)
* TXN 2 - Backrun (Base fee: 50 Gwei, Priority fee 100 Gwei, Gas: 150k)
* `refundPercent`: 90%
* Current block base fee: 50 Gwei

**Calculation:**

* ETH reward of the last transaction in the bundle = (150k x 100 Gwei) = 15,000 Gwei
* ETH reward after transfer transaction fees = 15000 - (21k x 50 Gwei) = 13,950 Gwei
* Refund amount = 0.9 x 13,950 Gwei = 12,555 Gwei‍

### **Sponsored Bundles**

Our builder supports Sponsored Bundles. If we receive a bundle that fails with `LackOfFundForGasLimit` error, we will automatically send the ETH required to cover the gas fees and value transfer for the transaction to succeed.

The caveat here is that the bundle must of course increase the builder balance, as we will need to recoup this sponsoring cost with the bundle’s execution.

For further details, see our [substack article](https://titanbuilder.substack.com/p/titan-tech-teatime-1).

## **CURL example**

```json
curl -s --data '{"jsonrpc": "2.0","id": "1","method": "eth_sendBundle","params": [{"txs": ["0x12…ab","0x34..cd"], "blockNumber": "0x102286B","replacementUuid": "abcd1234"}]}' -H "Content-Type: application/json" -X POST https://rpc.titanbuilder.xyz
```

## **Response example**

```javascript
{"result":{"bundleHash":"0x164d7d41f24b7f333af3b4a70b690cf93f636227165ea2b699fbb7eed09c46c7"},"error":null,"id":1}
```

## Bundle Hash

Here is the algorithm for determining the bundle hash:

```rust
#[derive(Hash, Serialize, Deserialize)]
pub struct RawBundle {
   #[serde(default)]
    pub block_number: U64,
    #[serde(default)]
    pub txs: Vec<Bytes>,
    pub reverting_tx_hashes: Option<Vec<String>>,
    pub dropping_tx_hashes: Option<Vec<String>>,
    pub replacement_uuid: Option<String>,
    pub refund_percent: Option<u64>,
    pub refund_recipient: Option<Address>,
    pub refund_tx_hashes: Option<Vec<String>>,
}

pub fn bundle_hash(bundle: &RawBundle) -> B256 {
    let mut hasher = wyhash::WyHash::default();
    let mut bytes = [0u8; 32];
    for i in 0..4 {
        bundle.hash(&mut hasher);
        let hash = hasher.finish();
        bytes[(i * 8)..((i + 1) * 8)].copy_from_slice(&hash.to_be_bytes());
    }

    B256::from(bytes)
}
```
