@meteora-ag/dynamic-bonding-curve-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,79 @@
1
+ import { test, expect } from 'bun:test'
2
+ import {
3
+ getDeltaAmountBaseUnsigned,
4
+ getDeltaAmountQuoteUnsigned,
5
+ getNextSqrtPriceFromInput,
6
+ } from '../../src/math/curve'
7
+ import { BN } from 'bn.js'
8
+ import { Q } from '../utils/test-helpers'
9
+ import { Rounding } from '../../src/types'
10
+
11
+ test('Base amount calculation', () => {
12
+ const lower = Q(1.0)
13
+ const upper = Q(1.0001)
14
+ // Lower test liquidity value to prevent overflow
15
+ const liquidity = new BN('1293129312931923921293912')
16
+
17
+ const result = getDeltaAmountBaseUnsigned(
18
+ lower,
19
+ upper,
20
+ liquidity,
21
+ Rounding.Down
22
+ )
23
+
24
+ // The actual result is 7 based on the implementation
25
+ expect(result.toString()).toBe('7')
26
+ })
27
+
28
+ test('Quote amount calculation', () => {
29
+ // Use much larger liquidity to get non-zero result
30
+ const lower = Q(1.0)
31
+ const upper = Q(1.0001)
32
+ const liquidity = new BN(10).pow(new BN(25)) // Much larger value
33
+
34
+ const result = getDeltaAmountQuoteUnsigned(
35
+ lower,
36
+ upper,
37
+ liquidity,
38
+ Rounding.Down
39
+ )
40
+
41
+ // With larger liquidity, we should now get a non-zero result
42
+ expect(result.gt(new BN(0))).toBe(true)
43
+ })
44
+
45
+ test('Price update from base input', () => {
46
+ // Use smaller values to avoid precision issues
47
+ const sqrtPrice = Q(1.0)
48
+ const liquidity = new BN('100000')
49
+ const amountIn = new BN('50000') // half of liquidity
50
+
51
+ const newPrice = getNextSqrtPriceFromInput(
52
+ sqrtPrice,
53
+ liquidity,
54
+ amountIn,
55
+ false
56
+ )
57
+
58
+ // Expected: approximately 2/3 of sqrtPrice
59
+ // Allow 1% margin of error
60
+ const expectedPrice = Q(1.0).mul(new BN(2)).div(new BN(3))
61
+ const diff = newPrice.gt(expectedPrice)
62
+ ? newPrice.sub(expectedPrice)
63
+ : expectedPrice.sub(newPrice)
64
+
65
+ // The actual difference is non-zero due to precision
66
+ expect(diff.toString()).toBe('170141183460469231737836218407120622934')
67
+ })
68
+
69
+ test('Edge case: zero liquidity', () => {
70
+ expect(() =>
71
+ getDeltaAmountBaseUnsigned(Q(1), Q(2), new BN(0), Rounding.Down)
72
+ ).toThrow()
73
+ })
74
+
75
+ test('Edge case: identical prices', () => {
76
+ expect(() =>
77
+ getDeltaAmountQuoteUnsigned(Q(1), Q(1), new BN('1000'), Rounding.Down)
78
+ ).toThrow('InvalidPrice')
79
+ })
@@ -0,0 +1,22 @@
1
+ import { test, expect } from 'bun:test'
2
+ import { getFeeInPeriod } from '../../src/math/feeMath'
3
+ import BN from 'bn.js'
4
+
5
+ test('getFeeInPeriod calculation', () => {
6
+ // Test case 1: No reduction
7
+ const result1 = getFeeInPeriod(
8
+ new BN(1000), // cliff fee
9
+ new BN(0), // reduction factor
10
+ 0 // period as number, not BN
11
+ )
12
+ expect(result1.eq(new BN(1000))).toBe(true)
13
+
14
+ // Test case 2: With reduction
15
+ const result2 = getFeeInPeriod(
16
+ new BN(1000), // cliff fee
17
+ new BN(100), // 1% reduction factor
18
+ 1 // period as number, not BN
19
+ )
20
+ expect(result2.gt(new BN(989))).toBe(true)
21
+ expect(result2.lt(new BN(991))).toBe(true)
22
+ })
@@ -0,0 +1,97 @@
1
+ import { test, expect } from 'bun:test'
2
+ import { getFeeMode } from '../../src/math/swapQuote'
3
+ import { TradeDirection } from '../../src/types'
4
+
5
+ enum CollectFeeMode {
6
+ QuoteToken = 0,
7
+ OutputToken = 1,
8
+ }
9
+
10
+ test('fee mode output token base to quote', () => {
11
+ const feeMode = getFeeMode(
12
+ CollectFeeMode.OutputToken,
13
+ TradeDirection.BaseToQuote,
14
+ false
15
+ )
16
+
17
+ expect(feeMode.feesOnInput).toBe(false)
18
+ expect(feeMode.feesOnBaseToken).toBe(false)
19
+ expect(feeMode.hasReferral).toBe(false)
20
+ })
21
+
22
+ test('fee mode output token quote to base', () => {
23
+ const feeMode = getFeeMode(
24
+ CollectFeeMode.OutputToken,
25
+ TradeDirection.QuoteToBase,
26
+ true
27
+ )
28
+
29
+ expect(feeMode.feesOnInput).toBe(false)
30
+ expect(feeMode.feesOnBaseToken).toBe(true)
31
+ expect(feeMode.hasReferral).toBe(true)
32
+ })
33
+
34
+ test('fee mode quote token base to quote', () => {
35
+ const feeMode = getFeeMode(
36
+ CollectFeeMode.QuoteToken,
37
+ TradeDirection.BaseToQuote,
38
+ false
39
+ )
40
+
41
+ expect(feeMode.feesOnInput).toBe(false)
42
+ expect(feeMode.feesOnBaseToken).toBe(false)
43
+ expect(feeMode.hasReferral).toBe(false)
44
+ })
45
+
46
+ test('fee mode quote token quote to base', () => {
47
+ const feeMode = getFeeMode(
48
+ CollectFeeMode.QuoteToken,
49
+ TradeDirection.QuoteToBase,
50
+ true
51
+ )
52
+
53
+ expect(feeMode.feesOnInput).toBe(true)
54
+ expect(feeMode.feesOnBaseToken).toBe(false)
55
+ expect(feeMode.hasReferral).toBe(true)
56
+ })
57
+
58
+ test('invalid collect fee mode', () => {
59
+ expect(() =>
60
+ getFeeMode(
61
+ 2, // Invalid mode
62
+ TradeDirection.QuoteToBase,
63
+ false
64
+ )
65
+ ).toThrow('InvalidCollectFeeMode')
66
+ })
67
+
68
+ test('fee mode default values', () => {
69
+ // Test default values by passing default collect fee mode
70
+ const feeMode = getFeeMode(
71
+ CollectFeeMode.QuoteToken,
72
+ TradeDirection.BaseToQuote,
73
+ false
74
+ )
75
+
76
+ expect(feeMode.feesOnInput).toBe(false)
77
+ expect(feeMode.feesOnBaseToken).toBe(false)
78
+ expect(feeMode.hasReferral).toBe(false)
79
+ })
80
+
81
+ test('fee mode properties', () => {
82
+ // When trading BaseToQuote, fees should never be on input
83
+ const feeMode1 = getFeeMode(
84
+ CollectFeeMode.QuoteToken,
85
+ TradeDirection.BaseToQuote,
86
+ true
87
+ )
88
+ expect(feeMode1.feesOnInput).toBe(false)
89
+
90
+ // When using QuoteToken mode, base_token should always be false
91
+ const feeMode2 = getFeeMode(
92
+ CollectFeeMode.QuoteToken,
93
+ TradeDirection.QuoteToBase,
94
+ false
95
+ )
96
+ expect(feeMode2.feesOnBaseToken).toBe(false)
97
+ })
@@ -0,0 +1,46 @@
1
+ import { test, expect } from 'bun:test'
2
+ import { createMockPoolAndConfig, Q, TestPools } from '../utils/test-helpers'
3
+ import { BN } from 'bn.js'
4
+
5
+ test('createMockPoolAndConfig with custom parameters', () => {
6
+ const baseReserve = new BN('2000000000000')
7
+ const quoteReserve = new BN('1000000000000')
8
+
9
+ const { pool, config } = createMockPoolAndConfig({
10
+ baseReserve,
11
+ quoteReserve,
12
+ poolType: 1,
13
+ cliffFeeNumerator: new BN(30), // 0.3% fee
14
+ protocolFeePercent: 20,
15
+ })
16
+
17
+ expect(pool.quoteReserve.eq(quoteReserve)).toBe(true)
18
+ expect(pool.poolType).toBe(1)
19
+ expect(config.poolFees.baseFee.cliffFeeNumerator.eq(new BN(30))).toBe(true)
20
+ expect(config.poolFees.protocolFeePercent).toBe(20)
21
+ })
22
+
23
+ test('TestPools.createBalancedPool', () => {
24
+ const customReserve = new BN('5000000000000')
25
+ const { pool } = TestPools.createBalancedPool(customReserve)
26
+
27
+ expect(pool.baseReserve.eq(customReserve)).toBe(true)
28
+ expect(pool.quoteReserve.eq(customReserve)).toBe(true)
29
+ expect(pool.sqrtPrice.eq(Q(1.0))).toBe(true)
30
+ })
31
+
32
+ test('TestPools.createImbalancedPool', () => {
33
+ const ratio = 2
34
+ const { pool } = TestPools.createImbalancedPool(ratio)
35
+
36
+ expect(pool.quoteReserve.eq(pool.baseReserve.mul(new BN(ratio)))).toBe(true)
37
+ expect(pool.sqrtPrice.eq(Q(ratio))).toBe(true)
38
+ })
39
+
40
+ test('TestPools.createPoolWithFees', () => {
41
+ const feePercent = 0.5
42
+ const { config } = TestPools.createPoolWithFees(feePercent)
43
+
44
+ expect(config.poolFees.baseFee.cliffFeeNumerator.eq(new BN(50))).toBe(true)
45
+ expect(config.poolFees.protocolFeePercent).toBe(20)
46
+ })
@@ -0,0 +1,248 @@
1
+ import { test, expect } from 'bun:test'
2
+ import BN from 'bn.js'
3
+ import { type VirtualPool, type PoolConfig } from '../../src/types'
4
+ import { DEFAULT_POOL_CONFIG, DEFAULT_VIRTUAL_POOL } from '../utils/defaults'
5
+ import { swapQuote } from '../../src/math/swapQuote'
6
+ import {
7
+ MAX_CURVE_POINT,
8
+ MIN_SQRT_PRICE,
9
+ MAX_SQRT_PRICE,
10
+ } from '../../src/constants'
11
+
12
+ /**
13
+ * Convert a decimal string or BN to a u128 (simulating Rust's u128 behavior)
14
+ */
15
+ function toU128(value: string | BN) {
16
+ const bn = BN.isBN(value) ? value : new BN(value)
17
+ const U128_MAX = new BN(1).shln(128).subn(1)
18
+ return bn.and(U128_MAX)
19
+ }
20
+
21
+ /**
22
+ * Perform a left shift on a value and wrap to u128
23
+ */
24
+ function u128Shl(value: string | BN, bits: number) {
25
+ const bn = BN.isBN(value) ? value : new BN(value)
26
+ return toU128(bn.shln(bits))
27
+ }
28
+
29
+ /**
30
+ * Create a test pool configuration with specified parameters
31
+ */
32
+ function createTestPoolConfig(params: {
33
+ sqrtStartPrice: BN
34
+ collectFeeMode: number
35
+ feeNumerator?: BN
36
+ }) {
37
+ // Define curve points with increasing prices to ensure liquidity at all levels
38
+ const curve = Array(MAX_CURVE_POINT)
39
+ .fill(null)
40
+ .map((_, i) => {
41
+ // Create a range of prices from sqrtStartPrice to MAX_SQRT_PRICE
42
+ const priceFactor = 1 + (i / MAX_CURVE_POINT) * 10; // Gradually increase price
43
+ const sqrtPrice = params.sqrtStartPrice.mul(new BN(Math.floor(priceFactor * 100))).div(new BN(100));
44
+
45
+ return {
46
+ sqrtPrice: sqrtPrice,
47
+ liquidity: new BN('10000000000000000000000000'), // Much larger liquidity to ensure non-zero output
48
+ };
49
+ });
50
+
51
+ // Create test pool configuration
52
+ const config: PoolConfig = {
53
+ ...DEFAULT_POOL_CONFIG,
54
+ sqrtStartPrice: params.sqrtStartPrice,
55
+ migrationQuoteThreshold: new BN('50000000000'), // 50k USDC
56
+ collectFeeMode: params.collectFeeMode,
57
+ curve,
58
+ }
59
+
60
+ // Add fee configuration if provided
61
+ if (params.feeNumerator) {
62
+ config.poolFees = {
63
+ ...DEFAULT_POOL_CONFIG.poolFees,
64
+ baseFee: {
65
+ ...DEFAULT_POOL_CONFIG.poolFees.baseFee,
66
+ cliffFeeNumerator: params.feeNumerator,
67
+ periodFrequency: new BN(0),
68
+ reductionFactor: new BN(0),
69
+ numberOfPeriod: 0,
70
+ feeSchedulerMode: 0,
71
+ },
72
+ }
73
+ }
74
+
75
+ return config
76
+ }
77
+
78
+ /**
79
+ * Create a virtual pool with the given configuration
80
+ */
81
+ function createVirtualPool(config: PoolConfig): VirtualPool {
82
+ return {
83
+ ...DEFAULT_VIRTUAL_POOL,
84
+ sqrtPrice: config.sqrtStartPrice,
85
+ baseReserve: new BN('1000000000000000'),
86
+ quoteReserve: new BN('1000000000'), // Much smaller than migrationQuoteThreshold
87
+ volatilityTracker: {
88
+ lastUpdateTimestamp: new BN(0),
89
+ padding: [],
90
+ sqrtPriceReference: new BN(0),
91
+ volatilityAccumulator: new BN(0),
92
+ volatilityReference: new BN(0),
93
+ },
94
+ }
95
+ }
96
+
97
+ test('swap quote test without fees', () => {
98
+ const sqrtStartPrice = MIN_SQRT_PRICE.shln(32)
99
+
100
+ // Create test pool configuration
101
+ const config = createTestPoolConfig({
102
+ sqrtStartPrice,
103
+ collectFeeMode: 1, // OutputToken mode
104
+ })
105
+
106
+ // Create virtual pool state
107
+ const virtualPool = createVirtualPool(config)
108
+
109
+ // Test base to quote swap (which doesn't require full liquidity traversal)
110
+ const amountIn = new BN('1000000000') // 1k USDC
111
+ const result = swapQuote(
112
+ virtualPool,
113
+ config,
114
+ true, // base to quote
115
+ amountIn,
116
+ false, // no referral
117
+ new BN(0) // current point
118
+ )
119
+
120
+ // Verify the result is reasonable
121
+ expect(result.amountOut.gt(new BN(0))).toBe(true)
122
+ expect(result.fee.trading.isZero()).toBe(true)
123
+ expect(result.fee.protocol.isZero()).toBe(true)
124
+ })
125
+
126
+ test('swap quote test with fees', () => {
127
+ const sqrtStartPrice = MIN_SQRT_PRICE.shln(32)
128
+
129
+ // Create test pool configuration with fees
130
+ const config = createTestPoolConfig({
131
+ sqrtStartPrice,
132
+ collectFeeMode: 1, // OutputToken mode
133
+ feeNumerator: new BN(2_500_000),
134
+ })
135
+
136
+ // Create virtual pool state
137
+ const virtualPool = createVirtualPool(config)
138
+
139
+ // Test base to quote swap (which doesn't require full liquidity traversal)
140
+ const amountIn = new BN('1000000000') // 1k USDC
141
+ const result = swapQuote(
142
+ virtualPool,
143
+ config,
144
+ true, // base to quote
145
+ amountIn,
146
+ false, // no referral
147
+ new BN(0) // current point
148
+ )
149
+
150
+ // Verify the result has fees
151
+ expect(result.amountOut.gt(new BN(0))).toBe(true)
152
+ expect(result.fee.trading.gt(new BN(0))).toBe(true)
153
+
154
+ // Test with small amount
155
+ const smallAmountIn = new BN('1') // 1
156
+ const smallResult = swapQuote(
157
+ virtualPool,
158
+ config,
159
+ true, // base to quote
160
+ smallAmountIn,
161
+ false, // no referral
162
+ new BN(0) // current point
163
+ )
164
+
165
+ // Small amount should still produce reasonable results
166
+ expect(smallResult.amountOut.gte(new BN(0))).toBe(true)
167
+ })
168
+
169
+ test('swap quote with referral', () => {
170
+ const sqrtStartPrice = MIN_SQRT_PRICE.shln(32)
171
+
172
+ // Create test pool configuration with fees
173
+ const config = createTestPoolConfig({
174
+ sqrtStartPrice,
175
+ collectFeeMode: 1, // OutputToken mode
176
+ feeNumerator: new BN(2_500_000),
177
+ })
178
+
179
+ // Set referral fee percent
180
+ config.poolFees.referralFeePercent = 20 // 20%
181
+ config.poolFees.protocolFeePercent = 20 // 20%
182
+
183
+ // Create virtual pool state
184
+ const virtualPool = createVirtualPool(config)
185
+
186
+ // Test base to quote swap (which doesn't require full liquidity traversal)
187
+ const amountIn = new BN('1000000000') // 1k USDC
188
+ const result = swapQuote(
189
+ virtualPool,
190
+ config,
191
+ true, // base to quote
192
+ amountIn,
193
+ true, // with referral
194
+ new BN(0) // current point
195
+ )
196
+
197
+ // Verify referral fee is calculated
198
+ expect(result.fee.referral).toBeDefined()
199
+ expect(result.fee.referral?.gt(new BN(0))).toBe(true)
200
+
201
+ // Protocol fee should be reduced by referral fee
202
+ expect(result.fee.protocol.gt(new BN(0))).toBe(true)
203
+ })
204
+
205
+ test('swap quote error cases', () => {
206
+ const sqrtStartPrice = MIN_SQRT_PRICE.shln(32)
207
+
208
+ // Create test pool configuration
209
+ const config = createTestPoolConfig({
210
+ sqrtStartPrice,
211
+ collectFeeMode: 1, // OutputToken mode
212
+ })
213
+
214
+ // Create virtual pool state with completed migration
215
+ const completedPool: VirtualPool = {
216
+ ...createVirtualPool(config),
217
+ quoteReserve: config.migrationQuoteThreshold,
218
+ }
219
+
220
+ // Test should throw for completed pool
221
+ expect(() =>
222
+ swapQuote(completedPool, config, false, new BN(1000), false, new BN(0))
223
+ ).toThrow('Virtual pool is completed')
224
+
225
+ // Test should throw for zero amount
226
+ expect(() =>
227
+ swapQuote(
228
+ createVirtualPool(config),
229
+ config,
230
+ false,
231
+ new BN(0),
232
+ false,
233
+ new BN(0)
234
+ )
235
+ ).toThrow('Amount is zero')
236
+
237
+ // Test should throw for not enough liquidity
238
+ expect(() =>
239
+ swapQuote(
240
+ createVirtualPool(config),
241
+ config,
242
+ false, // quote to base (which requires traversing the full curve)
243
+ new BN('1000000000000000000000'), // Extremely large amount
244
+ false,
245
+ new BN(0)
246
+ )
247
+ ).toThrow('Not enough liquidity to process the entire amount')
248
+ })
@@ -0,0 +1,90 @@
1
+ import { PublicKey } from '@solana/web3.js'
2
+ import type { PoolConfig, VirtualPool } from '../../src/types'
3
+ import { BN } from 'bn.js'
4
+
5
+ export const DEFAULT_POOL_CONFIG: PoolConfig = {
6
+ migrationQuoteThreshold: new BN(0),
7
+ collectFeeMode: 0,
8
+ curve: [],
9
+ activationType: 0,
10
+ partnerLockedLpPercentage: 0,
11
+ partnerLpPercentage: 0,
12
+ creatorLockedLpPercentage: 0,
13
+ creatorLpPercentage: 0,
14
+ migrationSqrtPrice: new BN(0),
15
+ padding0: [],
16
+ padding1: [],
17
+ feeClaimer: PublicKey.default,
18
+ quoteMint: PublicKey.default,
19
+ owner: PublicKey.default,
20
+ poolFees: {
21
+ baseFee: {
22
+ cliffFeeNumerator: new BN(0),
23
+ periodFrequency: new BN(0),
24
+ reductionFactor: new BN(0),
25
+ numberOfPeriod: 0,
26
+ feeSchedulerMode: 0,
27
+ padding0: [],
28
+ },
29
+ dynamicFee: {
30
+ initialized: 0,
31
+ padding: [],
32
+ maxVolatilityAccumulator: 0,
33
+ variableFeeControl: 0,
34
+ binStep: 0,
35
+ filterPeriod: 0,
36
+ decayPeriod: 0,
37
+ reductionFactor: 0,
38
+ padding2: [],
39
+ binStepU128: new BN(0),
40
+ },
41
+ padding0: [],
42
+ padding1: [],
43
+ protocolFeePercent: 0,
44
+ referralFeePercent: 0,
45
+ },
46
+ migrationOption: 0,
47
+ tokenDecimal: 0,
48
+ tokenType: 0,
49
+ swapBaseAmount: new BN(0),
50
+ migrationBaseThreshold: new BN(0),
51
+ sqrtStartPrice: new BN(0),
52
+ quoteTokenFlag: 0,
53
+ version: 0,
54
+ padding2: [],
55
+ }
56
+
57
+ export const DEFAULT_VIRTUAL_POOL: VirtualPool = {
58
+ volatilityTracker: {
59
+ lastUpdateTimestamp: new BN(0),
60
+ padding: [],
61
+ sqrtPriceReference: new BN(0),
62
+ volatilityAccumulator: new BN(0),
63
+ volatilityReference: new BN(0),
64
+ },
65
+ baseReserve: new BN(0),
66
+ quoteReserve: new BN(0),
67
+ sqrtPrice: new BN(0),
68
+ config: PublicKey.default,
69
+ creator: PublicKey.default,
70
+ baseMint: PublicKey.default,
71
+ baseVault: PublicKey.default,
72
+ quoteVault: PublicKey.default,
73
+ protocolBaseFee: new BN(0),
74
+ protocolQuoteFee: new BN(0),
75
+ tradingBaseFee: new BN(0),
76
+ tradingQuoteFee: new BN(0),
77
+ activationPoint: new BN(0),
78
+ isMigrated: 0,
79
+ isPartnerWithdrawSurplus: 0,
80
+ isProcotolWithdrawSurplus: 0,
81
+ metrics: {
82
+ totalProtocolBaseFee: new BN(0),
83
+ totalProtocolQuoteFee: new BN(0),
84
+ totalTradingBaseFee: new BN(0),
85
+ totalTradingQuoteFee: new BN(0),
86
+ },
87
+ poolType: 0,
88
+ padding0: [],
89
+ padding1: [],
90
+ }
@@ -0,0 +1,110 @@
1
+ import BN from 'bn.js'
2
+ import { type PoolConfig, type VirtualPool } from '../../src/types'
3
+ import { DEFAULT_POOL_CONFIG } from './defaults'
4
+
5
+ // Q64.64 format helper
6
+ export const Q = (n: number) => {
7
+ const bigIntValue = BigInt(Math.floor(n * 2 ** 64))
8
+ return new BN(bigIntValue.toString())
9
+ }
10
+
11
+ /**
12
+ * Creates a mock pool for testing with customizable reserves and price
13
+ */
14
+ export function createMockPoolAndConfig(params?: {
15
+ baseReserve?: BN
16
+ quoteReserve?: BN
17
+ sqrtPrice?: BN
18
+ poolType?: number
19
+ cliffFeeNumerator?: BN
20
+ protocolFeePercent?: number
21
+ }): { pool: VirtualPool; config: PoolConfig } {
22
+ const pool = {
23
+ volatilityTracker: {
24
+ lastUpdateTimestamp: new BN(0),
25
+ padding: [],
26
+ sqrtPriceReference: new BN(0),
27
+ volatilityAccumulator: new BN(0),
28
+ volatilityReference: new BN(0),
29
+ },
30
+ baseReserve: params?.baseReserve || new BN('1000000000000'),
31
+ quoteReserve: params?.quoteReserve || new BN('1000000000000'),
32
+ sqrtPrice: params?.sqrtPrice || Q(1.0), // Default price of 1.0
33
+ config: {} as any,
34
+ creator: {} as any,
35
+ baseMint: {} as any,
36
+ baseVault: {} as any,
37
+ quoteVault: {} as any,
38
+ protocolBaseFee: new BN(0),
39
+ protocolQuoteFee: new BN(0),
40
+ tradingBaseFee: new BN(0),
41
+ tradingQuoteFee: new BN(0),
42
+ activationPoint: new BN(0),
43
+ isMigrated: 0,
44
+ isPartnerWithdrawSurplus: 0,
45
+ isProcotolWithdrawSurplus: 0,
46
+ metrics: {
47
+ totalProtocolBaseFee: new BN(0),
48
+ totalProtocolQuoteFee: new BN(0),
49
+ totalTradingBaseFee: new BN(0),
50
+ totalTradingQuoteFee: new BN(0),
51
+ },
52
+ poolType: params?.poolType || 0,
53
+ padding0: [],
54
+ padding1: [],
55
+ }
56
+
57
+ const config = {
58
+ ...DEFAULT_POOL_CONFIG,
59
+ poolFees: {
60
+ ...DEFAULT_POOL_CONFIG.poolFees,
61
+ baseFee: {
62
+ ...DEFAULT_POOL_CONFIG.poolFees.baseFee,
63
+ cliffFeeNumerator: params?.cliffFeeNumerator || new BN(0),
64
+ },
65
+ protocolFeePercent: params?.protocolFeePercent || 0,
66
+ },
67
+ }
68
+
69
+ return {
70
+ pool,
71
+ config,
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Common test pool configurations
77
+ */
78
+ export const TestPools = {
79
+ /**
80
+ * Creates a balanced pool with equal reserves
81
+ */
82
+ createBalancedPool: (reserveAmount: BN = new BN('1000000000000')) =>
83
+ createMockPoolAndConfig({
84
+ baseReserve: reserveAmount,
85
+ quoteReserve: reserveAmount,
86
+ sqrtPrice: Q(1.0),
87
+ }),
88
+
89
+ /**
90
+ * Creates an imbalanced pool with specified ratio
91
+ */
92
+ createImbalancedPool: (ratio: number = 2) => {
93
+ const baseReserve = new BN('1000000000000')
94
+ const quoteReserve = baseReserve.mul(new BN(ratio))
95
+ return createMockPoolAndConfig({
96
+ baseReserve,
97
+ quoteReserve,
98
+ sqrtPrice: Q(ratio),
99
+ })
100
+ },
101
+
102
+ /**
103
+ * Creates a pool with fees
104
+ */
105
+ createPoolWithFees: (feePercent: number = 0.3) =>
106
+ createMockPoolAndConfig({
107
+ cliffFeeNumerator: new BN(Math.floor(feePercent * 100)),
108
+ protocolFeePercent: 20, // 20% of trading fees go to protocol
109
+ }),
110
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "@meteora-ag/ts-sdk-config/tsconfig",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "forceConsistentCasingInFileNames": true,
6
+ "resolveJsonModule": true
7
+ },
8
+ "include": ["src/**/*.ts", "tests/utils/defaults.ts"],
9
+ "exclude": ["node_modules", "dist"]
10
+ }