# Ranger Options

Ranger is a 4-strike, zone-bound payoff that pays the buyer the maximum amount when the settlement price lands inside a configured zone, with linearly decaying payouts outside that zone. Available on Base mainnet via the `client.ranger` module (Base\_r12 onwards).

## When you'd use a Ranger

* You expect the underlying to **stay within a range** at expiry (e.g., ETH between $2,300 and $2,500).
* A vanilla call/put or even a condor is too narrow — you want a clean way to express a range view with a single trade.
* You're comfortable with the seller side too: collecting premium when you expect the price to **break out** of the zone.

## Anatomy

A Ranger has 4 strikes: `[s1, s2, s3, s4]`.

* The **zone** is bounded by `s2` and `s3` — that's where the buyer earns the max payout.
* Outside the zone, the payout decays linearly toward zero between `s1`-to-`s2` and `s3`-to-`s4`.
* Below `s1` or above `s4`, the payout is zero.

The contract enforces equal **spread widths**: `s2 - s1 == s4 - s3`. This is what makes the payoff symmetric around the zone.

## Quick reference

```typescript
import { ThetanutsClient } from '@thetanuts-finance/thetanuts-client';

const client = new ThetanutsClient({ chainId: 8453, provider, signer });

// Read a Ranger option's full state
const info = await client.ranger.getInfo(rangerAddress);
// {
//   buyer, seller, creator,
//   collateralToken, collateralAmount, numContracts, expiryTimestamp,
//   chainlinkPriceFeed, strikes,
//   zone: { zoneLower, zoneUpper },
//   spreadWidth,
//   optionSettled,
// }

// Read just the zone bounds
const { zoneLower, zoneUpper } = await client.ranger.getZone(rangerAddress);

// Read the per-leg spread width
const width = await client.ranger.getSpreadWidth(rangerAddress);

// Simulate the payout at a hypothetical settlement price
const payout = await client.ranger.simulatePayout(
  rangerAddress,
  client.utils.toPriceDecimals(2400),  // settlement price (8 decimals)
  await client.ranger.getStrikes(rangerAddress),
  await client.ranger.getInfo(rangerAddress).then(i => i.numContracts),
);

// On-chain payout at an exact settlement price (no off-chain math)
const exact = await client.ranger.calculatePayout(rangerAddress, settlementPrice);

// Current TWAP from the option's price-feed consumer
const twap = await client.ranger.getTWAP(rangerAddress);
```

## Lifecycle

```typescript
// After expiry, the buyer claims the settlement payout
await client.ranger.payout(rangerAddress);

// Either party can close before expiry (mutual cancellation paths)
await client.ranger.close(rangerAddress);

// Split the position by collateral amount (returns child option address)
await client.ranger.split(rangerAddress, splitCollateralAmount);

// Transfer the buyer or seller side
await client.ranger.transfer(rangerAddress, /* isBuyer */ true, recipientAddress);

// Reclaim collateral after settlement
// Note: ownedOption is the option being reclaimed FROM, not a transfer destination.
// The reclaimed collateral goes to the caller (the signer).
// The contract keys getReclaimFee on ownedOption — the SDK forwards it as msg.value.
await client.ranger.reclaimCollateral(rangerAddress, ownedOption);

// Return any excess collateral the contract still holds
await client.ranger.returnExcessCollateral(rangerAddress);
```

## Chain support

`client.ranger` is gated on the chain registry. On chains where `chainConfig.implementations.RANGER` is missing or set to the zero address (e.g., Ethereum mainnet today), every method throws `NETWORK_UNSUPPORTED` up front instead of failing deep inside `eth_call` with a cryptic error.

```typescript
const ethClient = new ThetanutsClient({ chainId: 1, provider });
await ethClient.ranger.getInfo('0x...');
// throws { code: 'NETWORK_UNSUPPORTED',
//          message: 'RangerModule requires a chain with RangerOption deployed; chainId 1 has no RANGER implementation.' }
```

## Fees

`split()` and `reclaimCollateral()` are **payable** in r12. The SDK reads the on-chain fee (`getSplitFee()` and `getReclaimFee(ownedOption)` respectively) and forwards it as `msg.value`. Callers don't need to do anything — just have a signer with enough native-token balance to cover the fee.

## Events

Ranger options emit the same events as every other BaseOption-derived contract: `OptionInitialized`, `OptionPayout`, `OptionClosed`, `OptionExpired`, `OptionSettlementFailed`, `OptionSplit`, `ExcessCollateralReturned`, `TransferApproval`. Query them via `client.events.*` — see the [Events guide](/sdk/guides/events.md).

## See also

* [Modules Overview](/sdk/sdk-reference/modules-overview.md#clientranger--rangermodule) — full RangerModule API reference
* [Migration Guide](/sdk/resources/migration-guide.md) — what changed when moving from v0.1.x or v0.2.0
* [Events guide](/sdk/guides/events.md) — querying historical Ranger activity


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.thetanuts.finance/sdk/guides/ranger.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
