## Before you start

**Origin chain gas required**: The user must have a small amount of native gas token (e.g., ETH) on the origin chain to submit the deposit transaction. While Relay handles destination chain execution and deducts fees from the user’s tokens, the initial onchain deposit still requires native gas — this is an EVM-level requirement. If your users have **zero native tokens**, see [Gasless Swaps](https://docs.relay.link/features/gasless-swaps) to find the right approach, or use [Smart Accounts](https://docs.relay.link/references/api/api_guides/smart_accounts/smart-accounts) (EIP-7702 or ERC-4337) / [Gasless Execution](https://docs.relay.link/features/gasless-execution) for a fully gasless flow.

While not mandatory for integration, doing the following will improve the UX for your users considerably:

- **Verify user balance** \- Confirm user has sufficient funds for amount + fees, including native gas on the origin chain for the deposit transaction
- **Check chain support** \- Confirm both origin and destination chains are supported
- **Validate quote** \- Quotes are revalidated when being filled, keep your quotes as fresh as possible.
- **Handle errors** \- Implement proper error handling for API requests and transaction failures

## Get a Quote

To execute a cross-chain transaction, you need to specify the origin chain for payment, the destination chain where the contract is deployed, and the transaction data to execute. Use the [quote endpoint](https://docs.relay.link/references/api/get-quote-v2) with specific parameters for cross-chain calling. Cross-chain calls support both `EXACT_INPUT` and `EXACT_OUTPUT`. Use `EXACT_OUTPUT` when the destination call requires a precise output amount. Use `EXACT_INPUT` when you want to cap how much the user spends and can tolerate variable output.

### Using `EXACT_INPUT` with proxy contracts

For `EXACT_INPUT` calls, integrators usually need their own proxy contract on the destination chain. Because Relay delivers a variable output amount, you cannot always precompute the final calldata at quote time. Depositing into Aave is a good example. With `EXACT_OUTPUT`, the request can include two calls directly: approve the Aave pool, then call `supply()` with a fixed amount. With `EXACT_INPUT`, the destination amount is variable, so route the calls through your own Aave-specific proxy contract instead. A simple proxy contract can:

- pull the full approved token balance from the caller that initiated execution, such as Relay’s router in a Relay deposit flow
- approve the Aave pool contract
- call `supply()` using its full current balance

In that flow, your Relay request should include:

- an approval to your proxy contract, usually for `MAX_UINT256`
- a call to your proxy contract, such as `execute()`

Your proxy contract then reads its live balance at execution time and builds the final Aave interaction from that balance. The request below is schematic. In practice, `txs[].data` must contain ABI-encoded calldata.

```
curl -X POST "https://api.relay.link/quote/v2" \
  -H "Content-Type: application/json" \
  -d '{\
    "user": "WALLET",\
    "originChainId": 42161,\
    "destinationChainId": 137,\
    "originCurrency": "0x0000000000000000000000000000000000000000",\
    "destinationCurrency": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",\
    "amount": "100000000000000",\
    "tradeType": "EXACT_INPUT",\
    "txs": [\
      {\
        "to": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",\
        "data": "approve(PROXY_CONTRACT, MAX_UINT256)",\
        "value": "0"\
      },\
      {\
        "to": "PROXY_CONTRACT",\
        "data": "execute()",\
        "value": "0"\
      }\
    ]\
  }'
```

In `execute()`, your proxy can read its token balance, approve the Aave pool, and call `supply(asset, balance, onBehalfOf, referralCode)` with the live balance.

### Request and Response Examples

```
curl -X POST "https://api.relay.link/quote/v2" \
  -H "Content-Type: application/json" \
  -d '{\
    "user": "0x03508bb71268bba25ecacc8f620e01866650532c",\
    "originChainId": 1,\
    "destinationChainId": 8453,\
    "originCurrency": "0x0000000000000000000000000000000000000000",\
    "destinationCurrency": "0x0000000000000000000000000000000000000000",\
    "amount": "100000000000000000",\
    "tradeType": "EXACT_OUTPUT", // use EXACT_INPUT to cap spend and accept variable output\
    "txs": [\
      {\
        "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",\
        "value": "100000000000000000",\
        "data": "0xd0e30db0"\
      }\
    ]\
  }'
```

#### Steps for Transaction Execution

```
{
  "steps": [\
    {\
      "id": "deposit",\
      "action": "Confirm transaction in your wallet",\
      "description": "Depositing funds to the relayer to execute the swap for ETH",\
      "kind": "transaction",\
      "items": [\
        {\
          "status": "incomplete",\
          "data": {\
            "from": "0x03508bb71268bba25ecacc8f620e01866650532c",\
            "to": "0x4cd00e387622c35bddb9b4c962c136462338bc31",\
            "data": "0x49290c1c00000000000000000000000003508bb71268bba25ecacc8f620e01866650532c0d0f5bc9e030aa965a11905d83e54a407697e6fcdba5c300875db0fbf93e186b",\
            "value": "100012440985606146",\
            "chainId": 1,\
            "gas": "32713",\
            "maxFeePerGas": "386206132",\
            "maxPriorityFeePerGas": "246844318"\
          },\
          "check": {\
            "endpoint": "/intents/status/v3?requestId=0xa8de0141e504d2f7ed6b17cfd03455ecc2b17ab4e63120e43c38dce8015c1004",\
            "method": "GET"\
          }\
        }\
      ],\
      "requestId": "0xa8de0141e504d2f7ed6b17cfd03455ecc2b17ab4e63120e43c38dce8015c1004",\
      "depositAddress": ""\
    }\
  ],\
  "fees": {...},  
  "details": {...}
}
```

### Important Considerations

- Ensure your contract is compatible with Relay. Review our [Contract Compatibility](https://docs.relay.link/references/api/api_core_concepts/contract-compatibility) overview to make any necessary changes to your smart contracts.
- Include approval transactions before any ERC20 spending calls.

### Common Use Cases

- **NFT Minting with ETH**: Mint NFTs on L2s while paying from L1
- **NFT Minting with ERC20**: Mint NFTs using USDC
- **DeFi Operations**: Execute swaps, provide liquidity, or claim rewards on other chains
- **Gaming**: Execute game actions, purchase items, or claim rewards across chains

```javascript
// Mint NFT cross-chain with ETH
const mintTx = {
  to: "0xNFTContract",
  value: "50000000000000000", // 0.05 ETH mint price
  data: encodeFunctionData({
    abi: nftABI,
    functionName: "mint",
    args: [userAddress, tokenId],
  }),
};
```

```javascript
// Mint NFT cross-chain with USDC (requires approval first)
const usdcAmount = parseUnits("50", 6); // 50 USDC

const txs = [\
  {\
    to: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC contract\
    value: "0",\
    data: encodeFunctionData({\
      abi: erc20ABI,\
      functionName: "approve",\
      args: ["0xNFTContract", usdcAmount],\
    }),\
  },\
  {\
    to: "0xNFTContract",\
    value: "0",\
    data: encodeFunctionData({\
      abi: nftABI,\
      functionName: "mintWithUSDC",\
      args: [userAddress, tokenId, usdcAmount],\
    }),\
  },\
];
```
