> ## 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.

# Examples & Best Practices

> End-to-end pnp-core recipes — read-only clients, browser wallets, unit handling, error handling, and security guidance.

Practical patterns for building on `pnp-core`. For per-method details see the
[API Reference](https://pnpprotocol.mintlify.site/sdk/api-reference.md).

## Full market lifecycle

Create → take a position → settle → redeem, end to end:

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

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

// 1) Create a parimutuel market seeded with 100 USDC on YES
const { marketId } = await client.p2p.createMarket({
  question: "Will it ship this month?",
  initialAmount: uiToBaseUnits(100, 6),
  side: "yes",
  endTime: new Date(Date.now() + 7 * 864e5),
});

// 2) A taker buys the NO side with slippage protection
await client.p2p.buy({
  market: marketId,
  side: "no",
  amount: uiToBaseUnits(40, 6),
  minTokensOut: uiToBaseUnits(38, 6),
});

// 3) Inspect live state
const m = await client.p2p.getMarket(marketId);
console.log(`YES ${(m.impliedYesProbability * 100).toFixed(1)}%`);

// 4) After endTime, an authorized settler resolves it
await client.p2p.settle({ market: marketId, winner: "yes" });

// 5) Winners redeem
await client.p2p.redeem({ market: marketId });
```

## Read-only client

Omit `wallet` for a client that only reads and derives — perfect for indexers, dashboards, and
server-side rendering. Write methods throw if called.

```ts theme={null}
const reader = PnpClient.mainnet();

const m = await reader.p2p.getMarket(42n);
const price = await reader.amm.readPrice(7n);
const status = await reader.oracle.getResolvableStatus(m.address);
```

## Browser wallet adapter

Pass any wallet-adapter-compatible object (exposing `publicKey` + `signTransaction`). If it also
exposes `signMessage`, off-chain flows like `setSettlementCriteria` work too.

```ts theme={null}
import { PnpClient } from "pnp-core";
import { useWallet } from "@solana/wallet-adapter-react";

function usePnp() {
  const wallet = useWallet();
  return PnpClient.mainnet({ wallet, rpcUrl: process.env.NEXT_PUBLIC_RPC });
}
```

## Working with units

On-chain amounts are **base units**; UI values are human-readable. Convert explicitly.

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

uiToBaseUnits(100, 6);          // 100_000000n  (100 USDC)
baseUnitsToUi(100_000000n, 6);  // 100

// pot sizes come back as bigint base units
const m = await client.p2p.getMarket(42n);
console.log(`pot: ${baseUnitsToUi(m.totalPot, 6)} USDC`);
```

> [!WARNING]
>
> Never mix UI and base units. Passing `100` (meaning 100 USDC) where base units are expected
> creates a market seeded with 0.0001 USDC.

## Error handling

SDK writes are normal `async` calls — wrap them and surface program logs, which carry the
on-chain revert reason.

```ts theme={null}
try {
  await client.p2p.buy({ market: 42n, side: "yes", amount: uiToBaseUnits(10, 6) });
} catch (err: any) {
  console.error(err.message);
  if (err.logs) console.error(err.logs.join("\n")); // anchor/program logs
}
```

Common reverts:

| Symptom | Likely cause |
| - | - |
| "read-only client" thrown before send | No `wallet` passed to the client |
| Buy reverts on a new-rules market | Creator-only side, or not whitelisted on the gate (id ≥ 79) |
| `settle` reverts | Signer isn't an authorized settler, or market isn't past `endTime` |
| `redeem` reverts | Market not yet settled, or you don't hold winning-side tokens |
| Insufficient funds | Wallet lacks the collateral (base units) or SOL for rent/fees |

## Security

> [!WARNING]
>
> **Never hardcode or commit private keys.** Load them from the environment or a keystore, and use
> a read-only client (`PnpClient.mainnet()` with no wallet) wherever you only need reads.

* Keep custom-oracle / settler keys in a secrets manager — that key can settle markets.
* Set `minTokensOut` on `buy` to bound slippage.
* Use a private RPC endpoint for production throughput and reliability.

## Runnable examples

The SDK repo ships a script for every market type in
[`examples/create-markets/`](https://github.com/proxima424/pnp-sdk-v2/tree/main/examples/create-markets).

> [card] [Create a Market](https://pnpprotocol.mintlify.site/sdk/create-market.md)
>
> Every create path, with parameters.

> [card] [Trading & Redemption](https://pnpprotocol.mintlify.site/sdk/trading.md)
>
> Buy, read odds, redeem.

## FAQ

> [accordion] Which networks are supported?
>
> Mainnet and devnet, via `PnpClient.mainnet()` / `PnpClient.devnet()` (or `cluster` in the
> constructor). The program id is identical on both.

> [accordion] Do I need a wallet to read data?
>
> No. Construct the client without `wallet` for reads and PDA derivations. Only writes require
> a signer.

> [accordion] Can I create Twitter / DefiLlama / Kalshi markets?
>
> Those resolution kinds exist at the protocol level but have no dedicated SDK helper yet.
> Create a general market and attach [settlement criteria](https://pnpprotocol.mintlify.site/sdk/custom-oracles.md#settlement-criteria).

> [accordion] Does the SDK support AMM trading?
>
> AMM markets are create + read (`readPrice` / `readMultiplier`) in `pnp-core` today. The
> supported end-to-end trading flow is the parimutuel (`p2p`) path.

> [accordion] ESM or CommonJS?
>
> Both. `pnp-core` ships `import` (ESM), `require` (CJS), and TypeScript declarations.


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