@symmetry-hq/temp-v3-sdk 0.0.1

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.
Files changed (148) hide show
  1. package/dist/idl/idl.d.ts +8 -0
  2. package/dist/idl/idl.js +4958 -0
  3. package/dist/idl/types.d.ts +4955 -0
  4. package/dist/idl/types.js +2 -0
  5. package/dist/index.d.ts +24 -0
  6. package/dist/index.js +60 -0
  7. package/dist/layouts/basket.d.ts +42 -0
  8. package/dist/layouts/basket.js +43 -0
  9. package/dist/layouts/config.d.ts +97 -0
  10. package/dist/layouts/config.js +102 -0
  11. package/dist/layouts/fraction.d.ts +6 -0
  12. package/dist/layouts/fraction.js +9 -0
  13. package/dist/layouts/oracle.d.ts +36 -0
  14. package/dist/layouts/oracle.js +37 -0
  15. package/dist/src/constants.d.ts +15 -0
  16. package/dist/src/constants.js +19 -0
  17. package/dist/src/idl/idl.d.ts +8 -0
  18. package/dist/src/idl/idl.js +4958 -0
  19. package/dist/src/idl/types.d.ts +4955 -0
  20. package/dist/src/idl/types.js +2 -0
  21. package/dist/src/index.d.ts +53 -0
  22. package/dist/src/index.js +199 -0
  23. package/dist/src/instructions/accounts.d.ts +27 -0
  24. package/dist/src/instructions/accounts.js +110 -0
  25. package/dist/src/instructions/auction.d.ts +7 -0
  26. package/dist/src/instructions/auction.js +43 -0
  27. package/dist/src/instructions/automation/auction.d.ts +6 -0
  28. package/dist/src/instructions/automation/auction.js +40 -0
  29. package/dist/src/instructions/automation/claimBounty.d.ts +12 -0
  30. package/dist/src/instructions/automation/claimBounty.js +44 -0
  31. package/dist/src/instructions/automation/priceUpdate.d.ts +15 -0
  32. package/dist/src/instructions/automation/priceUpdate.js +47 -0
  33. package/dist/src/instructions/automation/rebalanceSwap.d.ts +10 -0
  34. package/dist/src/instructions/automation/rebalanceSwap.js +42 -0
  35. package/dist/src/instructions/basket.d.ts +120 -0
  36. package/dist/src/instructions/basket.js +622 -0
  37. package/dist/src/instructions/bounty.d.ts +18 -0
  38. package/dist/src/instructions/bounty.js +81 -0
  39. package/dist/src/instructions/fee.d.ts +8 -0
  40. package/dist/src/instructions/fee.js +46 -0
  41. package/dist/src/instructions/globalConfig.d.ts +11 -0
  42. package/dist/src/instructions/globalConfig.js +43 -0
  43. package/dist/src/instructions/luts.d.ts +33 -0
  44. package/dist/src/instructions/luts.js +91 -0
  45. package/dist/src/instructions/management/addBounty.d.ts +7 -0
  46. package/dist/src/instructions/management/addBounty.js +39 -0
  47. package/dist/src/instructions/management/admin.d.ts +9 -0
  48. package/dist/src/instructions/management/admin.js +43 -0
  49. package/dist/src/instructions/management/claimFees.d.ts +7 -0
  50. package/dist/src/instructions/management/claimFees.js +47 -0
  51. package/dist/src/instructions/management/createBasket.d.ts +22 -0
  52. package/dist/src/instructions/management/createBasket.js +101 -0
  53. package/dist/src/instructions/management/edit.d.ts +34 -0
  54. package/dist/src/instructions/management/edit.js +192 -0
  55. package/dist/src/instructions/management/luts.d.ts +29 -0
  56. package/dist/src/instructions/management/luts.js +88 -0
  57. package/dist/src/instructions/pda.d.ts +26 -0
  58. package/dist/src/instructions/pda.js +110 -0
  59. package/dist/src/instructions/price.d.ts +17 -0
  60. package/dist/src/instructions/price.js +47 -0
  61. package/dist/src/instructions/user/deposit.d.ts +32 -0
  62. package/dist/src/instructions/user/deposit.js +168 -0
  63. package/dist/src/instructions/user/withdraw.d.ts +16 -0
  64. package/dist/src/instructions/user/withdraw.js +82 -0
  65. package/dist/src/layouts/basket.d.ts +41 -0
  66. package/dist/src/layouts/basket.js +43 -0
  67. package/dist/src/layouts/config.d.ts +133 -0
  68. package/dist/src/layouts/config.js +137 -0
  69. package/dist/src/layouts/fraction.d.ts +6 -0
  70. package/dist/src/layouts/fraction.js +9 -0
  71. package/dist/src/layouts/intents/bounty.d.ts +18 -0
  72. package/dist/src/layouts/intents/bounty.js +19 -0
  73. package/dist/src/layouts/intents/intent.d.ts +101 -0
  74. package/dist/src/layouts/intents/intent.js +113 -0
  75. package/dist/src/layouts/intents/rebalanceIntent.d.ts +56 -0
  76. package/dist/src/layouts/intents/rebalanceIntent.js +63 -0
  77. package/dist/src/layouts/lookupTable.d.ts +7 -0
  78. package/dist/src/layouts/lookupTable.js +10 -0
  79. package/dist/src/layouts/oracle.d.ts +42 -0
  80. package/dist/src/layouts/oracle.js +43 -0
  81. package/dist/src/states/basket.d.ts +8 -0
  82. package/dist/src/states/basket.js +54 -0
  83. package/dist/src/states/intents/intent.d.ts +14 -0
  84. package/dist/src/states/intents/intent.js +90 -0
  85. package/dist/src/states/intents/rebalanceIntent.d.ts +8 -0
  86. package/dist/src/states/intents/rebalanceIntent.js +54 -0
  87. package/dist/src/states/oracles/clmm_oracle.d.ts +178 -0
  88. package/dist/src/states/oracles/clmm_oracle.js +546 -0
  89. package/dist/src/states/oracles/constants.d.ts +8 -0
  90. package/dist/src/states/oracles/constants.js +12 -0
  91. package/dist/src/states/oracles/oracle.d.ts +60 -0
  92. package/dist/src/states/oracles/oracle.js +237 -0
  93. package/dist/src/states/oracles/pythOracle.d.ts +39 -0
  94. package/dist/src/states/oracles/pythOracle.js +202 -0
  95. package/dist/src/states/oracles/pyth_oracle.d.ts +39 -0
  96. package/dist/src/states/oracles/pyth_oracle.js +202 -0
  97. package/dist/src/states/oracles/raydiumClmmOracle.d.ts +178 -0
  98. package/dist/src/states/oracles/raydiumClmmOracle.js +546 -0
  99. package/dist/src/states/oracles/raydiumCpmmOracle.d.ts +139 -0
  100. package/dist/src/states/oracles/raydiumCpmmOracle.js +420 -0
  101. package/dist/src/states/oracles/raydium_cpmm_oracle.d.ts +139 -0
  102. package/dist/src/states/oracles/raydium_cpmm_oracle.js +420 -0
  103. package/dist/src/states/oracles/switchboardOracle.d.ts +0 -0
  104. package/dist/src/states/oracles/switchboardOracle.js +1 -0
  105. package/dist/src/states/oracles/switchboard_oracle.d.ts +0 -0
  106. package/dist/src/states/oracles/switchboard_oracle.js +1 -0
  107. package/dist/src/txUtils.d.ts +26 -0
  108. package/dist/src/txUtils.js +183 -0
  109. package/dist/states/basket.d.ts +8 -0
  110. package/dist/states/basket.js +57 -0
  111. package/dist/test.d.ts +1 -0
  112. package/dist/test.js +39 -0
  113. package/package.json +30 -0
  114. package/src/constants.ts +24 -0
  115. package/src/index.ts +260 -0
  116. package/src/instructions/automation/auction.ts +55 -0
  117. package/src/instructions/automation/claimBounty.ts +69 -0
  118. package/src/instructions/automation/priceUpdate.ts +73 -0
  119. package/src/instructions/automation/rebalanceSwap.ts +60 -0
  120. package/src/instructions/management/addBounty.ts +56 -0
  121. package/src/instructions/management/admin.ts +65 -0
  122. package/src/instructions/management/claimFees.ts +59 -0
  123. package/src/instructions/management/createBasket.ts +148 -0
  124. package/src/instructions/management/edit.ts +255 -0
  125. package/src/instructions/management/luts.ts +134 -0
  126. package/src/instructions/pda.ts +160 -0
  127. package/src/instructions/user/deposit.ts +237 -0
  128. package/src/instructions/user/withdraw.ts +130 -0
  129. package/src/layouts/basket.ts +82 -0
  130. package/src/layouts/config.ts +301 -0
  131. package/src/layouts/fraction.ts +12 -0
  132. package/src/layouts/intents/bounty.ts +35 -0
  133. package/src/layouts/intents/intent.ts +204 -0
  134. package/src/layouts/intents/rebalanceIntent.ts +111 -0
  135. package/src/layouts/lookupTable.ts +14 -0
  136. package/src/layouts/oracle.ts +96 -0
  137. package/src/states/basket.ts +56 -0
  138. package/src/states/intents/intent.ts +107 -0
  139. package/src/states/intents/rebalanceIntent.ts +57 -0
  140. package/src/states/oracles/constants.ts +13 -0
  141. package/src/states/oracles/oracle.ts +260 -0
  142. package/src/states/oracles/pythOracle.ts +270 -0
  143. package/src/states/oracles/raydiumClmmOracle.ts +812 -0
  144. package/src/states/oracles/raydiumCpmmOracle.ts +614 -0
  145. package/src/states/oracles/switchboardOracle.ts +0 -0
  146. package/src/txUtils.ts +250 -0
  147. package/test.ts +30 -0
  148. package/tsconfig.json +101 -0
@@ -0,0 +1,614 @@
1
+ import Decimal from 'decimal.js';
2
+
3
+ import { BN } from '@coral-xyz/anchor';
4
+ import { Connection, PublicKey } from '@solana/web3.js';
5
+
6
+ import { ErrorCode, Oracle, OracleErrors, OraclePrice, OracleResult } from './oracle';
7
+
8
+ const CPMM_PROGRAM_ID = new PublicKey("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C");
9
+ const DEV_CPMM_PROGRAM_ID = new PublicKey("DRaycpLY18LhpbydsBWbVJtxpNv9oXPgjRSfpF2bWpYb");
10
+
11
+ enum Side {
12
+ Base,
13
+ Quote,
14
+ }
15
+
16
+ enum Quote {
17
+ Usdc,
18
+ Wsol,
19
+ }
20
+
21
+ class Observation {
22
+ timestamp: BN; // u64
23
+ cumT0Price: BN; // u128
24
+ cumT1Price: BN; // u128
25
+ constructor(params: {timestamp: BN, cumT0Price: BN, cumT1Price: BN}){
26
+ this.timestamp = params.timestamp;
27
+ this.cumT0Price = params.cumT0Price;
28
+ this.cumT1Price = params.cumT1Price;
29
+ }
30
+ static decode(data: Buffer, offset = 0): [Observation, number] {
31
+
32
+ const timestamp = new BN(
33
+ data.subarray(offset, offset+8),
34
+ "le"
35
+ );
36
+
37
+ const cumT0Price = new BN(
38
+ data.subarray(offset + 8, offset + 24),
39
+ 'le'
40
+ );
41
+
42
+ const cumT1Price = new BN(
43
+ data.subarray(offset + 24, offset + 40),
44
+ 'le'
45
+ );
46
+
47
+
48
+
49
+ return [
50
+ new Observation({
51
+ timestamp,
52
+ cumT0Price,
53
+ cumT1Price }),
54
+ offset + 40
55
+ ];
56
+ }
57
+
58
+
59
+
60
+ sub(other: Observation): Observation {
61
+ if (!(other instanceof Observation)) {
62
+ throw new TypeError("Subtraction is only supported between Observation instances");
63
+ }
64
+
65
+ return new Observation({
66
+ timestamp: this.timestamp.sub(other.timestamp),
67
+ cumT0Price: this.cumT0Price.sub(other.cumT0Price),
68
+ cumT1Price: this.cumT1Price.sub(other.cumT1Price),
69
+ });
70
+ }
71
+
72
+ add(other: Observation): Observation {
73
+ if (!(other instanceof Observation)) {
74
+ throw new TypeError("Addition is only supported between Observation instances");
75
+ }
76
+ return new Observation({
77
+ timestamp: this.timestamp.add(other.timestamp),
78
+ cumT0Price: this.cumT0Price.add(other.cumT0Price),
79
+ cumT1Price: this.cumT1Price.add(other.cumT1Price),
80
+ });
81
+ }
82
+
83
+ getWeightedObservation(time: BN): Observation {
84
+ const cumT0Price = this.cumT0Price.mul(time).div(this.timestamp);
85
+ const cumT1Price = this.cumT1Price.mul(time).div(this.timestamp);
86
+ return new Observation({
87
+ timestamp: time,
88
+ cumT0Price,
89
+ cumT1Price
90
+ });
91
+ }
92
+
93
+ adjustToTimestamp(targetTimestamp: BN, observationPrev: Observation): Observation {
94
+ // delta = self.sub(prevPbservation)
95
+ const delta = this.sub(observationPrev);
96
+
97
+ // weightedDelta = delta.getWeightedObservation(targetTimestamp - self.blockTimestamp)
98
+ const timeForWeighted = targetTimestamp.sub(this.timestamp);
99
+ const weightedDelta = delta.getWeightedObservation(timeForWeighted);
100
+
101
+ // return self.add(weightedDelta)
102
+ return this.add(weightedDelta);
103
+ }
104
+
105
+ public getTwap(side: Side): BN {
106
+ let cumPrice = new BN(0);
107
+ if(side === Side.Base)
108
+ cumPrice = this.cumT0Price;
109
+ else cumPrice = this.cumT1Price;
110
+ console.log("cumPrice", cumPrice.toString())
111
+ return cumPrice.div(this.timestamp);
112
+ }
113
+
114
+ }
115
+
116
+ class ObservationState {
117
+ initialized : boolean;
118
+ observationIndex: number; //u16
119
+ poolId: PublicKey;
120
+ observations: Observation[];
121
+ lastUpdateTimestamp: BN; // u64
122
+ padding: BN[]; // [u64; 3]
123
+
124
+ constructor(params: {
125
+ initialized: boolean,
126
+ observationIndex: number,
127
+ poolId: PublicKey,
128
+ observations: Observation[],
129
+ lastUpdateTimestamp: BN,
130
+ padding: BN[]
131
+ }){
132
+ this.initialized = params.initialized;
133
+ this.observationIndex = params.observationIndex;
134
+ this.poolId = params.poolId;
135
+ this.observations = params.observations;
136
+ this.lastUpdateTimestamp = params.lastUpdateTimestamp;
137
+ this.padding = params.padding;
138
+ }
139
+
140
+ static decode(data: Buffer, offset = 8): [ObservationState, number] {
141
+ let cursor = offset;
142
+
143
+ const initialized = data.readUInt8(cursor) !== 0;
144
+ cursor += 1;
145
+
146
+ const observationIndex = data.readUInt16LE(cursor);
147
+ cursor += 2;
148
+
149
+ const poolId = new PublicKey(data.subarray(cursor, cursor + 32));
150
+ cursor += 32;
151
+
152
+ const observations: Observation[] = [];
153
+ for (let i = 0; i < 100; i++) {
154
+ let obs: Observation;
155
+ [obs, cursor] = Observation.decode(data, cursor);
156
+ observations.push(obs);
157
+ }
158
+
159
+ const lastUpdateTimestamp = new BN(data.subarray(cursor, cursor + 8), "le");
160
+ cursor += 8;
161
+
162
+ const padding: BN[] = [];
163
+ for (let i = 0; i < 4; i++) {
164
+ padding.push(new BN(data.subarray(cursor, cursor + 8), "le"));
165
+ cursor += 8;
166
+ }
167
+
168
+ return [
169
+ new ObservationState({
170
+ initialized,
171
+ observationIndex,
172
+ poolId,
173
+ observations,
174
+ lastUpdateTimestamp,
175
+ padding
176
+ }),
177
+ cursor
178
+ ]
179
+ }
180
+ }
181
+
182
+ class PoolState {
183
+ ammConfig: PublicKey;
184
+ poolCreator: PublicKey;
185
+ token0Vault: PublicKey;
186
+ token1Vault: PublicKey;
187
+ lpMint: PublicKey;
188
+ token0Mint: PublicKey;
189
+ token1Mint: PublicKey;
190
+ token0Program: PublicKey;
191
+ token1Program: PublicKey;
192
+ observationKey: PublicKey;
193
+ authBump: number; // u8
194
+ status: number; // u8
195
+ lpMintDecimals: number; // u8
196
+ mint0Decimals: number; // u8
197
+ mint1Decimals: number; // u8
198
+ lpSupply: BN; // u64
199
+ protocolFeesToken0: BN; // u64
200
+ protocolFeesToken1: BN; // u64
201
+ fundFeesToken0: BN; // u64
202
+ fundFeesToken1: BN; // u64
203
+ openTime: BN; // u64
204
+ recentEpoch: BN; // u64
205
+ creatorFeeOn: number; //u8
206
+ enableCreatorFee: boolean;
207
+ padding1: number[]; // [u8; 6]
208
+ creatorFeesToken0: BN; // u64
209
+ creatorFeesToken1: BN; // u64
210
+ padding: BN[]; // [u64; 28]
211
+
212
+ constructor(
213
+ params: {
214
+ ammConfig: PublicKey;
215
+ poolCreator: PublicKey;
216
+ token0Vault: PublicKey;
217
+ token1Vault: PublicKey;
218
+ lpMint: PublicKey;
219
+ token0Mint: PublicKey;
220
+ token1Mint: PublicKey;
221
+ token0Program: PublicKey;
222
+ token1Program: PublicKey;
223
+ observationKey: PublicKey;
224
+ authBump: number; // u8
225
+ status: number; // u8
226
+ lpMintDecimals: number; // u8
227
+ mint0Decimals: number; // u8
228
+ mint1Decimals: number; // u8
229
+ lpSupply: BN; // u64
230
+ protocolFeesToken0: BN; // u64
231
+ protocolFeesToken1: BN; // u64
232
+ fundFeesToken0: BN; // u64
233
+ fundFeesToken1: BN; // u64
234
+ openTime: BN; // u64
235
+ recentEpoch: BN; // u64
236
+ creatorFeeOn: number; //u8
237
+ enableCreatorFee: boolean;
238
+ padding1: number[]; // [u8; 6]
239
+ creatorFeesToken0: BN; // u64
240
+ creatorFeesToken1: BN; // u64
241
+ padding: BN[]; // [u64; 28]
242
+ }){
243
+ this.ammConfig = params.ammConfig;
244
+ this.poolCreator = params.poolCreator;
245
+ this.token0Vault = params.token0Vault;
246
+ this.token1Vault = params.token1Vault;
247
+ this.lpMint = params.lpMint;
248
+ this.token0Mint = params.token0Mint;
249
+ this.token1Mint = params.token1Mint;
250
+ this.token0Program = params.token0Program;
251
+ this.token1Program = params.token1Program;
252
+ this.observationKey = params.observationKey;
253
+ this.authBump = params.authBump; // u8
254
+ this.status = params.status; // u8
255
+ this.lpMintDecimals = params.lpMintDecimals; // u8
256
+ this.mint0Decimals = params.mint0Decimals; // u8
257
+ this.mint1Decimals = params.mint1Decimals; // u8
258
+ this.lpSupply = params.lpSupply; // u64
259
+ this.protocolFeesToken0 = params.protocolFeesToken0; // u64
260
+ this.protocolFeesToken1 = params.protocolFeesToken1; // u64
261
+ this.fundFeesToken0 = params.fundFeesToken0; // u64
262
+ this.fundFeesToken1 = params.fundFeesToken1; // u64
263
+ this.openTime = params.openTime; // u64
264
+ this.recentEpoch = params.recentEpoch; // u64
265
+ this.creatorFeeOn = params.creatorFeeOn; //u8
266
+ this.enableCreatorFee = params.enableCreatorFee;
267
+ this.padding1 = params.padding1; // [u8; 6]
268
+ this.creatorFeesToken0 = params.creatorFeesToken0; // u64
269
+ this.creatorFeesToken1 = params.creatorFeesToken1; // u64
270
+ this.padding = params.padding // [u64; 28]
271
+ }
272
+
273
+ static decode(data: Buffer, offset: number = 8): [PoolState, number] {
274
+ let cursor = offset;
275
+
276
+ const ammConfig = new PublicKey(data.subarray(cursor, cursor + 32));
277
+ cursor += 32;
278
+
279
+ const poolCreator = new PublicKey(data.subarray(cursor, cursor + 32));
280
+ cursor += 32;
281
+
282
+ const token0Vault = new PublicKey(data.subarray(cursor, cursor + 32));
283
+ cursor += 32;
284
+
285
+ const token1Vault = new PublicKey(data.subarray(cursor, cursor + 32));
286
+ cursor += 32;
287
+
288
+ const lpMint = new PublicKey(data.subarray(cursor, cursor + 32));
289
+ cursor += 32;
290
+
291
+ const token0Mint = new PublicKey(data.subarray(cursor, cursor + 32));
292
+ cursor += 32;
293
+
294
+ const token1Mint = new PublicKey(data.subarray(cursor, cursor + 32));
295
+ cursor += 32;
296
+
297
+ const token0Program = new PublicKey(data.subarray(cursor, cursor + 32));
298
+ cursor += 32;
299
+
300
+ const token1Program = new PublicKey(data.subarray(cursor, cursor + 32));
301
+ cursor += 32;
302
+
303
+ const observationKey = new PublicKey(data.subarray(cursor, cursor + 32));
304
+ cursor += 32;
305
+
306
+ const authBump = data.readUInt8(cursor);
307
+ cursor += 1;
308
+
309
+ const status = data.readUInt8(cursor);
310
+ cursor += 1;
311
+
312
+ const lpMintDecimals = data.readUInt8(cursor);
313
+ cursor += 1;
314
+
315
+ const mint0Decimals = data.readUInt8(cursor);
316
+ cursor += 1;
317
+
318
+ const mint1Decimals = data.readUInt8(cursor);
319
+ cursor += 1;
320
+
321
+ const lpSupply = new BN(data.subarray(cursor, cursor + 8), "le");
322
+ cursor += 8;
323
+
324
+ const protocolFeesToken0 = new BN(data.subarray(cursor, cursor + 8), "le");
325
+ cursor += 8;
326
+
327
+ const protocolFeesToken1 = new BN(data.subarray(cursor, cursor + 8), "le");
328
+ cursor += 8;
329
+
330
+ const fundFeesToken0 = new BN(data.subarray(cursor, cursor + 8), "le");
331
+ cursor += 8;
332
+
333
+ const fundFeesToken1 = new BN(data.subarray(cursor, cursor + 8), "le");
334
+ cursor += 8;
335
+
336
+ const openTime = new BN(data.subarray(cursor, cursor + 8), "le");
337
+ cursor += 8;
338
+
339
+ const recentEpoch = new BN(data.subarray(cursor, cursor + 8), "le");
340
+ cursor += 8;
341
+
342
+ const creatorFeeOn = data.readUInt8(cursor);
343
+ cursor += 1;
344
+
345
+ const enableCreatorFee = !!data.readUInt8(cursor);
346
+ cursor += 1;
347
+
348
+ const padding1: number[] = [];
349
+ for (let i = 0; i < 6; i++) {
350
+ padding1.push(data.readUInt8(cursor));
351
+ cursor += 1;
352
+ }
353
+
354
+ const creatorFeesToken0 = new BN(data.subarray(cursor, cursor + 8), "le");
355
+ cursor += 8;
356
+
357
+ const creatorFeesToken1 = new BN(data.subarray(cursor, cursor + 8), "le");
358
+ cursor += 8;
359
+
360
+ const padding: BN[] = [];
361
+ for (let i = 0; i < 28; i++) {
362
+ padding.push(new BN(data.subarray(cursor, cursor + 8), "le"));
363
+ cursor += 8;
364
+ }
365
+
366
+ return [
367
+ new PoolState({
368
+ ammConfig,
369
+ poolCreator,
370
+ token0Vault,
371
+ token1Vault,
372
+ lpMint,
373
+ token0Mint,
374
+ token1Mint,
375
+ token0Program,
376
+ token1Program,
377
+ observationKey,
378
+ authBump,
379
+ status,
380
+ lpMintDecimals,
381
+ mint0Decimals,
382
+ mint1Decimals,
383
+ lpSupply,
384
+ protocolFeesToken0,
385
+ protocolFeesToken1,
386
+ fundFeesToken0,
387
+ fundFeesToken1,
388
+ openTime,
389
+ recentEpoch,
390
+ creatorFeeOn,
391
+ enableCreatorFee,
392
+ padding1,
393
+ creatorFeesToken0,
394
+ creatorFeesToken1,
395
+ padding,
396
+ }),
397
+ cursor,
398
+ ];
399
+ }
400
+ }
401
+
402
+ export class RaydiumCPMMOracle extends Oracle{
403
+ poolId: PublicKey;
404
+ quoteToken: Quote;
405
+ poolState: PoolState;
406
+ side: Side;
407
+ observationState: ObservationState;
408
+
409
+ private constructor(params: {
410
+ poolId: PublicKey;
411
+ quoteToken: Quote;
412
+ poolState: PoolState;
413
+ side: Side;
414
+ observationState: ObservationState,
415
+ weight: number,
416
+ confThreshBps?: number,
417
+ stalenessThresh?: number,
418
+ volatilityThresh?: number | Decimal,
419
+ minLiquidity?: number | Decimal,
420
+ stalenessConfRateBps?: number
421
+ }){
422
+ super(
423
+ params.weight,
424
+ params.confThreshBps,
425
+ params.stalenessThresh,
426
+ params.volatilityThresh,
427
+ params.minLiquidity,
428
+ params.stalenessConfRateBps
429
+ );
430
+
431
+ this.poolId = params.poolId;
432
+ this.quoteToken = params.quoteToken;
433
+ this.poolState = params.poolState;
434
+ this.side = params.side;
435
+ this.observationState = params.observationState;
436
+ }
437
+
438
+ static async create(params: {
439
+ connection: Connection,
440
+ poolId: PublicKey,
441
+ quoteToken: Quote,
442
+ side: Side,
443
+ weight: number,
444
+ confThreshBps?: number,
445
+ stalenessThresh?: number,
446
+ volatilityThresh?: number | Decimal,
447
+ minLiquidity?: number | Decimal,
448
+ stalenessConfRateBps?: number
449
+ }): Promise<RaydiumCPMMOracle> {
450
+ const { connection, poolId } = params;
451
+
452
+ // Fetch pooState
453
+ const poolAccountInfo = await connection.getAccountInfo(new PublicKey(poolId));
454
+ if (!poolAccountInfo) throw new Error("Pool account not found");
455
+ const [poolState, _] = PoolState.decode(poolAccountInfo.data, 8);
456
+
457
+ // Fetch observationState from poolState
458
+ const obsPubkey = poolState.observationKey;
459
+ const obsAccountInfo = await connection.getAccountInfo(new PublicKey(obsPubkey));
460
+ if (!obsAccountInfo) throw new Error("Observation account not found");
461
+ const [observationState, __] = ObservationState.decode(obsAccountInfo.data, 8);
462
+
463
+
464
+ return new RaydiumCPMMOracle({
465
+ poolId: poolId,
466
+ quoteToken: params.quoteToken,
467
+ poolState: poolState,
468
+ side: params.side,
469
+ observationState: observationState,
470
+ weight: params.weight,
471
+ confThreshBps: params.confThreshBps,
472
+ stalenessThresh: params.stalenessThresh,
473
+ volatilityThresh: params.volatilityThresh,
474
+ minLiquidity: params.minLiquidity,
475
+ stalenessConfRateBps: params.stalenessConfRateBps
476
+ });
477
+ }
478
+
479
+ public setSide(side: Side) {
480
+ this.side = side;
481
+ }
482
+
483
+ static deriveObservationKey(poolId: PublicKey): [PublicKey, number] {
484
+ const seeds = [
485
+ Buffer.from("observation"),
486
+ poolId.toBuffer(),
487
+ ];
488
+ return PublicKey.findProgramAddressSync(seeds, CPMM_PROGRAM_ID);
489
+ };
490
+
491
+ getObservationAtIndex(index: number) {
492
+ return this.observationState.observations[index];
493
+ }
494
+
495
+ getObservationAtTimestamp(timestamp: BN, startIndex: number): Observation {
496
+ let observationCurrent = this.getObservationAtIndex(startIndex);
497
+ let index = startIndex;
498
+ // Loop backwards until we find the observation <= timestamp
499
+ while (observationCurrent.timestamp.gt(timestamp)) {
500
+ index = (index - 1 + 100) % 100;
501
+ observationCurrent = this.getObservationAtIndex(index);
502
+
503
+ if (index === startIndex) {
504
+ throw Error("Observations do not go back far enough in time");
505
+ break; // looped all the way around
506
+ }
507
+ }
508
+
509
+ // Previous index for interpolation
510
+ const prevIndex = (index - 1 + 100) % 100;
511
+ const observationPrev = this.getObservationAtIndex(prevIndex);
512
+
513
+ // Adjust current observation to the target timestamp
514
+ const result = observationCurrent.adjustToTimestamp(timestamp, observationPrev);
515
+ return result;
516
+ }
517
+
518
+ getDeltaObservations(currentTime: BN): Observation[] {
519
+
520
+ const obsIndex = this.observationState.observationIndex;
521
+ const observationCurrent = this.getObservationAtTimestamp(currentTime, obsIndex);
522
+ const observation30s = this.getObservationAtTimestamp(new BN(currentTime.sub(new BN(30))), obsIndex);
523
+ const delta30s = observationCurrent.sub(observation30s);
524
+
525
+ const observation2min = this.getObservationAtTimestamp(new BN(currentTime.sub(new BN(120))), obsIndex);
526
+ const delta2min = observationCurrent.sub(observation2min);
527
+
528
+ const observation5min = this.getObservationAtTimestamp(new BN(currentTime.sub(new BN(300))), obsIndex);
529
+ const delta5min = observationCurrent.sub(observation5min);
530
+
531
+ const observation20min = this.getObservationAtTimestamp(new BN(currentTime.sub(new BN(1200))), obsIndex);
532
+ const delta20min = observationCurrent.sub(observation20min);
533
+
534
+ return [delta30s,delta2min, delta5min, delta20min];
535
+ };
536
+
537
+ getDecimals(): number {
538
+ let dec;
539
+ if(this.side === Side.Base)
540
+ dec = this.poolState.mint0Decimals - this.poolState.mint1Decimals;
541
+ else dec = this.poolState.mint1Decimals - this.poolState.mint0Decimals;
542
+ return dec;
543
+ }
544
+
545
+ getTwap30sec(currentTime: BN): Decimal {
546
+ let observation = this.getDeltaObservations(currentTime)[0];
547
+ let twapScaled = new Decimal(observation.getTwap(this.side).toString()).div(2**32);
548
+ let twap = new Decimal(twapScaled.toString()).div(10**this.getDecimals());
549
+ return twap;
550
+ }
551
+
552
+ getTwap2min(currentTime: BN): Decimal {
553
+ let observation = this.getDeltaObservations(currentTime)[1];
554
+ let twapScaled = new Decimal(observation.getTwap(this.side).toString()).div(2**32);
555
+ let twap = new Decimal(twapScaled.toString()).div(10**this.getDecimals())
556
+ return twap;
557
+ }
558
+
559
+ getTwap5min(currentTime: BN): Decimal {
560
+ let observation = this.getDeltaObservations(currentTime)[2];
561
+ let twapScaled = new Decimal(observation.getTwap(this.side).toString()).div(2**32);
562
+ let twap = new Decimal(twapScaled.toString()).div(10**this.getDecimals())
563
+ return twap;
564
+ }
565
+
566
+ getTwap20min(currentTime: BN): Decimal {
567
+ let observation = this.getDeltaObservations(currentTime)[3];
568
+ let twapScaled = new Decimal(observation.getTwap(this.side).toString()).div(2**32);
569
+ let twap = new Decimal(twapScaled.toString()).div(10**this.getDecimals())
570
+ return twap;
571
+ }
572
+
573
+ getConfidence(currentTime: BN): Decimal {
574
+
575
+ const twapNow = this.getTwap30sec(currentTime);
576
+
577
+ const diff2Min = twapNow.sub(this.getTwap2min(currentTime)).abs();
578
+ const diff5Min = twapNow.sub(this.getTwap5min(currentTime)).abs();
579
+ const diff20Min = twapNow.sub(this.getTwap20min(currentTime)).abs();
580
+
581
+ let max = diff2Min;
582
+ if (diff5Min.gt(max)) max = diff5Min;
583
+ if (diff20Min.gt(max)) max = diff20Min;
584
+
585
+ return max;
586
+ }
587
+
588
+ async fetch(): Promise<OracleResult> {
589
+ const currentTime = new BN(Math.floor(Date.now() / 1000)); // current UNIX timestamp in seconds
590
+
591
+ const confidence = this.getConfidence(currentTime);
592
+
593
+ // const liquidity = this.poolState.liquidity; // assuming poolState is already the decoded data
594
+ const price = this.getTwap30sec(currentTime);
595
+
596
+ let errors = 0;
597
+
598
+ // if (confidence.mul(10_000).greaterThan(this.confThreshBps!)) {
599
+ // errors |= ErrorCode.TOO_UNCERTAIN;
600
+ // }
601
+
602
+ // if (liquidity.lt(this.minLiquidity)) {
603
+ // errors |= ErrorCode.NOT_ENOUGH_LIQUIDITY;
604
+ // };
605
+ let err = new OracleErrors(errors);
606
+
607
+ let oraclePrice = new OraclePrice(price, confidence, currentTime);
608
+ return new OracleResult(
609
+ oraclePrice,
610
+ err
611
+ )
612
+ }
613
+
614
+ }
File without changes