@drift-labs/sdk 0.1.29 → 0.1.30-master.2
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/lib/accounts/bulkAccountLoader.d.ts +2 -1
- package/lib/accounts/bulkAccountLoader.js +44 -32
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +15 -0
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +50 -23
- package/lib/clearingHouse.d.ts +0 -1
- package/lib/clearingHouse.js +0 -14
- package/lib/constants/accounts.d.ts +15 -0
- package/lib/constants/accounts.js +18 -0
- package/lib/factory/clearingHouse.d.ts +14 -4
- package/lib/factory/clearingHouse.js +23 -6
- package/lib/idl/clearing_house.json +2 -33
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/math/amm.d.ts +20 -0
- package/lib/math/amm.js +151 -1
- package/lib/tx/retryTxSender.d.ts +5 -2
- package/lib/tx/retryTxSender.js +14 -1
- package/lib/util/promiseTimeout.d.ts +1 -0
- package/lib/util/promiseTimeout.js +14 -0
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +51 -40
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +73 -30
- package/src/clearingHouse.ts +0 -13
- package/src/constants/accounts.ts +26 -0
- package/src/factory/clearingHouse.ts +47 -7
- package/src/idl/clearing_house.json +2 -33
- package/src/index.ts +0 -1
- package/src/math/amm.ts +212 -1
- package/src/tx/retryTxSender.ts +19 -1
- package/src/util/promiseTimeout.ts +14 -0
- package/lib/math/repeg.d.ts +0 -32
- package/lib/math/repeg.js +0 -178
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -210
- package/src/accounts/pollingClearingHouseAccountSubscriber.js.map +0 -1
- package/src/accounts/pollingOracleSubscriber.js +0 -65
- package/src/accounts/pollingOracleSubscriber.js.map +0 -1
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -65
- package/src/accounts/pollingTokenAccountSubscriber.js.map +0 -1
- package/src/accounts/utils.js +0 -8
- package/src/accounts/utils.js.map +0 -1
- package/src/accounts/webSocketAccountSubscriber.js +0 -64
- package/src/accounts/webSocketAccountSubscriber.js.map +0 -1
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -212
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js.map +0 -1
- package/src/assert/assert.js +0 -10
- package/src/assert/assert.js.map +0 -1
- package/src/constants/markets.js +0 -167
- package/src/constants/markets.js.map +0 -1
- package/src/constants/numericConstants.js +0 -22
- package/src/constants/numericConstants.js.map +0 -1
- package/src/math/conversion.js +0 -16
- package/src/math/conversion.js.map +0 -1
- package/src/math/funding.js +0 -223
- package/src/math/funding.js.map +0 -1
- package/src/math/insuranceFund.js +0 -23
- package/src/math/insuranceFund.js.map +0 -1
- package/src/math/market.js +0 -30
- package/src/math/market.js.map +0 -1
- package/src/math/orders.js +0 -73
- package/src/math/orders.js.map +0 -1
- package/src/math/position.js +0 -121
- package/src/math/position.js.map +0 -1
- package/src/math/repeg.ts +0 -253
- package/src/math/trade.js +0 -182
- package/src/math/trade.js.map +0 -1
- package/src/math/utils.js +0 -27
- package/src/math/utils.js.map +0 -1
- package/src/oracles/switchboardClient.js +0 -60
- package/src/oracles/switchboardClient.js.map +0 -1
- package/src/oracles/types.js +0 -3
- package/src/oracles/types.js.map +0 -1
- package/src/token/index.js +0 -39
- package/src/token/index.js.map +0 -1
- package/src/tx/defaultTxSender.js +0 -13
- package/src/tx/defaultTxSender.js.map +0 -1
- package/src/tx/retryTxSender.js +0 -137
- package/src/tx/retryTxSender.js.map +0 -1
- package/src/tx/types.js +0 -3
- package/src/tx/types.js.map +0 -1
- package/src/tx/utils.js +0 -9
- package/src/tx/utils.js.map +0 -1
- package/src/util/computeUnits.js +0 -17
- package/src/util/computeUnits.js.map +0 -1
- package/src/util/tps.js +0 -17
- package/src/util/tps.js.map +0 -1
|
@@ -24,6 +24,8 @@ import { getClearingHouseStateAccountPublicKey } from '../addresses';
|
|
|
24
24
|
import { BulkAccountLoader } from './bulkAccountLoader';
|
|
25
25
|
import { capitalize } from './utils';
|
|
26
26
|
import { ClearingHouseConfigType } from '../factory/clearingHouse';
|
|
27
|
+
import { PublicKey } from '@solana/web3.js';
|
|
28
|
+
import { CLEARING_HOUSE_STATE_ACCOUNTS } from '../constants/accounts';
|
|
27
29
|
|
|
28
30
|
export class PollingClearingHouseAccountSubscriber
|
|
29
31
|
implements ClearingHouseAccountSubscriber
|
|
@@ -98,44 +100,38 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
98
100
|
return;
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
const
|
|
102
|
-
this.program.programId
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
const state = (await this.program.account.state.fetch(
|
|
106
|
-
statePublicKey
|
|
107
|
-
)) as StateAccount;
|
|
103
|
+
const accounts = await this.getClearingHouseAccounts();
|
|
108
104
|
|
|
109
|
-
this.accountsToPoll.set(
|
|
105
|
+
this.accountsToPoll.set(accounts.state.toString(), {
|
|
110
106
|
key: 'state',
|
|
111
|
-
publicKey:
|
|
107
|
+
publicKey: accounts.state,
|
|
112
108
|
eventType: 'stateAccountUpdate',
|
|
113
109
|
});
|
|
114
110
|
|
|
115
|
-
this.accountsToPoll.set(
|
|
111
|
+
this.accountsToPoll.set(accounts.markets.toString(), {
|
|
116
112
|
key: 'markets',
|
|
117
|
-
publicKey:
|
|
113
|
+
publicKey: accounts.markets,
|
|
118
114
|
eventType: 'marketsAccountUpdate',
|
|
119
115
|
});
|
|
120
116
|
|
|
121
|
-
this.accountsToPoll.set(
|
|
117
|
+
this.accountsToPoll.set(accounts.orderState.toString(), {
|
|
122
118
|
key: 'orderState',
|
|
123
|
-
publicKey:
|
|
119
|
+
publicKey: accounts.orderState,
|
|
124
120
|
eventType: 'orderStateAccountUpdate',
|
|
125
121
|
});
|
|
126
122
|
|
|
127
123
|
if (this.optionalExtraSubscriptions?.includes('tradeHistoryAccount')) {
|
|
128
|
-
this.accountsToPoll.set(
|
|
124
|
+
this.accountsToPoll.set(accounts.tradeHistory.toString(), {
|
|
129
125
|
key: 'tradeHistory',
|
|
130
|
-
publicKey:
|
|
126
|
+
publicKey: accounts.tradeHistory,
|
|
131
127
|
eventType: 'tradeHistoryAccountUpdate',
|
|
132
128
|
});
|
|
133
129
|
}
|
|
134
130
|
|
|
135
131
|
if (this.optionalExtraSubscriptions?.includes('depositHistoryAccount')) {
|
|
136
|
-
this.accountsToPoll.set(
|
|
132
|
+
this.accountsToPoll.set(accounts.depositHistory.toString(), {
|
|
137
133
|
key: 'depositHistory',
|
|
138
|
-
publicKey:
|
|
134
|
+
publicKey: accounts.depositHistory,
|
|
139
135
|
eventType: 'depositHistoryAccountUpdate',
|
|
140
136
|
});
|
|
141
137
|
}
|
|
@@ -143,9 +139,9 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
143
139
|
if (
|
|
144
140
|
this.optionalExtraSubscriptions?.includes('fundingPaymentHistoryAccount')
|
|
145
141
|
) {
|
|
146
|
-
this.accountsToPoll.set(
|
|
142
|
+
this.accountsToPoll.set(accounts.fundingPaymentHistory.toString(), {
|
|
147
143
|
key: 'fundingPaymentHistory',
|
|
148
|
-
publicKey:
|
|
144
|
+
publicKey: accounts.fundingPaymentHistory,
|
|
149
145
|
eventType: 'fundingPaymentHistoryAccountUpdate',
|
|
150
146
|
});
|
|
151
147
|
}
|
|
@@ -153,17 +149,17 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
153
149
|
if (
|
|
154
150
|
this.optionalExtraSubscriptions?.includes('fundingRateHistoryAccount')
|
|
155
151
|
) {
|
|
156
|
-
this.accountsToPoll.set(
|
|
152
|
+
this.accountsToPoll.set(accounts.fundingRateHistory.toString(), {
|
|
157
153
|
key: 'fundingRateHistory',
|
|
158
|
-
publicKey:
|
|
154
|
+
publicKey: accounts.fundingRateHistory,
|
|
159
155
|
eventType: 'fundingRateHistoryAccountUpdate',
|
|
160
156
|
});
|
|
161
157
|
}
|
|
162
158
|
|
|
163
159
|
if (this.optionalExtraSubscriptions?.includes('curveHistoryAccount')) {
|
|
164
|
-
this.accountsToPoll.set(
|
|
160
|
+
this.accountsToPoll.set(accounts.extendedCurveHistory.toString(), {
|
|
165
161
|
key: 'extendedCurveHistory',
|
|
166
|
-
publicKey:
|
|
162
|
+
publicKey: accounts.extendedCurveHistory,
|
|
167
163
|
eventType: 'curveHistoryAccountUpdate',
|
|
168
164
|
});
|
|
169
165
|
}
|
|
@@ -171,24 +167,58 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
171
167
|
if (
|
|
172
168
|
this.optionalExtraSubscriptions?.includes('liquidationHistoryAccount')
|
|
173
169
|
) {
|
|
174
|
-
this.accountsToPoll.set(
|
|
170
|
+
this.accountsToPoll.set(accounts.liquidationHistory.toString(), {
|
|
175
171
|
key: 'liquidationHistory',
|
|
176
|
-
publicKey:
|
|
172
|
+
publicKey: accounts.liquidationHistory,
|
|
177
173
|
eventType: 'liquidationHistoryAccountUpdate',
|
|
178
174
|
});
|
|
179
175
|
}
|
|
180
176
|
|
|
177
|
+
if (this.optionalExtraSubscriptions?.includes('orderHistoryAccount')) {
|
|
178
|
+
this.accountsToPoll.set(accounts.orderHistory.toString(), {
|
|
179
|
+
key: 'orderHistory',
|
|
180
|
+
publicKey: accounts.orderHistory,
|
|
181
|
+
eventType: 'orderHistoryAccountUpdate',
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async getClearingHouseAccounts(): Promise<ClearingHouseAccounts> {
|
|
187
|
+
// Skip extra calls to rpc if we already know all the accounts
|
|
188
|
+
if (CLEARING_HOUSE_STATE_ACCOUNTS[this.program.programId.toString()]) {
|
|
189
|
+
return CLEARING_HOUSE_STATE_ACCOUNTS[this.program.programId.toString()];
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const statePublicKey = await getClearingHouseStateAccountPublicKey(
|
|
193
|
+
this.program.programId
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
const state = (await this.program.account.state.fetch(
|
|
197
|
+
statePublicKey
|
|
198
|
+
)) as StateAccount;
|
|
199
|
+
|
|
200
|
+
const accounts = {
|
|
201
|
+
state: statePublicKey,
|
|
202
|
+
markets: state.markets,
|
|
203
|
+
orderState: state.orderState,
|
|
204
|
+
tradeHistory: state.tradeHistory,
|
|
205
|
+
depositHistory: state.depositHistory,
|
|
206
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
207
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
208
|
+
extendedCurveHistory: state.extendedCurveHistory,
|
|
209
|
+
liquidationHistory: state.liquidationHistory,
|
|
210
|
+
orderHistory: undefined,
|
|
211
|
+
};
|
|
212
|
+
|
|
181
213
|
if (this.optionalExtraSubscriptions?.includes('orderHistoryAccount')) {
|
|
182
214
|
const orderState = (await this.program.account.orderState.fetch(
|
|
183
215
|
state.orderState
|
|
184
216
|
)) as OrderStateAccount;
|
|
185
217
|
|
|
186
|
-
|
|
187
|
-
key: 'orderHistory',
|
|
188
|
-
publicKey: orderState.orderHistory,
|
|
189
|
-
eventType: 'orderHistoryAccountUpdate',
|
|
190
|
-
});
|
|
218
|
+
accounts.orderHistory = orderState.orderHistory;
|
|
191
219
|
}
|
|
220
|
+
|
|
221
|
+
return accounts;
|
|
192
222
|
}
|
|
193
223
|
|
|
194
224
|
async addToAccountLoader(): Promise<void> {
|
|
@@ -324,3 +354,16 @@ export class PollingClearingHouseAccountSubscriber
|
|
|
324
354
|
return this.orderHistory;
|
|
325
355
|
}
|
|
326
356
|
}
|
|
357
|
+
|
|
358
|
+
type ClearingHouseAccounts = {
|
|
359
|
+
state: PublicKey;
|
|
360
|
+
markets: PublicKey;
|
|
361
|
+
orderState: PublicKey;
|
|
362
|
+
tradeHistory?: PublicKey;
|
|
363
|
+
depositHistory?: PublicKey;
|
|
364
|
+
fundingPaymentHistory?: PublicKey;
|
|
365
|
+
fundingRateHistory?: PublicKey;
|
|
366
|
+
extendedCurveHistory?: PublicKey;
|
|
367
|
+
liquidationHistory?: PublicKey;
|
|
368
|
+
orderHistory?: PublicKey;
|
|
369
|
+
};
|
package/src/clearingHouse.ts
CHANGED
|
@@ -543,19 +543,6 @@ export class ClearingHouse {
|
|
|
543
543
|
return [txSig, userAccountPublicKey];
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
-
public async deleteUser(): Promise<TransactionSignature> {
|
|
547
|
-
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
548
|
-
const user = await this.program.account.user.fetch(userAccountPublicKey);
|
|
549
|
-
const deleteUserTx = await this.program.transaction.deleteUser({
|
|
550
|
-
accounts: {
|
|
551
|
-
user: userAccountPublicKey,
|
|
552
|
-
userPositions: user.positions,
|
|
553
|
-
authority: this.wallet.publicKey,
|
|
554
|
-
},
|
|
555
|
-
});
|
|
556
|
-
return this.txSender.send(deleteUserTx, [], this.opts);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
546
|
public async withdrawCollateral(
|
|
560
547
|
amount: BN,
|
|
561
548
|
collateralAccountPublicKey: PublicKey
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
|
|
3
|
+
export const CLEARING_HOUSE_STATE_ACCOUNTS = {
|
|
4
|
+
dammHkt7jmytvbS3nHTxQNEcP59aE57nxwV21YdqEDN: {
|
|
5
|
+
state: new PublicKey('FExhvPycCCwYnZGeDsVtLhpEQ3yEkVY2k1HuPyfLj91L'),
|
|
6
|
+
markets: new PublicKey('773hq3SbGPKVj93TXi5qV5CREuhxobywfALjS3XVHhLH'),
|
|
7
|
+
orderState: new PublicKey('4cC34bWwTPGncBaX2S6v5mH3Lj4Nb3byPMrxQSDcY985'),
|
|
8
|
+
tradeHistory: new PublicKey('FCuCXEoQppoaCYdttA7rK3HNQfYkTNEGpwuBESzYcENp'),
|
|
9
|
+
depositHistory: new PublicKey(
|
|
10
|
+
'C7rF2Qy2rnDGQLRijBRRArJyaeuQcFi81BXDrUCQ45ya'
|
|
11
|
+
),
|
|
12
|
+
fundingPaymentHistory: new PublicKey(
|
|
13
|
+
'895iPhzwT2tBufLnRpYtBG3gif1HDDUfpH2AqbS5joo4'
|
|
14
|
+
),
|
|
15
|
+
fundingRateHistory: new PublicKey(
|
|
16
|
+
'BWiJLMbmrwfqHVpcPJa8715XamNyNYamDDKQVQMnduEC'
|
|
17
|
+
),
|
|
18
|
+
extendedCurveHistory: new PublicKey(
|
|
19
|
+
'7vBbqvMdtZLQdTVdzt5y63pZdAFE5W42kP3avngSJKCk'
|
|
20
|
+
),
|
|
21
|
+
liquidationHistory: new PublicKey(
|
|
22
|
+
'CSFaaf8yVoTx6NcXUKtNPYAewv76CH2jATqSVRBvUWKM'
|
|
23
|
+
),
|
|
24
|
+
orderHistory: new PublicKey('DZ7XfUqyHoRKnJLRApxmJ943xHJ7NDBUTqpbooviEtbU'),
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -10,6 +10,7 @@ import { DefaultTxSender } from '../tx/defaultTxSender';
|
|
|
10
10
|
import { ClearingHouseAccountSubscriber } from '../accounts/types';
|
|
11
11
|
import { PollingClearingHouseAccountSubscriber } from '../accounts/pollingClearingHouseAccountSubscriber';
|
|
12
12
|
import { Admin } from '../admin';
|
|
13
|
+
import { RetryTxSender } from '../tx/retryTxSender';
|
|
13
14
|
|
|
14
15
|
export type ClearingHouseConfigType = 'websocket' | 'polling' | 'custom';
|
|
15
16
|
|
|
@@ -19,7 +20,7 @@ type BaseClearingHouseConfig = {
|
|
|
19
20
|
wallet: IWallet;
|
|
20
21
|
programID: PublicKey;
|
|
21
22
|
opts?: ConfirmOptions;
|
|
22
|
-
|
|
23
|
+
txSenderConfig?: TxSenderConfig;
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
type WebSocketClearingHouseConfiguration = BaseClearingHouseConfig;
|
|
@@ -32,12 +33,28 @@ type ClearingHouseConfig =
|
|
|
32
33
|
| PollingClearingHouseConfiguration
|
|
33
34
|
| WebSocketClearingHouseConfiguration;
|
|
34
35
|
|
|
36
|
+
export type TxSenderType = 'default' | 'retry';
|
|
37
|
+
|
|
38
|
+
type BaseTxSenderConfig = {
|
|
39
|
+
type: TxSenderType;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type DefaultTxSenderConfig = BaseTxSenderConfig;
|
|
43
|
+
|
|
44
|
+
type RetryTxSenderConfig = BaseTxSenderConfig & {
|
|
45
|
+
timeout?: number;
|
|
46
|
+
retrySleep?: number;
|
|
47
|
+
additionalConnections?: Connection[];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type TxSenderConfig = DefaultTxSenderConfig | RetryTxSenderConfig;
|
|
51
|
+
|
|
35
52
|
export function getWebSocketClearingHouseConfig(
|
|
36
53
|
connection: Connection,
|
|
37
54
|
wallet: IWallet,
|
|
38
55
|
programID: PublicKey,
|
|
39
56
|
opts: ConfirmOptions = Provider.defaultOptions(),
|
|
40
|
-
|
|
57
|
+
txSenderConfig?: TxSenderConfig
|
|
41
58
|
): WebSocketClearingHouseConfiguration {
|
|
42
59
|
return {
|
|
43
60
|
type: 'websocket',
|
|
@@ -45,7 +62,7 @@ export function getWebSocketClearingHouseConfig(
|
|
|
45
62
|
wallet,
|
|
46
63
|
programID,
|
|
47
64
|
opts,
|
|
48
|
-
|
|
65
|
+
txSenderConfig,
|
|
49
66
|
};
|
|
50
67
|
}
|
|
51
68
|
|
|
@@ -55,7 +72,7 @@ export function getPollingClearingHouseConfig(
|
|
|
55
72
|
programID: PublicKey,
|
|
56
73
|
accountLoader: BulkAccountLoader,
|
|
57
74
|
opts: ConfirmOptions = Provider.defaultOptions(),
|
|
58
|
-
|
|
75
|
+
txSenderConfig?: TxSenderConfig
|
|
59
76
|
): PollingClearingHouseConfiguration {
|
|
60
77
|
return {
|
|
61
78
|
type: 'polling',
|
|
@@ -64,7 +81,7 @@ export function getPollingClearingHouseConfig(
|
|
|
64
81
|
programID,
|
|
65
82
|
accountLoader,
|
|
66
83
|
opts,
|
|
67
|
-
|
|
84
|
+
txSenderConfig,
|
|
68
85
|
};
|
|
69
86
|
}
|
|
70
87
|
|
|
@@ -85,7 +102,19 @@ export function getClearingHouse(config: ClearingHouseConfig): ClearingHouse {
|
|
|
85
102
|
);
|
|
86
103
|
}
|
|
87
104
|
|
|
88
|
-
|
|
105
|
+
let txSender: TxSender;
|
|
106
|
+
if (config.txSenderConfig?.type === 'retry') {
|
|
107
|
+
const txSenderConfig = config.txSenderConfig as RetryTxSenderConfig;
|
|
108
|
+
txSender = new RetryTxSender(
|
|
109
|
+
provider,
|
|
110
|
+
txSenderConfig.timeout,
|
|
111
|
+
txSenderConfig.retrySleep,
|
|
112
|
+
txSenderConfig.additionalConnections
|
|
113
|
+
);
|
|
114
|
+
} else {
|
|
115
|
+
txSender = new DefaultTxSender(provider);
|
|
116
|
+
}
|
|
117
|
+
|
|
89
118
|
return new ClearingHouse(
|
|
90
119
|
config.connection,
|
|
91
120
|
config.wallet,
|
|
@@ -113,7 +142,18 @@ export function getAdmin(config: ClearingHouseConfig): Admin {
|
|
|
113
142
|
);
|
|
114
143
|
}
|
|
115
144
|
|
|
116
|
-
|
|
145
|
+
let txSender: TxSender;
|
|
146
|
+
if (config.txSenderConfig?.type === 'retry') {
|
|
147
|
+
const txSenderConfig = config.txSenderConfig as RetryTxSenderConfig;
|
|
148
|
+
txSender = new RetryTxSender(
|
|
149
|
+
provider,
|
|
150
|
+
txSenderConfig.timeout,
|
|
151
|
+
txSenderConfig.retrySleep,
|
|
152
|
+
txSenderConfig.additionalConnections
|
|
153
|
+
);
|
|
154
|
+
} else {
|
|
155
|
+
txSender = new DefaultTxSender(provider);
|
|
156
|
+
}
|
|
117
157
|
return new Admin(
|
|
118
158
|
config.connection,
|
|
119
159
|
config.wallet,
|
|
@@ -1482,32 +1482,6 @@
|
|
|
1482
1482
|
}
|
|
1483
1483
|
]
|
|
1484
1484
|
},
|
|
1485
|
-
{
|
|
1486
|
-
"name": "deleteUser",
|
|
1487
|
-
"accounts": [
|
|
1488
|
-
{
|
|
1489
|
-
"name": "user",
|
|
1490
|
-
"isMut": true,
|
|
1491
|
-
"isSigner": false
|
|
1492
|
-
},
|
|
1493
|
-
{
|
|
1494
|
-
"name": "userPositions",
|
|
1495
|
-
"isMut": true,
|
|
1496
|
-
"isSigner": false
|
|
1497
|
-
},
|
|
1498
|
-
{
|
|
1499
|
-
"name": "userOrders",
|
|
1500
|
-
"isMut": true,
|
|
1501
|
-
"isSigner": false
|
|
1502
|
-
},
|
|
1503
|
-
{
|
|
1504
|
-
"name": "authority",
|
|
1505
|
-
"isMut": false,
|
|
1506
|
-
"isSigner": true
|
|
1507
|
-
}
|
|
1508
|
-
],
|
|
1509
|
-
"args": []
|
|
1510
|
-
},
|
|
1511
1485
|
{
|
|
1512
1486
|
"name": "settleFundingPayment",
|
|
1513
1487
|
"accounts": [
|
|
@@ -3292,8 +3266,8 @@
|
|
|
3292
3266
|
"type": "u128"
|
|
3293
3267
|
},
|
|
3294
3268
|
{
|
|
3295
|
-
"name": "
|
|
3296
|
-
"type": "
|
|
3269
|
+
"name": "padding1",
|
|
3270
|
+
"type": "u64"
|
|
3297
3271
|
},
|
|
3298
3272
|
{
|
|
3299
3273
|
"name": "padding2",
|
|
@@ -4300,11 +4274,6 @@
|
|
|
4300
4274
|
"code": 6060,
|
|
4301
4275
|
"name": "CantExpireOrders",
|
|
4302
4276
|
"msg": "CantExpireOrders"
|
|
4303
|
-
},
|
|
4304
|
-
{
|
|
4305
|
-
"code": 6061,
|
|
4306
|
-
"name": "InvalidRepegPriceImpact",
|
|
4307
|
-
"msg": "AMM repeg mark price impact vs oracle too large"
|
|
4308
4277
|
}
|
|
4309
4278
|
]
|
|
4310
4279
|
}
|
package/src/index.ts
CHANGED
package/src/math/amm.ts
CHANGED
|
@@ -4,7 +4,11 @@ import {
|
|
|
4
4
|
MARK_PRICE_PRECISION,
|
|
5
5
|
PEG_PRECISION,
|
|
6
6
|
ZERO,
|
|
7
|
+
AMM_TO_QUOTE_PRECISION_RATIO,
|
|
8
|
+
QUOTE_PRECISION,
|
|
9
|
+
AMM_RESERVE_PRECISION,
|
|
7
10
|
} from '../constants/numericConstants';
|
|
11
|
+
import { calculateBaseAssetValue } from './position';
|
|
8
12
|
import {
|
|
9
13
|
AMM,
|
|
10
14
|
PositionDirection,
|
|
@@ -13,7 +17,12 @@ import {
|
|
|
13
17
|
isVariant,
|
|
14
18
|
} from '../types';
|
|
15
19
|
import { assert } from '../assert/assert';
|
|
16
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
calculatePositionPNL,
|
|
22
|
+
calculateMarkPrice,
|
|
23
|
+
convertToNumber,
|
|
24
|
+
squareRootBN,
|
|
25
|
+
} from '..';
|
|
17
26
|
|
|
18
27
|
/**
|
|
19
28
|
* Calculates a price given an arbitrary base and quote amount (they must have the same precision)
|
|
@@ -130,6 +139,125 @@ export function getSwapDirection(
|
|
|
130
139
|
return SwapDirection.ADD;
|
|
131
140
|
}
|
|
132
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Helper function calculating adjust k cost
|
|
144
|
+
* @param market
|
|
145
|
+
* @param marketIndex
|
|
146
|
+
* @param numerator
|
|
147
|
+
* @param denomenator
|
|
148
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
149
|
+
*/
|
|
150
|
+
export function calculateAdjustKCost(
|
|
151
|
+
market: Market,
|
|
152
|
+
marketIndex: BN,
|
|
153
|
+
numerator: BN,
|
|
154
|
+
denomenator: BN
|
|
155
|
+
): BN {
|
|
156
|
+
const netUserPosition = {
|
|
157
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
158
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
159
|
+
marketIndex: new BN(marketIndex),
|
|
160
|
+
quoteAssetAmount: new BN(0),
|
|
161
|
+
openOrders: new BN(0),
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
165
|
+
|
|
166
|
+
const marketNewK = Object.assign({}, market);
|
|
167
|
+
marketNewK.amm = Object.assign({}, market.amm);
|
|
168
|
+
|
|
169
|
+
marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
|
|
170
|
+
.mul(numerator)
|
|
171
|
+
.div(denomenator);
|
|
172
|
+
marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
|
|
173
|
+
.mul(numerator)
|
|
174
|
+
.div(denomenator);
|
|
175
|
+
marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
|
|
176
|
+
|
|
177
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
178
|
+
|
|
179
|
+
const cost = calculatePositionPNL(marketNewK, netUserPosition);
|
|
180
|
+
|
|
181
|
+
const p = PEG_PRECISION.mul(numerator).div(denomenator);
|
|
182
|
+
const x = market.amm.baseAssetReserve;
|
|
183
|
+
const y = market.amm.quoteAssetReserve;
|
|
184
|
+
const delta = market.baseAssetAmount;
|
|
185
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
186
|
+
|
|
187
|
+
const numer1 = PEG_PRECISION.sub(p).mul(y).div(PEG_PRECISION);
|
|
188
|
+
const numer20 = k
|
|
189
|
+
.mul(p)
|
|
190
|
+
.mul(p)
|
|
191
|
+
.div(PEG_PRECISION)
|
|
192
|
+
.div(PEG_PRECISION)
|
|
193
|
+
.div(x.mul(p).div(PEG_PRECISION).add(delta));
|
|
194
|
+
const numer21 = k.div(x.add(delta));
|
|
195
|
+
|
|
196
|
+
const formulaCost = numer21
|
|
197
|
+
.sub(numer20)
|
|
198
|
+
.sub(numer1)
|
|
199
|
+
.mul(market.amm.pegMultiplier)
|
|
200
|
+
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
201
|
+
console.log(convertToNumber(formulaCost, QUOTE_PRECISION));
|
|
202
|
+
|
|
203
|
+
// p.div(p.mul(x).add(delta)).sub()
|
|
204
|
+
|
|
205
|
+
return cost;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Helper function calculating adjust pegMultiplier (repeg) cost
|
|
210
|
+
*
|
|
211
|
+
* @param market
|
|
212
|
+
* @param marketIndex
|
|
213
|
+
* @param newPeg
|
|
214
|
+
* @returns cost : Precision QUOTE_ASSET_PRECISION
|
|
215
|
+
*/
|
|
216
|
+
export function calculateRepegCost(
|
|
217
|
+
market: Market,
|
|
218
|
+
marketIndex: BN,
|
|
219
|
+
newPeg: BN
|
|
220
|
+
): BN {
|
|
221
|
+
const netUserPosition = {
|
|
222
|
+
baseAssetAmount: market.baseAssetAmount,
|
|
223
|
+
lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
|
|
224
|
+
marketIndex: new BN(marketIndex),
|
|
225
|
+
quoteAssetAmount: new BN(0),
|
|
226
|
+
openOrders: new BN(0),
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const currentValue = calculateBaseAssetValue(market, netUserPosition);
|
|
230
|
+
netUserPosition.quoteAssetAmount = currentValue;
|
|
231
|
+
const prevMarketPrice = calculateMarkPrice(market);
|
|
232
|
+
const marketNewPeg = Object.assign({}, market);
|
|
233
|
+
marketNewPeg.amm = Object.assign({}, market.amm);
|
|
234
|
+
|
|
235
|
+
// const marketNewPeg = JSON.parse(JSON.stringify(market));
|
|
236
|
+
marketNewPeg.amm.pegMultiplier = newPeg;
|
|
237
|
+
|
|
238
|
+
console.log(
|
|
239
|
+
'Price moves from',
|
|
240
|
+
convertToNumber(prevMarketPrice),
|
|
241
|
+
'to',
|
|
242
|
+
convertToNumber(calculateMarkPrice(marketNewPeg))
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
const cost = calculatePositionPNL(marketNewPeg, netUserPosition);
|
|
246
|
+
|
|
247
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
248
|
+
const newQuoteAssetReserve = k.div(
|
|
249
|
+
market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount)
|
|
250
|
+
);
|
|
251
|
+
const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(
|
|
252
|
+
market.amm.quoteAssetReserve
|
|
253
|
+
);
|
|
254
|
+
const cost2 = deltaQuoteAssetReserves
|
|
255
|
+
.mul(market.amm.pegMultiplier.sub(newPeg))
|
|
256
|
+
.div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
|
|
257
|
+
console.log(convertToNumber(cost2, QUOTE_PRECISION));
|
|
258
|
+
return cost;
|
|
259
|
+
}
|
|
260
|
+
|
|
133
261
|
/**
|
|
134
262
|
* Helper function calculating terminal price of amm
|
|
135
263
|
*
|
|
@@ -187,3 +315,86 @@ export function calculateMaxBaseAssetAmountToTrade(
|
|
|
187
315
|
return [new BN(0), PositionDirection.LONG];
|
|
188
316
|
}
|
|
189
317
|
}
|
|
318
|
+
|
|
319
|
+
export function calculateBudgetedK(market: Market, cost: BN): [BN, BN] {
|
|
320
|
+
// wolframalpha.com
|
|
321
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
322
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
323
|
+
|
|
324
|
+
// todo: assumes k = x * y
|
|
325
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
326
|
+
|
|
327
|
+
// const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
328
|
+
const x = market.amm.baseAssetReserve;
|
|
329
|
+
const y = market.amm.quoteAssetReserve;
|
|
330
|
+
|
|
331
|
+
const d = market.baseAssetAmount;
|
|
332
|
+
const Q = market.amm.pegMultiplier;
|
|
333
|
+
|
|
334
|
+
const C = cost.mul(new BN(-1));
|
|
335
|
+
|
|
336
|
+
const numer1 = y.mul(d).mul(Q).div(AMM_RESERVE_PRECISION).div(PEG_PRECISION);
|
|
337
|
+
const numer2 = C.mul(x.add(d)).div(QUOTE_PRECISION);
|
|
338
|
+
const denom1 = C.mul(x)
|
|
339
|
+
.mul(x.add(d))
|
|
340
|
+
.div(AMM_RESERVE_PRECISION)
|
|
341
|
+
.div(QUOTE_PRECISION);
|
|
342
|
+
const denom2 = y
|
|
343
|
+
.mul(d)
|
|
344
|
+
.mul(d)
|
|
345
|
+
.mul(Q)
|
|
346
|
+
.div(AMM_RESERVE_PRECISION)
|
|
347
|
+
.div(AMM_RESERVE_PRECISION)
|
|
348
|
+
.div(PEG_PRECISION);
|
|
349
|
+
|
|
350
|
+
const numerator = d
|
|
351
|
+
.mul(numer1.add(numer2))
|
|
352
|
+
.div(AMM_RESERVE_PRECISION)
|
|
353
|
+
.div(AMM_RESERVE_PRECISION)
|
|
354
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
355
|
+
const denominator = denom1
|
|
356
|
+
.add(denom2)
|
|
357
|
+
.div(AMM_RESERVE_PRECISION)
|
|
358
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO);
|
|
359
|
+
console.log(numerator, denominator);
|
|
360
|
+
// const p = (numerator).div(denominator);
|
|
361
|
+
|
|
362
|
+
// const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
|
|
363
|
+
// console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
|
|
364
|
+
|
|
365
|
+
return [numerator, denominator];
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export function calculateBudgetedPeg(market: Market, cost: BN): BN {
|
|
369
|
+
// wolframalpha.com
|
|
370
|
+
// (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
|
|
371
|
+
// p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
|
|
372
|
+
|
|
373
|
+
// todo: assumes k = x * y
|
|
374
|
+
// otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
|
|
375
|
+
|
|
376
|
+
const k = market.amm.sqrtK.mul(market.amm.sqrtK);
|
|
377
|
+
const x = market.amm.baseAssetReserve;
|
|
378
|
+
const y = market.amm.quoteAssetReserve;
|
|
379
|
+
|
|
380
|
+
const d = market.baseAssetAmount;
|
|
381
|
+
const Q = market.amm.pegMultiplier;
|
|
382
|
+
|
|
383
|
+
const C = cost.mul(new BN(-1));
|
|
384
|
+
|
|
385
|
+
const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
|
|
386
|
+
const deltaPegMultiplier = C.mul(MARK_PRICE_PRECISION)
|
|
387
|
+
.div(deltaQuoteAssetReserves.div(AMM_TO_QUOTE_PRECISION_RATIO))
|
|
388
|
+
.mul(PEG_PRECISION)
|
|
389
|
+
.div(QUOTE_PRECISION);
|
|
390
|
+
console.log(
|
|
391
|
+
Q.toNumber(),
|
|
392
|
+
'change by',
|
|
393
|
+
deltaPegMultiplier.toNumber() / MARK_PRICE_PRECISION.toNumber()
|
|
394
|
+
);
|
|
395
|
+
const newPeg = Q.sub(
|
|
396
|
+
deltaPegMultiplier.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION)
|
|
397
|
+
);
|
|
398
|
+
|
|
399
|
+
return newPeg;
|
|
400
|
+
}
|
package/src/tx/retryTxSender.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
SignatureResult,
|
|
9
9
|
Transaction,
|
|
10
10
|
TransactionSignature,
|
|
11
|
+
Connection,
|
|
11
12
|
} from '@solana/web3.js';
|
|
12
13
|
import { Provider } from '@project-serum/anchor';
|
|
13
14
|
import assert from 'assert';
|
|
@@ -24,15 +25,18 @@ export class RetryTxSender implements TxSender {
|
|
|
24
25
|
provider: Provider;
|
|
25
26
|
timeout: number;
|
|
26
27
|
retrySleep: number;
|
|
28
|
+
additionalConnections: Connection[];
|
|
27
29
|
|
|
28
30
|
public constructor(
|
|
29
31
|
provider: Provider,
|
|
30
32
|
timeout?: number,
|
|
31
|
-
retrySleep?: number
|
|
33
|
+
retrySleep?: number,
|
|
34
|
+
additionalConnections = new Array<Connection>()
|
|
32
35
|
) {
|
|
33
36
|
this.provider = provider;
|
|
34
37
|
this.timeout = timeout ?? DEFAULT_TIMEOUT;
|
|
35
38
|
this.retrySleep = retrySleep ?? DEFAULT_RETRY;
|
|
39
|
+
this.additionalConnections = additionalConnections;
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
async send(
|
|
@@ -54,6 +58,7 @@ export class RetryTxSender implements TxSender {
|
|
|
54
58
|
|
|
55
59
|
const txid: TransactionSignature =
|
|
56
60
|
await this.provider.connection.sendRawTransaction(rawTransaction, opts);
|
|
61
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
57
62
|
|
|
58
63
|
let done = false;
|
|
59
64
|
const resolveReference: ResolveReference = {
|
|
@@ -76,6 +81,7 @@ export class RetryTxSender implements TxSender {
|
|
|
76
81
|
console.error(e);
|
|
77
82
|
stopWaiting();
|
|
78
83
|
});
|
|
84
|
+
this.sendToAdditionalConnections(rawTransaction, opts);
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
})();
|
|
@@ -193,4 +199,16 @@ export class RetryTxSender implements TxSender {
|
|
|
193
199
|
return result;
|
|
194
200
|
});
|
|
195
201
|
}
|
|
202
|
+
|
|
203
|
+
sendToAdditionalConnections(rawTx: Buffer, opts: ConfirmOptions): void {
|
|
204
|
+
this.additionalConnections.map((connection) => {
|
|
205
|
+
connection.sendRawTransaction(rawTx, opts).catch((e) => {
|
|
206
|
+
console.error(
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
`error sending tx to additional connection ${connection._rpcEndpoint}`
|
|
209
|
+
);
|
|
210
|
+
console.error(e);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
}
|
|
196
214
|
}
|