@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.
- package/README.md +53 -0
- package/dist/index.cjs +14641 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5024 -0
- package/dist/index.d.ts +5024 -0
- package/dist/index.js +14641 -0
- package/dist/index.js.map +1 -0
- package/docs.md +317 -0
- package/eslint.config.mjs +4 -0
- package/package.json +46 -0
- package/src/client.ts +1848 -0
- package/src/common.ts +275 -0
- package/src/constants.ts +42 -0
- package/src/derive.ts +488 -0
- package/src/design.ts +394 -0
- package/src/idl/damm-v1/idl.json +4615 -0
- package/src/idl/damm-v1/idl.ts +1158 -0
- package/src/idl/damm-v2/idl.json +6322 -0
- package/src/idl/damm-v2/idl.ts +5224 -0
- package/src/idl/dynamic-bonding-curve/idl.json +5351 -0
- package/src/idl/dynamic-bonding-curve/idl.ts +4428 -0
- package/src/idl/dynamic-vault/idl.json +1723 -0
- package/src/idl/dynamic-vault/idl.ts +295 -0
- package/src/index.ts +7 -0
- package/src/math/curve.ts +230 -0
- package/src/math/feeMath.ts +286 -0
- package/src/math/safeMath.ts +88 -0
- package/src/math/swapQuote.ts +464 -0
- package/src/math/utilsMath.ts +154 -0
- package/src/types.ts +465 -0
- package/src/utils.ts +252 -0
- package/tests/math/curveMath.test.ts +79 -0
- package/tests/math/feeMath.test.ts +22 -0
- package/tests/math/feeMode.test.ts +97 -0
- package/tests/math/pool.test.ts +46 -0
- package/tests/math/swapQuote.test.ts +248 -0
- package/tests/utils/defaults.ts +90 -0
- package/tests/utils/test-helpers.ts +110 -0
- package/tsconfig.json +10 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Accounts,
|
|
3
|
+
BN,
|
|
4
|
+
IdlAccounts,
|
|
5
|
+
IdlTypes,
|
|
6
|
+
Program,
|
|
7
|
+
} from '@coral-xyz/anchor'
|
|
8
|
+
import type { DynamicBondingCurve } from './idl/dynamic-bonding-curve/idl'
|
|
9
|
+
import type { Keypair, PublicKey, Transaction } from '@solana/web3.js'
|
|
10
|
+
import Decimal from 'decimal.js'
|
|
11
|
+
|
|
12
|
+
// Program Type
|
|
13
|
+
export type DynamicBondingCurveProgram = Program<DynamicBondingCurve>
|
|
14
|
+
|
|
15
|
+
/////////////////
|
|
16
|
+
// IX ACCOUNTS //
|
|
17
|
+
/////////////////
|
|
18
|
+
|
|
19
|
+
export type ClaimProtocolFeeAccounts = Accounts<
|
|
20
|
+
DynamicBondingCurve['instructions']['0']
|
|
21
|
+
>['claimProtocolFee']
|
|
22
|
+
|
|
23
|
+
export type ClaimTradingFeeAccounts = Accounts<
|
|
24
|
+
DynamicBondingCurve['instructions']['1']
|
|
25
|
+
>['claimTradingFee']
|
|
26
|
+
|
|
27
|
+
export type CloseClaimFeeOperatorAccounts = Accounts<
|
|
28
|
+
DynamicBondingCurve['instructions']['2']
|
|
29
|
+
>['closeClaimFeeOperator']
|
|
30
|
+
|
|
31
|
+
export type CreateClaimFeeOperatorAccounts = Accounts<
|
|
32
|
+
DynamicBondingCurve['instructions']['3']
|
|
33
|
+
>['createClaimFeeOperator']
|
|
34
|
+
|
|
35
|
+
export type CreateConfigAccounts = Accounts<
|
|
36
|
+
DynamicBondingCurve['instructions']['4']
|
|
37
|
+
>['createConfig']
|
|
38
|
+
|
|
39
|
+
export type CreateLockerAccounts = Accounts<
|
|
40
|
+
DynamicBondingCurve['instructions']['5']
|
|
41
|
+
>['createLocker']
|
|
42
|
+
|
|
43
|
+
export type CreatePartnerMetadata = Accounts<
|
|
44
|
+
DynamicBondingCurve['instructions']['6']
|
|
45
|
+
>['createPartnerMetadata']
|
|
46
|
+
|
|
47
|
+
export type CreateVirtualPoolMetadata = Accounts<
|
|
48
|
+
DynamicBondingCurve['instructions']['7']
|
|
49
|
+
>['createVirtualPoolMetadata']
|
|
50
|
+
|
|
51
|
+
export type InitializeVirtualPoolWithSplTokenAccounts = Accounts<
|
|
52
|
+
DynamicBondingCurve['instructions']['8']
|
|
53
|
+
>['initializeVirtualPoolWithSplToken']
|
|
54
|
+
|
|
55
|
+
export type InitializeVirtualPoolWithToken2022Accounts = Accounts<
|
|
56
|
+
DynamicBondingCurve['instructions']['9']
|
|
57
|
+
>['initializeVirtualPoolWithToken2022']
|
|
58
|
+
|
|
59
|
+
export type MigrateMeteoraDammAccounts = Accounts<
|
|
60
|
+
DynamicBondingCurve['instructions']['10']
|
|
61
|
+
>['migrateMeteoraDamm']
|
|
62
|
+
|
|
63
|
+
export type MigrateMeteoraDammClaimLpTokenAccounts = Accounts<
|
|
64
|
+
DynamicBondingCurve['instructions']['11']
|
|
65
|
+
>['migrateMeteoraDammClaimLpToken']
|
|
66
|
+
|
|
67
|
+
export type MigrateMeteoraDammLockLpTokenAccounts = Accounts<
|
|
68
|
+
DynamicBondingCurve['instructions']['12']
|
|
69
|
+
>['migrateMeteoraDammLockLpToken']
|
|
70
|
+
|
|
71
|
+
export type MigrationDammV2Accounts = Accounts<
|
|
72
|
+
DynamicBondingCurve['instructions']['13']
|
|
73
|
+
>['migrationDammV2']
|
|
74
|
+
|
|
75
|
+
export type MigrationDammV2CreateMetadataAccounts = Accounts<
|
|
76
|
+
DynamicBondingCurve['instructions']['14']
|
|
77
|
+
>['migrationDammV2CreateMetadata']
|
|
78
|
+
|
|
79
|
+
export type MigrationMeteoraDammCreateMetadataAccounts = Accounts<
|
|
80
|
+
DynamicBondingCurve['instructions']['15']
|
|
81
|
+
>['migrationMeteoraDammCreateMetadata']
|
|
82
|
+
|
|
83
|
+
export type PartnerWithdrawSurplusAccounts = Accounts<
|
|
84
|
+
DynamicBondingCurve['instructions']['16']
|
|
85
|
+
>['partnerWithdrawSurplus']
|
|
86
|
+
|
|
87
|
+
export type SwapAccounts = Accounts<
|
|
88
|
+
DynamicBondingCurve['instructions']['18']
|
|
89
|
+
>['swap']
|
|
90
|
+
|
|
91
|
+
///////////////
|
|
92
|
+
// IDL Types //
|
|
93
|
+
///////////////
|
|
94
|
+
|
|
95
|
+
export type ConfigParameters = IdlTypes<DynamicBondingCurve>['configParameters']
|
|
96
|
+
export type InitializePoolParameters =
|
|
97
|
+
IdlTypes<DynamicBondingCurve>['initializePoolParameters']
|
|
98
|
+
export type SwapParameters = IdlTypes<DynamicBondingCurve>['swapParameters']
|
|
99
|
+
export type PoolFeeParameters =
|
|
100
|
+
IdlTypes<DynamicBondingCurve>['poolFeeParameters']
|
|
101
|
+
export type DynamicFeeParameters =
|
|
102
|
+
IdlTypes<DynamicBondingCurve>['dynamicFeeParameters']
|
|
103
|
+
export type LiquidityDistributionParameters =
|
|
104
|
+
IdlTypes<DynamicBondingCurve>['liquidityDistributionParameters']
|
|
105
|
+
export type PoolFeesConfig = IdlTypes<DynamicBondingCurve>['poolFeesConfig']
|
|
106
|
+
export type DynamicFeeConfig = IdlTypes<DynamicBondingCurve>['dynamicFeeConfig']
|
|
107
|
+
export type BaseFeeConfig = IdlTypes<DynamicBondingCurve>['baseFeeConfig']
|
|
108
|
+
export type PoolFees = IdlTypes<DynamicBondingCurve>['poolFees']
|
|
109
|
+
export type PoolMetrics = IdlTypes<DynamicBondingCurve>['poolMetrics']
|
|
110
|
+
export type SwapResult = IdlTypes<DynamicBondingCurve>['swapResult']
|
|
111
|
+
export type CreatePartnerMetadataParameters =
|
|
112
|
+
IdlTypes<DynamicBondingCurve>['createPartnerMetadataParameters']
|
|
113
|
+
export type CreateVirtualPoolMetadataParameters =
|
|
114
|
+
IdlTypes<DynamicBondingCurve>['createVirtualPoolMetadataParameters']
|
|
115
|
+
|
|
116
|
+
//////////////////
|
|
117
|
+
// IDL ACCOUNTS //
|
|
118
|
+
//////////////////
|
|
119
|
+
|
|
120
|
+
export type ClaimFeeOperator =
|
|
121
|
+
IdlAccounts<DynamicBondingCurve>['claimFeeOperator']
|
|
122
|
+
export type Config = IdlAccounts<DynamicBondingCurve>['config']
|
|
123
|
+
export type MeteoraDammMigrationMetadata =
|
|
124
|
+
IdlAccounts<DynamicBondingCurve>['meteoraDammMigrationMetadata']
|
|
125
|
+
export type LockEscrow = IdlAccounts<DynamicBondingCurve>['lockEscrow']
|
|
126
|
+
export type VolatilityTracker =
|
|
127
|
+
IdlTypes<DynamicBondingCurve>['volatilityTracker']
|
|
128
|
+
export type VirtualPool = IdlAccounts<DynamicBondingCurve>['virtualPool']
|
|
129
|
+
export type PoolConfig = IdlAccounts<DynamicBondingCurve>['poolConfig']
|
|
130
|
+
export type PartnerMetadata =
|
|
131
|
+
IdlAccounts<DynamicBondingCurve>['partnerMetadata']
|
|
132
|
+
export type VirtualPoolMetadata =
|
|
133
|
+
IdlAccounts<DynamicBondingCurve>['virtualPoolMetadata']
|
|
134
|
+
|
|
135
|
+
///////////
|
|
136
|
+
// ENUMS //
|
|
137
|
+
///////////
|
|
138
|
+
|
|
139
|
+
export enum ActivationType {
|
|
140
|
+
Slot = 0,
|
|
141
|
+
Timestamp = 1,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export enum TokenType {
|
|
145
|
+
SPL = 0,
|
|
146
|
+
Token2022 = 1,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export enum CollectFeeMode {
|
|
150
|
+
OnlyQuote = 0,
|
|
151
|
+
Both = 1,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export enum MigrationOption {
|
|
155
|
+
MET_DAMM = 0,
|
|
156
|
+
MET_DAMM_V2 = 1,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export enum CollectFeeMode {
|
|
160
|
+
QuoteToken = 0,
|
|
161
|
+
OutputToken = 1,
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export enum FeeSchedulerMode {
|
|
165
|
+
Linear = 0,
|
|
166
|
+
Exponential = 1,
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export enum MigrationFeeOption {
|
|
170
|
+
FixedBps25 = 0,
|
|
171
|
+
FixedBps30 = 1,
|
|
172
|
+
FixedBps100 = 2,
|
|
173
|
+
FixedBps200 = 3,
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export enum TokenDecimal {
|
|
177
|
+
SIX = 6,
|
|
178
|
+
NINE = 9,
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export enum TradeDirection {
|
|
182
|
+
BaseToQuote = 0,
|
|
183
|
+
QuoteToBase = 1,
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export enum Rounding {
|
|
187
|
+
Up,
|
|
188
|
+
Down,
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
///////////
|
|
192
|
+
// TYPES //
|
|
193
|
+
///////////
|
|
194
|
+
|
|
195
|
+
export type CreateConfigParam = Omit<
|
|
196
|
+
CreateConfigAccounts,
|
|
197
|
+
'program' | 'eventAuthority' | 'systemProgram'
|
|
198
|
+
> &
|
|
199
|
+
ConfigParameters
|
|
200
|
+
|
|
201
|
+
export type CreateDammMigrationMetadataParam = {
|
|
202
|
+
payer: PublicKey
|
|
203
|
+
virtualPool: PublicKey
|
|
204
|
+
config: PublicKey
|
|
205
|
+
migrateToDammV2: boolean
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export type CreateConstantProductConfigWithLockVestingParam = {
|
|
209
|
+
lockVestingParams: {
|
|
210
|
+
percentageSupplyVesting: number
|
|
211
|
+
frequency: number
|
|
212
|
+
numberOfPeriod: number
|
|
213
|
+
cliffUnlockEnabled: boolean
|
|
214
|
+
}
|
|
215
|
+
totalTokenSupply: number
|
|
216
|
+
percentageSupplyOnMigration: number
|
|
217
|
+
startPrice: Decimal
|
|
218
|
+
migrationPrice: Decimal
|
|
219
|
+
tokenBaseDecimal: number
|
|
220
|
+
tokenQuoteDecimal: number
|
|
221
|
+
swapBufferPercentage: number
|
|
222
|
+
baseFeeBps: number
|
|
223
|
+
dynamicFeeEnabled: boolean
|
|
224
|
+
activationType: ActivationType
|
|
225
|
+
collectFeeMode: CollectFeeMode
|
|
226
|
+
migrationOption: MigrationOption
|
|
227
|
+
migrationFeeOption: MigrationFeeOption
|
|
228
|
+
tokenType: TokenType
|
|
229
|
+
partnerLpPercentage: number
|
|
230
|
+
creatorLpPercentage: number
|
|
231
|
+
partnerLockedLpPercentage: number
|
|
232
|
+
creatorLockedLpPercentage: number
|
|
233
|
+
feeClaimer: PublicKey
|
|
234
|
+
leftoverReceiver: PublicKey
|
|
235
|
+
payer: PublicKey
|
|
236
|
+
quoteMint: PublicKey
|
|
237
|
+
config: PublicKey
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export type CreateConstantProductConfigWithoutLockVestingParam = {
|
|
241
|
+
totalTokenSupply: number
|
|
242
|
+
percentageSupplyOnMigration: number
|
|
243
|
+
startPrice: Decimal
|
|
244
|
+
tokenBaseDecimal: number
|
|
245
|
+
tokenQuoteDecimal: number
|
|
246
|
+
swapBufferPercentage: number
|
|
247
|
+
baseFeeBps: number
|
|
248
|
+
dynamicFeeEnabled: boolean
|
|
249
|
+
activationType: ActivationType
|
|
250
|
+
collectFeeMode: CollectFeeMode
|
|
251
|
+
migrationOption: MigrationOption
|
|
252
|
+
migrationFeeOption: MigrationFeeOption
|
|
253
|
+
tokenType: TokenType
|
|
254
|
+
partnerLpPercentage: number
|
|
255
|
+
creatorLpPercentage: number
|
|
256
|
+
partnerLockedLpPercentage: number
|
|
257
|
+
creatorLockedLpPercentage: number
|
|
258
|
+
feeClaimer: PublicKey
|
|
259
|
+
leftoverReceiver: PublicKey
|
|
260
|
+
payer: PublicKey
|
|
261
|
+
quoteMint: PublicKey
|
|
262
|
+
config: PublicKey
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export type DesignCurveParam = {
|
|
266
|
+
tokenDecimal: TokenDecimal
|
|
267
|
+
migrationQuoteThreshold: BN
|
|
268
|
+
tokenBaseSupply: BN
|
|
269
|
+
migrationBasePercent: number
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export type DesignConstantProductCurveWithLockVestingParam = {
|
|
273
|
+
lockVestingParams: {
|
|
274
|
+
percentageSupplyVesting: number
|
|
275
|
+
frequency: number
|
|
276
|
+
numberOfPeriod: number
|
|
277
|
+
cliffUnlockEnabled: boolean
|
|
278
|
+
}
|
|
279
|
+
totalTokenSupply: number
|
|
280
|
+
percentageSupplyOnMigration: number
|
|
281
|
+
startPrice: Decimal
|
|
282
|
+
migrationPrice: Decimal
|
|
283
|
+
tokenBaseDecimal: number
|
|
284
|
+
tokenQuoteDecimal: number
|
|
285
|
+
swapBufferPercentage: number
|
|
286
|
+
baseFeeBps: number
|
|
287
|
+
dynamicFeeEnabled: boolean
|
|
288
|
+
activationType: ActivationType
|
|
289
|
+
collectFeeMode: CollectFeeMode
|
|
290
|
+
migrationOption: MigrationOption
|
|
291
|
+
migrationFeeOption: MigrationFeeOption
|
|
292
|
+
tokenType: TokenType
|
|
293
|
+
partnerLpPercentage: number
|
|
294
|
+
creatorLpPercentage: number
|
|
295
|
+
partnerLockedLpPercentage: number
|
|
296
|
+
creatorLockedLpPercentage: number
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export type DesignConstantProductCurveWithoutLockVestingParam = {
|
|
300
|
+
totalTokenSupply: number
|
|
301
|
+
percentageSupplyOnMigration: number
|
|
302
|
+
startPrice: Decimal
|
|
303
|
+
tokenBaseDecimal: number
|
|
304
|
+
tokenQuoteDecimal: number
|
|
305
|
+
swapBufferPercentage: number
|
|
306
|
+
baseFeeBps: number
|
|
307
|
+
dynamicFeeEnabled: boolean
|
|
308
|
+
activationType: ActivationType
|
|
309
|
+
collectFeeMode: CollectFeeMode
|
|
310
|
+
migrationOption: MigrationOption
|
|
311
|
+
migrationFeeOption: MigrationFeeOption
|
|
312
|
+
tokenType: TokenType
|
|
313
|
+
partnerLpPercentage: number
|
|
314
|
+
creatorLpPercentage: number
|
|
315
|
+
partnerLockedLpPercentage: number
|
|
316
|
+
creatorLockedLpPercentage: number
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export type DesignCurveResponse = {
|
|
320
|
+
sqrtStartPrice: BN
|
|
321
|
+
curve: LiquidityDistributionParameters[]
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export type MigrateToDammV1Param = {
|
|
325
|
+
payer: PublicKey
|
|
326
|
+
virtualPool: PublicKey
|
|
327
|
+
dammConfig: PublicKey
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export type MigrateToDammV2Param = {
|
|
331
|
+
payer: PublicKey
|
|
332
|
+
virtualPool: PublicKey
|
|
333
|
+
dammConfig: PublicKey
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export type MigrateToDammV2Response = {
|
|
337
|
+
transaction: Transaction
|
|
338
|
+
firstPositionNftKeypair: Keypair
|
|
339
|
+
secondPositionNftKeypair: Keypair
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export type ClaimTradingFeeParam = {
|
|
343
|
+
feeClaimer: PublicKey
|
|
344
|
+
pool: PublicKey
|
|
345
|
+
maxBaseAmount: BN
|
|
346
|
+
maxQuoteAmount: BN
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export type CreateVirtualPoolMetadataParam = {
|
|
350
|
+
virtualPool: PublicKey
|
|
351
|
+
name: string
|
|
352
|
+
website: string
|
|
353
|
+
logo: string
|
|
354
|
+
creator: PublicKey
|
|
355
|
+
payer: PublicKey
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export type CreatePartnerMetadataParam = {
|
|
359
|
+
name: string
|
|
360
|
+
website: string
|
|
361
|
+
logo: string
|
|
362
|
+
feeClaimer: PublicKey
|
|
363
|
+
payer: PublicKey
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export type CreatePoolParam = {
|
|
367
|
+
name: string
|
|
368
|
+
symbol: string
|
|
369
|
+
uri: string
|
|
370
|
+
config: PublicKey
|
|
371
|
+
creator: PublicKey
|
|
372
|
+
baseMint: PublicKey
|
|
373
|
+
quoteMint: PublicKey
|
|
374
|
+
baseTokenType: TokenType
|
|
375
|
+
quoteTokenType: TokenType
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export type SwapParam = {
|
|
379
|
+
owner: PublicKey
|
|
380
|
+
amountIn: BN
|
|
381
|
+
minimumAmountOut: BN
|
|
382
|
+
swapBaseForQuote: boolean
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export type SwapQuoteParam = {
|
|
386
|
+
virtualPool: VirtualPool
|
|
387
|
+
config: PoolConfig
|
|
388
|
+
swapBaseForQuote: boolean
|
|
389
|
+
amountIn: BN
|
|
390
|
+
hasReferral: boolean
|
|
391
|
+
currentPoint: BN
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
export type DammLpTokenParam = {
|
|
395
|
+
payer: PublicKey
|
|
396
|
+
virtualPool: PublicKey
|
|
397
|
+
dammConfig: PublicKey
|
|
398
|
+
isPartner: boolean
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export type PartnerWithdrawSurplusParam = {
|
|
402
|
+
feeClaimer: PublicKey
|
|
403
|
+
virtualPool: PublicKey
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export type WithdrawLeftoverParam = {
|
|
407
|
+
payer: PublicKey
|
|
408
|
+
virtualPool: PublicKey
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export type CreateLockerParam = {
|
|
412
|
+
payer: PublicKey
|
|
413
|
+
virtualPool: PublicKey
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
////////////////
|
|
417
|
+
// INTERFACES //
|
|
418
|
+
////////////////
|
|
419
|
+
|
|
420
|
+
export interface FeeResult {
|
|
421
|
+
amount: BN
|
|
422
|
+
protocolFee: BN
|
|
423
|
+
tradingFee: BN
|
|
424
|
+
referralFee: BN
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export interface FeeMode {
|
|
428
|
+
feesOnInput: boolean
|
|
429
|
+
feesOnBaseToken: boolean
|
|
430
|
+
hasReferral: boolean
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export interface QuoteResult {
|
|
434
|
+
amountOut: BN
|
|
435
|
+
minimumAmountOut: BN
|
|
436
|
+
nextSqrtPrice: BN
|
|
437
|
+
fee: {
|
|
438
|
+
trading: BN
|
|
439
|
+
protocol: BN
|
|
440
|
+
referral?: BN
|
|
441
|
+
}
|
|
442
|
+
price: {
|
|
443
|
+
beforeSwap: number
|
|
444
|
+
afterSwap: number
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export interface FeeOnAmountResult {
|
|
449
|
+
amount: BN // Amount remaining after taking trading fee
|
|
450
|
+
protocolFee: BN // Final protocol fee (after referral deduction)
|
|
451
|
+
tradingFee: BN // Portion of trading fee NOT going to protocol
|
|
452
|
+
referralFee: BN // Referral fee amount
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export interface PrepareSwapParams {
|
|
456
|
+
inputMint: PublicKey
|
|
457
|
+
outputMint: PublicKey
|
|
458
|
+
inputTokenProgram: PublicKey
|
|
459
|
+
outputTokenProgram: PublicKey
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
export interface SwapAmount {
|
|
463
|
+
outputAmount: BN
|
|
464
|
+
nextSqrtPrice: BN
|
|
465
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { AnchorProvider, Program, Wallet } from '@coral-xyz/anchor'
|
|
2
|
+
import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'
|
|
3
|
+
import {
|
|
4
|
+
PublicKey,
|
|
5
|
+
SystemProgram,
|
|
6
|
+
TransactionInstruction,
|
|
7
|
+
type Connection,
|
|
8
|
+
type GetProgramAccountsFilter,
|
|
9
|
+
} from '@solana/web3.js'
|
|
10
|
+
import type { DynamicBondingCurve } from './idl/dynamic-bonding-curve/idl'
|
|
11
|
+
import DynamicBondingCurveIDL from './idl/dynamic-bonding-curve/idl.json'
|
|
12
|
+
import type { DynamicVault } from './idl/dynamic-vault/idl'
|
|
13
|
+
import DynamicVaultIDL from './idl/dynamic-vault/idl.json'
|
|
14
|
+
import type { DammV1 } from './idl/damm-v1/idl'
|
|
15
|
+
import DammV1IDL from './idl/damm-v1/idl.json'
|
|
16
|
+
import {
|
|
17
|
+
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
18
|
+
createCloseAccountInstruction,
|
|
19
|
+
getAssociatedTokenAddressSync,
|
|
20
|
+
NATIVE_MINT,
|
|
21
|
+
TOKEN_PROGRAM_ID,
|
|
22
|
+
} from '@solana/spl-token'
|
|
23
|
+
import { TokenType } from './types'
|
|
24
|
+
import BN from 'bn.js'
|
|
25
|
+
|
|
26
|
+
export function getSecondKey(key1: PublicKey, key2: PublicKey) {
|
|
27
|
+
const buf1 = key1.toBuffer()
|
|
28
|
+
const buf2 = key2.toBuffer()
|
|
29
|
+
// Buf1 > buf2
|
|
30
|
+
if (Buffer.compare(buf1, buf2) === 1) {
|
|
31
|
+
return buf2
|
|
32
|
+
}
|
|
33
|
+
return buf1
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function getFirstKey(key1: PublicKey, key2: PublicKey) {
|
|
37
|
+
const buf1 = key1.toBuffer()
|
|
38
|
+
const buf2 = key2.toBuffer()
|
|
39
|
+
// Buf1 > buf2
|
|
40
|
+
if (Buffer.compare(buf1, buf2) === 1) {
|
|
41
|
+
return buf1
|
|
42
|
+
}
|
|
43
|
+
return buf2
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a program instance
|
|
48
|
+
* @param connection - The connection to the network
|
|
49
|
+
* @returns The program instance
|
|
50
|
+
*/
|
|
51
|
+
export function createProgram(connection: Connection) {
|
|
52
|
+
const provider = new AnchorProvider(connection, null as unknown as Wallet, {
|
|
53
|
+
commitment: 'confirmed',
|
|
54
|
+
})
|
|
55
|
+
const program = new Program<DynamicBondingCurve>(
|
|
56
|
+
DynamicBondingCurveIDL,
|
|
57
|
+
provider
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
return { program }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Create a vault program instance
|
|
65
|
+
* @param connection - The connection to the network
|
|
66
|
+
* @returns The vault program instance
|
|
67
|
+
*/
|
|
68
|
+
export function createVaultProgram(
|
|
69
|
+
connection: Connection
|
|
70
|
+
): Program<DynamicVault> {
|
|
71
|
+
const provider = new AnchorProvider(connection, null as unknown as Wallet, {
|
|
72
|
+
commitment: 'confirmed',
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const program = new Program<DynamicVault>(DynamicVaultIDL, provider)
|
|
76
|
+
return program
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Create a DAMM V1 program instance
|
|
81
|
+
* @param connection - The connection to the network
|
|
82
|
+
* @returns The DAMM V1 program instance
|
|
83
|
+
*/
|
|
84
|
+
export function createDammV1Program(connection: Connection): Program<DammV1> {
|
|
85
|
+
const provider = new AnchorProvider(connection, null as unknown as Wallet, {
|
|
86
|
+
commitment: 'confirmed',
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const program = new Program<DammV1>(DammV1IDL, provider)
|
|
90
|
+
return program
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Find the associated token address for a wallet and token mint
|
|
95
|
+
* @param walletAddress - The wallet address
|
|
96
|
+
* @param tokenMintAddress - The token mint address
|
|
97
|
+
* @param tokenProgramId - The token program ID
|
|
98
|
+
* @returns The associated token address
|
|
99
|
+
*/
|
|
100
|
+
export function findAssociatedTokenAddress(
|
|
101
|
+
walletAddress: PublicKey,
|
|
102
|
+
tokenMintAddress: PublicKey,
|
|
103
|
+
tokenProgramId: PublicKey
|
|
104
|
+
): PublicKey {
|
|
105
|
+
return PublicKey.findProgramAddressSync(
|
|
106
|
+
[
|
|
107
|
+
walletAddress.toBuffer(),
|
|
108
|
+
tokenProgramId.toBuffer(),
|
|
109
|
+
tokenMintAddress.toBuffer(),
|
|
110
|
+
],
|
|
111
|
+
ASSOCIATED_TOKEN_PROGRAM_ID
|
|
112
|
+
)[0]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Create a wrap SOL instruction
|
|
117
|
+
* @param from - The from address
|
|
118
|
+
* @param to - The to address
|
|
119
|
+
* @param amount - The amount to wrap
|
|
120
|
+
* @returns The wrap SOL instruction
|
|
121
|
+
*/
|
|
122
|
+
export function wrapSOLInstruction(
|
|
123
|
+
from: PublicKey,
|
|
124
|
+
to: PublicKey,
|
|
125
|
+
amount: bigint
|
|
126
|
+
): TransactionInstruction[] {
|
|
127
|
+
return [
|
|
128
|
+
SystemProgram.transfer({
|
|
129
|
+
fromPubkey: from,
|
|
130
|
+
toPubkey: to,
|
|
131
|
+
lamports: amount,
|
|
132
|
+
}),
|
|
133
|
+
new TransactionInstruction({
|
|
134
|
+
keys: [
|
|
135
|
+
{
|
|
136
|
+
pubkey: to,
|
|
137
|
+
isSigner: false,
|
|
138
|
+
isWritable: true,
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
data: Buffer.from(new Uint8Array([17])),
|
|
142
|
+
programId: TOKEN_PROGRAM_ID,
|
|
143
|
+
}),
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Create an unwrap SOL instruction
|
|
149
|
+
* @param owner - The owner of the SOL
|
|
150
|
+
* @param allowOwnerOffCurve - Whether to allow the owner to be off curve
|
|
151
|
+
* @returns The unwrap SOL instruction
|
|
152
|
+
*/
|
|
153
|
+
export function unwrapSOLInstruction(
|
|
154
|
+
owner: PublicKey,
|
|
155
|
+
allowOwnerOffCurve = true
|
|
156
|
+
): TransactionInstruction | null {
|
|
157
|
+
const wSolATAAccount = getAssociatedTokenAddressSync(
|
|
158
|
+
NATIVE_MINT,
|
|
159
|
+
owner,
|
|
160
|
+
allowOwnerOffCurve
|
|
161
|
+
)
|
|
162
|
+
if (wSolATAAccount) {
|
|
163
|
+
const closedWrappedSolInstruction = createCloseAccountInstruction(
|
|
164
|
+
wSolATAAccount,
|
|
165
|
+
owner,
|
|
166
|
+
owner,
|
|
167
|
+
[],
|
|
168
|
+
TOKEN_PROGRAM_ID
|
|
169
|
+
)
|
|
170
|
+
return closedWrappedSolInstruction
|
|
171
|
+
}
|
|
172
|
+
return null
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Get the token program for a given token type
|
|
177
|
+
* @param tokenType - The token type
|
|
178
|
+
* @returns The token program
|
|
179
|
+
*/
|
|
180
|
+
export function getTokenProgram(tokenType: TokenType): PublicKey {
|
|
181
|
+
return tokenType === TokenType.SPL
|
|
182
|
+
? TOKEN_PROGRAM_ID
|
|
183
|
+
: TOKEN_2022_PROGRAM_ID
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Create a memcmp filter for owner-based filtering
|
|
188
|
+
* @param owner - The owner public key or string
|
|
189
|
+
* @param offset - The offset where the owner field is located in the account data
|
|
190
|
+
* @returns A GetProgramAccountsFilter array with the owner filter
|
|
191
|
+
*/
|
|
192
|
+
export function createProgramAccountFilter(
|
|
193
|
+
owner: PublicKey | string,
|
|
194
|
+
offset: number
|
|
195
|
+
): GetProgramAccountsFilter[] {
|
|
196
|
+
const ownerKey = typeof owner === 'string' ? new PublicKey(owner) : owner
|
|
197
|
+
return [
|
|
198
|
+
{
|
|
199
|
+
memcmp: {
|
|
200
|
+
offset,
|
|
201
|
+
bytes: ownerKey.toBase58(),
|
|
202
|
+
encoding: 'base58',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Generic account fetch helper
|
|
210
|
+
* @param accountAddress - The address of the account to fetch
|
|
211
|
+
* @param accountType - The type of account to fetch from program.account
|
|
212
|
+
* @returns The fetched account data
|
|
213
|
+
*/
|
|
214
|
+
export async function getAccountData<T>(
|
|
215
|
+
accountAddress: PublicKey | string,
|
|
216
|
+
accountType: keyof Program<DynamicBondingCurve>['account'],
|
|
217
|
+
program: Program<DynamicBondingCurve>
|
|
218
|
+
): Promise<T> {
|
|
219
|
+
const address =
|
|
220
|
+
accountAddress instanceof PublicKey
|
|
221
|
+
? accountAddress
|
|
222
|
+
: new PublicKey(accountAddress)
|
|
223
|
+
|
|
224
|
+
return (await program.account[accountType].fetchNullable(address)) as T
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Check if a mint is the native SOL mint
|
|
229
|
+
* @param mint - The mint to check
|
|
230
|
+
* @returns Whether the mint is the native SOL mint
|
|
231
|
+
*/
|
|
232
|
+
export function isNativeSol(mint: PublicKey): boolean {
|
|
233
|
+
return mint.toString() === NATIVE_MINT.toString()
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Helper function to convert BN values to decimal strings
|
|
237
|
+
export function convertBNToDecimal<T>(obj: T): T {
|
|
238
|
+
if (obj instanceof BN) {
|
|
239
|
+
return obj.toString(10) as T
|
|
240
|
+
}
|
|
241
|
+
if (Array.isArray(obj)) {
|
|
242
|
+
return obj.map((item) => convertBNToDecimal(item)) as T
|
|
243
|
+
}
|
|
244
|
+
if (obj && typeof obj === 'object') {
|
|
245
|
+
const result = {} as T
|
|
246
|
+
for (const key in obj) {
|
|
247
|
+
result[key] = convertBNToDecimal(obj[key])
|
|
248
|
+
}
|
|
249
|
+
return result
|
|
250
|
+
}
|
|
251
|
+
return obj
|
|
252
|
+
}
|