# SDK API

***

## DopplerSDK (EVM)

The top-level entry point for all EVM SDK operations. Import from `@whetstone-research/doppler-sdk`.

```ts
import { DopplerSDK } from '@whetstone-research/doppler-sdk'

const sdk = new DopplerSDK({
  publicClient,   // viem PublicClient
  walletClient,   // viem WalletClient (optional for read-only)
  chainId,        // SupportedChainId
})
```

### Builder shortcuts

```ts
sdk.buildStaticAuction()       // → StaticAuctionBuilder<C>
sdk.buildDynamicAuction()      // → DynamicAuctionBuilder<C>
sdk.buildMulticurveAuction()   // → MulticurveBuilder<C>
sdk.buildOpeningAuction()      // → OpeningAuctionBuilder<C>
```

### Token / governance helpers

| Method                           | Returns                                                   |
| -------------------------------- | --------------------------------------------------------- |
| `getAirlockOwner()`              | `Promise<Address>`                                        |
| `getAirlockBeneficiary(shares?)` | `Promise<BeneficiaryData>` — defaults to 5% (0.05e18 WAD) |
| `getPoolInfo(poolAddress)`       | `Promise<PoolInfo>`                                       |
| `getHookInfo(hookAddress)`       | `Promise<HookInfo>`                                       |

### Entity getters

These return entity instances bound to a specific on-chain address.

| Method                                                                                                       | Returns                                                                                       |
| ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| `getStaticAuction(poolAddress)`                                                                              | `Promise<StaticAuction>`                                                                      |
| `getDynamicAuction(hookAddress)`                                                                             | `Promise<DynamicAuction>`                                                                     |
| `getMulticurvePool(tokenAddress)`                                                                            | `Promise<MulticurvePool>`                                                                     |
| `getRehypeDopplerHook(hookAddress)`                                                                          | `Promise<RehypeDopplerHook>`                                                                  |
| `getOpeningAuction(hookAddress)`                                                                             | `Promise<OpeningAuction>`                                                                     |
| `getOpeningAuctionLifecycle(initializerAddress?)`                                                            | `Promise<OpeningAuctionLifecycle>` — falls back to chain config; throws if unconfigured       |
| `getOpeningAuctionPositionManager(positionManagerAddress?)`                                                  | `Promise<OpeningAuctionPositionManager>` — falls back to chain config; throws if unconfigured |
| `getOpeningAuctionBidManager({ openingAuctionHookAddress, openingAuctionPoolKey, positionManagerAddress? })` | `Promise<OpeningAuctionBidManager>`                                                           |
| `getDerc20(tokenAddress)`                                                                                    | `Derc20`                                                                                      |

***

## Builder API Reference

Builders assemble type‑safe parameter objects for `DopplerFactory.createStaticAuction`, `DopplerFactory.createDynamicAuction`, and `DopplerFactory.createMulticurve`.

* Static auctions: Uniswap V3 style, fixed price range liquidity bootstrapping
* Dynamic auctions: Uniswap V4 hook, dynamic Dutch auction with epoch steps
* Multicurve auctions: Uniswap V4 initializer with multiple curves

### Common Concepts

* Governance defaults to `noOp` on supported chains (all except Ink)
* Fee tiers and tick spacing: 100→1, 500→10, 3000→60, 10000→200

***

## StaticAuctionBuilder

Methods (chainable):

* `tokenConfig({ name, symbol, tokenURI, yearlyMintRate? })`
* `saleConfig({ initialSupply, numTokensToSell, numeraire })`
* `withMarketCapRange({ marketCap: { start, end }, numerairePrice, fee?, numPositions?, maxShareToBeSold? })`
  * `marketCap.start` and `marketCap.end` are fully diluted market caps in USD (or whatever unit your numeraire is priced in)
  * Requires `saleConfig()` first
* `poolByTicks({ startTick, endTick, fee?, numPositions?, maxShareToBeSold? })`
* `withVesting({ duration?, cliffDuration?, recipients?, amounts? })`
* `withGovernance({ type: 'default' | 'custom' | 'noOp' })`
* `withMigration(MigrationConfig)`
* `withUserAddress(address)`
* `build()` → `CreateStaticAuctionParams`

***

## DynamicAuctionBuilder

Methods (chainable):

* `tokenConfig({ name, symbol, tokenURI, yearlyMintRate? })`
* `saleConfig({ initialSupply, numTokensToSell, numeraire? })`
* `poolConfig({ fee, tickSpacing })`
* `withMarketCapRange({ marketCap: { start, min }, numerairePrice, minProceeds, maxProceeds, duration?, epochLength? })`
  * `marketCap.start` is the starting market cap (auction begins here), `marketCap.min` is the floor price the auction descends to
  * Both values are fully diluted market caps in USD (or whatever unit your numeraire is priced in)
  * Requires `saleConfig()` first (do NOT use `poolConfig()` with this method - they are mutually exclusive)
* `auctionByTicks({ startTick, endTick, minProceeds, maxProceeds, duration?, epochLength?, gamma? })`
* `withVesting({ duration?, cliffDuration?, recipients?, amounts? })`
* `withGovernance({ type: 'default' | 'custom' | 'noOp' })`
* `withMigration(MigrationConfig)`
* `withUserAddress(address)`
* `withTime({ startTimeOffset?, blockTimestamp? })`
* `build()` → `CreateDynamicAuctionParams`

***

## MulticurveBuilder

Methods (chainable):

* `tokenConfig({ name, symbol, tokenURI, yearlyMintRate? })`
* `saleConfig({ initialSupply, numTokensToSell, numeraire })`
* `withCurves({ numerairePrice, curves, fee?, tickSpacing?, beneficiaries? })`
  * Requires `saleConfig()` first
  * `curves`: Array of `{ marketCap: { start, end }, numPositions, shares }`
  * `marketCap.start` and `marketCap.end` are fully diluted market caps in USD (or whatever unit your numeraire is priced in)
  * Shares must sum to 1e18 (100%)
* `poolConfig({ fee, tickSpacing, curves, beneficiaries? })`
  * `curves`: Array of `{ tickLower, tickUpper, numPositions, shares }`
* `withRehypeDopplerHook({ hookAddress, buybackDestination, customFee, assetBuybackPercentWad, numeraireBuybackPercentWad, beneficiaryPercentWad, lpPercentWad, graduationCalldata? })`
  * `hookAddress` — Deployed RehypeDopplerHook (must be whitelisted)
  * `buybackDestination` — Receives bought-back tokens
  * `customFee` — Swap fee in bps (3000 = 0.3%)
  * `assetBuybackPercentWad` — % for asset buyback (WAD, 1e18 = 100%)
  * `numeraireBuybackPercentWad` — % for numeraire buyback (WAD)
  * `beneficiaryPercentWad` — % for beneficiaries (WAD)
  * `lpPercentWad` — % for LPs (WAD)
  * `graduationCalldata` — Optional calldata executed on graduation
* `withVesting({ duration?, cliffDuration?, recipients?, amounts? })`
* `withGovernance({ type: 'default' | 'custom' | 'noOp' })`
* `withMigration(MigrationConfig)`
* `withUserAddress(address)`
* `build()` → `CreateMulticurveParams`

### Multicurve rules

* First curve's `marketCap.start` = the launch price
* Curves must be contiguous or overlapping (no gaps)
* Shares must sum to exactly 1e18 (100%)

***

## OpeningAuctionBuilder

An auction used to place single sided LP positions in advance of a Doppler Dynamic auction. It can be used to mitigate sniping or more effectively set the clearing price prior to other price discovery auctions. Obtain via `sdk.buildOpeningAuction()`.

Methods (chainable):

* `tokenConfig(params)` — standard or doppler404 token
  * Standard: `{ name, symbol, tokenURI, yearlyMintRate? }`
  * Doppler404: `{ type: 'doppler404', name, symbol, baseURI, unit? }`
* `saleConfig({ initialSupply, numTokensToSell, numeraire })` — `numTokensToSell ≤ initialSupply`
* `openingAuctionConfig(params: OpeningAuctionConfig)`:
  * `auctionDuration` — opening auction duration in seconds (positive integer)
  * `tickSpacing` — opening auction pool tick spacing
  * `fee` — opening auction pool fee (0–`V4_MAX_FEE`)
  * `minAcceptableTickToken0` / `minAcceptableTickToken1` — int24 price floor/ceiling
  * `minLiquidity` — minimum liquidity the auction must attract (bigint, positive)
  * `shareToAuctionBps` — share of `numTokensToSell` allocated to the opening pool (1–10000)
  * `incentiveShareBps` — bidder incentive share in bps (0–10000)
* `dopplerConfig(params: OpeningAuctionDopplerConfig)`:
  * `minProceeds`, `maxProceeds` — soft and hard raise targets (bigint)
  * `startTick`, `endTick` — Doppler price range (direction depends on numeraire token ordering)
  * `duration?` — Doppler auction duration in seconds
  * `epochLength?` — Doppler epoch length in seconds; must divide `duration` evenly
  * `gamma?` — tick step per epoch; computed optimally when omitted
  * `numPdSlugs?` — number of price-discovery slugs
  * `fee?` — Doppler pool fee
  * `tickSpacing?` — Doppler pool tick spacing; must divide `openingAuction.tickSpacing` evenly
* `withVesting({ duration?, cliffDuration?, recipients?, amounts? })`
* `withGovernance(params: GovernanceOption<C>)` — `{ type: 'default' | 'noOp' | 'launchpad' | 'custom' }`
* `withMigration(migration: MigrationConfig)` — required; e.g. `{ type: 'uniswapV2' }`
* `withUserAddress(address)` — required
* `withIntegrator(address?)` — optional integrator fee recipient
* `withGasLimit(gas?)` — optional gas override (bigint)
* `withTime({ startTimeOffset?, startingTime?, blockTimestamp? })` — mutually exclusive: use `startTimeOffset` (seconds from now) or `startingTime` (absolute unix timestamp or Date)
* Module overrides (advanced): `withOpeningAuctionInitializer(address)`, `withOpeningAuctionPositionManager(address)`, `withAirlock(address)`, `withTokenFactory(address)`, `withDopplerDeployer(address)`, `withGovernanceFactory(address)`, `withV2Migrator(address)`, `withV4Migrator(address)`, `withNoOpMigrator(address)`
* `build()` → `CreateOpeningAuctionParams` — validates all constraints; throws descriptive errors on invalid config

Factory method:

```ts
const { hookAddress, tokenAddress, poolId } = await sdk.factory.createOpeningAuction(params)
```

***

## Factory methods

```ts
const { poolAddress, tokenAddress } = await sdk.factory.createStaticAuction(params)
const { hookAddress, tokenAddress, poolId } = await sdk.factory.createDynamicAuction(params)
const { poolId, tokenAddress } = await sdk.factory.createMulticurve(params)
const { hookAddress, tokenAddress, poolId } = await sdk.factory.createOpeningAuction(params)
```

***

## Solana SDK

### Initializer

The `initializer` namespace handles Doppler launches on Solana.

**`createInitializeLaunchInstruction(accounts, args)`**

Builds the on-chain instruction for a new Doppler launch.

Accounts (key fields):

| Account                    | Description                                                                  |
| -------------------------- | ---------------------------------------------------------------------------- |
| `config`                   | Global initializer config PDA                                                |
| `launch`                   | New launch PDA                                                               |
| `launchAuthority`          | Launch authority PDA                                                         |
| `baseMint`                 | New base token mint keypair (signer)                                         |
| `quoteMint`                | Numeraire mint (e.g. WSOL)                                                   |
| `baseVault` / `quoteVault` | Token vault keypairs (signers)                                               |
| `payer` / `authority`      | Fee payer and launch authority (signers)                                     |
| `migratorProgram`          | Migrator program ID (e.g. `CPMM_MIGRATOR_PROGRAM_ID`)                        |
| `metadataAccount`          | Token metadata account                                                       |
| `addressLookupTable`       | ALT address for transaction compression (use `DOPPLER_DEVNET_ALT` on devnet) |

Args (key fields):

| Arg                                               | Type         | Description                                                                  |
| ------------------------------------------------- | ------------ | ---------------------------------------------------------------------------- |
| `namespace`                                       | `Address`    | Namespace for PDA uniqueness (typically payer address)                       |
| `launchId`                                        | `Uint8Array` | 8-byte launch ID (from `launchIdFromU64`)                                    |
| `baseDecimals`                                    | `number`     | Decimals of the base token                                                   |
| `baseTotalSupply`                                 | `bigint`     | Total base token supply (with decimals)                                      |
| `baseForDistribution`                             | `bigint`     | Tokens reserved for creator at graduation                                    |
| `baseForLiquidity`                                | `bigint`     | Tokens reserved for post-graduation liquidity                                |
| `curveVirtualBase`                                | `bigint`     | XYK virtual base reserves (from `marketCapToCurveParams`)                    |
| `curveVirtualQuote`                               | `bigint`     | XYK virtual quote reserves (from `marketCapToCurveParams`)                   |
| `curveFeeBps`                                     | `number`     | Swap fee during bonding curve phase (e.g. 100 = 1%)                          |
| `curveKind`                                       | `number`     | Curve type — use `CURVE_KIND_XYK`                                            |
| `curveParams`                                     | `Uint8Array` | Curve encoding — use `new Uint8Array([CURVE_PARAMS_FORMAT_XYK_V0])`          |
| `migratorProgram`                                 | `Address`    | Migrator program that handles graduation                                     |
| `migratorInitCalldata`                            | `Uint8Array` | Encoded graduation params (from `cpmmMigrator.encodeRegisterLaunchCalldata`) |
| `migratorMigrateCalldata`                         | `Uint8Array` | Encoded migration args (from `cpmmMigrator.encodeMigrateCalldata`)           |
| `metadataName` / `metadataSymbol` / `metadataUri` | `string`     | On-chain token metadata                                                      |

After building the instruction, append the `cpmmMigratorState` PDA as a writable remaining account so the register\_launch CPI can write graduation parameters:

```ts
const [cpmmMigratorState] = await cpmmMigrator.getCpmmMigratorStateAddress(launch)

const baseLaunchIx = createInitializeLaunchInstruction(accounts, args)

const launchIx = {
  ...baseLaunchIx,
  accounts: [
    ...(baseLaunchIx.accounts ?? []),
    { address: cpmmMigratorState, role: ACCOUNT_ROLE_WRITABLE },
  ],
}
```

***

### CPMM Migrator

The `cpmmMigrator` namespace encodes the calldata forwarded to the CPMM migrator at graduation.

**`encodeRegisterLaunchCalldata(args)`** → `Uint8Array` (`migratorInitCalldata`)

Encodes the `migratorInitCalldata` passed to `createInitializeLaunchInstruction`. Called once at launch creation to register graduation parameters.

```ts
const migratorInitCalldata = cpmmMigrator.encodeRegisterLaunchCalldata({
  cpmmConfig:              CPMM_CONFIG,   // Address of the CPMM AmmConfig
  initialSwapFeeBps:       30,            // Swap fee on graduated CPMM pool (0.3%)
  initialFeeSplitBps:      5000,          // % of fees distributed to LPs (50%)
  recipients: [
    { wallet: creatorAddress, amount: BASE_FOR_DISTRIBUTION },
  ],
  minRaiseQuote:           50_000_000_000n, // Graduation threshold in lamports (50 SOL)
  minMigrationPriceQ64Opt: null,            // Optional minimum graduation price floor
})
```

**`encodeMigrateCalldata(args)`** → `Uint8Array` (`migratorMigrateCalldata`)

Encodes the `migratorMigrateCalldata` passed to `createInitializeLaunchInstruction`. Forwarded at graduation time.

```ts
const migratorMigrateCalldata = cpmmMigrator.encodeMigrateCalldata({
  baseForDistribution: BASE_FOR_DISTRIBUTION,
  baseForLiquidity:    BASE_FOR_LIQUIDITY,
})
```

***

### CPMM

After graduation the bonding curve becomes a CPMM pool. These are the core helpers for swaps.

**`createSwapInstruction(accounts)` / `createSwapExactInInstruction(accounts, args)`**

`createSwapInstruction` is a convenience wrapper; `createSwapExactInInstruction` is the low-level form.

```ts
const ix = createSwapInstruction({
  config,
  pool:        poolAddress,
  authority:   pool.authority,
  vault0:      pool.vault0,
  vault1:      pool.vault1,
  token0Mint:  pool.token0Mint,
  token1Mint:  pool.token1Mint,
  userToken0:  userAta0,
  userToken1:  userAta1,
  user:        payer.address,
  amountIn:    1_000_000n,
  minAmountOut,
  direction:   0,
})
```

**Swap quote (off-chain, no RPC)**

```ts
const quote = getSwapQuote(pool, amountIn, direction)
// direction: 0 = token0→token1, 1 = token1→token0
// quote: { amountOut, feeTotal, feeDist, feeComp, priceImpact, executionPrice }
```

**Q64.64 fixed-point helpers**

```ts
numberToQ64(n: number): bigint   // multiply by 2^64
q64ToNumber(q: bigint): number   // divide by 2^64
```

**Pool fetching**

```ts
const [config]      = await getConfigAddress()
const [poolAddress] = await getPoolAddress(config, token0Mint, token1Mint)

// By address
const pool = await fetchPool(rpc, poolAddress)         // Pool | null

// By token pair (order-independent)
const result = await getPoolByMints(rpc, mint0, mint1) // { address, account: Pool } | null
```


---

# 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.doppler.lol/reference/api-reference.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.
