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

# Intent schema

> The public (on-chain) part and the encrypted (off-chain) part of an intent, and which fields live where.

A complete submission is **two artifacts** with different confidentiality levels:

* The **on-chain intent**, public, passed as arguments to `BridgeIntentV2.createIntent` on the source chain. Solver-facing.
* The **encrypted recipient bundle**, stored off-chain on the relayer via [`POST /store-recipients`](/api/relayer), ECIES-encrypted to the relayer's public key. Recipient-facing.

## Public (on-chain) fields

These are the arguments to `createIntent`. Visible to anyone watching the source chain:

```solidity theme={null}
function createIntent(
  address _tokenA,
  address _tokenB,
  uint256 _amountA,
  uint256 _expectedAmountB,
  uint256 _reward,
  uint256 _destChainId,
  uint256 _auctionDuration
)
```

<ParamField path="_tokenA" type="address" required>
  ERC-20 address on source chain. Must be a supported asset.
</ParamField>

<ParamField path="_tokenB" type="address" required>
  ERC-20 address on destination chain.
</ParamField>

<ParamField path="_amountA" type="uint256" required>
  Amount of `_tokenA` the user is offering. The user's approval to the bridge contract must cover `_amountA + _reward`.
</ParamField>

<ParamField path="_expectedAmountB" type="uint256" required>
  Minimum acceptable amount of `_tokenB` delivered to the recipient(s). Acts as a slippage floor.
</ParamField>

<ParamField path="_reward" type="uint256" required>
  Reward paid to the winning solver, in `_tokenA`. Deducted from the user's approval alongside `_amountA`.
</ParamField>

<ParamField path="_destChainId" type="uint256" required>
  Numeric destination chain ID. Must be a directly supported chain.
</ParamField>

<ParamField path="_auctionDuration" type="uint256" required>
  Seconds the solver auction stays open after intent creation. Minimum 20 seconds (enforced by the TWAP service; tighter minimums may be enforced on `BridgeIntentV2`).
</ParamField>

The contract also emits an **encrypted blob** in the same event, containing recipient-side metadata recoverable only with the relayer's private key. This is the on-chain recovery anchor, if the relayer is ever lost, the key holder can reconstruct intent state from on-chain history. Integrators never construct this blob; the protocol handles it.

## Encrypted (off-chain) fields

Posted to [`POST /store-recipients`](/api/relayer) after `createIntent` mines:

```ts theme={null}
interface RecipientBundle {
  recipients: Address[];   // destination addresses (one or many)
  amounts:    string[];    // per-recipient amounts on destination, sum <= expectedAmountB
}
```

The bundle is JSON-serialized and ECIES-encrypted with the relayer's public key (fetched from [`GET /ecies-pubkey`](/api/relayer)), then posted hex-encoded. The relayer decrypts in its trusted environment and never writes plaintext anywhere persistent. Only the winning solver receives the bundle, re-encrypted to the solver's own keypair.

## Planned SDK shape

The SDK (WIP) will accept a single object and split it into the two artifacts internally:

```ts theme={null}
interface IntentParams {
  sourceChain: ChainId;
  destChain:   ChainId;
  tokenIn:     Address;
  tokenOut:    Address;
  amountIn:    bigint;
  minAmountOut: bigint;
  reward:      bigint;
  deadline:    number;      // unix seconds, maps to auctionDuration when contract is called
  recipients:  { address: Address; amount: bigint }[];
  metadata?:   Record<string, string>;   // off-chain only, never published
  viewers?:    Address[];                // scoped read access, off-chain only
}
```

The SDK will:

1. Call `createIntent` with the public fields above.
2. Encrypt `{ recipients, amounts }` and `POST /store-recipients`.
3. Store `metadata` and `viewers` against the intent in the relayer (off-chain only).

## Field semantics

<ParamField path="sourceChain / destChain" type="ChainId">
  Source chain the user funds from; destination chain the recipient receives on. See [supported chains](/concepts/supported-chains).
</ParamField>

<ParamField path="amountIn + reward" type="bigint">
  The user's approval to the bridge contract must be at least `amountIn + reward`. The bridge pulls this on `createIntent`; the reward pays the winning solver, the remainder is what the solver delivers on destination.
</ParamField>

<ParamField path="minAmountOut" type="bigint">
  Solvers need to deliver at least this much (summed across all recipients) for their bid to be valid at settlement.
</ParamField>

<ParamField path="deadline / auctionDuration" type="number">
  Seconds of auction window. Longer = more solver participation (better rates); shorter = faster commitment.

  * UI flows: 60–120 seconds
  * Batch / payroll: 60–300 seconds per intent
  * Server-to-server backfill: 300–600 seconds
  * TWAP tranche: `period / 2` (service default, minimum 20 seconds)
</ParamField>

<ParamField path="recipients" type="{ address, amount }[]">
  One or many. Amounts are in `tokenOut`'s base units on the destination chain. Their sum must not exceed `minAmountOut`; it can be less if solvers are expected to deliver more than the minimum (any slippage cushion stays with the recipient).
</ParamField>

<ParamField path="metadata" type="Record<string, string>">
  Integrator-defined key/value data. **Stored off-chain only**, never published on any chain. Useful for correlation with your internal records (invoice IDs, payroll periods, etc.).
</ParamField>

<ParamField path="viewers" type="Address[]">
  Addresses granted scoped read access to this intent's decrypted details (via the relayer, after the intent settles). See [viewing permissions](/guides/viewing-permissions). Cannot be modified after submission.
</ParamField>

## Allowed `ChainId` values

```ts theme={null}
type ChainId =
  | "horizen_mainnet"
  | "base_mainnet"
  | "polygon_mainnet"
  | "ethereum_mainnet"
  | "optimism_mainnet"
  | "rari_mainnet"
  // and their testnet variants, see /concepts/supported-chains
  | string;
```

Numeric chain IDs are used on-chain (the `_destChainId` arg). Call [`POST /get-routes`](/api/relayer) to enumerate live source–destination pairs at any time.

## What observers actually see

| Data                | On-chain (source)        | Relayer broadcast (to solvers, pre-bid) | Relayer (post-bid, to winning solver) |
| ------------------- | ------------------------ | --------------------------------------- | ------------------------------------- |
| Token pair          | ✓                        | ✓ (batched)                             | ✓                                     |
| Amount              | ✓                        | Aggregated across batch                 | ✓                                     |
| Reward / fees       | ✓                        | ✓ (batched)                             | ✓                                     |
| Destination chain   | ✓                        | ✓                                       | ✓                                     |
| Sender address      | ✓ (calls `createIntent`) |                                         |                                       |
| Recipient addresses | Encrypted blob only      |                                         | ✓ (re-encrypted to solver)            |
| Permit signatures   |                          |                                         | ✓ (re-encrypted to solver)            |

See [privacy guarantees](/concepts/privacy-guarantees) for the full threat model.

<Card title="SDK API reference" icon="code" href="/reference/sdk-api">
  Method signatures and return types.
</Card>
