# Execute Solana Swap

Execute a quote whose source chain is Solana. This path is an alias of Execute Swap.

## Overview

`POST /v1/swap/execute-solana` uses the same request schema and the same handler as [Execute Swap](https://docs.aureahub.com/docs/swap-execute.md). The handler takes the Solana path when the target chain is `solana` — the target chain is `chain`, or the wallet's chain if omitted. With any other chain it runs the EVM path described on Execute Swap.

For a quote with `sourceChainType: "solana"`, the quote carries the swap as a base64-encoded Solana `VersionedTransaction` in `transactionData.data`. Pass `transactionData` unchanged. Aurea signs that transaction with the wallet's server-held keypair, sends it, and waits for confirmation before responding.

- The response has `status: "confirmed"` and the Solana transaction signature in `txHash`; `fromToken`, `toToken`, `fromAmount` and `expectedToAmount` are empty strings. There is no broadcast step.
- There is no approval step on Solana: Check Allowance and Approve Token return `not_applicable` values.
- **Non-custodial Solana wallets are not supported.** Wallets with key management scheme `client_side`, `client_side_pending` or `mpc_tss` get `400` `Non-custodial Solana swaps are not yet supported`.
- **The wallet must be a Solana wallet.** An EVM wallet named for a swap on `solana` answers `404` `Wallet not found`, as a wallet that does not exist does.
- `quoteExpiry` and `gasless` have no effect on this path.

> ℹ️ **Institutional tenants only.** For a tenant on the institutional security profile, this route needs an `Idempotency-Key`, and the tenant's policy decides before anything is signed or handed out to sign. A rule that asks for an approval holds the operation: the route answers `202` with the operation to follow (the **202** tab below), and nothing is signed or sent until the rule's approvers approve it — [Approvals](https://docs.aureahub.com/docs/guide-approvals.md). The policy's other refusals: [Policy Sets](https://docs.aureahub.com/docs/guide-policy-sets.md). Every other tenant gets the answers below, unchanged.

## Endpoint

### `POST /v1/swap/execute-solana`

Authentication: bearer token required.

Alias of POST /v1/swap/execute. For custodial Solana wallets, signs and sends the quote's VersionedTransaction.

**Headers**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Optional — required for a tenant on the institutional security profile (`400` `IDEMPOTENCY_KEY_REQUIRED` without it). Up to 255 letters, digits, - or _. The same key with the same request answers with the first answer (`idempotency-replayed: true`) instead of running it again; see [Idempotency](https://docs.aureahub.com/docs/idempotency.md) |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `walletId` | string (uuid) | yes | Solana wallet that executes the swap. Must belong to the authenticated user. |
| `quoteId` | string | yes | `quoteId` from Get Quote; stored with the transaction. |
| `transactionData` | object | yes | `transactionData` from the quote. `data` (required) holds the base64 `VersionedTransaction`; `to` may be `null`; `value` and `gasLimit` are not needed on Solana. |
| `chain` | string | no | `solana` selects the Solana path. Defaults to the wallet's chain. |
| `isTestnet` | boolean | no | Use Solana devnet. Defaults to `false`. |
| `fromAmount` | string | no | Stored in transaction metadata and used as the record's amount. |
| `toAmount` | string | no | Stored in transaction metadata. |
| `fromTokenSymbol` | string | no | Stored in transaction metadata. |
| `toTokenSymbol` | string | no | Stored in transaction metadata. |
| `fromTokenDecimals` | integer | no | Stored in transaction metadata. |
| `toTokenDecimals` | integer | no | Stored in transaction metadata. |
| `fromTokenAddress` | string | no | Stored in transaction metadata. |
| `toTokenAddress` | string | no | Stored in transaction metadata. |
| `quoteExpiry` | string | no | Accepted (shared schema); not used on the Solana path. |
| `gasless` | boolean | no | Accepted (shared schema); not used. |

**Responses**

`200` OK

```json
{
  "transactionId": "…",
  "txHash": "5Uf…",
  "status": "confirmed",
  "fromToken": "",
  "toToken": "",
  "fromAmount": "",
  "expectedToAmount": ""
}
```

`202` Held for approval

```json
{
  "operationId": "1d7a3c52-8e4b-4f19-a0c6-2b9e7d5f3a18",
  "state": "PENDING_AUTHORIZATION",
  "subState": "awaiting_approval",
  "approval": {
    "id": "c3e1a9f4-6b2d-4e8a-9f17-5d0c2b8e4a63",
    "ruleId": "e2b6d9f1-7a3c-4c58-8b0e-5f1a4d2c9b73",
    "ruleName": "Large transfers need two approvers",
    "threshold": 2,
    "expiresAt": null
  }
}
```

`400` Bad Request

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "Non-custodial Solana swaps are not yet supported"
}
```

`404` Not Found

```json
{
  "statusCode": 404,
  "error": "NotFoundError",
  "message": "Wallet not found"
}
```

Other `400` responses: `Request validation failed`, `Cannot execute swap from watch-only wallet`, and `Failed to execute Solana swap: …` when signing or sending fails.

## Implementation

```javascript
// quote = response of POST /v1/swap/quote with sourceChainType 'solana'
async function executeSolanaSwap(token, walletId, quote) {
  if (quote.sourceChainType !== 'solana') throw new Error('Not a Solana-source quote');

  const res = await fetch('https://api.aureahub.com/v1/swap/execute-solana', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      walletId,
      chain: 'solana',
      quoteId: quote.quoteId,
      transactionData: quote.transactionData, // data = base64 VersionedTransaction
      fromAmount: quote.fromAmount,
      toAmount: quote.toAmount,
      fromTokenSymbol: quote.fromToken.symbol,
      toTokenSymbol: quote.toToken.symbol
    })
  });

  const body = await res.json();
  if (!res.ok) throw new Error(`${res.status}: ${body.message}`);

  // { transactionId, txHash: '<Solana signature>', status: 'confirmed', ... }
  return body;
}
```

---

Web version: https://docs.aureahub.com/#swap-execute-solana
