Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions packages/dynamic-bonding-curve/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,32 @@

All notable changes to the Dynamic Bonding Curve SDK will be documented in this file.

## [1.6.0] - 2026-10-02

### Added

- `client.partner.createConfig2`. Pass `transferFeeParameters` for a base-mint transfer fee, or `null` when there is none.
- `TransferFeeWithheldAuthority` and `MigratedTransferFeeAuthorityOption`.
- Swap quotes account for Token-2022 transfer fees and return `includedTransferFeeAmountIn` and `excludedTransferFeeAmountOut`. `getSwapQuoteTransferFees` fetches the quote mint and current epoch.
- `quoteSwap2` quotes `SwapMode.ExactIn`, `SwapMode.PartialFill`, and `SwapMode.ExactOut`. Pass `virtualPool` for an existing pool. Omit it to quote a `buildCurve` result before the pool exists. `client.pool.swapQuote2`, `getQuoteFromInputAmount`, and `getQuoteFromOutputAmount` call it.

### Changed

- `createConfigAndPool` and `createConfigAndPoolWithFirstBuy` always use `createConfig2`. Omitting `transferFeeParameters` is the same as `null`.
- A base transfer fee, or a quote mint with a non-zero transfer fee or a live transfer fee config authority, requires a constant token supply, no locked vesting, `MigrationFeeOption.Customizable`, and `MigratedCollectFeeMode.Compounding`. The base fee is Token-2022 only and at most 10%.
- `MigratedCollectFeeMode.Compounding` allows `compoundingFeeBps` of `0`.
- Curve builders reserve the program migration base, `ceil(migrationQuoteThreshold * (100 - migrationFee.feePercentage) / 100)`. `buildCurveWithLiquidityWeights` and `buildCurveWithCustomSqrtPrices` use constant product for `Compounding`, and concentrated liquidity for `QuoteToken` and `OutputToken`.

### Deprecated

- `client.partner.createConfig` in favour of `createConfig2`. `createConfig` and `createConfigWithTransferHook` reject a quote mint with a non-zero transfer fee or a live transfer fee config authority.

### Breaking Changes

- Swap quotes for a Token-2022 quote mint require `quoteMint` and `currentEpoch`.
- `getMigratedPoolFeeParams` throws for `MigrationFeeOption.Customizable` when `migratedPoolFee.poolFeeBps` is not set.
- `swap`, `swap2`, `claimPartnerTradingFee`, and `claimCreatorTradingFee` reject transfer-hook pools. Use `swap2WithTransferHook`, `claimPartnerTradingFee2`, and `claimCreatorTradingFee2`. Standard pool creation rejects a transfer-hook config, and transfer-hook pool creation rejects a standard config.

## [1.5.13] - 2026-09-24

### Changed
Expand Down
222 changes: 216 additions & 6 deletions packages/dynamic-bonding-curve/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- [Partner Functions](#partner-functions)
- [createConfig](#createConfig)
- [createConfig2](#createConfig2)
- [createConfigWithTransferHook](#createConfigWithTransferHook)
- [createConfigAndPool](#createConfigAndPool)
- [createConfigAndPoolWithTransferHook](#createConfigAndPoolWithTransferHook)
Expand Down Expand Up @@ -31,6 +32,7 @@
- [swap2](#swap2)
- [swap2WithTransferHook](#swap2WithTransferHook)
- [swapQuote2](#swapQuote2)
- [quoteSwap2](#quoteSwap2)
- [getQuoteFromInputAmount](#getQuoteFromInputAmount)
- [getQuoteFromOutputAmount](#getQuoteFromOutputAmount)

Expand Down Expand Up @@ -78,6 +80,9 @@
- [getPoolsFeesByCreator](#getPoolsFeesByCreator)
- [getDammV1MigrationMetadata](#getDammV1MigrationMetadata)
- [getTokenBadge](#getTokenBadge)
- [isTransferHookConfig](#isTransferHookConfig)
- [isTransferHookPool](#isTransferHookPool)
- [getConfigWithTransferHook](#getConfigWithTransferHook)

- [Helper Functions](#helper-functions)
- [deriveDbcPoolAddress](#deriveDbcPoolAddress)
Expand Down Expand Up @@ -173,7 +178,7 @@ interface CreateConfigParams {
collectFeeMode: number // 0: QuoteToken, 1: OutputToken, 2: Compounding
dynamicFee: number // 0: Disabled, 1: Enabled
poolFeeBps: number // The pool fee in basis points. Minimum 10, Maximum 1000 bps.
compoundingFeeBps?: number // Required when collectFeeMode = 2 (Compounding), otherwise must be 0
compoundingFeeBps?: number // 0 to 10_000 when collectFeeMode = 2 (Compounding). 0 collects the trading fee in the quote token. Otherwise must be 0
}
poolCreationFee: BN // The pool creation fee
partnerLiquidityVestingInfo: {
Expand Down Expand Up @@ -330,7 +335,9 @@ When creating a new configuration for a dynamic bonding curve, several validatio
**Migration and Token Type**

- New configs must use DAMM v2 (`MigrationOption.MET_DAMM_V2`). DAMM v1 migration is deprecated for new configs and new pools. Existing DAMM v1 pools can still migrate.
- Token-badge remaining account is required when the quote mint is not permissionless-supported. Use `deriveTokenBadgeAddress(quoteMint)` and pass it as `tokenBadge`. A token badge does not allow a non-zero transfer fee.
- Token-badge remaining account is required when the quote mint is not permissionless-supported. Use `deriveTokenBadgeAddress(quoteMint)` and pass it as `tokenBadge`.
- A quote mint with a zero transfer fee and a revoked transfer fee config authority is permissionless-supported. A non-zero transfer fee or a live transfer fee config authority is only accepted by `createConfig2`, and still needs a token badge when the mint is not otherwise permissionless-supported.
- `createConfig` and `createConfigWithTransferHook` reject those quote mints. Use `createConfig2`.

**Activation Type**

Expand Down Expand Up @@ -423,6 +430,66 @@ When creating a new configuration for a dynamic bonding curve, several validatio

---

### createConfig2

Creates a config through `create_config2`. This is the instruction that accepts a base-mint transfer fee and a quote mint with a non-zero transfer fee or a live transfer fee config authority.

`createConfig` is deprecated. It still creates a config with no base transfer fee, and the program rejects the quote mints above.

**Function**

```typescript
async createConfig2(params: CreateConfig2Params): Promise<Transaction>
```

**Parameters**

`CreateConfig2Params` is `CreateConfigParams` plus:

```typescript
transferFeeParameters?: {
transferFeeBasisPoints: number // 0, or 1 to 1000 (10%) for a Token-2022 base mint
withheldAuthority: number // 0: Partner, 1: Creator. Must be 0 when the fee is 0
migratedTransferFeeAuthorityOption: number // 0: Immutable, 1: RevokeZeroFee, 2: Creator, 3: Partner. Must be 0 when the fee is 0
} | null
```

Pass `null` or omit the field when the base mint has no transfer fee, including when only the quote mint has one.

`createConfigAndPool` and `createConfigAndPoolWithFirstBuy` always call `createConfig2`. Omitting `transferFeeParameters` is the same as passing `null`.

**Returns**

- A transaction that can be signed and sent to the network. The `config` account must sign.

**Example**

```typescript
const transaction = await client.partner.createConfig2({
payer,
config: configKeypair.publicKey,
feeClaimer,
leftoverReceiver,
quoteMint,
...configParameters,
transferFeeParameters: {
transferFeeBasisPoints: 250,
withheldAuthority: TransferFeeWithheldAuthority.Partner,
migratedTransferFeeAuthorityOption:
MigratedTransferFeeAuthorityOption.Immutable,
},
})
```

**Notes**

- A non-zero `transferFeeBasisPoints` requires `tokenType` Token-2022 and cannot exceed 1000 bps. The base mint is created with that fee and `maximumFee = u64::MAX`.
- When the base mint has a transfer fee, or the quote mint has a non-zero transfer fee or a live transfer fee config authority, the config must use a constant token supply (`preMigrationTokenSupply == postMigrationTokenSupply`), no locked vesting, `MigrationFeeOption.Customizable`, and `MigratedCollectFeeMode.Compounding`.
- A base or quote transfer fee lowers what DAMM v2 receives at migration. The program keeps the migration price by depositing proportionally less of the other token, so the migrated pool starts with less liquidity. The amount not deposited is added to the protocol migration fee.
- Swap quotes read the base transfer fee from `config.transferFeeBasisPoints`. For a Token-2022 quote mint they throw unless `quoteMint` and `currentEpoch` are passed. `getSwapQuoteTransferFees(connection, config)` fetches both. See [swapQuote2](#swapQuote2).

---

### createConfigWithTransferHook

Creates a Token-2022 transfer-hook config. This is the transfer-hook variant of `createConfig` and stores the transfer-hook program in the config account.
Expand Down Expand Up @@ -547,7 +614,7 @@ interface CreateConfigAndPoolParams {
collectFeeMode: number // 0: QuoteToken, 1: OutputToken, 2: Compounding
dynamicFee: number // 0: Disabled, 1: Enabled
poolFeeBps: number // The pool fee in basis points. Minimum 10, Maximum 1000 bps.
compoundingFeeBps?: number // Required when collectFeeMode = 2 (Compounding), otherwise must be 0
compoundingFeeBps?: number // 0 to 10_000 when collectFeeMode = 2 (Compounding). 0 collects the trading fee in the quote token. Otherwise must be 0
}
migratedPoolBaseFeeMode: number // 0: FeeTimeSchedulerLinear, 1: FeeTimeSchedulerExponential, 3: FeeMarketCapSchedulerLinear, 4: FeeMarketCapSchedulerExponential (defaults to FeeTimeSchedulerLinear)
migratedPoolMarketCapFeeSchedulerParams: {
Expand Down Expand Up @@ -845,7 +912,7 @@ interface CreateConfigAndPoolWithFirstBuyParams {
collectFeeMode: number // 0: QuoteToken, 1: OutputToken, 2: Compounding
dynamicFee: number // 0: Disabled, 1: Enabled
poolFeeBps: number // The pool fee in basis points. Minimum 10, Maximum 1000 bps.
compoundingFeeBps?: number // Required when collectFeeMode = 2 (Compounding), otherwise must be 0
compoundingFeeBps?: number // 0 to 10_000 when collectFeeMode = 2 (Compounding). 0 collects the trading fee in the quote token. Otherwise must be 0
}
migratedPoolBaseFeeMode: number // 0: FeeTimeSchedulerLinear, 1: FeeTimeSchedulerExponential, 3: FeeMarketCapSchedulerLinear, 4: FeeMarketCapSchedulerExponential (defaults to FeeTimeSchedulerLinear)
migratedPoolMarketCapFeeSchedulerParams: {
Expand Down Expand Up @@ -1455,7 +1522,7 @@ interface BuildCurveParams {
collectFeeMode: MigratedCollectFeeMode // 0: QuoteToken, 1: OutputToken, 2: Compounding
dynamicFee: DammV2DynamicFeeMode // 0: Disabled, 1: Enabled
poolFeeBps: number // The pool fee in basis points
compoundingFeeBps?: number // Required when collectFeeMode = 2 (Compounding), otherwise must be 0
compoundingFeeBps?: number // 0 to 10_000 when collectFeeMode = 2 (Compounding). 0 collects the trading fee in the quote token. Otherwise must be 0
baseFeeMode?: DammV2BaseFeeMode // 0: FeeTimeSchedulerLinear, 1: FeeTimeSchedulerExponential, 3: FeeMarketCapSchedulerLinear, 4: FeeMarketCapSchedulerExponential
marketCapFeeSchedulerParams?: {
// Configure for market cap-based fee scheduling
Expand Down Expand Up @@ -1690,7 +1757,7 @@ const transaction = await client.partner.createConfig({
- `priceMultiple` is required and must be greater than 1.
- The SDK derives on-chain `sqrtPriceStepBps` from `priceMultiple` and `numberOfPeriod`.
- `poolFeeBps` must be greater than 0.
- If `migratedPoolFee.collectFeeMode = MigratedCollectFeeMode.Compounding` (2), `compoundingFeeBps` must be `> 0` and `<= 10_000`; otherwise `compoundingFeeBps` must be `0`.
- If `migratedPoolFee.collectFeeMode = MigratedCollectFeeMode.Compounding` (2), `compoundingFeeBps` must be `>= 0` and `<= 10_000`. `0` collects the trading fee in the quote token. Otherwise `compoundingFeeBps` must be `0`.
- For DAMM V1 migration, all `migratedPoolFee` parameters are ignored and defaults are used.

---
Expand Down Expand Up @@ -2458,6 +2525,7 @@ const quote = await client.pool.swapQuote({
- The `amountIn` is the amount of tokens you want to swap, denominated in the smallest unit and token decimals. (e.g., lamports for SOL).
- The `slippageBps` parameter protects against slippage. Set it to a value slightly lower than the expected output.
- The `referralTokenAccount` parameter is an optional token account. If provided, the referral fee will be applied to the transaction.
- `swapQuote` applies transfer fees the same way as `swapQuote2` for exact-in. `minimumAmountOut` is based on `excludedTransferFeeAmountOut`.

---

Expand Down Expand Up @@ -2632,6 +2700,44 @@ const transaction = await client.pool.swap2WithTransferHook({

---

### quoteSwap2

Quotes `SwapMode.ExactIn`, `SwapMode.PartialFill`, or `SwapMode.ExactOut` without a client. Pass `virtualPool` for an existing pool. Omit it to quote a `buildCurve` result before the pool exists. `client.pool.swapQuote2`, `getQuoteFromInputAmount`, and `getQuoteFromOutputAmount` call this function.

**Function**

```typescript
quoteSwap2(params: QuoteSwap2Params): SwapQuote2Result
```

**Example**

```typescript
const curveConfig = buildCurve({
// token, fee, migration, liquidity distribution, and activation params
})

const exactIn = quoteSwap2({
config: curveConfig,
swapBaseForQuote: false,
swapMode: SwapMode.ExactIn,
amountIn: new BN(10_000_000_000),
slippageBps: 100,
})

const exactOut = quoteSwap2({
config: curveConfig,
swapBaseForQuote: false,
swapMode: SwapMode.ExactOut,
amountOut: exactIn.outputAmount,
slippageBps: 100,
})
```

Pass `baseTransferFeeBasisPoints` when `createConfig2` sets a base transfer fee. A Token-2022 quote mint still needs `quoteMint` and `currentEpoch`.

---

### swapQuote2

Gets the exact swap out quotation in between quote and base swaps with specific swap modes (ExactIn, ExactOut, PartialFill).
Expand Down Expand Up @@ -2707,6 +2813,24 @@ const quote = await client.pool.swapQuote2({
- The `amountIn` is the amount of tokens you want to swap, denominated in the smallest unit and token decimals. (e.g., lamports for SOL).
- The `slippageBps` parameter protects against slippage. Set it to a value slightly lower than the expected output.
- The `referralTokenAccount` parameter is an optional token account. If provided, the referral fee will be applied to the transaction.
- Transfer fees are applied before the curve on the input mint and after the curve on the output mint. `amountIn` and `amountOut` are the amounts the user pays and receives. `includedTransferFeeAmountIn` is what the user pays. `excludedTransferFeeAmountOut` is what the user receives. `minimumAmountOut` and `maximumAmountIn` use those amounts.
- A base transfer fee is read from `config.transferFeeBasisPoints`. Pass `baseMint` to use the mint's epoch fee instead, or `baseTransferFeeBasisPoints` before the mint exists. `currentEpoch` is required when either mint is set.
- When `config.quoteTokenFlag` is Token-2022, `quoteMint` and `currentEpoch` are required, because the program applies the quote mint's fee for the current epoch. `getSwapQuoteTransferFees` fetches both and returns an empty object for an SPL Token quote mint:

```typescript
const quote = client.pool.swapQuote2({
virtualPool: virtualPoolState,
config: poolConfigState,
swapBaseForQuote: false,
amountIn,
slippageBps: 50,
hasReferral: false,
eligibleForFirstSwapWithMinFee: false,
currentPoint,
swapMode: SwapMode.ExactIn,
...(await getSwapQuoteTransferFees(connection, poolConfigState)),
})
```

---

Expand Down Expand Up @@ -4398,6 +4522,92 @@ const tokenBadge = await client.state.getTokenBadge(quoteMint)

---

### isTransferHookConfig

Checks whether a config account is a transfer-hook config.

**Function**

```typescript
async isTransferHookConfig(configAddress: PublicKey | string): Promise<boolean>
```

**Parameters**

```typescript
configAddress: PublicKey | string // The address of the config account
```

**Returns**

- `true` if the account is a `ConfigWithTransferHook`, `false` otherwise or if the account does not exist.

**Example**

```typescript
const isTransferHookConfig =
await client.state.isTransferHookConfig(configAddress)
```

---

### isTransferHookPool

Checks whether a pool account is a transfer-hook pool.

**Function**

```typescript
async isTransferHookPool(poolAddress: PublicKey | string): Promise<boolean>
```

**Parameters**

```typescript
poolAddress: PublicKey | string // The address of the pool account
```

**Returns**

- `true` if the account is a `TransferHookPool`, `false` otherwise or if the account does not exist.

**Example**

```typescript
const isTransferHookPool = await client.state.isTransferHookPool(poolAddress)
```

---

### getConfigWithTransferHook

Fetches a transfer-hook config account, including its transfer hook program.

**Function**

```typescript
async getConfigWithTransferHook(configAddress: PublicKey | string): Promise<ConfigWithTransferHook | null>
```

**Parameters**

```typescript
configAddress: PublicKey | string // The address of the transfer-hook config account
```

**Returns**

- The `ConfigWithTransferHook` account (`config` and `transferHookProgram`), or `null` if it does not exist.

**Example**

```typescript
const configWithTransferHook =
await client.state.getConfigWithTransferHook(configAddress)
```

---

### getPoolFeeMetrics

Gets the fee metrics for a specific pool.
Expand Down
2 changes: 1 addition & 1 deletion packages/dynamic-bonding-curve/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@meteora-ag/dynamic-bonding-curve-sdk",
"version": "1.5.13",
"version": "1.6.0",
"main": "dist/index.cjs",
"module": "dist/index.js",
"source": "src/index.ts",
Expand Down
7 changes: 7 additions & 0 deletions packages/dynamic-bonding-curve/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const ONE_Q64 = new BN(1).shln(RESOLUTION)

export const FEE_DENOMINATOR = 1_000_000_000
export const MAX_BASIS_POINT = 10_000
export const MAX_BASE_TRANSFER_FEE_BPS = 1_000

export const U16_MAX = 65_535
export const U24_MAX = 16_777_215
Expand Down Expand Up @@ -52,6 +53,12 @@ export const HOST_FEE_PERCENT = 20 // 20%
// Swap Buffer
export const SWAP_BUFFER_PERCENTAGE = 25 // 25%

// Protocol liquidity migration fee
export const PROTOCOL_LIQUIDITY_MIGRATION_FEE_BPS = 20 // 0.2%

// DAMM v2 locks this liquidity in a compounding pool
export const DAMM_V2_COMPOUNDING_DEAD_LIQUIDITY = new BN(100).shln(64)

// Migration Fee
export const MAX_MIGRATION_FEE_PERCENTAGE = 99 // 99% // previously 50%
export const MAX_CREATOR_MIGRATION_FEE_PERCENTAGE = 100 // 100%
Expand Down
Loading
Loading