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

# Getting a quote

> Request a Quote for an Intent

To get started with Warp, let's get a quote for a cross-chain intent.

You can do that using the `/intents/route` endpoint.

To get a quote, you'll need the **destination chain**, the **token** and **amount** on that chain, and the **account address**:

<CodeGroup dropdown>
  ```ts Get Quote theme={null}
  const baseUrl = "https://v1.orchestrator.rhinestone.dev";
  const endpoint = `${baseUrl}/intents/route`;
  const apiKey = "YOUR_RHINESTONE_API_KEY";

  const payload = {
    account: {
      address: EOA_ADDRESS,
      accountType: "EOA",
    },
    destinationChainId: 8453,
    tokenRequests: [
      {
        tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        amount: "5000000",
      },
    ],
  };

  const res = await fetch(endpoint, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": apiKey,
      Accept: "application/json",
    },
    body: JSON.stringify(payload),
  });

  if (!res.ok) {
    const errorBody = await res.text().catch(() => "");
    throw new Error(
      `Request failed: ${res.status} ${res.statusText}${errorBody ? ` - ${errorBody}` : ""}`
    );
  }

  const data = await res.json();
  console.log("Quote:", data);
  ```
</CodeGroup>

The API response includes three top-level fields:

* `intentOp`: the full intent operation the user must sign (see below)
* `intentCost`: the cost breakdown including tokens spent, tokens received, and fees
* `tokenRequirements`: the list of [token requirements](./token-requirements) to fulfill before signing

## Understanding the response

### `intentOp`

The `intentOp` object contains everything needed to build signatures and submit the intent. Key fields:

| Field            | Description                                                                                                                                       |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `elements`       | One entry per source chain involved. Each element describes what tokens are pulled from that chain and what the user receives on the destination. |
| `nonce`          | A unique nonce for Permit2 signing.                                                                                                               |
| `expires`        | Unix timestamp when the quote expires. Fetch a fresh quote if this has passed.                                                                    |
| `signedMetadata` | Orchestrator-signed metadata including token prices. Do not modify this.                                                                          |

#### Element fields

Each element in `intentOp.elements` describes one source chain:

| Field                        | Description                                                                    |
| ---------------------------- | ------------------------------------------------------------------------------ |
| `chainId`                    | The source chain ID (e.g. `"8453"` for Base).                                  |
| `arbiter`                    | The arbiter contract that validates the fill.                                  |
| `idsAndAmounts`              | Array of `[tokenId, amount]` pairs: tokens pulled from the user on this chain. |
| `mandate.recipient`          | Address that receives tokens on the destination.                               |
| `mandate.tokenOut`           | Array of `[tokenId, amount]` pairs: tokens delivered to the recipient.         |
| `mandate.destinationChainId` | The destination chain ID.                                                      |
| `mandate.fillDeadline`       | Unix timestamp by which the solver must fill.                                  |
| `mandate.destinationOps`     | Calls to execute on the destination chain after fill.                          |

Token amounts in `elements` use a packed uint256 encoding called a **token ID**. The token ID encodes the ERC-20 address in its lower 160 bits. To extract the address:

```ts theme={null}
function toToken(id: bigint): `0x${string}` {
  return `0x${(id & ((1n << 160n) - 1n)).toString(16).padStart(40, "0")}`;
}

// Example: extract the token address from an element
const element = intentOp.elements[0];
const [tokenId, amount] = element.idsAndAmounts[0];
const tokenAddress = toToken(BigInt(tokenId));
// tokenAddress = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" (USDC on Base)
```

The same encoding applies to:

* `element.idsAndAmounts`: tokens pulled from the source chain (what the user spends)
* `element.spendTokens`: tokens the solver must lock
* `element.mandate.tokenOut`: tokens delivered on the destination chain

### `intentCost`

The `intentCost` object breaks down what the user pays:

| Field             | Description                                                                                                               |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `tokensSpent`     | Map of `chainId -> tokenAddress -> { locked, unlocked, version }`. Shows exactly what leaves the user's wallet per chain. |
| `tokensReceived`  | Array of objects showing what arrives on the destination, including `amountSpent`, `destinationAmount`, and `fee`.        |
| `feeBreakdownUSD` | USD breakdown of swap, bridge, gas, and settlement fees (when available).                                                 |

## Executions (calls)

You can make executions on behalf of the EOA on the destination chain.

Note: the executions run in the context of the multicall contract. If you're sending any tokens, make sure to add a call to transfer any output back to the EOA.

```ts theme={null}
const payload = {
  // …
  destinationExecutions: [
    // Deposit USDC to a vault
    {
      to: VAULT_CONTRACT,
      value: 0n,
      data: encodeFunctionData({
        abi: vaultAbi,
        functionName: 'deposit',
        args: [usdcAmount],
      }),
    },
    // Send vault receipt token back to the EOA
    {
      to: USDC_VAULT_CONTRACT,
      value: 0n,
      data: encodeFunctionData({
        abi: erc20Abi,
        functionName: 'transfer',
        args: [tokenAmount, EOA_ADDRESS],
      }),
    }
  ],
}
```

## Sponsorship

You can mark the intent as sponsored (covering the gas and bridging costs for the user) by setting the `sponsorSettings` field:

<CodeGroup dropdown>
  ```ts {13-19} Sponsor the Intent theme={null}
  const payload = {
    destinationChainId: 8453,
    tokenRequests: [
      {
        tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        amount: "5000000",
      },
    ],
    account: {
      address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      accountType: "EOA",
    },
    options: {
      sponsorSettings: {
        gasSponsored: true,
        bridgeFeesSponsored: true,
        swapFeesSponsored: false
      }
    }
  };
  ```
</CodeGroup>

## Source Chain / Token

You can select which tokens and/or chains to use as the source of funds.

To limit the source of funds to specific chains:

<CodeGroup dropdown>
  ```ts Select Input Chains theme={null}
  const payload = {
    // …
    accountAccessList: {
      chainIds: [10, 8453]
    }
  };
  ```
</CodeGroup>

To limit the source of funds to specific tokens:

<CodeGroup dropdown>
  ```ts Select Input Tokens theme={null}
  const payload = {
    // …
    accountAccessList: {
      tokens: ["USDC", "0x4200000000000000000000000000000000000006"]
    }
  };
  ```
</CodeGroup>

To limit the source of funds to specific chains *and* tokens:

<CodeGroup dropdown>
  ```ts Select Input Chains and Tokens theme={null}
  const payload = {
    // …
    accountAccessList: {
      chainIds: [10, 8453],
      tokens: ["USDC"]
    }
  };
  ```
</CodeGroup>

or:

<CodeGroup dropdown>
  ```ts Select Input Chains and Tokens theme={null}
  const payload = {
    // …
    accountAccessList: {
      chainTokens: {
        "10": ["USDC"],
        "8453": ["WETH"]
      }
    }
  };
  ```
</CodeGroup>

## Swaps

If the destination token differs from the user's source token, Warp handles the bridge and swap automatically. No additional parameters are needed — just specify the token you want on the destination chain.

In a swap quote, `tokensSpent` and `tokensReceived` will show different tokens:

```json theme={null}
{
  "intentCost": {
    "tokensReceived": [
      {
        "tokenAddress": "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
        "hasFulfilled": true,
        "amountSpent": "81032981",
        "destinationAmount": "81029468",
        "fee": "3513"
      }
    ],
    "tokensSpent": {
      "8453": {
        "0x4200000000000000000000000000000000000006": {
          "locked": "0",
          "unlocked": "22291303013436002",
          "version": 0
        }
      }
    }
  }
}
```

Here the user is spending WETH on Base (chain 8453) to receive USDC on Optimism. The fee is deducted from the received amount (`amountSpent` minus `destinationAmount`).

## Next Steps

<Card title="Token Requirements" icon="list-checks" href="./token-requirements">
  What the intent requirements are and how to fulfill them
</Card>
