@drift-labs/sdk 2.142.0-beta.8 → 2.142.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/VERSION +1 -1
- package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.d.ts +46 -5
- package/lib/browser/accounts/grpcDriftClientAccountSubscriberV2.js +245 -44
- package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +7 -4
- package/lib/browser/accounts/grpcMultiAccountSubscriber.js +115 -19
- package/lib/browser/adminClient.d.ts +4 -0
- package/lib/browser/adminClient.js +34 -0
- package/lib/browser/constants/perpMarkets.js +35 -0
- package/lib/browser/constants/spotMarkets.js +4 -4
- package/lib/browser/driftClient.d.ts +35 -5
- package/lib/browser/driftClient.js +41 -14
- package/lib/browser/events/parse.d.ts +2 -0
- package/lib/browser/events/parse.js +94 -1
- package/lib/browser/events/types.d.ts +22 -3
- package/lib/browser/idl/drift.json +105 -6
- package/lib/browser/math/amm.d.ts +1 -0
- package/lib/browser/math/amm.js +28 -4
- package/lib/browser/types.d.ts +20 -0
- package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts +46 -5
- package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/grpcDriftClientAccountSubscriberV2.js +245 -44
- package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +7 -4
- package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcMultiAccountSubscriber.js +115 -19
- package/lib/node/adminClient.d.ts +4 -0
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +34 -0
- package/lib/node/constants/perpMarkets.d.ts.map +1 -1
- package/lib/node/constants/perpMarkets.js +35 -0
- package/lib/node/constants/spotMarkets.js +4 -4
- package/lib/node/driftClient.d.ts +35 -5
- package/lib/node/driftClient.d.ts.map +1 -1
- package/lib/node/driftClient.js +41 -14
- package/lib/node/events/parse.d.ts +2 -0
- package/lib/node/events/parse.d.ts.map +1 -1
- package/lib/node/events/parse.js +94 -1
- package/lib/node/events/types.d.ts +22 -3
- package/lib/node/events/types.d.ts.map +1 -1
- package/lib/node/idl/drift.json +105 -6
- package/lib/node/math/amm.d.ts +1 -0
- package/lib/node/math/amm.d.ts.map +1 -1
- package/lib/node/math/amm.js +28 -4
- package/lib/node/types.d.ts +20 -0
- package/lib/node/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/scripts/client-test.ts +294 -126
- package/src/accounts/grpcDriftClientAccountSubscriberV2.ts +401 -75
- package/src/accounts/grpcMultiAccountSubscriber.ts +167 -34
- package/src/adminClient.ts +74 -0
- package/src/constants/perpMarkets.ts +37 -0
- package/src/constants/spotMarkets.ts +4 -4
- package/src/driftClient.ts +65 -14
- package/src/events/parse.ts +115 -0
- package/src/events/types.ts +26 -2
- package/src/idl/drift.json +105 -6
- package/src/math/amm.ts +52 -8
- package/src/types.ts +22 -0
- package/tests/events/parseLogsForCuUsage.ts +139 -0
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseLogsWithRaw = exports.parseLogs = void 0;
|
|
3
|
+
exports.parseLogsForCuUsage = exports.parseLogsWithRaw = exports.parseLogs = void 0;
|
|
4
4
|
const driftProgramId = 'dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH';
|
|
5
5
|
const PROGRAM_LOG = 'Program log: ';
|
|
6
|
+
const PROGRAM_INSTRUCTION = 'Program log: Instruction: ';
|
|
6
7
|
const PROGRAM_DATA = 'Program data: ';
|
|
7
8
|
const PROGRAM_LOG_START_INDEX = PROGRAM_LOG.length;
|
|
8
9
|
const PROGRAM_DATA_START_INDEX = PROGRAM_DATA.length;
|
|
10
|
+
const PROGRAM_INSTRUCTION_START_INDEX = PROGRAM_INSTRUCTION.length;
|
|
9
11
|
function parseLogs(program, logs, programId = driftProgramId) {
|
|
10
12
|
const { events } = parseLogsWithRaw(program, logs, programId);
|
|
11
13
|
return events;
|
|
@@ -87,6 +89,7 @@ function handleSystemLog(log, programId = driftProgramId) {
|
|
|
87
89
|
class ExecutionContext {
|
|
88
90
|
constructor() {
|
|
89
91
|
this.stack = [];
|
|
92
|
+
this.ixStack = [];
|
|
90
93
|
}
|
|
91
94
|
program() {
|
|
92
95
|
if (!this.stack.length) {
|
|
@@ -103,4 +106,94 @@ class ExecutionContext {
|
|
|
103
106
|
}
|
|
104
107
|
this.stack.pop();
|
|
105
108
|
}
|
|
109
|
+
ix() {
|
|
110
|
+
if (!this.ixStack.length) {
|
|
111
|
+
throw new Error('Expected the ix stack to have elements');
|
|
112
|
+
}
|
|
113
|
+
return this.ixStack[this.ixStack.length - 1];
|
|
114
|
+
}
|
|
115
|
+
pushIx(newIx) {
|
|
116
|
+
this.ixStack.push(newIx);
|
|
117
|
+
}
|
|
118
|
+
popIx() {
|
|
119
|
+
this.ixStack.pop();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function parseLogsForCuUsage(logs, programId = driftProgramId) {
|
|
123
|
+
const cuUsageEvents = [];
|
|
124
|
+
const execution = new ExecutionContext();
|
|
125
|
+
for (const log of logs) {
|
|
126
|
+
if (log.startsWith('Log truncated')) {
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
const [newProgram, newIx, didPopProgram, didPopIx] = handleLogForCuUsage(execution, log, programId);
|
|
130
|
+
if (newProgram) {
|
|
131
|
+
execution.push(newProgram);
|
|
132
|
+
}
|
|
133
|
+
if (newIx) {
|
|
134
|
+
execution.pushIx(newIx);
|
|
135
|
+
}
|
|
136
|
+
if (didPopProgram) {
|
|
137
|
+
execution.pop();
|
|
138
|
+
}
|
|
139
|
+
if (didPopIx !== null) {
|
|
140
|
+
cuUsageEvents.push({
|
|
141
|
+
name: 'CuUsage',
|
|
142
|
+
data: {
|
|
143
|
+
instruction: execution.ix(),
|
|
144
|
+
cuUsage: didPopIx,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
execution.popIx();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return cuUsageEvents;
|
|
151
|
+
}
|
|
152
|
+
exports.parseLogsForCuUsage = parseLogsForCuUsage;
|
|
153
|
+
function handleLogForCuUsage(execution, log, programId = driftProgramId) {
|
|
154
|
+
if (execution.stack.length > 0 && execution.program() === programId) {
|
|
155
|
+
return handleProgramLogForCuUsage(log, programId);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
return handleSystemLogForCuUsage(log, programId);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function handleProgramLogForCuUsage(log, programId = driftProgramId) {
|
|
162
|
+
if (log.startsWith(PROGRAM_INSTRUCTION)) {
|
|
163
|
+
const ixStr = log.slice(PROGRAM_INSTRUCTION_START_INDEX);
|
|
164
|
+
return [null, ixStr, false, null];
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
return handleSystemLogForCuUsage(log, programId);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function handleSystemLogForCuUsage(log, programId = driftProgramId) {
|
|
171
|
+
// System component.
|
|
172
|
+
const logStart = log.split(':')[0];
|
|
173
|
+
const programStart = `Program ${programId} invoke`;
|
|
174
|
+
// Did the program finish executing?
|
|
175
|
+
if (logStart.match(/^Program (.*) success/g) !== null) {
|
|
176
|
+
return [null, null, true, null];
|
|
177
|
+
// Recursive call.
|
|
178
|
+
}
|
|
179
|
+
else if (logStart.startsWith(programStart)) {
|
|
180
|
+
return [programId, null, false, null];
|
|
181
|
+
// Consumed CU log.
|
|
182
|
+
}
|
|
183
|
+
else if (log.startsWith(`Program ${programId} consumed `)) {
|
|
184
|
+
// Extract CU usage, e.g. 'Program ... consumed 29242 of 199700 compute units'
|
|
185
|
+
// We need to extract the consumed value (29242)
|
|
186
|
+
const matches = log.match(/consumed (\d+) of \d+ compute units/);
|
|
187
|
+
if (matches) {
|
|
188
|
+
return [null, null, false, Number(matches[1])];
|
|
189
|
+
}
|
|
190
|
+
return [null, null, false, null];
|
|
191
|
+
}
|
|
192
|
+
// CPI call.
|
|
193
|
+
else if (logStart.includes('invoke')) {
|
|
194
|
+
return ['cpi', null, false, null]; // Any string will do.
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
return [null, null, false, null];
|
|
198
|
+
}
|
|
106
199
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Commitment, PublicKey, TransactionSignature } from '@solana/web3.js';
|
|
3
|
-
import { DepositRecord, FundingPaymentRecord, FundingRateRecord, LiquidationRecord, NewUserRecord, OrderActionRecord, OrderRecord, SettlePnlRecord, LPRecord, InsuranceFundRecord, SpotInterestRecord, InsuranceFundStakeRecord, CurveRecord, SwapRecord, SpotMarketVaultDepositRecord, SignedMsgOrderRecord, DeleteUserRecord, FuelSweepRecord, FuelSeasonRecord, InsuranceFundSwapRecord, TransferProtocolIfSharesToRevenuePoolRecord, LPMintRedeemRecord, LPSettleRecord, LPSwapRecord } from '../types';
|
|
3
|
+
import { DepositRecord, FundingPaymentRecord, FundingRateRecord, LiquidationRecord, NewUserRecord, OrderActionRecord, OrderRecord, SettlePnlRecord, LPRecord, InsuranceFundRecord, SpotInterestRecord, InsuranceFundStakeRecord, CurveRecord, SwapRecord, SpotMarketVaultDepositRecord, SignedMsgOrderRecord, DeleteUserRecord, FuelSweepRecord, FuelSeasonRecord, InsuranceFundSwapRecord, TransferProtocolIfSharesToRevenuePoolRecord, LPMintRedeemRecord, LPSettleRecord, LPSwapRecord, LPBorrowLendDepositRecord } from '../types';
|
|
4
4
|
import { EventEmitter } from 'events';
|
|
5
5
|
export type EventSubscriptionOptions = {
|
|
6
6
|
address?: PublicKey;
|
|
@@ -47,12 +47,12 @@ export type EventMap = {
|
|
|
47
47
|
FuelSeasonRecord: Event<FuelSeasonRecord>;
|
|
48
48
|
InsuranceFundSwapRecord: Event<InsuranceFundSwapRecord>;
|
|
49
49
|
TransferProtocolIfSharesToRevenuePoolRecord: Event<TransferProtocolIfSharesToRevenuePoolRecord>;
|
|
50
|
-
LPMintRedeemRecord: Event<LPMintRedeemRecord>;
|
|
51
50
|
LPSettleRecord: Event<LPSettleRecord>;
|
|
51
|
+
LPMintRedeemRecord: Event<LPMintRedeemRecord>;
|
|
52
52
|
LPSwapRecord: Event<LPSwapRecord>;
|
|
53
53
|
};
|
|
54
54
|
export type EventType = keyof EventMap;
|
|
55
|
-
export type DriftEvent = Event<DepositRecord> | Event<FundingPaymentRecord> | Event<LiquidationRecord> | Event<FundingRateRecord> | Event<OrderRecord> | Event<OrderActionRecord> | Event<SettlePnlRecord> | Event<NewUserRecord> | Event<LPRecord> | Event<InsuranceFundRecord> | Event<SpotInterestRecord> | Event<InsuranceFundStakeRecord> | Event<CurveRecord> | Event<SwapRecord> | Event<SpotMarketVaultDepositRecord> | Event<SignedMsgOrderRecord> | Event<DeleteUserRecord> | Event<FuelSweepRecord> | Event<FuelSeasonRecord> | Event<InsuranceFundSwapRecord> | Event<TransferProtocolIfSharesToRevenuePoolRecord> | Event<LPSettleRecord> | Event<LPSwapRecord> | Event<
|
|
55
|
+
export type DriftEvent = Event<DepositRecord> | Event<FundingPaymentRecord> | Event<LiquidationRecord> | Event<FundingRateRecord> | Event<OrderRecord> | Event<OrderActionRecord> | Event<SettlePnlRecord> | Event<NewUserRecord> | Event<LPRecord> | Event<InsuranceFundRecord> | Event<SpotInterestRecord> | Event<InsuranceFundStakeRecord> | Event<CurveRecord> | Event<SwapRecord> | Event<SpotMarketVaultDepositRecord> | Event<SignedMsgOrderRecord> | Event<DeleteUserRecord> | Event<FuelSweepRecord> | Event<FuelSeasonRecord> | Event<InsuranceFundSwapRecord> | Event<TransferProtocolIfSharesToRevenuePoolRecord> | Event<LPSettleRecord> | Event<LPMintRedeemRecord> | Event<LPSwapRecord> | Event<LPBorrowLendDepositRecord> | Event<CuUsage>;
|
|
56
56
|
export interface EventSubscriberEvents {
|
|
57
57
|
newEvent: (event: WrappedEvent<EventType>) => void;
|
|
58
58
|
}
|
|
@@ -84,3 +84,22 @@ export type EventsServerLogProviderConfig = StreamingLogProviderConfig & {
|
|
|
84
84
|
url: string;
|
|
85
85
|
};
|
|
86
86
|
export type LogProviderConfig = WebSocketLogProviderConfig | PollingLogProviderConfig | EventsServerLogProviderConfig;
|
|
87
|
+
export type CuUsageEvent = {
|
|
88
|
+
name: 'CuUsage';
|
|
89
|
+
fields: [
|
|
90
|
+
{
|
|
91
|
+
name: 'instruction';
|
|
92
|
+
type: 'string';
|
|
93
|
+
index: false;
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'cuUsage';
|
|
97
|
+
type: 'u32';
|
|
98
|
+
index: false;
|
|
99
|
+
}
|
|
100
|
+
];
|
|
101
|
+
};
|
|
102
|
+
export type CuUsage = {
|
|
103
|
+
instruction: string;
|
|
104
|
+
cuUsage: number;
|
|
105
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.142.0",
|
|
3
3
|
"name": "drift",
|
|
4
4
|
"instructions": [
|
|
5
5
|
{
|
|
@@ -5874,6 +5874,32 @@
|
|
|
5874
5874
|
}
|
|
5875
5875
|
]
|
|
5876
5876
|
},
|
|
5877
|
+
{
|
|
5878
|
+
"name": "updatePerpMarketReferencePriceOffsetDeadbandPct",
|
|
5879
|
+
"accounts": [
|
|
5880
|
+
{
|
|
5881
|
+
"name": "admin",
|
|
5882
|
+
"isMut": false,
|
|
5883
|
+
"isSigner": true
|
|
5884
|
+
},
|
|
5885
|
+
{
|
|
5886
|
+
"name": "state",
|
|
5887
|
+
"isMut": false,
|
|
5888
|
+
"isSigner": false
|
|
5889
|
+
},
|
|
5890
|
+
{
|
|
5891
|
+
"name": "perpMarket",
|
|
5892
|
+
"isMut": true,
|
|
5893
|
+
"isSigner": false
|
|
5894
|
+
}
|
|
5895
|
+
],
|
|
5896
|
+
"args": [
|
|
5897
|
+
{
|
|
5898
|
+
"name": "referencePriceOffsetDeadbandPct",
|
|
5899
|
+
"type": "u8"
|
|
5900
|
+
}
|
|
5901
|
+
]
|
|
5902
|
+
},
|
|
5877
5903
|
{
|
|
5878
5904
|
"name": "updateLpCooldownTime",
|
|
5879
5905
|
"accounts": [
|
|
@@ -11209,12 +11235,16 @@
|
|
|
11209
11235
|
],
|
|
11210
11236
|
"type": "i8"
|
|
11211
11237
|
},
|
|
11238
|
+
{
|
|
11239
|
+
"name": "referencePriceOffsetDeadbandPct",
|
|
11240
|
+
"type": "u8"
|
|
11241
|
+
},
|
|
11212
11242
|
{
|
|
11213
11243
|
"name": "padding",
|
|
11214
11244
|
"type": {
|
|
11215
11245
|
"array": [
|
|
11216
11246
|
"u8",
|
|
11217
|
-
|
|
11247
|
+
2
|
|
11218
11248
|
]
|
|
11219
11249
|
}
|
|
11220
11250
|
},
|
|
@@ -14875,6 +14905,11 @@
|
|
|
14875
14905
|
"name": "lpPrice",
|
|
14876
14906
|
"type": "u128",
|
|
14877
14907
|
"index": false
|
|
14908
|
+
},
|
|
14909
|
+
{
|
|
14910
|
+
"name": "lpPool",
|
|
14911
|
+
"type": "publicKey",
|
|
14912
|
+
"index": false
|
|
14878
14913
|
}
|
|
14879
14914
|
]
|
|
14880
14915
|
},
|
|
@@ -14985,6 +15020,11 @@
|
|
|
14985
15020
|
"name": "outSwapId",
|
|
14986
15021
|
"type": "u64",
|
|
14987
15022
|
"index": false
|
|
15023
|
+
},
|
|
15024
|
+
{
|
|
15025
|
+
"name": "lpPool",
|
|
15026
|
+
"type": "publicKey",
|
|
15027
|
+
"index": false
|
|
14988
15028
|
}
|
|
14989
15029
|
]
|
|
14990
15030
|
},
|
|
@@ -15080,6 +15120,68 @@
|
|
|
15080
15120
|
"name": "inMarketTargetWeight",
|
|
15081
15121
|
"type": "i64",
|
|
15082
15122
|
"index": false
|
|
15123
|
+
},
|
|
15124
|
+
{
|
|
15125
|
+
"name": "lpPool",
|
|
15126
|
+
"type": "publicKey",
|
|
15127
|
+
"index": false
|
|
15128
|
+
}
|
|
15129
|
+
]
|
|
15130
|
+
},
|
|
15131
|
+
{
|
|
15132
|
+
"name": "LPBorrowLendDepositRecord",
|
|
15133
|
+
"fields": [
|
|
15134
|
+
{
|
|
15135
|
+
"name": "ts",
|
|
15136
|
+
"type": "i64",
|
|
15137
|
+
"index": false
|
|
15138
|
+
},
|
|
15139
|
+
{
|
|
15140
|
+
"name": "slot",
|
|
15141
|
+
"type": "u64",
|
|
15142
|
+
"index": false
|
|
15143
|
+
},
|
|
15144
|
+
{
|
|
15145
|
+
"name": "spotMarketIndex",
|
|
15146
|
+
"type": "u16",
|
|
15147
|
+
"index": false
|
|
15148
|
+
},
|
|
15149
|
+
{
|
|
15150
|
+
"name": "constituentIndex",
|
|
15151
|
+
"type": "u16",
|
|
15152
|
+
"index": false
|
|
15153
|
+
},
|
|
15154
|
+
{
|
|
15155
|
+
"name": "direction",
|
|
15156
|
+
"type": {
|
|
15157
|
+
"defined": "DepositDirection"
|
|
15158
|
+
},
|
|
15159
|
+
"index": false
|
|
15160
|
+
},
|
|
15161
|
+
{
|
|
15162
|
+
"name": "tokenBalance",
|
|
15163
|
+
"type": "i64",
|
|
15164
|
+
"index": false
|
|
15165
|
+
},
|
|
15166
|
+
{
|
|
15167
|
+
"name": "lastTokenBalance",
|
|
15168
|
+
"type": "i64",
|
|
15169
|
+
"index": false
|
|
15170
|
+
},
|
|
15171
|
+
{
|
|
15172
|
+
"name": "interestAccruedTokenAmount",
|
|
15173
|
+
"type": "i64",
|
|
15174
|
+
"index": false
|
|
15175
|
+
},
|
|
15176
|
+
{
|
|
15177
|
+
"name": "amountDepositWithdraw",
|
|
15178
|
+
"type": "u64",
|
|
15179
|
+
"index": false
|
|
15180
|
+
},
|
|
15181
|
+
{
|
|
15182
|
+
"name": "lpPool",
|
|
15183
|
+
"type": "publicKey",
|
|
15184
|
+
"index": false
|
|
15083
15185
|
}
|
|
15084
15186
|
]
|
|
15085
15187
|
}
|
|
@@ -16710,8 +16812,5 @@
|
|
|
16710
16812
|
"name": "UnableToLoadRevenueShareAccount",
|
|
16711
16813
|
"msg": "Unable to load builder account"
|
|
16712
16814
|
}
|
|
16713
|
-
]
|
|
16714
|
-
"metadata": {
|
|
16715
|
-
"address": "dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH"
|
|
16716
|
-
}
|
|
16815
|
+
]
|
|
16717
16816
|
}
|
|
@@ -35,6 +35,7 @@ export type AssetType = 'quote' | 'base';
|
|
|
35
35
|
export declare function calculateAmmReservesAfterSwap(amm: Pick<AMM, 'pegMultiplier' | 'quoteAssetReserve' | 'sqrtK' | 'baseAssetReserve'>, inputAssetType: AssetType, swapAmount: BN, swapDirection: SwapDirection): [BN, BN];
|
|
36
36
|
export declare function calculateMarketOpenBidAsk(baseAssetReserve: BN, minBaseAssetReserve: BN, maxBaseAssetReserve: BN, stepSize?: BN): [BN, BN];
|
|
37
37
|
export declare function calculateInventoryLiquidityRatio(baseAssetAmountWithAmm: BN, baseAssetReserve: BN, minBaseAssetReserve: BN, maxBaseAssetReserve: BN): BN;
|
|
38
|
+
export declare function calculateInventoryLiquidityRatioForReferencePriceOffset(baseAssetAmountWithAmm: BN, baseAssetReserve: BN, minBaseAssetReserve: BN, maxBaseAssetReserve: BN): BN;
|
|
38
39
|
export declare function calculateInventoryScale(baseAssetAmountWithAmm: BN, baseAssetReserve: BN, minBaseAssetReserve: BN, maxBaseAssetReserve: BN, directionalSpread: number, maxSpread: number): number;
|
|
39
40
|
export declare function calculateReferencePriceOffset(reservePrice: BN, last24hAvgFundingRate: BN, liquidityFraction: BN, oracleTwapFast: BN, markTwapFast: BN, oracleTwapSlow: BN, markTwapSlow: BN, maxOffsetPct: number): BN;
|
|
40
41
|
export declare function calculateEffectiveLeverage(baseSpread: number, quoteAssetReserve: BN, terminalQuoteAssetReserve: BN, pegMultiplier: BN, netBaseAssetAmount: BN, reservePrice: BN, totalFeeMinusDistributions: BN): number;
|
package/lib/browser/math/amm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.getQuoteAssetReservePredictionMarketBounds = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateVolSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateReferencePriceOffset = exports.calculateInventoryScale = exports.calculateInventoryLiquidityRatio = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
3
|
+
exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.getQuoteAssetReservePredictionMarketBounds = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateVolSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateReferencePriceOffset = exports.calculateInventoryScale = exports.calculateInventoryLiquidityRatioForReferencePriceOffset = exports.calculateInventoryLiquidityRatio = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
|
|
4
4
|
const anchor_1 = require("@coral-xyz/anchor");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
@@ -213,6 +213,17 @@ function calculateInventoryLiquidityRatio(baseAssetAmountWithAmm, baseAssetReser
|
|
|
213
213
|
return inventoryScaleBN;
|
|
214
214
|
}
|
|
215
215
|
exports.calculateInventoryLiquidityRatio = calculateInventoryLiquidityRatio;
|
|
216
|
+
function calculateInventoryLiquidityRatioForReferencePriceOffset(baseAssetAmountWithAmm, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve) {
|
|
217
|
+
// inventory skew
|
|
218
|
+
const [openBids, openAsks] = calculateMarketOpenBidAsk(baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve);
|
|
219
|
+
const avgSideLiquidity = openBids.abs().add(openAsks.abs()).div(numericConstants_1.TWO);
|
|
220
|
+
const inventoryScaleBN = anchor_1.BN.min(baseAssetAmountWithAmm
|
|
221
|
+
.mul(numericConstants_1.PERCENTAGE_PRECISION)
|
|
222
|
+
.div(anchor_1.BN.max(avgSideLiquidity, numericConstants_1.ONE))
|
|
223
|
+
.abs(), numericConstants_1.PERCENTAGE_PRECISION);
|
|
224
|
+
return inventoryScaleBN;
|
|
225
|
+
}
|
|
226
|
+
exports.calculateInventoryLiquidityRatioForReferencePriceOffset = calculateInventoryLiquidityRatioForReferencePriceOffset;
|
|
216
227
|
function calculateInventoryScale(baseAssetAmountWithAmm, baseAssetReserve, minBaseAssetReserve, maxBaseAssetReserve, directionalSpread, maxSpread) {
|
|
217
228
|
if (baseAssetAmountWithAmm.eq(numericConstants_1.ZERO)) {
|
|
218
229
|
return 1;
|
|
@@ -227,7 +238,7 @@ function calculateInventoryScale(baseAssetAmountWithAmm, baseAssetReserve, minBa
|
|
|
227
238
|
}
|
|
228
239
|
exports.calculateInventoryScale = calculateInventoryScale;
|
|
229
240
|
function calculateReferencePriceOffset(reservePrice, last24hAvgFundingRate, liquidityFraction, oracleTwapFast, markTwapFast, oracleTwapSlow, markTwapSlow, maxOffsetPct) {
|
|
230
|
-
if (last24hAvgFundingRate.eq(numericConstants_1.ZERO)) {
|
|
241
|
+
if (last24hAvgFundingRate.eq(numericConstants_1.ZERO) || liquidityFraction.eq(numericConstants_1.ZERO)) {
|
|
231
242
|
return numericConstants_1.ZERO;
|
|
232
243
|
}
|
|
233
244
|
const maxOffsetInPrice = new anchor_1.BN(maxOffsetPct)
|
|
@@ -526,9 +537,22 @@ function calculateSpreadReserves(amm, mmOraclePriceData, now, isPrediction = fal
|
|
|
526
537
|
if (amm.curveUpdateIntensity > 100) {
|
|
527
538
|
maxOffset = Math.max(amm.maxSpread / 2, (numericConstants_1.PERCENTAGE_PRECISION.toNumber() / 10000) *
|
|
528
539
|
(amm.curveUpdateIntensity - 100));
|
|
529
|
-
const liquidityFraction =
|
|
540
|
+
const liquidityFraction = calculateInventoryLiquidityRatioForReferencePriceOffset(amm.baseAssetAmountWithAmm, amm.baseAssetReserve, amm.minBaseAssetReserve, amm.maxBaseAssetReserve);
|
|
530
541
|
const liquidityFractionSigned = liquidityFraction.mul((0, utils_1.sigNum)(amm.baseAssetAmountWithAmm.add(amm.baseAssetAmountWithUnsettledLp)));
|
|
531
|
-
|
|
542
|
+
let liquidityFractionAfterDeadband = liquidityFractionSigned;
|
|
543
|
+
const deadbandPct = amm.referencePriceOffsetDeadbandPct
|
|
544
|
+
? numericConstants_1.PERCENTAGE_PRECISION.mul(new anchor_1.BN(amm.referencePriceOffsetDeadbandPct)).divn(100)
|
|
545
|
+
: numericConstants_1.ZERO;
|
|
546
|
+
if (!liquidityFractionAfterDeadband.eq(numericConstants_1.ZERO) && deadbandPct.gt(numericConstants_1.ZERO)) {
|
|
547
|
+
const abs = liquidityFractionAfterDeadband.abs();
|
|
548
|
+
if (abs.lte(deadbandPct)) {
|
|
549
|
+
liquidityFractionAfterDeadband = numericConstants_1.ZERO;
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
liquidityFractionAfterDeadband = liquidityFractionAfterDeadband.sub(deadbandPct.mul((0, utils_1.sigNum)(liquidityFractionAfterDeadband)));
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
referencePriceOffset = calculateReferencePriceOffset(reservePrice, amm.last24HAvgFundingRate, liquidityFractionAfterDeadband, amm.historicalOracleData.lastOraclePriceTwap5Min, amm.lastMarkPriceTwap5Min, amm.historicalOracleData.lastOraclePriceTwap, amm.lastMarkPriceTwap, maxOffset).toNumber();
|
|
532
556
|
}
|
|
533
557
|
let [longSpread, shortSpread] = calculateSpread(amm, mmOraclePriceData, now, reservePrice);
|
|
534
558
|
const doReferencePricOffsetSmooth = Math.sign(referencePriceOffset) !== Math.sign(amm.referencePriceOffset) &&
|
package/lib/browser/types.d.ts
CHANGED
|
@@ -866,6 +866,7 @@ export type LPSwapRecord = {
|
|
|
866
866
|
outMarketTargetWeight: BN;
|
|
867
867
|
inSwapId: BN;
|
|
868
868
|
outSwapId: BN;
|
|
869
|
+
lpPool: PublicKey;
|
|
869
870
|
};
|
|
870
871
|
export type LPMintRedeemRecord = {
|
|
871
872
|
ts: BN;
|
|
@@ -887,6 +888,7 @@ export type LPMintRedeemRecord = {
|
|
|
887
888
|
lastAumSlot: BN;
|
|
888
889
|
inMarketCurrentWeight: BN;
|
|
889
890
|
inMarketTargetWeight: BN;
|
|
891
|
+
lpPool: PublicKey;
|
|
890
892
|
};
|
|
891
893
|
export type LPSettleRecord = {
|
|
892
894
|
recordId: BN;
|
|
@@ -900,6 +902,19 @@ export type LPSettleRecord = {
|
|
|
900
902
|
perpAmmExFeeDelta: BN;
|
|
901
903
|
lpAum: BN;
|
|
902
904
|
lpPrice: BN;
|
|
905
|
+
lpPool: PublicKey;
|
|
906
|
+
};
|
|
907
|
+
export type LPBorrowLendDepositRecord = {
|
|
908
|
+
ts: BN;
|
|
909
|
+
slot: BN;
|
|
910
|
+
spotMarketIndex: number;
|
|
911
|
+
constituentIndex: number;
|
|
912
|
+
direction: DepositDirection;
|
|
913
|
+
tokenBalance: BN;
|
|
914
|
+
lastTokenBalance: BN;
|
|
915
|
+
interestAccruedTokenAmount: BN;
|
|
916
|
+
amountDepositWithdraw: BN;
|
|
917
|
+
lpPool: PublicKey;
|
|
903
918
|
};
|
|
904
919
|
export type StateAccount = {
|
|
905
920
|
admin: PublicKey;
|
|
@@ -971,6 +986,10 @@ export type PerpMarketAccount = {
|
|
|
971
986
|
protectedMakerLimitPriceDivisor: number;
|
|
972
987
|
protectedMakerDynamicDivisor: number;
|
|
973
988
|
lastFillPrice: BN;
|
|
989
|
+
lpFeeTransferScalar: number;
|
|
990
|
+
lpExchangeFeeExcluscionScalar: number;
|
|
991
|
+
lpStatus: number;
|
|
992
|
+
lpPausedOperations: number;
|
|
974
993
|
};
|
|
975
994
|
export type HistoricalOracleData = {
|
|
976
995
|
lastOraclePrice: BN;
|
|
@@ -1150,6 +1169,7 @@ export type AMM = {
|
|
|
1150
1169
|
ammSpreadAdjustment: number;
|
|
1151
1170
|
ammInventorySpreadAdjustment: number;
|
|
1152
1171
|
lastFundingOracleTwap: BN;
|
|
1172
|
+
referencePriceOffsetDeadbandPct: number;
|
|
1153
1173
|
};
|
|
1154
1174
|
export type PerpPosition = {
|
|
1155
1175
|
baseAssetAmount: BN;
|
|
@@ -1,24 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
import { OracleInfo, OraclePriceData } from '../oracles/types';
|
|
3
5
|
import { Program } from '@coral-xyz/anchor';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
6
|
+
import { PublicKey } from '@solana/web3.js';
|
|
7
|
+
import { AccountSubscriber, DataAndSlot, DelistedMarketSetting, DriftClientAccountEvents, DriftClientAccountSubscriber, GrpcConfigs, ResubOpts } from './types';
|
|
8
|
+
import { PerpMarketAccount, SpotMarketAccount, StateAccount } from '../types';
|
|
9
|
+
import { OracleClientCache } from '../oracles/oracleClientCache';
|
|
10
|
+
export declare class grpcDriftClientAccountSubscriberV2 implements DriftClientAccountSubscriber {
|
|
7
11
|
private grpcConfigs;
|
|
8
12
|
private perpMarketsSubscriber?;
|
|
9
13
|
private spotMarketsSubscriber?;
|
|
10
14
|
private oracleMultiSubscriber?;
|
|
11
15
|
private perpMarketIndexToAccountPubkeyMap;
|
|
12
16
|
private spotMarketIndexToAccountPubkeyMap;
|
|
17
|
+
private delistedMarketSetting;
|
|
18
|
+
eventEmitter: StrictEventEmitter<EventEmitter, DriftClientAccountEvents>;
|
|
19
|
+
isSubscribed: boolean;
|
|
20
|
+
isSubscribing: boolean;
|
|
21
|
+
program: Program;
|
|
22
|
+
perpMarketIndexes: number[];
|
|
23
|
+
spotMarketIndexes: number[];
|
|
24
|
+
shouldFindAllMarketsAndOracles: boolean;
|
|
25
|
+
oracleInfos: OracleInfo[];
|
|
26
|
+
initialPerpMarketAccountData: Map<number, PerpMarketAccount>;
|
|
27
|
+
initialSpotMarketAccountData: Map<number, SpotMarketAccount>;
|
|
28
|
+
initialOraclePriceData: Map<string, OraclePriceData>;
|
|
29
|
+
perpOracleMap: Map<number, PublicKey>;
|
|
30
|
+
perpOracleStringMap: Map<number, string>;
|
|
31
|
+
spotOracleMap: Map<number, PublicKey>;
|
|
32
|
+
spotOracleStringMap: Map<number, string>;
|
|
33
|
+
private oracleIdToOracleDataMap;
|
|
34
|
+
stateAccountSubscriber?: AccountSubscriber<StateAccount>;
|
|
35
|
+
oracleClientCache: OracleClientCache;
|
|
36
|
+
private resubOpts?;
|
|
37
|
+
private subscriptionPromise;
|
|
38
|
+
protected subscriptionPromiseResolver: (val: boolean) => void;
|
|
13
39
|
constructor(grpcConfigs: GrpcConfigs, program: Program, perpMarketIndexes: number[], spotMarketIndexes: number[], oracleInfos: OracleInfo[], shouldFindAllMarketsAndOracles: boolean, delistedMarketSetting: DelistedMarketSetting, resubOpts?: ResubOpts);
|
|
40
|
+
chunks: <T>(array: readonly T[], size: number) => T[][];
|
|
41
|
+
setInitialData(): Promise<void>;
|
|
42
|
+
addPerpMarket(_marketIndex: number): Promise<boolean>;
|
|
43
|
+
addSpotMarket(_marketIndex: number): Promise<boolean>;
|
|
44
|
+
addOracle(oracleInfo: OracleInfo): Promise<boolean>;
|
|
14
45
|
subscribe(): Promise<boolean>;
|
|
46
|
+
fetch(): Promise<void>;
|
|
47
|
+
private assertIsSubscribed;
|
|
48
|
+
getStateAccountAndSlot(): DataAndSlot<StateAccount>;
|
|
49
|
+
getMarketAccountsAndSlots(): DataAndSlot<PerpMarketAccount>[];
|
|
50
|
+
getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
|
|
15
51
|
getMarketAccountAndSlot(marketIndex: number): DataAndSlot<PerpMarketAccount> | undefined;
|
|
16
52
|
getSpotMarketAccountAndSlot(marketIndex: number): DataAndSlot<SpotMarketAccount> | undefined;
|
|
53
|
+
getOraclePriceDataAndSlot(oracleId: string): DataAndSlot<OraclePriceData> | undefined;
|
|
54
|
+
getOraclePriceDataAndSlotForPerpMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
55
|
+
getOraclePriceDataAndSlotForSpotMarket(marketIndex: number): DataAndSlot<OraclePriceData> | undefined;
|
|
17
56
|
setPerpOracleMap(): Promise<void>;
|
|
18
57
|
setSpotOracleMap(): Promise<void>;
|
|
19
58
|
subscribeToPerpMarketAccounts(): Promise<boolean>;
|
|
20
59
|
subscribeToSpotMarketAccounts(): Promise<boolean>;
|
|
21
60
|
subscribeToOracles(): Promise<boolean>;
|
|
61
|
+
handleDelistedMarkets(): Promise<void>;
|
|
62
|
+
removeInitialData(): void;
|
|
22
63
|
unsubscribeFromOracles(): Promise<void>;
|
|
23
64
|
unsubscribe(): Promise<void>;
|
|
24
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grpcDriftClientAccountSubscriberV2.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcDriftClientAccountSubscriberV2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"grpcDriftClientAccountSubscriberV2.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcDriftClientAccountSubscriberV2.ts"],"names":[],"mappings":"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"}
|