> ## Documentation Index
> Fetch the complete documentation index at: https://docs.socket.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Destination Payload Execution

> Execute arbitrary contract calls on the destination chain after a bridge or swap completes

Pass `destinationPayload` + `destinationGasLimit` on a `userOps=tx` quote to run arbitrary logic atomically after tokens are delivered on the destination chain — stake, swap, vault deposit, etc.

<Info>
  Only supported on `userOps=tx` routes. Not available for deposit-address routes or Sui destinations.
</Info>

## Quote parameters

| Field                 | Type       | Description                                                                        |
| --------------------- | ---------- | ---------------------------------------------------------------------------------- |
| `receiverAddress`     | address    | Your `IBungeeExecutor` contract on the destination chain — **not** a plain wallet. |
| `destinationPayload`  | hex string | ABI-encoded calldata passed verbatim into `executeData`.                           |
| `destinationGasLimit` | string     | Gas forwarded for `executeData` execution.                                         |

Both `destinationPayload` and `destinationGasLimit` must be set together — passing only one is rejected.

## How it works

Tokens are delivered to Socket's **BungeeReceiver** contract (same address on all supported chains via CREATE3), which then calls your executor:

```
bridge delivery → BungeeReceiver → YourExecutor.executeData(quoteId, amount, token, calldata)
```

BungeeReceiver pre-approves `amount` of `token` before the call, so your executor can pull from it directly.

## IBungeeExecutor interface

This is the v3 / OpenRouter single-output signature. Do not use the older marketplace executor (different multi-output signature).

```solidity theme={null}
interface IBungeeExecutor {
    function executeData(
        bytes32 quoteId,
        uint256 amount,
        address token,
        bytes calldata callData
    ) external;
}
```

`callData` is exactly what was passed as `destinationPayload` at quote time.

## Constraints

* `destinationPayload` + `destinationGasLimit` are all-or-nothing.
* Not supported on Sui or deposit-address (`userOps=deposit`) routes.
* BungeeReceiver is deployed on all `OPEN_ROUTER_CHAIN_IDS` (Ethereum, Arbitrum, Base, Optimism, Polygon, BNB, Gnosis, Linea, Mantle, Scroll, Sonic, Soneium, Unichain, Worldchain, HyperEVM, and more).
* `CalldataExecutor` (`0xC914...9008`) is a reference no-op executor that forwards calldata to an arbitrary target — useful for simple forwarding. No registration needed; security is handled by BungeeReceiver's per-quote signature verification.

## Examples

<AccordionGroup>
  <Accordion title="Quote request (TypeScript)">
    ```typescript theme={null}
    const route = await fetch(
      `https://dedicated-backend.socket.tech/v3/swap/quote?${new URLSearchParams({
        userOps: "tx",
        userAddress: "0xYourWallet",
        originChainId: "8453",
        destinationChainId: "8453",
        inputToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",  // USDC Base
        outputToken: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2", // USDT Base
        inputAmount: "10000000",
        receiverAddress: "0xYourExecutorContract",
        destinationPayload: "0xYourAbiEncodedCalldata",
        destinationGasLimit: "500000",
      })}`,
      { headers: { affiliate: "YOUR_AFFILIATE_ID" } }
    ).then(r => r.json());
    ```
  </Accordion>

  <Accordion title="Example executor contract (Solidity)">
    <Warning>For example purposes only — audit before production use.</Warning>

    ```solidity theme={null}
    // SPDX-License-Identifier: UNLICENSED
    pragma solidity ^0.8.28;

    import {SafeTransferLib} from "solady/utils/SafeTransferLib.sol";

    interface IBungeeExecutor {
        function executeData(bytes32 quoteId, uint256 amount, address token, bytes calldata callData) external;
    }

    contract MyExecutor is IBungeeExecutor {
        address constant NATIVE = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

        function executeData(bytes32, uint256 amount, address token, bytes calldata callData) external override {
            address recipient = abi.decode(callData, (address));
            if (token == NATIVE) {
                SafeTransferLib.safeTransferETH(recipient, amount);
            } else {
                SafeTransferLib.safeTransfer(token, recipient, amount);
            }
        }

        receive() external payable {}
    }
    ```
  </Accordion>
</AccordionGroup>
