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

# Custom Oracles & Settlement

> Designate your own settler, resolve markets, attach settlement criteria, and read the PnP AI oracle with pnp-core.

Every market resolves through a **settler** — the authority allowed to declare the winner. By
default that's the PnP protocol oracle. With `createMarketCustom` you designate your own settler
instead, giving you full programmatic control over resolution.

| Mode | How to create | Who can settle |
| - | - | - |
| **Protocol oracle** (default) | `p2p.createMarket` / `amm.createMarket` | The PnP AI oracle |
| **Custom settler** | `p2p.createMarketCustom` / `amm.createMarketCustom` | The `oracle` pubkey you pass |

> [!NOTE]
>
> Custom settlers are ideal for AI agents, DAOs, game studios, and enterprises that resolve
> markets from their own data feeds. The settler is just a Solana pubkey — a wallet, a multisig,
> or a program-derived signer.

## Create a market with your own settler

```ts theme={null}
import { PnpClient, uiToBaseUnits } from "pnp-core";

const client = PnpClient.mainnet({ wallet });

const res = await client.p2p.createMarketCustom({
  question: "Will BTC hit $150k by Dec 2026?",
  initialAmount: uiToBaseUnits(50, 6),
  side: "yes",
  endTime: new Date(Date.now() + 365 * 864e5),
  oracle: ORACLE_PUBKEY, // ← the authorized settler for this market
});

console.log("market:", res.market.toBase58());
console.log("extension:", res.extension?.toBase58()); // custom settler → extension PDA
```

The AMM path is identical, with `initialLiquidity` instead of `initialAmount`/`side`:

```ts theme={null}
await client.amm.createMarketCustom({
  question: "Will our product launch in Q2?",
  initialLiquidity: uiToBaseUnits(100, 6),
  endTime: new Date(Date.now() + 60 * 864e5),
  oracle: ORACLE_PUBKEY,
  oddsBps: 5000, // optional
});
```

> [!WARNING]
>
> The pubkey you pass as `oracle` becomes an **authorized settler** for this market — it can call
> `settle()` and `setEndTime()`. Treat it like a privileged key. Use the plain `createMarket`
> (protocol oracle) unless you deliberately want your own settler.

## Settle a market

Once the event concludes and the market is **past its `endTime`**, the settler declares the
winner. `winner` maps to the program's `yes_winner` flag.

```ts theme={null}
// Signer must be an authorized settler: the market's custom oracle, the protocol oracle,
// the P2P admin, or the global admin. An unauthorized signer reverts on-chain.
const res = await client.p2p.settle({ market: 42n, winner: "yes" });
console.log("settled:", res.signature);
```

After settlement the market's `status` becomes `"resolved"` and winners can
[redeem](https://pnpprotocol.mintlify.site/sdk/trading.md#redeem-a-winning-position).

## Reschedule the end time

An authorized settler can move a market's `endTime` (e.g. to settle early or extend). It accepts
a `Date` or unix-seconds, and may be in the past.

```ts theme={null}
await client.p2p.setEndTime({ market: 42n, endTime: new Date() }); // end it now
```

## Hand over the creator role

Transfer the creator role (fee recipient + creator privileges) to another wallet:

```ts theme={null}
await client.p2p.updateCreator({ market: 42n, newCreator: NEW_CREATOR_PUBKEY });
```

## Settlement criteria

Attach human-readable rules describing **how** a market resolves. Criteria are signed by the
creator and stored on the PnP criteria server (off-chain), where the oracle and frontend read
them. This works for protocol-oracle markets too — it's how the AI knows what to resolve.

```ts theme={null}
// Creator-signed; the client signs the message with your wallet automatically.
await client.p2p.setSettlementCriteria({
  market: 42n,
  criteria: "Resolves YES if BTC/USD on Coinbase is ≥ $150,000 at 2026-12-31 23:59 UTC.",
  data: { source: "coinbase", symbol: "BTC-USD", threshold: 150000 }, // optional structured data
});

// Read it back
const record = await client.p2p.getSettlementCriteria(42n);
console.log(record?.settlement_criteria);
```

> [!NOTE]
>
> `setSettlementCriteria` requires a wallet that can sign messages — a Node `Keypair`, or a
> browser adapter exposing `signMessage`. You must be the market's creator.

## Read the PnP AI oracle

For **protocol-oracle** markets, the AI decides whether a market can be objectively resolved and
publishes its own criteria to the indexer. Read that via `client.oracle`.

```ts theme={null}
// "checking" | "resolvable" | "unresolvable"
const status = await client.oracle.getResolvableStatus(marketPda);

// The AI's settlement criteria (or null if not processed yet)
const ai = await client.oracle.getSettlementCriteria(marketPda);
console.log(ai?.resolvable, ai?.criteria, ai?.reasoning);

// Block until the oracle finishes (polls; default 3s interval, 120s timeout)
const { status: final, criteria } = await client.oracle.waitForResolvable(marketPda, {
  intervalMs: 3000,
  timeoutMs: 120_000,
});
```

> [!NOTE]
>
> `client.oracle.getSettlementCriteria` returns the **AI's** decision; `client.p2p.getSettlementCriteria`
> returns the **creator-set** rules. They're different sources — the creator states intent, the
> oracle decides resolvability.

## Lifecycle at a glance

**1. Create with a settler**

`p2p.createMarketCustom({ …, oracle })` — your pubkey is the authorized settler.

**2. (Optional) attach criteria**

`p2p.setSettlementCriteria(...)` so users and tooling know the resolution rules.

**3. Wait for endTime**

Users trade until the market ends. Adjust with `setEndTime` if needed.

**4. Settle**

`p2p.settle({ market, winner })` from the settler wallet.

**5. Winners redeem**

Holders of the winning side call `p2p.redeem`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.