@drift-labs/sdk 0.1.20 → 0.1.21-master.5
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 +0 -1
- package/lib/accounts/bulkAccountLoader.js +17 -6
- package/lib/accounts/bulkUserSubscription.d.ts +0 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +5 -2
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +23 -1
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts +0 -1
- package/lib/accounts/pollingUserAccountSubscriber.d.ts +3 -2
- package/lib/accounts/pollingUserAccountSubscriber.js +13 -0
- package/lib/accounts/types.d.ts +8 -3
- package/lib/accounts/utils.d.ts +0 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts +0 -1
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +5 -2
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +25 -0
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts +3 -2
- package/lib/accounts/webSocketUserAccountSubscriber.js +11 -0
- package/lib/addresses.d.ts +4 -1
- package/lib/addresses.js +28 -1
- package/lib/admin.d.ts +10 -4
- package/lib/admin.js +48 -3
- package/lib/assert/assert.d.ts +0 -1
- package/lib/clearingHouse.d.ts +27 -2
- package/lib/clearingHouse.js +307 -7
- package/lib/clearingHouseUser.d.ts +16 -3
- package/lib/clearingHouseUser.js +79 -9
- package/lib/config.d.ts +0 -1
- package/lib/constants/markets.d.ts +0 -1
- package/lib/constants/markets.js +8 -0
- package/lib/constants/numericConstants.d.ts +1 -1
- package/lib/constants/numericConstants.js +2 -1
- package/lib/examples/makeTradeExample.d.ts +0 -1
- package/lib/factory/clearingHouse.d.ts +0 -1
- package/lib/factory/clearingHouseUser.d.ts +0 -1
- package/lib/idl/clearing_house.json +1077 -50
- package/lib/index.d.ts +3 -1
- package/lib/index.js +3 -0
- package/lib/math/amm.d.ts +3 -1
- package/lib/math/amm.js +121 -8
- package/lib/math/conversion.d.ts +0 -1
- package/lib/math/funding.d.ts +0 -1
- package/lib/math/insuranceFund.d.ts +0 -1
- package/lib/math/market.d.ts +2 -2
- package/lib/math/market.js +11 -1
- package/lib/math/orders.d.ts +3 -0
- package/lib/math/orders.js +32 -0
- package/lib/math/position.d.ts +4 -2
- package/lib/math/position.js +18 -4
- package/lib/math/trade.d.ts +0 -1
- package/lib/math/utils.d.ts +0 -1
- package/lib/mockUSDCFaucet.d.ts +0 -1
- package/lib/orderParams.d.ts +7 -0
- package/lib/orderParams.js +108 -0
- package/lib/orders.d.ts +6 -0
- package/lib/orders.js +136 -0
- package/lib/pythClient.d.ts +0 -1
- package/lib/token/index.d.ts +0 -1
- package/lib/tx/defaultTxSender.d.ts +0 -1
- package/lib/tx/types.d.ts +0 -1
- package/lib/tx/utils.d.ts +0 -1
- package/lib/types.d.ts +145 -2
- package/lib/types.js +36 -1
- package/lib/util/computeUnits.d.ts +0 -1
- package/lib/util/tps.d.ts +0 -1
- package/lib/wallet.d.ts +0 -1
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +21 -13
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +33 -0
- package/src/accounts/pollingUserAccountSubscriber.ts +30 -2
- package/src/accounts/types.ts +11 -2
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +47 -0
- package/src/accounts/webSocketUserAccountSubscriber.ts +29 -2
- package/src/addresses.ts +37 -0
- package/src/admin.ts +84 -6
- package/src/clearingHouse.ts +430 -5
- package/src/clearingHouseUser.ts +129 -12
- package/src/constants/markets.ts +8 -0
- package/src/constants/numericConstants.ts +1 -0
- package/src/idl/clearing_house.json +1077 -50
- package/src/index.ts +3 -0
- package/src/math/amm.ts +169 -14
- package/src/math/market.ts +28 -2
- package/src/math/orders.ts +44 -0
- package/src/math/position.ts +23 -3
- package/src/orderParams.ts +151 -0
- package/src/orders.ts +236 -0
- package/src/types.ts +129 -1
- package/tsconfig.json +0 -1
- package/lib/accounts/bulkAccountLoader.d.ts.map +0 -1
- package/lib/accounts/bulkUserSubscription.d.ts.map +0 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/pollingTokenAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/pollingUserAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/types.d.ts.map +0 -1
- package/lib/accounts/utils.d.ts.map +0 -1
- package/lib/accounts/webSocketAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts.map +0 -1
- package/lib/accounts/webSocketUserAccountSubscriber.d.ts.map +0 -1
- package/lib/addresses.d.ts.map +0 -1
- package/lib/admin.d.ts.map +0 -1
- package/lib/assert/assert.d.ts.map +0 -1
- package/lib/clearingHouse.d.ts.map +0 -1
- package/lib/clearingHouseUser.d.ts.map +0 -1
- package/lib/config.d.ts.map +0 -1
- package/lib/constants/markets.d.ts.map +0 -1
- package/lib/constants/numericConstants.d.ts.map +0 -1
- package/lib/examples/makeTradeExample.d.ts.map +0 -1
- package/lib/factory/clearingHouse.d.ts.map +0 -1
- package/lib/factory/clearingHouseUser.d.ts.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/math/amm.d.ts.map +0 -1
- package/lib/math/conversion.d.ts.map +0 -1
- package/lib/math/funding.d.ts.map +0 -1
- package/lib/math/insuranceFund.d.ts.map +0 -1
- package/lib/math/market.d.ts.map +0 -1
- package/lib/math/position.d.ts.map +0 -1
- package/lib/math/trade.d.ts.map +0 -1
- package/lib/math/utils.d.ts.map +0 -1
- package/lib/mockUSDCFaucet.d.ts.map +0 -1
- package/lib/pythClient.d.ts.map +0 -1
- package/lib/token/index.d.ts.map +0 -1
- package/lib/tx/defaultTxSender.d.ts.map +0 -1
- package/lib/tx/types.d.ts.map +0 -1
- package/lib/tx/utils.d.ts.map +0 -1
- package/lib/types.d.ts.map +0 -1
- package/lib/util/computeUnits.d.ts.map +0 -1
- package/lib/util/tps.d.ts.map +0 -1
- package/lib/wallet.d.ts.map +0 -1
package/src/addresses.ts
CHANGED
|
@@ -10,6 +10,21 @@ export async function getClearingHouseStateAccountPublicKeyAndNonce(
|
|
|
10
10
|
);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
export async function getOrderStateAccountPublicKey(
|
|
14
|
+
programId: PublicKey
|
|
15
|
+
): Promise<PublicKey> {
|
|
16
|
+
return (await getOrderStateAccountPublicKeyAndNonce(programId))[0];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function getOrderStateAccountPublicKeyAndNonce(
|
|
20
|
+
programId: PublicKey
|
|
21
|
+
): Promise<[PublicKey, number]> {
|
|
22
|
+
return anchor.web3.PublicKey.findProgramAddress(
|
|
23
|
+
[Buffer.from(anchor.utils.bytes.utf8.encode('order_state'))],
|
|
24
|
+
programId
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
13
28
|
export async function getClearingHouseStateAccountPublicKey(
|
|
14
29
|
programId: PublicKey
|
|
15
30
|
): Promise<PublicKey> {
|
|
@@ -32,3 +47,25 @@ export async function getUserAccountPublicKey(
|
|
|
32
47
|
): Promise<PublicKey> {
|
|
33
48
|
return (await getUserAccountPublicKeyAndNonce(programId, authority))[0];
|
|
34
49
|
}
|
|
50
|
+
|
|
51
|
+
export async function getUserOrdersAccountPublicKeyAndNonce(
|
|
52
|
+
programId: PublicKey,
|
|
53
|
+
userAccount: PublicKey
|
|
54
|
+
): Promise<[PublicKey, number]> {
|
|
55
|
+
return anchor.web3.PublicKey.findProgramAddress(
|
|
56
|
+
[
|
|
57
|
+
Buffer.from(anchor.utils.bytes.utf8.encode('user_orders')),
|
|
58
|
+
userAccount.toBuffer(),
|
|
59
|
+
],
|
|
60
|
+
programId
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function getUserOrdersAccountPublicKey(
|
|
65
|
+
programId: PublicKey,
|
|
66
|
+
userAccount: PublicKey
|
|
67
|
+
): Promise<PublicKey> {
|
|
68
|
+
return (
|
|
69
|
+
await getUserOrdersAccountPublicKeyAndNonce(programId, userAccount)
|
|
70
|
+
)[0];
|
|
71
|
+
}
|
package/src/admin.ts
CHANGED
|
@@ -5,10 +5,20 @@ import {
|
|
|
5
5
|
SYSVAR_RENT_PUBKEY,
|
|
6
6
|
TransactionSignature,
|
|
7
7
|
} from '@solana/web3.js';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
FeeStructure,
|
|
10
|
+
IWallet,
|
|
11
|
+
OracleGuardRails,
|
|
12
|
+
OracleSource,
|
|
13
|
+
OrderFillerRewardStructure,
|
|
14
|
+
} from './types';
|
|
9
15
|
import { BN, Provider } from '@project-serum/anchor';
|
|
10
16
|
import * as anchor from '@project-serum/anchor';
|
|
11
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
getClearingHouseStateAccountPublicKey,
|
|
19
|
+
getClearingHouseStateAccountPublicKeyAndNonce,
|
|
20
|
+
getOrderStateAccountPublicKeyAndNonce,
|
|
21
|
+
} from './addresses';
|
|
12
22
|
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
|
13
23
|
import { ClearingHouse } from './clearingHouse';
|
|
14
24
|
import { PEG_PRECISION } from './constants/numericConstants';
|
|
@@ -38,7 +48,9 @@ export class Admin extends ClearingHouse {
|
|
|
38
48
|
public async initialize(
|
|
39
49
|
usdcMint: PublicKey,
|
|
40
50
|
adminControlsPrices: boolean
|
|
41
|
-
): Promise<
|
|
51
|
+
): Promise<
|
|
52
|
+
[TransactionSignature, TransactionSignature, TransactionSignature]
|
|
53
|
+
> {
|
|
42
54
|
const stateAccountRPCResponse = await this.connection.getParsedAccountInfo(
|
|
43
55
|
await this.getStatePublicKey()
|
|
44
56
|
);
|
|
@@ -162,7 +174,40 @@ export class Admin extends ClearingHouse {
|
|
|
162
174
|
this.opts
|
|
163
175
|
);
|
|
164
176
|
|
|
165
|
-
|
|
177
|
+
const initializeOrderStateTxSig = await this.initializeOrderState();
|
|
178
|
+
|
|
179
|
+
return [initializeTxSig, initializeHistoryTxSig, initializeOrderStateTxSig];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public async initializeOrderState(): Promise<TransactionSignature> {
|
|
183
|
+
const orderHistory = anchor.web3.Keypair.generate();
|
|
184
|
+
const [orderStatePublicKey, orderStateNonce] =
|
|
185
|
+
await getOrderStateAccountPublicKeyAndNonce(this.program.programId);
|
|
186
|
+
const clearingHouseStatePublicKey =
|
|
187
|
+
await getClearingHouseStateAccountPublicKey(this.program.programId);
|
|
188
|
+
|
|
189
|
+
const initializeOrderStateTx =
|
|
190
|
+
await this.program.transaction.initializeOrderState(orderStateNonce, {
|
|
191
|
+
accounts: {
|
|
192
|
+
admin: this.wallet.publicKey,
|
|
193
|
+
state: clearingHouseStatePublicKey,
|
|
194
|
+
orderHistory: orderHistory.publicKey,
|
|
195
|
+
orderState: orderStatePublicKey,
|
|
196
|
+
rent: SYSVAR_RENT_PUBKEY,
|
|
197
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
198
|
+
},
|
|
199
|
+
instructions: [
|
|
200
|
+
await this.program.account.orderHistory.createInstruction(
|
|
201
|
+
orderHistory
|
|
202
|
+
),
|
|
203
|
+
],
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
return await this.txSender.send(
|
|
207
|
+
initializeOrderStateTx,
|
|
208
|
+
[orderHistory],
|
|
209
|
+
this.opts
|
|
210
|
+
);
|
|
166
211
|
}
|
|
167
212
|
|
|
168
213
|
public async initializeMarket(
|
|
@@ -508,6 +553,21 @@ export class Admin extends ClearingHouse {
|
|
|
508
553
|
);
|
|
509
554
|
}
|
|
510
555
|
|
|
556
|
+
public async updateOrderFillerRewardStructure(
|
|
557
|
+
orderFillerRewardStructure: OrderFillerRewardStructure
|
|
558
|
+
): Promise<TransactionSignature> {
|
|
559
|
+
return await this.program.rpc.updateOrderFillerRewardStructure(
|
|
560
|
+
orderFillerRewardStructure,
|
|
561
|
+
{
|
|
562
|
+
accounts: {
|
|
563
|
+
admin: this.wallet.publicKey,
|
|
564
|
+
state: await this.getStatePublicKey(),
|
|
565
|
+
orderState: await this.getOrderStatePublicKey(),
|
|
566
|
+
},
|
|
567
|
+
}
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
|
|
511
571
|
public async updateFee(fees: FeeStructure): Promise<TransactionSignature> {
|
|
512
572
|
return await this.program.rpc.updateFee(fees, {
|
|
513
573
|
accounts: {
|
|
@@ -548,12 +608,30 @@ export class Admin extends ClearingHouse {
|
|
|
548
608
|
);
|
|
549
609
|
}
|
|
550
610
|
|
|
551
|
-
public async
|
|
611
|
+
public async updateMarketMinimumQuoteAssetTradeSize(
|
|
612
|
+
marketIndex: BN,
|
|
613
|
+
minimumTradeSize: BN
|
|
614
|
+
): Promise<TransactionSignature> {
|
|
615
|
+
const state = this.getStateAccount();
|
|
616
|
+
return await this.program.rpc.updateMarketMinimumQuoteAssetTradeSize(
|
|
617
|
+
marketIndex,
|
|
618
|
+
minimumTradeSize,
|
|
619
|
+
{
|
|
620
|
+
accounts: {
|
|
621
|
+
admin: this.wallet.publicKey,
|
|
622
|
+
state: await this.getStatePublicKey(),
|
|
623
|
+
markets: state.markets,
|
|
624
|
+
},
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
public async updateMarketMinimumBaseAssetTradeSize(
|
|
552
630
|
marketIndex: BN,
|
|
553
631
|
minimumTradeSize: BN
|
|
554
632
|
): Promise<TransactionSignature> {
|
|
555
633
|
const state = this.getStateAccount();
|
|
556
|
-
return await this.program.rpc.
|
|
634
|
+
return await this.program.rpc.updateMarketMinimumBaseAssetTradeSize(
|
|
557
635
|
marketIndex,
|
|
558
636
|
minimumTradeSize,
|
|
559
637
|
{
|
package/src/clearingHouse.ts
CHANGED
|
@@ -16,6 +16,10 @@ import {
|
|
|
16
16
|
TradeHistoryAccount,
|
|
17
17
|
UserAccount,
|
|
18
18
|
Market,
|
|
19
|
+
OrderHistoryAccount,
|
|
20
|
+
OrderStateAccount,
|
|
21
|
+
OrderParams,
|
|
22
|
+
Order,
|
|
19
23
|
ExtendedCurveHistoryAccount,
|
|
20
24
|
} from './types';
|
|
21
25
|
import * as anchor from '@project-serum/anchor';
|
|
@@ -36,8 +40,11 @@ import { EventEmitter } from 'events';
|
|
|
36
40
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
37
41
|
import {
|
|
38
42
|
getClearingHouseStateAccountPublicKey,
|
|
43
|
+
getOrderStateAccountPublicKey,
|
|
39
44
|
getUserAccountPublicKey,
|
|
40
45
|
getUserAccountPublicKeyAndNonce,
|
|
46
|
+
getUserOrdersAccountPublicKey,
|
|
47
|
+
getUserOrdersAccountPublicKeyAndNonce,
|
|
41
48
|
} from './addresses';
|
|
42
49
|
import {
|
|
43
50
|
ClearingHouseAccountSubscriber,
|
|
@@ -144,6 +151,7 @@ export class ClearingHouse {
|
|
|
144
151
|
'fundingRateHistoryAccount',
|
|
145
152
|
'liquidationHistoryAccount',
|
|
146
153
|
'tradeHistoryAccount',
|
|
154
|
+
'orderHistoryAccount',
|
|
147
155
|
]);
|
|
148
156
|
}
|
|
149
157
|
|
|
@@ -212,6 +220,25 @@ export class ClearingHouse {
|
|
|
212
220
|
return this.accountSubscriber.getCurveHistoryAccount();
|
|
213
221
|
}
|
|
214
222
|
|
|
223
|
+
public getOrderHistoryAccount(): OrderHistoryAccount {
|
|
224
|
+
return this.accountSubscriber.getOrderHistoryAccount();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
orderStatePublicKey?: PublicKey;
|
|
228
|
+
public async getOrderStatePublicKey(): Promise<PublicKey> {
|
|
229
|
+
if (this.orderStatePublicKey) {
|
|
230
|
+
return this.orderStatePublicKey;
|
|
231
|
+
}
|
|
232
|
+
this.orderStatePublicKey = await getOrderStateAccountPublicKey(
|
|
233
|
+
this.program.programId
|
|
234
|
+
);
|
|
235
|
+
return this.orderStatePublicKey;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
public getOrderStateAccount(): OrderStateAccount {
|
|
239
|
+
return this.accountSubscriber.getOrderStateAccount();
|
|
240
|
+
}
|
|
241
|
+
|
|
215
242
|
/**
|
|
216
243
|
* Update the wallet to use for clearing house transactions and linked user account
|
|
217
244
|
* @param newWallet
|
|
@@ -240,9 +267,12 @@ export class ClearingHouse {
|
|
|
240
267
|
userPositionsAccount,
|
|
241
268
|
userAccountPublicKey,
|
|
242
269
|
initializeUserAccountIx,
|
|
270
|
+
initializeUserOrdersAccountIx,
|
|
243
271
|
] = await this.getInitializeUserInstructions();
|
|
244
272
|
|
|
245
|
-
const tx = new Transaction()
|
|
273
|
+
const tx = new Transaction()
|
|
274
|
+
.add(initializeUserAccountIx)
|
|
275
|
+
.add(initializeUserOrdersAccountIx);
|
|
246
276
|
const txSig = await this.txSender.send(
|
|
247
277
|
tx,
|
|
248
278
|
[userPositionsAccount],
|
|
@@ -252,9 +282,9 @@ export class ClearingHouse {
|
|
|
252
282
|
}
|
|
253
283
|
|
|
254
284
|
async getInitializeUserInstructions(): Promise<
|
|
255
|
-
[Keypair, PublicKey, TransactionInstruction]
|
|
285
|
+
[Keypair, PublicKey, TransactionInstruction, TransactionInstruction]
|
|
256
286
|
> {
|
|
257
|
-
const [
|
|
287
|
+
const [userAccountPublicKey, userAccountNonce] =
|
|
258
288
|
await getUserAccountPublicKeyAndNonce(
|
|
259
289
|
this.program.programId,
|
|
260
290
|
this.wallet.publicKey
|
|
@@ -288,7 +318,7 @@ export class ClearingHouse {
|
|
|
288
318
|
optionalAccounts,
|
|
289
319
|
{
|
|
290
320
|
accounts: {
|
|
291
|
-
user:
|
|
321
|
+
user: userAccountPublicKey,
|
|
292
322
|
authority: this.wallet.publicKey,
|
|
293
323
|
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
294
324
|
systemProgram: anchor.web3.SystemProgram.programId,
|
|
@@ -298,7 +328,44 @@ export class ClearingHouse {
|
|
|
298
328
|
remainingAccounts: remainingAccounts,
|
|
299
329
|
}
|
|
300
330
|
);
|
|
301
|
-
|
|
331
|
+
|
|
332
|
+
const initializeUserOrdersAccountIx =
|
|
333
|
+
await this.getInitializeUserOrdersInstruction(userAccountPublicKey);
|
|
334
|
+
|
|
335
|
+
return [
|
|
336
|
+
userPositions,
|
|
337
|
+
userAccountPublicKey,
|
|
338
|
+
initializeUserAccountIx,
|
|
339
|
+
initializeUserOrdersAccountIx,
|
|
340
|
+
];
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async getInitializeUserOrdersInstruction(
|
|
344
|
+
userAccountPublicKey?: PublicKey
|
|
345
|
+
): Promise<TransactionInstruction> {
|
|
346
|
+
if (!userAccountPublicKey) {
|
|
347
|
+
userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const [userOrdersAccountPublicKey, userOrdersAccountNonce] =
|
|
351
|
+
await getUserOrdersAccountPublicKeyAndNonce(
|
|
352
|
+
this.program.programId,
|
|
353
|
+
userAccountPublicKey
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
return await this.program.instruction.initializeUserOrders(
|
|
357
|
+
userOrdersAccountNonce,
|
|
358
|
+
{
|
|
359
|
+
accounts: {
|
|
360
|
+
user: userAccountPublicKey,
|
|
361
|
+
authority: this.wallet.publicKey,
|
|
362
|
+
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
363
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
364
|
+
userOrders: userOrdersAccountPublicKey,
|
|
365
|
+
state: await this.getStatePublicKey(),
|
|
366
|
+
},
|
|
367
|
+
}
|
|
368
|
+
);
|
|
302
369
|
}
|
|
303
370
|
|
|
304
371
|
userAccountPublicKey?: PublicKey;
|
|
@@ -330,6 +397,37 @@ export class ClearingHouse {
|
|
|
330
397
|
return this.userAccount;
|
|
331
398
|
}
|
|
332
399
|
|
|
400
|
+
userOrdersAccountPublicKey?: PublicKey;
|
|
401
|
+
/**
|
|
402
|
+
* Get the address for the Clearing House User Order's account. NOT the user's wallet address.
|
|
403
|
+
* @returns
|
|
404
|
+
*/
|
|
405
|
+
public async getUserOrdersAccountPublicKey(): Promise<PublicKey> {
|
|
406
|
+
if (this.userOrdersAccountPublicKey) {
|
|
407
|
+
return this.userOrdersAccountPublicKey;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
this.userOrdersAccountPublicKey = await getUserOrdersAccountPublicKey(
|
|
411
|
+
this.program.programId,
|
|
412
|
+
await this.getUserAccountPublicKey()
|
|
413
|
+
);
|
|
414
|
+
return this.userOrdersAccountPublicKey;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
userOrdersExist?: boolean;
|
|
418
|
+
async userOrdersAccountExists(): Promise<boolean> {
|
|
419
|
+
if (this.userOrdersExist) {
|
|
420
|
+
return this.userOrdersExist;
|
|
421
|
+
}
|
|
422
|
+
const userOrdersAccountRPCResponse =
|
|
423
|
+
await this.connection.getParsedAccountInfo(
|
|
424
|
+
await this.getUserOrdersAccountPublicKey()
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
this.userOrdersExist = userOrdersAccountRPCResponse.value !== null;
|
|
428
|
+
return this.userOrdersExist;
|
|
429
|
+
}
|
|
430
|
+
|
|
333
431
|
public async depositCollateral(
|
|
334
432
|
amount: BN,
|
|
335
433
|
collateralAccountPublicKey: PublicKey,
|
|
@@ -387,6 +485,7 @@ export class ClearingHouse {
|
|
|
387
485
|
userPositionsAccount,
|
|
388
486
|
userAccountPublicKey,
|
|
389
487
|
initializeUserAccountIx,
|
|
488
|
+
initializeUserOrdersAccountIx,
|
|
390
489
|
] = await this.getInitializeUserInstructions();
|
|
391
490
|
|
|
392
491
|
const depositCollateralIx = await this.getDepositCollateralInstruction(
|
|
@@ -397,6 +496,7 @@ export class ClearingHouse {
|
|
|
397
496
|
|
|
398
497
|
const tx = new Transaction()
|
|
399
498
|
.add(initializeUserAccountIx)
|
|
499
|
+
.add(initializeUserOrdersAccountIx)
|
|
400
500
|
.add(depositCollateralIx);
|
|
401
501
|
|
|
402
502
|
const txSig = await this.program.provider.send(tx, [userPositionsAccount]);
|
|
@@ -418,6 +518,7 @@ export class ClearingHouse {
|
|
|
418
518
|
userPositionsAccount,
|
|
419
519
|
userAccountPublicKey,
|
|
420
520
|
initializeUserAccountIx,
|
|
521
|
+
initializeUserOrdersAccountIx,
|
|
421
522
|
] = await this.getInitializeUserInstructions();
|
|
422
523
|
|
|
423
524
|
const depositCollateralIx = await this.getDepositCollateralInstruction(
|
|
@@ -430,6 +531,7 @@ export class ClearingHouse {
|
|
|
430
531
|
.add(createAssociatedAccountIx)
|
|
431
532
|
.add(mintToIx)
|
|
432
533
|
.add(initializeUserAccountIx)
|
|
534
|
+
.add(initializeUserOrdersAccountIx)
|
|
433
535
|
.add(depositCollateralIx);
|
|
434
536
|
|
|
435
537
|
const txSig = await this.program.provider.send(tx, [userPositionsAccount]);
|
|
@@ -580,6 +682,329 @@ export class ClearingHouse {
|
|
|
580
682
|
);
|
|
581
683
|
}
|
|
582
684
|
|
|
685
|
+
public async initializeUserOrdersThenPlaceOrder(
|
|
686
|
+
orderParams: OrderParams,
|
|
687
|
+
discountToken?: PublicKey,
|
|
688
|
+
referrer?: PublicKey
|
|
689
|
+
): Promise<TransactionSignature> {
|
|
690
|
+
const instructions: anchor.web3.TransactionInstruction[] = [];
|
|
691
|
+
const userOrdersAccountExists = await this.userOrdersAccountExists();
|
|
692
|
+
if (!userOrdersAccountExists) {
|
|
693
|
+
instructions.push(await this.getInitializeUserOrdersInstruction());
|
|
694
|
+
}
|
|
695
|
+
instructions.push(
|
|
696
|
+
await this.getPlaceOrderIx(orderParams, discountToken, referrer)
|
|
697
|
+
);
|
|
698
|
+
const tx = new Transaction();
|
|
699
|
+
for (const instruction of instructions) {
|
|
700
|
+
tx.add(instruction);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
return await this.txSender.send(tx, [], this.opts);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
public async placeOrder(
|
|
707
|
+
orderParams: OrderParams,
|
|
708
|
+
discountToken?: PublicKey,
|
|
709
|
+
referrer?: PublicKey
|
|
710
|
+
): Promise<TransactionSignature> {
|
|
711
|
+
return await this.txSender.send(
|
|
712
|
+
wrapInTx(
|
|
713
|
+
await this.getPlaceOrderIx(orderParams, discountToken, referrer)
|
|
714
|
+
),
|
|
715
|
+
[],
|
|
716
|
+
this.opts
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
public async getPlaceOrderIx(
|
|
721
|
+
orderParams: OrderParams,
|
|
722
|
+
discountToken?: PublicKey,
|
|
723
|
+
referrer?: PublicKey
|
|
724
|
+
): Promise<TransactionInstruction> {
|
|
725
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
726
|
+
const userAccount = await this.getUserAccount();
|
|
727
|
+
|
|
728
|
+
const priceOracle =
|
|
729
|
+
this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
|
|
730
|
+
.oracle;
|
|
731
|
+
|
|
732
|
+
const remainingAccounts = [];
|
|
733
|
+
if (orderParams.optionalAccounts.discountToken) {
|
|
734
|
+
if (!discountToken) {
|
|
735
|
+
throw Error(
|
|
736
|
+
'Optional accounts specified discount token but no discount token present'
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
remainingAccounts.push({
|
|
741
|
+
pubkey: discountToken,
|
|
742
|
+
isWritable: false,
|
|
743
|
+
isSigner: false,
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
if (orderParams.optionalAccounts.referrer) {
|
|
748
|
+
if (!referrer) {
|
|
749
|
+
throw Error(
|
|
750
|
+
'Optional accounts specified referrer but no referrer present'
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
remainingAccounts.push({
|
|
755
|
+
pubkey: referrer,
|
|
756
|
+
isWritable: false,
|
|
757
|
+
isSigner: false,
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const state = this.getStateAccount();
|
|
762
|
+
const orderState = this.getOrderStateAccount();
|
|
763
|
+
return await this.program.instruction.placeOrder(orderParams, {
|
|
764
|
+
accounts: {
|
|
765
|
+
state: await this.getStatePublicKey(),
|
|
766
|
+
user: userAccountPublicKey,
|
|
767
|
+
authority: this.wallet.publicKey,
|
|
768
|
+
markets: state.markets,
|
|
769
|
+
userOrders: await this.getUserOrdersAccountPublicKey(),
|
|
770
|
+
userPositions: userAccount.positions,
|
|
771
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
772
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
773
|
+
orderState: await this.getOrderStatePublicKey(),
|
|
774
|
+
orderHistory: orderState.orderHistory,
|
|
775
|
+
oracle: priceOracle,
|
|
776
|
+
},
|
|
777
|
+
remainingAccounts,
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
public async cancelOrder(orderId: BN): Promise<TransactionSignature> {
|
|
782
|
+
return await this.txSender.send(
|
|
783
|
+
wrapInTx(await this.getCancelOrderIx(orderId)),
|
|
784
|
+
[],
|
|
785
|
+
this.opts
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
public async getCancelOrderIx(orderId: BN): Promise<TransactionInstruction> {
|
|
790
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
791
|
+
const userAccount = await this.getUserAccount();
|
|
792
|
+
|
|
793
|
+
const state = this.getStateAccount();
|
|
794
|
+
const orderState = this.getOrderStateAccount();
|
|
795
|
+
return await this.program.instruction.cancelOrder(orderId, {
|
|
796
|
+
accounts: {
|
|
797
|
+
state: await this.getStatePublicKey(),
|
|
798
|
+
user: userAccountPublicKey,
|
|
799
|
+
authority: this.wallet.publicKey,
|
|
800
|
+
markets: state.markets,
|
|
801
|
+
userOrders: await this.getUserOrdersAccountPublicKey(),
|
|
802
|
+
userPositions: userAccount.positions,
|
|
803
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
804
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
805
|
+
orderState: await this.getOrderStatePublicKey(),
|
|
806
|
+
orderHistory: orderState.orderHistory,
|
|
807
|
+
},
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
public async cancelOrderByUserId(
|
|
812
|
+
userOrderId: number
|
|
813
|
+
): Promise<TransactionSignature> {
|
|
814
|
+
return await this.txSender.send(
|
|
815
|
+
wrapInTx(await this.getCancelOrderByUserIdIx(userOrderId)),
|
|
816
|
+
[],
|
|
817
|
+
this.opts
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
public async getCancelOrderByUserIdIx(
|
|
822
|
+
userOrderId: number
|
|
823
|
+
): Promise<TransactionInstruction> {
|
|
824
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
825
|
+
const userAccount = await this.getUserAccount();
|
|
826
|
+
|
|
827
|
+
const state = this.getStateAccount();
|
|
828
|
+
const orderState = this.getOrderStateAccount();
|
|
829
|
+
return await this.program.instruction.cancelOrderByUserId(userOrderId, {
|
|
830
|
+
accounts: {
|
|
831
|
+
state: await this.getStatePublicKey(),
|
|
832
|
+
user: userAccountPublicKey,
|
|
833
|
+
authority: this.wallet.publicKey,
|
|
834
|
+
markets: state.markets,
|
|
835
|
+
userOrders: await this.getUserOrdersAccountPublicKey(),
|
|
836
|
+
userPositions: userAccount.positions,
|
|
837
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
838
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
839
|
+
orderState: await this.getOrderStatePublicKey(),
|
|
840
|
+
orderHistory: orderState.orderHistory,
|
|
841
|
+
},
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
public async fillOrder(
|
|
846
|
+
userAccountPublicKey: PublicKey,
|
|
847
|
+
userOrdersAccountPublicKey: PublicKey,
|
|
848
|
+
order: Order
|
|
849
|
+
): Promise<TransactionSignature> {
|
|
850
|
+
return await this.txSender.send(
|
|
851
|
+
wrapInTx(
|
|
852
|
+
await this.getFillOrderIx(
|
|
853
|
+
userAccountPublicKey,
|
|
854
|
+
userOrdersAccountPublicKey,
|
|
855
|
+
order
|
|
856
|
+
)
|
|
857
|
+
),
|
|
858
|
+
[],
|
|
859
|
+
this.opts
|
|
860
|
+
);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
public async getFillOrderIx(
|
|
864
|
+
userAccountPublicKey: PublicKey,
|
|
865
|
+
userOrdersAccountPublicKey: PublicKey,
|
|
866
|
+
order: Order
|
|
867
|
+
): Promise<TransactionInstruction> {
|
|
868
|
+
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
869
|
+
const userAccount: any = await this.program.account.user.fetch(
|
|
870
|
+
userAccountPublicKey
|
|
871
|
+
);
|
|
872
|
+
|
|
873
|
+
const marketIndex = order.marketIndex;
|
|
874
|
+
const oracle = this.getMarket(marketIndex).amm.oracle;
|
|
875
|
+
|
|
876
|
+
const state = this.getStateAccount();
|
|
877
|
+
const orderState = this.getOrderStateAccount();
|
|
878
|
+
|
|
879
|
+
const remainingAccounts = [];
|
|
880
|
+
if (!order.referrer.equals(PublicKey.default)) {
|
|
881
|
+
remainingAccounts.push({
|
|
882
|
+
pubkey: order.referrer,
|
|
883
|
+
isWritable: true,
|
|
884
|
+
isSigner: false,
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
const orderId = order.orderId;
|
|
889
|
+
return await this.program.instruction.fillOrder(orderId, {
|
|
890
|
+
accounts: {
|
|
891
|
+
state: await this.getStatePublicKey(),
|
|
892
|
+
filler: fillerPublicKey,
|
|
893
|
+
user: userAccountPublicKey,
|
|
894
|
+
authority: this.wallet.publicKey,
|
|
895
|
+
markets: state.markets,
|
|
896
|
+
userPositions: userAccount.positions,
|
|
897
|
+
userOrders: userOrdersAccountPublicKey,
|
|
898
|
+
tradeHistory: state.tradeHistory,
|
|
899
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
900
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
901
|
+
orderState: await this.getOrderStatePublicKey(),
|
|
902
|
+
orderHistory: orderState.orderHistory,
|
|
903
|
+
extendedCurveHistory: state.extendedCurveHistory,
|
|
904
|
+
oracle: oracle,
|
|
905
|
+
},
|
|
906
|
+
remainingAccounts,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
public async initializeUserOrdersThenPlaceAndFillOrder(
|
|
911
|
+
orderParams: OrderParams,
|
|
912
|
+
discountToken?: PublicKey,
|
|
913
|
+
referrer?: PublicKey
|
|
914
|
+
): Promise<TransactionSignature> {
|
|
915
|
+
const instructions: anchor.web3.TransactionInstruction[] = [];
|
|
916
|
+
const userOrdersAccountExists = await this.userOrdersAccountExists();
|
|
917
|
+
if (!userOrdersAccountExists) {
|
|
918
|
+
instructions.push(await this.getInitializeUserOrdersInstruction());
|
|
919
|
+
}
|
|
920
|
+
instructions.push(
|
|
921
|
+
await this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)
|
|
922
|
+
);
|
|
923
|
+
const tx = new Transaction();
|
|
924
|
+
for (const instruction of instructions) {
|
|
925
|
+
tx.add(instruction);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
return await this.txSender.send(tx, [], this.opts);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
public async placeAndFillOrder(
|
|
932
|
+
orderParams: OrderParams,
|
|
933
|
+
discountToken?: PublicKey,
|
|
934
|
+
referrer?: PublicKey
|
|
935
|
+
): Promise<TransactionSignature> {
|
|
936
|
+
return await this.txSender.send(
|
|
937
|
+
wrapInTx(
|
|
938
|
+
await this.getPlaceAndFillOrderIx(orderParams, discountToken, referrer)
|
|
939
|
+
),
|
|
940
|
+
[],
|
|
941
|
+
this.opts
|
|
942
|
+
);
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
public async getPlaceAndFillOrderIx(
|
|
946
|
+
orderParams: OrderParams,
|
|
947
|
+
discountToken?: PublicKey,
|
|
948
|
+
referrer?: PublicKey
|
|
949
|
+
): Promise<TransactionInstruction> {
|
|
950
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
951
|
+
const userAccount = await this.getUserAccount();
|
|
952
|
+
|
|
953
|
+
const priceOracle =
|
|
954
|
+
this.getMarketsAccount().markets[orderParams.marketIndex.toNumber()].amm
|
|
955
|
+
.oracle;
|
|
956
|
+
|
|
957
|
+
const remainingAccounts = [];
|
|
958
|
+
if (orderParams.optionalAccounts.discountToken) {
|
|
959
|
+
if (!discountToken) {
|
|
960
|
+
throw Error(
|
|
961
|
+
'Optional accounts specified discount token but no discount token present'
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
remainingAccounts.push({
|
|
966
|
+
pubkey: discountToken,
|
|
967
|
+
isWritable: false,
|
|
968
|
+
isSigner: false,
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
if (orderParams.optionalAccounts.referrer) {
|
|
973
|
+
if (!referrer) {
|
|
974
|
+
throw Error(
|
|
975
|
+
'Optional accounts specified referrer but no referrer present'
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
remainingAccounts.push({
|
|
980
|
+
pubkey: referrer,
|
|
981
|
+
isWritable: true,
|
|
982
|
+
isSigner: false,
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
const state = this.getStateAccount();
|
|
987
|
+
const orderState = this.getOrderStateAccount();
|
|
988
|
+
return await this.program.instruction.placeAndFillOrder(orderParams, {
|
|
989
|
+
accounts: {
|
|
990
|
+
state: await this.getStatePublicKey(),
|
|
991
|
+
user: userAccountPublicKey,
|
|
992
|
+
authority: this.wallet.publicKey,
|
|
993
|
+
markets: state.markets,
|
|
994
|
+
userOrders: await this.getUserOrdersAccountPublicKey(),
|
|
995
|
+
userPositions: userAccount.positions,
|
|
996
|
+
tradeHistory: state.tradeHistory,
|
|
997
|
+
fundingPaymentHistory: state.fundingPaymentHistory,
|
|
998
|
+
fundingRateHistory: state.fundingRateHistory,
|
|
999
|
+
orderState: await this.getOrderStatePublicKey(),
|
|
1000
|
+
orderHistory: orderState.orderHistory,
|
|
1001
|
+
extendedCurveHistory: state.extendedCurveHistory,
|
|
1002
|
+
oracle: priceOracle,
|
|
1003
|
+
},
|
|
1004
|
+
remainingAccounts,
|
|
1005
|
+
});
|
|
1006
|
+
}
|
|
1007
|
+
|
|
583
1008
|
/**
|
|
584
1009
|
* Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
|
|
585
1010
|
* @param marketIndex
|