@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,420 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.RaydiumCPMMOracle = void 0;
16
+ const decimal_js_1 = __importDefault(require("decimal.js"));
17
+ const anchor_1 = require("@coral-xyz/anchor");
18
+ const web3_js_1 = require("@solana/web3.js");
19
+ const oracle_1 = require("./oracle");
20
+ const CPMM_PROGRAM_ID = new web3_js_1.PublicKey("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C");
21
+ const DEV_CPMM_PROGRAM_ID = new web3_js_1.PublicKey("DRaycpLY18LhpbydsBWbVJtxpNv9oXPgjRSfpF2bWpYb");
22
+ var Side;
23
+ (function (Side) {
24
+ Side[Side["Base"] = 0] = "Base";
25
+ Side[Side["Quote"] = 1] = "Quote";
26
+ })(Side || (Side = {}));
27
+ var Quote;
28
+ (function (Quote) {
29
+ Quote[Quote["Usdc"] = 0] = "Usdc";
30
+ Quote[Quote["Wsol"] = 1] = "Wsol";
31
+ })(Quote || (Quote = {}));
32
+ class Observation {
33
+ constructor(params) {
34
+ this.timestamp = params.timestamp;
35
+ this.cumT0Price = params.cumT0Price;
36
+ this.cumT1Price = params.cumT1Price;
37
+ }
38
+ static decode(data, offset = 0) {
39
+ const timestamp = new anchor_1.BN(data.subarray(offset, offset + 8), "le");
40
+ const cumT0Price = new anchor_1.BN(data.subarray(offset + 8, offset + 24), 'le');
41
+ const cumT1Price = new anchor_1.BN(data.subarray(offset + 24, offset + 40), 'le');
42
+ return [
43
+ new Observation({
44
+ timestamp,
45
+ cumT0Price,
46
+ cumT1Price
47
+ }),
48
+ offset + 40
49
+ ];
50
+ }
51
+ sub(other) {
52
+ if (!(other instanceof Observation)) {
53
+ throw new TypeError("Subtraction is only supported between Observation instances");
54
+ }
55
+ return new Observation({
56
+ timestamp: this.timestamp.sub(other.timestamp),
57
+ cumT0Price: this.cumT0Price.sub(other.cumT0Price),
58
+ cumT1Price: this.cumT1Price.sub(other.cumT1Price),
59
+ });
60
+ }
61
+ add(other) {
62
+ if (!(other instanceof Observation)) {
63
+ throw new TypeError("Addition is only supported between Observation instances");
64
+ }
65
+ return new Observation({
66
+ timestamp: this.timestamp.add(other.timestamp),
67
+ cumT0Price: this.cumT0Price.add(other.cumT0Price),
68
+ cumT1Price: this.cumT1Price.add(other.cumT1Price),
69
+ });
70
+ }
71
+ getWeightedObservation(time) {
72
+ const cumT0Price = this.cumT0Price.mul(time).div(this.timestamp);
73
+ const cumT1Price = this.cumT1Price.mul(time).div(this.timestamp);
74
+ return new Observation({
75
+ timestamp: time,
76
+ cumT0Price,
77
+ cumT1Price
78
+ });
79
+ }
80
+ adjustToTimestamp(targetTimestamp, observationPrev) {
81
+ // delta = self.sub(prevPbservation)
82
+ const delta = this.sub(observationPrev);
83
+ // weightedDelta = delta.getWeightedObservation(targetTimestamp - self.blockTimestamp)
84
+ const timeForWeighted = targetTimestamp.sub(this.timestamp);
85
+ const weightedDelta = delta.getWeightedObservation(timeForWeighted);
86
+ // return self.add(weightedDelta)
87
+ return this.add(weightedDelta);
88
+ }
89
+ getTwap(side) {
90
+ let cumPrice = new anchor_1.BN(0);
91
+ if (side === Side.Base)
92
+ cumPrice = this.cumT0Price;
93
+ else
94
+ cumPrice = this.cumT1Price;
95
+ console.log("cumPrice", cumPrice.toString());
96
+ return cumPrice.div(this.timestamp);
97
+ }
98
+ }
99
+ class ObservationState {
100
+ constructor(params) {
101
+ this.initialized = params.initialized;
102
+ this.observationIndex = params.observationIndex;
103
+ this.poolId = params.poolId;
104
+ this.observations = params.observations;
105
+ this.lastUpdateTimestamp = params.lastUpdateTimestamp;
106
+ this.padding = params.padding;
107
+ }
108
+ static decode(data, offset = 8) {
109
+ let cursor = offset;
110
+ const initialized = data.readUInt8(cursor) !== 0;
111
+ cursor += 1;
112
+ const observationIndex = data.readUInt16LE(cursor);
113
+ cursor += 2;
114
+ const poolId = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
115
+ cursor += 32;
116
+ const observations = [];
117
+ for (let i = 0; i < 100; i++) {
118
+ let obs;
119
+ [obs, cursor] = Observation.decode(data, cursor);
120
+ observations.push(obs);
121
+ }
122
+ const lastUpdateTimestamp = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
123
+ cursor += 8;
124
+ const padding = [];
125
+ for (let i = 0; i < 4; i++) {
126
+ padding.push(new anchor_1.BN(data.subarray(cursor, cursor + 8), "le"));
127
+ cursor += 8;
128
+ }
129
+ return [
130
+ new ObservationState({
131
+ initialized,
132
+ observationIndex,
133
+ poolId,
134
+ observations,
135
+ lastUpdateTimestamp,
136
+ padding
137
+ }),
138
+ cursor
139
+ ];
140
+ }
141
+ }
142
+ class PoolState {
143
+ constructor(params) {
144
+ this.ammConfig = params.ammConfig;
145
+ this.poolCreator = params.poolCreator;
146
+ this.token0Vault = params.token0Vault;
147
+ this.token1Vault = params.token1Vault;
148
+ this.lpMint = params.lpMint;
149
+ this.token0Mint = params.token0Mint;
150
+ this.token1Mint = params.token1Mint;
151
+ this.token0Program = params.token0Program;
152
+ this.token1Program = params.token1Program;
153
+ this.observationKey = params.observationKey;
154
+ this.authBump = params.authBump; // u8
155
+ this.status = params.status; // u8
156
+ this.lpMintDecimals = params.lpMintDecimals; // u8
157
+ this.mint0Decimals = params.mint0Decimals; // u8
158
+ this.mint1Decimals = params.mint1Decimals; // u8
159
+ this.lpSupply = params.lpSupply; // u64
160
+ this.protocolFeesToken0 = params.protocolFeesToken0; // u64
161
+ this.protocolFeesToken1 = params.protocolFeesToken1; // u64
162
+ this.fundFeesToken0 = params.fundFeesToken0; // u64
163
+ this.fundFeesToken1 = params.fundFeesToken1; // u64
164
+ this.openTime = params.openTime; // u64
165
+ this.recentEpoch = params.recentEpoch; // u64
166
+ this.creatorFeeOn = params.creatorFeeOn; //u8
167
+ this.enableCreatorFee = params.enableCreatorFee;
168
+ this.padding1 = params.padding1; // [u8; 6]
169
+ this.creatorFeesToken0 = params.creatorFeesToken0; // u64
170
+ this.creatorFeesToken1 = params.creatorFeesToken1; // u64
171
+ this.padding = params.padding; // [u64; 28]
172
+ }
173
+ static decode(data, offset = 8) {
174
+ let cursor = offset;
175
+ const ammConfig = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
176
+ cursor += 32;
177
+ const poolCreator = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
178
+ cursor += 32;
179
+ const token0Vault = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
180
+ cursor += 32;
181
+ const token1Vault = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
182
+ cursor += 32;
183
+ const lpMint = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
184
+ cursor += 32;
185
+ const token0Mint = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
186
+ cursor += 32;
187
+ const token1Mint = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
188
+ cursor += 32;
189
+ const token0Program = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
190
+ cursor += 32;
191
+ const token1Program = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
192
+ cursor += 32;
193
+ const observationKey = new web3_js_1.PublicKey(data.subarray(cursor, cursor + 32));
194
+ cursor += 32;
195
+ const authBump = data.readUInt8(cursor);
196
+ cursor += 1;
197
+ const status = data.readUInt8(cursor);
198
+ cursor += 1;
199
+ const lpMintDecimals = data.readUInt8(cursor);
200
+ cursor += 1;
201
+ const mint0Decimals = data.readUInt8(cursor);
202
+ cursor += 1;
203
+ const mint1Decimals = data.readUInt8(cursor);
204
+ cursor += 1;
205
+ const lpSupply = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
206
+ cursor += 8;
207
+ const protocolFeesToken0 = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
208
+ cursor += 8;
209
+ const protocolFeesToken1 = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
210
+ cursor += 8;
211
+ const fundFeesToken0 = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
212
+ cursor += 8;
213
+ const fundFeesToken1 = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
214
+ cursor += 8;
215
+ const openTime = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
216
+ cursor += 8;
217
+ const recentEpoch = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
218
+ cursor += 8;
219
+ const creatorFeeOn = data.readUInt8(cursor);
220
+ cursor += 1;
221
+ const enableCreatorFee = !!data.readUInt8(cursor);
222
+ cursor += 1;
223
+ const padding1 = [];
224
+ for (let i = 0; i < 6; i++) {
225
+ padding1.push(data.readUInt8(cursor));
226
+ cursor += 1;
227
+ }
228
+ const creatorFeesToken0 = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
229
+ cursor += 8;
230
+ const creatorFeesToken1 = new anchor_1.BN(data.subarray(cursor, cursor + 8), "le");
231
+ cursor += 8;
232
+ const padding = [];
233
+ for (let i = 0; i < 28; i++) {
234
+ padding.push(new anchor_1.BN(data.subarray(cursor, cursor + 8), "le"));
235
+ cursor += 8;
236
+ }
237
+ return [
238
+ new PoolState({
239
+ ammConfig,
240
+ poolCreator,
241
+ token0Vault,
242
+ token1Vault,
243
+ lpMint,
244
+ token0Mint,
245
+ token1Mint,
246
+ token0Program,
247
+ token1Program,
248
+ observationKey,
249
+ authBump,
250
+ status,
251
+ lpMintDecimals,
252
+ mint0Decimals,
253
+ mint1Decimals,
254
+ lpSupply,
255
+ protocolFeesToken0,
256
+ protocolFeesToken1,
257
+ fundFeesToken0,
258
+ fundFeesToken1,
259
+ openTime,
260
+ recentEpoch,
261
+ creatorFeeOn,
262
+ enableCreatorFee,
263
+ padding1,
264
+ creatorFeesToken0,
265
+ creatorFeesToken1,
266
+ padding,
267
+ }),
268
+ cursor,
269
+ ];
270
+ }
271
+ }
272
+ class RaydiumCPMMOracle extends oracle_1.Oracle {
273
+ constructor(params) {
274
+ super(params.weight, params.confThreshBps, params.stalenessThresh, params.volatilityThresh, params.minLiquidity, params.stalenessConfRateBps);
275
+ this.poolId = params.poolId;
276
+ this.quoteToken = params.quoteToken;
277
+ this.poolState = params.poolState;
278
+ this.side = params.side;
279
+ this.observationState = params.observationState;
280
+ }
281
+ static create(params) {
282
+ return __awaiter(this, void 0, void 0, function* () {
283
+ const { connection, poolId } = params;
284
+ // Fetch pooState
285
+ const poolAccountInfo = yield connection.getAccountInfo(new web3_js_1.PublicKey(poolId));
286
+ if (!poolAccountInfo)
287
+ throw new Error("Pool account not found");
288
+ const [poolState, _] = PoolState.decode(poolAccountInfo.data, 8);
289
+ // Fetch observationState from poolState
290
+ const obsPubkey = poolState.observationKey;
291
+ const obsAccountInfo = yield connection.getAccountInfo(new web3_js_1.PublicKey(obsPubkey));
292
+ if (!obsAccountInfo)
293
+ throw new Error("Observation account not found");
294
+ const [observationState, __] = ObservationState.decode(obsAccountInfo.data, 8);
295
+ return new RaydiumCPMMOracle({
296
+ poolId: poolId,
297
+ quoteToken: params.quoteToken,
298
+ poolState: poolState,
299
+ side: params.side,
300
+ observationState: observationState,
301
+ weight: params.weight,
302
+ confThreshBps: params.confThreshBps,
303
+ stalenessThresh: params.stalenessThresh,
304
+ volatilityThresh: params.volatilityThresh,
305
+ minLiquidity: params.minLiquidity,
306
+ stalenessConfRateBps: params.stalenessConfRateBps
307
+ });
308
+ });
309
+ }
310
+ setSide(side) {
311
+ this.side = side;
312
+ }
313
+ static deriveObservationKey(poolId) {
314
+ const seeds = [
315
+ Buffer.from("observation"),
316
+ poolId.toBuffer(),
317
+ ];
318
+ return web3_js_1.PublicKey.findProgramAddressSync(seeds, CPMM_PROGRAM_ID);
319
+ }
320
+ ;
321
+ getObservationAtIndex(index) {
322
+ return this.observationState.observations[index];
323
+ }
324
+ getObservationAtTimestamp(timestamp, startIndex) {
325
+ let observationCurrent = this.getObservationAtIndex(startIndex);
326
+ let index = startIndex;
327
+ // Loop backwards until we find the observation <= timestamp
328
+ while (observationCurrent.timestamp.gt(timestamp)) {
329
+ index = (index - 1 + 100) % 100;
330
+ observationCurrent = this.getObservationAtIndex(index);
331
+ if (index === startIndex) {
332
+ throw Error("Observations do not go back far enough in time");
333
+ break; // looped all the way around
334
+ }
335
+ }
336
+ // Previous index for interpolation
337
+ const prevIndex = (index - 1 + 100) % 100;
338
+ const observationPrev = this.getObservationAtIndex(prevIndex);
339
+ // Adjust current observation to the target timestamp
340
+ const result = observationCurrent.adjustToTimestamp(timestamp, observationPrev);
341
+ return result;
342
+ }
343
+ getDeltaObservations(currentTime) {
344
+ const obsIndex = this.observationState.observationIndex;
345
+ const observationCurrent = this.getObservationAtTimestamp(currentTime, obsIndex);
346
+ const observation30s = this.getObservationAtTimestamp(new anchor_1.BN(currentTime.sub(new anchor_1.BN(30))), obsIndex);
347
+ const delta30s = observationCurrent.sub(observation30s);
348
+ const observation2min = this.getObservationAtTimestamp(new anchor_1.BN(currentTime.sub(new anchor_1.BN(120))), obsIndex);
349
+ const delta2min = observationCurrent.sub(observation2min);
350
+ const observation5min = this.getObservationAtTimestamp(new anchor_1.BN(currentTime.sub(new anchor_1.BN(300))), obsIndex);
351
+ const delta5min = observationCurrent.sub(observation5min);
352
+ const observation20min = this.getObservationAtTimestamp(new anchor_1.BN(currentTime.sub(new anchor_1.BN(1200))), obsIndex);
353
+ const delta20min = observationCurrent.sub(observation20min);
354
+ return [delta30s, delta2min, delta5min, delta20min];
355
+ }
356
+ ;
357
+ getDecimals() {
358
+ let dec;
359
+ if (this.side === Side.Base)
360
+ dec = this.poolState.mint0Decimals - this.poolState.mint1Decimals;
361
+ else
362
+ dec = this.poolState.mint1Decimals - this.poolState.mint0Decimals;
363
+ return dec;
364
+ }
365
+ getTwap30sec(currentTime) {
366
+ let observation = this.getDeltaObservations(currentTime)[0];
367
+ let twapScaled = new decimal_js_1.default(observation.getTwap(this.side).toString()).div(2 ** 32);
368
+ let twap = new decimal_js_1.default(twapScaled.toString()).div(10 ** this.getDecimals());
369
+ return twap;
370
+ }
371
+ getTwap2min(currentTime) {
372
+ let observation = this.getDeltaObservations(currentTime)[1];
373
+ let twapScaled = new decimal_js_1.default(observation.getTwap(this.side).toString()).div(2 ** 32);
374
+ let twap = new decimal_js_1.default(twapScaled.toString()).div(10 ** this.getDecimals());
375
+ return twap;
376
+ }
377
+ getTwap5min(currentTime) {
378
+ let observation = this.getDeltaObservations(currentTime)[2];
379
+ let twapScaled = new decimal_js_1.default(observation.getTwap(this.side).toString()).div(2 ** 32);
380
+ let twap = new decimal_js_1.default(twapScaled.toString()).div(10 ** this.getDecimals());
381
+ return twap;
382
+ }
383
+ getTwap20min(currentTime) {
384
+ let observation = this.getDeltaObservations(currentTime)[3];
385
+ let twapScaled = new decimal_js_1.default(observation.getTwap(this.side).toString()).div(2 ** 32);
386
+ let twap = new decimal_js_1.default(twapScaled.toString()).div(10 ** this.getDecimals());
387
+ return twap;
388
+ }
389
+ getConfidence(currentTime) {
390
+ const twapNow = this.getTwap30sec(currentTime);
391
+ const diff2Min = twapNow.sub(this.getTwap2min(currentTime)).abs();
392
+ const diff5Min = twapNow.sub(this.getTwap5min(currentTime)).abs();
393
+ const diff20Min = twapNow.sub(this.getTwap20min(currentTime)).abs();
394
+ let max = diff2Min;
395
+ if (diff5Min.gt(max))
396
+ max = diff5Min;
397
+ if (diff20Min.gt(max))
398
+ max = diff20Min;
399
+ return max;
400
+ }
401
+ fetch() {
402
+ return __awaiter(this, void 0, void 0, function* () {
403
+ const currentTime = new anchor_1.BN(Math.floor(Date.now() / 1000)); // current UNIX timestamp in seconds
404
+ const confidence = this.getConfidence(currentTime);
405
+ // const liquidity = this.poolState.liquidity; // assuming poolState is already the decoded data
406
+ const price = this.getTwap30sec(currentTime);
407
+ let errors = 0;
408
+ // if (confidence.mul(10_000).greaterThan(this.confThreshBps!)) {
409
+ // errors |= ErrorCode.TOO_UNCERTAIN;
410
+ // }
411
+ // if (liquidity.lt(this.minLiquidity)) {
412
+ // errors |= ErrorCode.NOT_ENOUGH_LIQUIDITY;
413
+ // };
414
+ let err = new oracle_1.OracleErrors(errors);
415
+ let oraclePrice = new oracle_1.OraclePrice(price, confidence, currentTime);
416
+ return new oracle_1.OracleResult(oraclePrice, err);
417
+ });
418
+ }
419
+ }
420
+ exports.RaydiumCPMMOracle = RaydiumCPMMOracle;
@@ -0,0 +1,139 @@
1
+ import Decimal from 'decimal.js';
2
+ import { BN } from '@coral-xyz/anchor';
3
+ import { Connection, PublicKey } from '@solana/web3.js';
4
+ import { Oracle, OracleResult } from './oracle';
5
+ declare enum Side {
6
+ Base = 0,
7
+ Quote = 1
8
+ }
9
+ declare enum Quote {
10
+ Usdc = 0,
11
+ Wsol = 1
12
+ }
13
+ declare class Observation {
14
+ timestamp: BN;
15
+ cum_t_0_price: BN;
16
+ cum_t_1_price: BN;
17
+ constructor(params: {
18
+ timestamp: BN;
19
+ cum_t_0_price: BN;
20
+ cum_t_1_price: BN;
21
+ });
22
+ static decode(data: Buffer, offset?: number): [Observation, number];
23
+ sub(other: Observation): Observation;
24
+ add(other: Observation): Observation;
25
+ get_weighted_observation(time: BN): Observation;
26
+ adjust_to_timestamp(target_timestamp: BN, observation_prev: Observation): Observation;
27
+ get_twap(side: Side): BN;
28
+ }
29
+ declare class ObservationState {
30
+ initialized: boolean;
31
+ observation_index: number;
32
+ pool_id: PublicKey;
33
+ observations: Observation[];
34
+ last_update_timestamp: BN;
35
+ padding: BN[];
36
+ constructor(params: {
37
+ initialized: boolean;
38
+ observation_index: number;
39
+ pool_id: PublicKey;
40
+ observations: Observation[];
41
+ last_update_timestamp: BN;
42
+ padding: BN[];
43
+ });
44
+ static decode(data: Buffer, offset?: number): [ObservationState, number];
45
+ }
46
+ declare class PoolState {
47
+ amm_config: PublicKey;
48
+ pool_creator: PublicKey;
49
+ token_0_vault: PublicKey;
50
+ token_1_vault: PublicKey;
51
+ lp_mint: PublicKey;
52
+ token_0_mint: PublicKey;
53
+ token_1_mint: PublicKey;
54
+ token_0_program: PublicKey;
55
+ token_1_program: PublicKey;
56
+ observation_key: PublicKey;
57
+ auth_bump: number;
58
+ status: number;
59
+ lp_mint_decimals: number;
60
+ mint_0_decimals: number;
61
+ mint_1_decimals: number;
62
+ lp_supply: BN;
63
+ protocol_fees_token_0: BN;
64
+ protocol_fees_token_1: BN;
65
+ fund_fees_token_0: BN;
66
+ fund_fees_token_1: BN;
67
+ open_time: BN;
68
+ recent_epoch: BN;
69
+ creator_fee_on: number;
70
+ enable_creator_fee: boolean;
71
+ padding1: number[];
72
+ creator_fees_token_0: BN;
73
+ creator_fees_token_1: BN;
74
+ padding: BN[];
75
+ constructor(params: {
76
+ amm_config: PublicKey;
77
+ pool_creator: PublicKey;
78
+ token_0_vault: PublicKey;
79
+ token_1_vault: PublicKey;
80
+ lp_mint: PublicKey;
81
+ token_0_mint: PublicKey;
82
+ token_1_mint: PublicKey;
83
+ token_0_program: PublicKey;
84
+ token_1_program: PublicKey;
85
+ observation_key: PublicKey;
86
+ auth_bump: number;
87
+ status: number;
88
+ lp_mint_decimals: number;
89
+ mint_0_decimals: number;
90
+ mint_1_decimals: number;
91
+ lp_supply: BN;
92
+ protocol_fees_token_0: BN;
93
+ protocol_fees_token_1: BN;
94
+ fund_fees_token_0: BN;
95
+ fund_fees_token_1: BN;
96
+ open_time: BN;
97
+ recent_epoch: BN;
98
+ creator_fee_on: number;
99
+ enable_creator_fee: boolean;
100
+ padding1: number[];
101
+ creator_fees_token_0: BN;
102
+ creator_fees_token_1: BN;
103
+ padding: BN[];
104
+ });
105
+ static decode(data: Buffer, offset?: number): [PoolState, number];
106
+ }
107
+ export declare class RaydiumCPMMOracle extends Oracle {
108
+ pool_id: PublicKey;
109
+ quote_token: Quote;
110
+ pool_state: PoolState;
111
+ side: Side;
112
+ observation_state: ObservationState;
113
+ private constructor();
114
+ static create(params: {
115
+ connection: Connection;
116
+ pool_id: PublicKey;
117
+ quote_token: Quote;
118
+ side: Side;
119
+ weight: number;
120
+ conf_thresh_bps?: number;
121
+ staleness_thresh?: number;
122
+ volatility_thresh?: number | Decimal;
123
+ min_liquidity?: number | Decimal;
124
+ staleness_conf_rate_bps?: number;
125
+ }): Promise<RaydiumCPMMOracle>;
126
+ set_side(side: Side): void;
127
+ static derive_observation_key(poolId: PublicKey): [PublicKey, number];
128
+ get_observation_at_index(index: number): Observation;
129
+ get_observation_at_timestamp(timestamp: BN, startIndex: number): Observation;
130
+ get_delta_observations(currentTime: BN): Observation[];
131
+ get_decimals(): number;
132
+ get_twap_30sec(current_time: BN): Decimal;
133
+ get_twap_2min(current_time: BN): Decimal;
134
+ get_twap_5min(current_time: BN): Decimal;
135
+ get_twap_20min(current_time: BN): Decimal;
136
+ get_confidence(current_time: BN): Decimal;
137
+ fetch(): Promise<OracleResult>;
138
+ }
139
+ export {};