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

# Build requests onchain

> Create and submit crosschain requests directly through smart contracts

Building requests onchain involves creating a `IBungeeInbox.Request` with all required parameters, including deadline, nonce, and token specifications. The request is then submitted through the `createRequest` function.

## Creating a Request

### Step 1: Generate Request Parameters

Establish the timing and uniqueness parameters for your request:

```solidity theme={null}
uint256 currentTimestamp = block.timestamp;
uint256 deadline = currentTimestamp + 600; // 10 minutes deadline
uint256 nonce = uint256(
    uint32(
        bytes4(
            keccak256(
                abi.encodePacked(
                    currentTimestamp,
                    block.number,
                    block.prevrandao,
                    msg.sender,
                    inputAmount,
                    chainSlug_,
                    gasleft()
                )
            )
        )
    )
);
```

The nonce generation combines multiple blockchain parameters to ensure uniqueness and prevent repeated numbers.

### Step 2: Build the Basic Request

Create the basic request structure with chain identifiers, token details, and execution parameters:

```solidity theme={null}
IBungeeInbox.BasicRequest memory basicReq = IBungeeInbox.BasicRequest({
    originChainId: request[user].inputChainSlug,
    destinationChainId: request[user].outputChainSlug,
    deadline: deadline,
    nonce: nonce,
    sender: sourceBungeeInboxAddress,
    receiver: request[user].monitorAddress,
    delegate: request[user].monitorAddress,
    bungeeGateway: sourceBungeeGatewayAddress,
    switchboardId: 1, // Fixed value for standard operations
    inputToken: request[user].inputTokenAddress,
    inputAmount: request[user].inputAmount,
    outputToken: request[user].outputTokenAddress,
    minOutputAmount: request[user].minSwapOutput,
    refuelAmount: 0 // Add refuel amount if native token transfer needed
});
```

### Step 3: Complete the Request Structure

Build the full request with additional parameters for swap execution and metadata:

```solidity theme={null}
IBungeeInbox.Request memory bungeeRequest = IBungeeInbox.Request({
    basicReq: basicReq,
    swapOutputToken: request[user].outputTokenAddress,
    minSwapOutput: request[user].minSwapOutput,
    metadata: bytes32(0), // Metadata: first 16 bytes = quoteId. Last 16 bytes = integrator id
    affiliateFees: "", // Add affiliate fee structure if needed
    minDestGas: 0,
    destinationPayload: "", // Add destination payload encoding if needed
    exclusiveTransmitter: address(0) // Add specific transmitter if needed
});
```

Detailed explanation of all parameters of both structures may be seen in the IBungeeInbox structure definition. Also, validate all inputs before creating requests to prevent invalid submissions.

## Submitting the Request

Once your request structure is complete, submit it through the BungeeInbox contract on the source chain:

```solidity theme={null}
IBungeeInbox(bungeeInboxAddress).createRequest(bungeeRequest);
```

## Helper Libraries

The utility libraries below are for request handling and validation. These libraries include EIP-712 compliant hashing functions and request verification tools that ensure proper request formatting and security.

<Accordion title="Simple utilities for building and verifying BungeeInbox crosschain request payloads">
  ```solidity theme={null}
  // SPDX-License-Identifier: MIT
  pragma solidity ^0.8.22;

  import {IBungeeInbox} from "./IBungeeInbox.sol";

  /// @title Basic Request Library
  /// @notice Provides helpers for handling and hashing BasicRequest structs
  /// @dev Contains EIP-712 type hash and origin hash logic for BasicRequest
  library BasicRequestLib {
      /// @dev EIP-712 type definition for BasicRequest struct
      bytes internal constant BASIC_REQUEST_TYPE = abi.encodePacked(
          "BasicRequest(",
          "uint256 originChainId,",
          "uint256 destinationChainId,",
          "uint256 deadline,",
          "uint256 nonce,",
          "address sender,",
          "address receiver,",
          "address delegate,",
          "address bungeeGateway,",
          "uint32 switchboardId,",
          "address inputToken,",
          "uint256 inputAmount,",
          "address outputToken,",
          "uint256 minOutputAmount,",
          "uint256 refuelAmount)"
      );
      /// @dev Keccak256 hash of the BASIC_REQUEST_TYPE
      bytes32 internal constant BASIC_REQUEST_TYPE_HASH = keccak256(BASIC_REQUEST_TYPE);

      /// @notice Computes the EIP-712 hash of a BasicRequest struct for the origin chain
      /// @dev Enforces originChainId to be the current chainId. Resulting hash is the same on all chains.
      ///      Helps avoid extra checking of chainId in the contract.
      /// @param basicReq BasicRequest object to be hashed
      /// @return bytes32 The EIP-712 hash of the BasicRequest struct
      function originHash(IBungeeInbox.BasicRequest memory basicReq) internal view returns (bytes32) {
          return keccak256(
              abi.encodePacked(
                  BASIC_REQUEST_TYPE_HASH,
                  abi.encode(
                      block.chainid,
                      basicReq.destinationChainId,
                      basicReq.deadline,
                      basicReq.nonce,
                      basicReq.sender,
                      basicReq.receiver,
                      basicReq.delegate,
                      basicReq.bungeeGateway,
                      basicReq.switchboardId,
                      basicReq.inputToken,
                      basicReq.inputAmount,
                      basicReq.outputToken,
                      basicReq.minOutputAmount,
                      basicReq.refuelAmount
                  )
              )
          );
      }
  }

  /// @title Bungee Request Library.
  /// @author bungee protocol
  /// @notice This library is responsible for all the hashing related to Request object.
  library BungeeInboxRequest {
      using BasicRequestLib for IBungeeInbox.BasicRequest;

      /// @dev EIP-712 type definition for Request struct
      bytes internal constant REQUEST_TYPE = abi.encodePacked(
          "Request(",
          "BasicRequest basicReq,",
          "address swapOutputToken,",
          "uint256 minSwapOutput,",
          "bytes32 metadata,",
          "bytes affiliateFees,",
          "uint256 minDestGas,",
          "bytes destinationPayload,",
          "address exclusiveTransmitter)"
      );

      /// @dev EIP-712 type definition for Bungee Request, including BasicRequest
      bytes internal constant BUNGEE_REQUEST_TYPE = abi.encodePacked(REQUEST_TYPE, BasicRequestLib.BASIC_REQUEST_TYPE);

      /// @dev Keccak256 hash of the BUNGEE_REQUEST_TYPE
      bytes32 internal constant BUNGEE_REQUEST_TYPE_HASH = keccak256(BUNGEE_REQUEST_TYPE);

      /**
       * @notice Creates a deterministic hash for a complete swap request
       * @dev Generates an EIP-712 compliant hash that uniquely identifies a swap request
       *      This hash is used for request tracking, validation, and preventing replay attacks
       * @param request The complete swap request structure containing all swap parameters
       * @return bytes32 The deterministic hash of the swap request
       */
      function createSORHash(IBungeeInbox.Request memory request) internal view returns (bytes32) {
          return keccak256(
              abi.encode(
                  BUNGEE_REQUEST_TYPE_HASH,
                  request.basicReq.originHash(),
                  request.swapOutputToken,
                  request.minSwapOutput,
                  request.metadata,
                  keccak256(request.affiliateFees),
                  request.minDestGas,
                  keccak256(request.destinationPayload),
                  request.exclusiveTransmitter
              )
          );
      }
  }
  ```
</Accordion>

<Accordion title="Simple IBungeeInbox interface for structuring and submitting crosschain requests">
  ```solidity theme={null}
  // SPDX-License-Identifier: MIT
  pragma solidity ^0.8.22;

  /// @title Bungee Inbox Interface
  /// @notice Interface for submitting and handling Bungee crosschain requests
  /// @dev Defines the structure and function for Bungee Inbox requests
  interface IBungeeInbox {
      /// @notice Basic details in the request
      /// @dev Contains all the fundamental parameters required for a Bungee request
      struct BasicRequest {
          /// @notice Source chain ID
          uint256 originChainId;
          /// @notice Destination chain ID
          uint256 destinationChainId;
          /// @notice Deadline of the request
          uint256 deadline;
          /// @notice Nonce used for uniqueness in signature
          uint256 nonce;
          /// @notice Address of the user placing the request
          address sender;
          /// @notice Address of the receiver on destination chain
          address receiver;
          /// @notice Delegate address that has some rights over the request signed (e.g., cancellation)
          address delegate;
          /// @notice Address of bungee gateway, this address will have access to pull funds from the sender
          address bungeeGateway;
          /// @notice ID of the switchboard for settlement
          uint32 switchboardId;
          /// @notice Address of the input token
          address inputToken;
          /// @notice Amount of the input token
          uint256 inputAmount;
          /// @notice Output token to be received on the destination
          address outputToken;
          /// @notice Minimum amount of output token to be received on the destination
          uint256 minOutputAmount;
          /// @notice Native token refuel amount on the destination chain
          uint256 refuelAmount;
      }

      /// @notice The Request which user signs
      /// @dev Contains all parameters for a complete Bungee request, including swap and execution details
      struct Request {
          /// @notice Basic details in the request
          BasicRequest basicReq;
          /// @notice Swap output token that the user is permitting to swap input token to
          address swapOutputToken;
          /// @notice Minimum swap output the user is okay with swapping the input token to
          /// @dev Transmitter can choose or not choose to swap tokens
          uint256 minSwapOutput;
          /// @notice Any sort of metadata to be passed with the request
          bytes32 metadata;
          /// @notice Fees of the affiliate if any
          bytes affiliateFees;
          /// @notice Minimum destination gas limit to execute calldata on destination
          /// @dev Only to be used when execution is required on destination
          uint256 minDestGas;
          /// @notice Calldata to be executed on the destination
          /// @dev Calldata can only be executed on the receiver in the request
          bytes destinationPayload;
          /// @notice Address of the only transmitter that is permitted to execute the request
          /// @dev If the transmitter is not set, anyone can execute the request. This validation would be done off-chain by the auction house
          address exclusiveTransmitter;
      }

      /// @notice Creates a new Bungee request
      /// @dev Accepts a complete Request struct and processes it. May require a payment depending on the request.
      /// @param singleOutputRequest The complete request structure containing all parameters
      function createRequest(Request calldata singleOutputRequest) external payable;
  }
  ```
</Accordion>
