# Gasless Relayer

Submit gasless on-chain transactions using EIP-2612 permit signatures. The relayer pays gas on your behalf.

## CTF Approval

Approve the settlement contract to transfer your CTF (Conditional Token) positions gaslessly.

POST /api/v1/relayer/ctf-approval

### Request Body

```json
{
  "chainId": 137,
  "owner": "0xYourAddress...",
  "operator": "0xSettlementContract...",
  "approved": true,
  "deadline": "1735689600",
  "v": 27,
  "r": "0x...",
  "s": "0x..."
}
```

| Field      | Type    | Description                                  |
| ---------- | ------- | -------------------------------------------- |
| `chainId`  | int64   | Chain ID (e.g., `137`)                       |
| `owner`    | address | Your wallet address                          |
| `operator` | address | Settlement contract to approve               |
| `approved` | bool    | `true` to approve, `false` to revoke         |
| `deadline` | string  | Permit expiration (Unix timestamp as string) |
| `v`        | uint8   | Signature component                          |
| `r`        | string  | Signature component (32 bytes hex)           |
| `s`        | string  | Signature component (32 bytes hex)           |

### Response

```json
{
  "success": true,
  "tx_hash": "0xTransactionHash..."
}
```

### Example

```bash
curl -X POST https://api.turbinefi.com/api/v1/relayer/ctf-approval \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "chainId": 137,
    "owner": "0xYourAddress",
    "operator": "0xSettlementContract",
    "approved": true,
    "deadline": "1735689600",
    "v": 27,
    "r": "0x...",
    "s": "0x..."
  }'
```

## USDC Permit

Approve USDC spending gaslessly using an EIP-2612 permit. Use this for a one-time max approval so future orders don't need per-order permits.

POST /api/v1/relayer/usdc-permit

### Request Body

```json
{
  "chainId": 137,
  "owner": "0xYourAddress...",
  "spender": "0xSettlementContract...",
  "value": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
  "deadline": "1735689600",
  "v": 27,
  "r": "0x...",
  "s": "0x..."
}
```

| Field      | Type    | Description                                                    |
| ---------- | ------- | -------------------------------------------------------------- |
| `chainId`  | int64   | Chain ID (e.g., `137`)                                         |
| `owner`    | address | Your wallet address                                            |
| `spender`  | address | Contract to approve for spending                               |
| `value`    | string  | Amount to approve (as string). Use `uint256.max` for unlimited |
| `deadline` | string  | Permit expiration (Unix timestamp as string)                   |
| `v`        | uint8   | Signature component                                            |
| `r`        | string  | Signature component (32 bytes hex)                             |
| `s`        | string  | Signature component (32 bytes hex)                             |

### Response

```json
{
  "success": true,
  "tx_hash": "0xTransactionHash..."
}
```

### Example

```bash
curl -X POST https://api.turbinefi.com/api/v1/relayer/usdc-permit \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "chainId": 137,
    "owner": "0xYourAddress",
    "spender": "0xSettlementContract",
    "value": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
    "deadline": "1735689600",
    "v": 27,
    "r": "0x...",
    "s": "0x..."
  }'
```

## CTF Redemption

Redeem CTF outcome tokens for USDC after a market resolves. The relayer submits the `redeemPositionsWithPermit` transaction on your behalf.

POST /api/v1/relayer/ctf-redemption

### Request Body

```json
{
  "chainId": 137,
  "owner": "0xYourAddress...",
  "collateralToken": "0xUSDCAddress...",
  "parentCollectionId": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "conditionId": "0xConditionId...",
  "indexSets": ["1", "2"],
  "deadline": "1735689600",
  "v": 27,
  "r": "0x...",
  "s": "0x...",
  "marketAddress": "0xMarketContract..."
}
```

| Field                | Type      | Description                                          |
| -------------------- | --------- | ---------------------------------------------------- |
| `chainId`            | int64     | Chain ID (e.g., `137`)                               |
| `owner`              | address   | Your wallet address                                  |
| `collateralToken`    | address   | USDC contract address                                |
| `parentCollectionId` | bytes32   | Parent collection (use zero bytes for top-level)     |
| `conditionId`        | bytes32   | Gnosis CTF condition identifier                      |
| `indexSets`          | string\[] | Outcome index sets to redeem (e.g., `["1", "2"]`)    |
| `deadline`           | string    | Permit expiration (Unix timestamp as string)         |
| `v`                  | uint8     | Signature component                                  |
| `r`                  | string    | Signature component (32 bytes hex)                   |
| `s`                  | string    | Signature component (32 bytes hex)                   |
| `marketAddress`      | address   | Market contract address (optional, for PNL tracking) |

### Response

```json
{
  "success": true,
  "tx_hash": "0xTransactionHash..."
}
```

### Example

```bash
curl -X POST https://api.turbinefi.com/api/v1/relayer/ctf-redemption \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "chainId": 137,
    "owner": "0xYourAddress",
    "collateralToken": "0xUSDCAddress",
    "parentCollectionId": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "conditionId": "0xConditionId",
    "indexSets": ["1", "2"],
    "deadline": "1735689600",
    "v": 27,
    "r": "0x...",
    "s": "0x...",
    "marketAddress": "0xMarketContract"
  }'
```

## Batch CTF Redemption

Redeem positions across multiple markets in a single transaction using Multicall3. More gas-efficient than individual redemptions.

POST /api/v1/relayer/batch-ctf-redemption

### Request Body

```json
{
  "chainId": 137,
  "owner": "0xYourAddress...",
  "redemptions": [
    {
      "marketAddress": "0xMarketA...",
      "collateralToken": "0xUSDCAddress...",
      "parentCollectionId": "0x000...000",
      "conditionId": "0xConditionIdA...",
      "indexSets": ["1", "2"],
      "deadline": "1735689600",
      "v": 27,
      "r": "0x...",
      "s": "0x..."
    },
    {
      "marketAddress": "0xMarketB...",
      "collateralToken": "0xUSDCAddress...",
      "parentCollectionId": "0x000...000",
      "conditionId": "0xConditionIdB...",
      "indexSets": ["1", "2"],
      "deadline": "1735689600",
      "v": 28,
      "r": "0x...",
      "s": "0x..."
    }
  ]
}
```

| Field         | Type    | Description                                                                                          |
| ------------- | ------- | ---------------------------------------------------------------------------------------------------- |
| `chainId`     | int64   | Chain ID (e.g., `137`)                                                                               |
| `owner`       | address | Your wallet address                                                                                  |
| `redemptions` | array   | Array of individual redemption data (see CTF Redemption fields above, plus `marketAddress` required) |

### Response

```json
{
  "success": true,
  "txHash": "0xTransactionHash...",
  "status": "pending"
}
```

| Field     | Type   | Description                           |
| --------- | ------ | ------------------------------------- |
| `success` | bool   | Whether the transaction was submitted |
| `txHash`  | string | Transaction hash                      |
| `status`  | string | `"pending"` or `"confirmed"`          |

### Example

```bash
curl -X POST https://api.turbinefi.com/api/v1/relayer/batch-ctf-redemption \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "chainId": 137,
    "owner": "0xYourAddress",
    "redemptions": [
      {
        "marketAddress": "0xMarketA",
        "collateralToken": "0xUSDC",
        "parentCollectionId": "0x000...000",
        "conditionId": "0xConditionA",
        "indexSets": ["1", "2"],
        "deadline": "1735689600",
        "v": 27,
        "r": "0x...",
        "s": "0x..."
      }
    ]
  }'
```

## Propose Resolution

Submit a resolution proposal for an expired market. The proposer asserts an outcome via the UMA Optimistic Oracle with a bond.

POST /api/v1/relayer/propose-resolution

### Request Body

```json
{
  "chainId": 137,
  "marketAddress": "0xMarketContract...",
  "proposer": "0xYourAddress...",
  "outcome": true,
  "deadline": "1735689600",
  "v": 27,
  "r": "0x...",
  "s": "0x...",
  "bondPermitDeadline": "1735689600",
  "bondV": 27,
  "bondR": "0x...",
  "bondS": "0x..."
}
```

| Field                | Type    | Description                                            |
| -------------------- | ------- | ------------------------------------------------------ |
| `chainId`            | int64   | Chain ID (e.g., `137`)                                 |
| `marketAddress`      | address | Market contract address                                |
| `proposer`           | address | Your wallet address                                    |
| `outcome`            | bool    | Proposed outcome: `true` = YES, `false` = NO           |
| `deadline`           | string  | Permit expiration (Unix timestamp as string)           |
| `v`                  | uint8   | Signature component                                    |
| `r`                  | string  | Signature component (32 bytes hex)                     |
| `s`                  | string  | Signature component (32 bytes hex)                     |
| `bondPermitDeadline` | string  | Bond USDC permit deadline (optional, omit for testnet) |
| `bondV`              | uint8   | Bond permit signature component (optional)             |
| `bondR`              | string  | Bond permit signature component (optional)             |
| `bondS`              | string  | Bond permit signature component (optional)             |

The bond permit fields are required on mainnet where the proposer must post a UMA bond in USDC. On testnet, these can be omitted.

### Response

```json
{
  "success": true,
  "tx_hash": "0xTransactionHash..."
}
```

### Example

```bash
curl -X POST https://api.turbinefi.com/api/v1/relayer/propose-resolution \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "chainId": 137,
    "marketAddress": "0xMarketContract",
    "proposer": "0xYourAddress",
    "outcome": true,
    "deadline": "1735689600",
    "v": 27,
    "r": "0x...",
    "s": "0x..."
  }'
```

## Settle Market

Settle a market after the UMA oracle dispute window has passed (2 hours). Finalizes the winning outcome and enables redemptions.

POST /api/v1/relayer/settle-market

### Request Body

```json
{
  "chainId": 137,
  "marketAddress": "0xMarketContract...",
  "settler": "0xYourAddress...",
  "deadline": "1735689600",
  "v": 27,
  "r": "0x...",
  "s": "0x...",
  "winningOutcome": 0
}
```

| Field            | Type    | Description                                  |
| ---------------- | ------- | -------------------------------------------- |
| `chainId`        | int64   | Chain ID (e.g., `137`)                       |
| `marketAddress`  | address | Market contract address                      |
| `settler`        | address | Your wallet address                          |
| `deadline`       | string  | Permit expiration (Unix timestamp as string) |
| `v`              | uint8   | Signature component                          |
| `r`              | string  | Signature component (32 bytes hex)           |
| `s`              | string  | Signature component (32 bytes hex)           |
| `winningOutcome` | uint8   | `0` = YES, `1` = NO                          |

### Response

```json
{
  "success": true,
  "tx_hash": "0xTransactionHash..."
}
```

### Example

```bash
curl -X POST https://api.turbinefi.com/api/v1/relayer/settle-market \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{
    "chainId": 137,
    "marketAddress": "0xMarketContract",
    "settler": "0xYourAddress",
    "deadline": "1735689600",
    "v": 27,
    "r": "0x...",
    "s": "0x...",
    "winningOutcome": 0
  }'
```

## Get Pending Claims

Returns CTF redemptions waiting for on-chain confirmation.

GET /api/v1/pending-claims

### Response

```json
{
  "pendingClaims": [
    {
      "txHash": "0x...",
      "userAddress": "0x...",
      "marketAddress": "0x...",
      "marketId": "0x...",
      "payout": 50000000,
      "winningOutcome": 0,
      "submittedAt": 1735689000
    }
  ],
  "count": 1
}
```

| Field            | Type    | Description                                            |
| ---------------- | ------- | ------------------------------------------------------ |
| `txHash`         | string  | Redemption transaction hash                            |
| `userAddress`    | address | User who redeemed                                      |
| `marketAddress`  | address | Market contract address                                |
| `marketId`       | string  | Market identifier                                      |
| `payout`         | int64   | Expected payout in USDC (6 decimals). `50000000` = $50 |
| `winningOutcome` | int     | `0` = YES, `1` = NO                                    |
| `submittedAt`    | int64   | Unix timestamp when redemption was submitted           |

### Example

```bash
curl "https://api.turbinefi.com/api/v1/pending-claims"
```

## Get Failed Claims

Returns CTF redemptions that failed on-chain.

GET /api/v1/failed-claims

### Response

```json
{
  "failedClaims": [
    {
      "txHash": "0x...",
      "userAddress": "0x...",
      "marketAddress": "0x...",
      "marketId": "0x...",
      "payout": 50000000,
      "winningOutcome": 0,
      "submittedAt": 1735689000
    }
  ],
  "count": 1
}
```

The response fields are the same as pending claims.

### Example

```bash
curl "https://api.turbinefi.com/api/v1/failed-claims"
```

## Error Responses

All relayer endpoints return the same error format:

```json
{
  "success": false,
  "error": "Description of what went wrong"
}
```

<details>

<summary>Common errors</summary>

| Error                             | Description                                     |
| --------------------------------- | ----------------------------------------------- |
| `Invalid request body`            | Malformed JSON                                  |
| `Invalid address format`          | Address is not valid hex                        |
| `Invalid signature format`        | `r` and `s` must be 66 characters (0x + 64 hex) |
| `No relayer configured for chain` | Chain ID is not supported                       |

</details>
