@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.
- package/dist/idl/idl.d.ts +8 -0
- package/dist/idl/idl.js +4958 -0
- package/dist/idl/types.d.ts +4955 -0
- package/dist/idl/types.js +2 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +60 -0
- package/dist/layouts/basket.d.ts +42 -0
- package/dist/layouts/basket.js +43 -0
- package/dist/layouts/config.d.ts +97 -0
- package/dist/layouts/config.js +102 -0
- package/dist/layouts/fraction.d.ts +6 -0
- package/dist/layouts/fraction.js +9 -0
- package/dist/layouts/oracle.d.ts +36 -0
- package/dist/layouts/oracle.js +37 -0
- package/dist/src/constants.d.ts +15 -0
- package/dist/src/constants.js +19 -0
- package/dist/src/idl/idl.d.ts +8 -0
- package/dist/src/idl/idl.js +4958 -0
- package/dist/src/idl/types.d.ts +4955 -0
- package/dist/src/idl/types.js +2 -0
- package/dist/src/index.d.ts +53 -0
- package/dist/src/index.js +199 -0
- package/dist/src/instructions/accounts.d.ts +27 -0
- package/dist/src/instructions/accounts.js +110 -0
- package/dist/src/instructions/auction.d.ts +7 -0
- package/dist/src/instructions/auction.js +43 -0
- package/dist/src/instructions/automation/auction.d.ts +6 -0
- package/dist/src/instructions/automation/auction.js +40 -0
- package/dist/src/instructions/automation/claimBounty.d.ts +12 -0
- package/dist/src/instructions/automation/claimBounty.js +44 -0
- package/dist/src/instructions/automation/priceUpdate.d.ts +15 -0
- package/dist/src/instructions/automation/priceUpdate.js +47 -0
- package/dist/src/instructions/automation/rebalanceSwap.d.ts +10 -0
- package/dist/src/instructions/automation/rebalanceSwap.js +42 -0
- package/dist/src/instructions/basket.d.ts +120 -0
- package/dist/src/instructions/basket.js +622 -0
- package/dist/src/instructions/bounty.d.ts +18 -0
- package/dist/src/instructions/bounty.js +81 -0
- package/dist/src/instructions/fee.d.ts +8 -0
- package/dist/src/instructions/fee.js +46 -0
- package/dist/src/instructions/globalConfig.d.ts +11 -0
- package/dist/src/instructions/globalConfig.js +43 -0
- package/dist/src/instructions/luts.d.ts +33 -0
- package/dist/src/instructions/luts.js +91 -0
- package/dist/src/instructions/management/addBounty.d.ts +7 -0
- package/dist/src/instructions/management/addBounty.js +39 -0
- package/dist/src/instructions/management/admin.d.ts +9 -0
- package/dist/src/instructions/management/admin.js +43 -0
- package/dist/src/instructions/management/claimFees.d.ts +7 -0
- package/dist/src/instructions/management/claimFees.js +47 -0
- package/dist/src/instructions/management/createBasket.d.ts +22 -0
- package/dist/src/instructions/management/createBasket.js +101 -0
- package/dist/src/instructions/management/edit.d.ts +34 -0
- package/dist/src/instructions/management/edit.js +192 -0
- package/dist/src/instructions/management/luts.d.ts +29 -0
- package/dist/src/instructions/management/luts.js +88 -0
- package/dist/src/instructions/pda.d.ts +26 -0
- package/dist/src/instructions/pda.js +110 -0
- package/dist/src/instructions/price.d.ts +17 -0
- package/dist/src/instructions/price.js +47 -0
- package/dist/src/instructions/user/deposit.d.ts +32 -0
- package/dist/src/instructions/user/deposit.js +168 -0
- package/dist/src/instructions/user/withdraw.d.ts +16 -0
- package/dist/src/instructions/user/withdraw.js +82 -0
- package/dist/src/layouts/basket.d.ts +41 -0
- package/dist/src/layouts/basket.js +43 -0
- package/dist/src/layouts/config.d.ts +133 -0
- package/dist/src/layouts/config.js +137 -0
- package/dist/src/layouts/fraction.d.ts +6 -0
- package/dist/src/layouts/fraction.js +9 -0
- package/dist/src/layouts/intents/bounty.d.ts +18 -0
- package/dist/src/layouts/intents/bounty.js +19 -0
- package/dist/src/layouts/intents/intent.d.ts +101 -0
- package/dist/src/layouts/intents/intent.js +113 -0
- package/dist/src/layouts/intents/rebalanceIntent.d.ts +56 -0
- package/dist/src/layouts/intents/rebalanceIntent.js +63 -0
- package/dist/src/layouts/lookupTable.d.ts +7 -0
- package/dist/src/layouts/lookupTable.js +10 -0
- package/dist/src/layouts/oracle.d.ts +42 -0
- package/dist/src/layouts/oracle.js +43 -0
- package/dist/src/states/basket.d.ts +8 -0
- package/dist/src/states/basket.js +54 -0
- package/dist/src/states/intents/intent.d.ts +14 -0
- package/dist/src/states/intents/intent.js +90 -0
- package/dist/src/states/intents/rebalanceIntent.d.ts +8 -0
- package/dist/src/states/intents/rebalanceIntent.js +54 -0
- package/dist/src/states/oracles/clmm_oracle.d.ts +178 -0
- package/dist/src/states/oracles/clmm_oracle.js +546 -0
- package/dist/src/states/oracles/constants.d.ts +8 -0
- package/dist/src/states/oracles/constants.js +12 -0
- package/dist/src/states/oracles/oracle.d.ts +60 -0
- package/dist/src/states/oracles/oracle.js +237 -0
- package/dist/src/states/oracles/pythOracle.d.ts +39 -0
- package/dist/src/states/oracles/pythOracle.js +202 -0
- package/dist/src/states/oracles/pyth_oracle.d.ts +39 -0
- package/dist/src/states/oracles/pyth_oracle.js +202 -0
- package/dist/src/states/oracles/raydiumClmmOracle.d.ts +178 -0
- package/dist/src/states/oracles/raydiumClmmOracle.js +546 -0
- package/dist/src/states/oracles/raydiumCpmmOracle.d.ts +139 -0
- package/dist/src/states/oracles/raydiumCpmmOracle.js +420 -0
- package/dist/src/states/oracles/raydium_cpmm_oracle.d.ts +139 -0
- package/dist/src/states/oracles/raydium_cpmm_oracle.js +420 -0
- package/dist/src/states/oracles/switchboardOracle.d.ts +0 -0
- package/dist/src/states/oracles/switchboardOracle.js +1 -0
- package/dist/src/states/oracles/switchboard_oracle.d.ts +0 -0
- package/dist/src/states/oracles/switchboard_oracle.js +1 -0
- package/dist/src/txUtils.d.ts +26 -0
- package/dist/src/txUtils.js +183 -0
- package/dist/states/basket.d.ts +8 -0
- package/dist/states/basket.js +57 -0
- package/dist/test.d.ts +1 -0
- package/dist/test.js +39 -0
- package/package.json +30 -0
- package/src/constants.ts +24 -0
- package/src/index.ts +260 -0
- package/src/instructions/automation/auction.ts +55 -0
- package/src/instructions/automation/claimBounty.ts +69 -0
- package/src/instructions/automation/priceUpdate.ts +73 -0
- package/src/instructions/automation/rebalanceSwap.ts +60 -0
- package/src/instructions/management/addBounty.ts +56 -0
- package/src/instructions/management/admin.ts +65 -0
- package/src/instructions/management/claimFees.ts +59 -0
- package/src/instructions/management/createBasket.ts +148 -0
- package/src/instructions/management/edit.ts +255 -0
- package/src/instructions/management/luts.ts +134 -0
- package/src/instructions/pda.ts +160 -0
- package/src/instructions/user/deposit.ts +237 -0
- package/src/instructions/user/withdraw.ts +130 -0
- package/src/layouts/basket.ts +82 -0
- package/src/layouts/config.ts +301 -0
- package/src/layouts/fraction.ts +12 -0
- package/src/layouts/intents/bounty.ts +35 -0
- package/src/layouts/intents/intent.ts +204 -0
- package/src/layouts/intents/rebalanceIntent.ts +111 -0
- package/src/layouts/lookupTable.ts +14 -0
- package/src/layouts/oracle.ts +96 -0
- package/src/states/basket.ts +56 -0
- package/src/states/intents/intent.ts +107 -0
- package/src/states/intents/rebalanceIntent.ts +57 -0
- package/src/states/oracles/constants.ts +13 -0
- package/src/states/oracles/oracle.ts +260 -0
- package/src/states/oracles/pythOracle.ts +270 -0
- package/src/states/oracles/raydiumClmmOracle.ts +812 -0
- package/src/states/oracles/raydiumCpmmOracle.ts +614 -0
- package/src/states/oracles/switchboardOracle.ts +0 -0
- package/src/txUtils.ts +250 -0
- package/test.ts +30 -0
- 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 {};
|