@drift-labs/sdk 0.2.0-master.32 → 0.2.0-master.33
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.js +2 -1
- package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +2 -2
- package/lib/accounts/pollingClearingHouseAccountSubscriber.js +8 -8
- package/lib/accounts/types.d.ts +1 -0
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +2 -2
- package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +7 -7
- package/lib/addresses/marketAddresses.js +1 -1
- package/lib/addresses/pda.d.ts +4 -4
- package/lib/addresses/pda.js +23 -22
- package/lib/admin.d.ts +30 -32
- package/lib/admin.js +111 -119
- package/lib/clearingHouse.d.ts +43 -34
- package/lib/clearingHouse.js +353 -193
- package/lib/clearingHouseConfig.d.ts +2 -2
- package/lib/clearingHouseUser.d.ts +26 -5
- package/lib/clearingHouseUser.js +151 -51
- package/lib/config.d.ts +2 -0
- package/lib/config.js +5 -1
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +3 -2
- package/lib/dlob/DLOB.d.ts +18 -11
- package/lib/dlob/DLOB.js +179 -107
- package/lib/dlob/DLOBNode.js +2 -10
- package/lib/dlob/NodeList.js +1 -1
- package/lib/events/eventSubscriber.d.ts +1 -0
- package/lib/events/eventSubscriber.js +11 -4
- package/lib/events/fetchLogs.d.ts +3 -1
- package/lib/events/fetchLogs.js +13 -5
- package/lib/events/pollingLogProvider.js +1 -1
- package/lib/events/types.d.ts +1 -1
- package/lib/events/webSocketLogProvider.js +1 -1
- package/lib/factory/bigNum.d.ts +5 -4
- package/lib/factory/bigNum.js +36 -6
- package/lib/idl/clearing_house.json +1527 -1242
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/math/amm.js +9 -9
- package/lib/math/exchangeStatus.d.ts +4 -0
- package/lib/math/exchangeStatus.js +18 -0
- package/lib/math/funding.js +10 -10
- package/lib/math/margin.js +6 -1
- package/lib/math/market.js +9 -9
- package/lib/math/orders.d.ts +7 -3
- package/lib/math/orders.js +39 -31
- package/lib/math/repeg.js +3 -3
- package/lib/math/spotBalance.js +3 -3
- package/lib/math/spotPosition.js +2 -2
- package/lib/serum/serumFulfillmentConfigMap.d.ts +10 -0
- package/lib/serum/serumFulfillmentConfigMap.js +17 -0
- package/lib/serum/serumSubscriber.d.ts +4 -0
- package/lib/serum/serumSubscriber.js +16 -1
- package/lib/types.d.ts +60 -75
- package/lib/types.js +2 -1
- package/lib/userMap/userMap.d.ts +17 -1
- package/lib/userMap/userMap.js +12 -0
- package/lib/userName.d.ts +1 -0
- package/lib/userName.js +3 -2
- package/package.json +1 -1
- package/src/accounts/bulkAccountLoader.ts +5 -1
- package/src/accounts/pollingClearingHouseAccountSubscriber.ts +9 -9
- package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +8 -8
- package/src/addresses/marketAddresses.ts +2 -2
- package/src/addresses/pda.ts +20 -20
- package/src/admin.ts +246 -221
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +556 -236
- package/src/clearingHouseConfig.ts +2 -2
- package/src/clearingHouseUser.ts +237 -87
- package/src/config.ts +8 -1
- package/src/constants/numericConstants.ts +5 -1
- package/src/dlob/DLOB.ts +257 -120
- package/src/dlob/DLOBNode.ts +2 -14
- package/src/dlob/NodeList.ts +1 -1
- package/src/events/eventList.js +77 -0
- package/src/events/eventSubscriber.ts +18 -4
- package/src/events/fetchLogs.ts +20 -5
- package/src/events/pollingLogProvider.ts +1 -1
- package/src/events/types.ts +2 -1
- package/src/events/webSocketLogProvider.ts +1 -1
- package/src/examples/makeTradeExample.js +157 -0
- package/src/factory/bigNum.ts +59 -6
- package/src/idl/clearing_house.json +1527 -1242
- package/src/idl/pyth.json +98 -2
- package/src/index.ts +3 -0
- package/src/math/amm.ts +9 -9
- package/src/math/exchangeStatus.ts +31 -0
- package/src/math/funding.ts +20 -10
- package/src/math/margin.ts +7 -1
- package/src/math/market.ts +9 -9
- package/src/math/orders.ts +44 -29
- package/src/math/repeg.ts +3 -3
- package/src/math/spotBalance.ts +4 -4
- package/src/math/spotPosition.ts +2 -2
- package/src/serum/serumFulfillmentConfigMap.ts +26 -0
- package/src/serum/serumSubscriber.ts +20 -1
- package/src/token/index.js +38 -0
- package/src/tx/types.js +2 -0
- package/src/tx/utils.js +17 -0
- package/src/types.ts +65 -51
- package/src/userMap/userMap.ts +25 -1
- package/src/userName.ts +2 -1
- package/src/util/computeUnits.js +27 -0
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/tests/bn/test.ts +22 -1
- package/tests/dlob/helpers.ts +252 -81
- package/tests/dlob/test.ts +1040 -219
package/src/clearingHouse.ts
CHANGED
|
@@ -50,9 +50,10 @@ import {
|
|
|
50
50
|
getClearingHouseSignerPublicKey,
|
|
51
51
|
getClearingHouseStateAccountPublicKey,
|
|
52
52
|
getInsuranceFundStakeAccountPublicKey,
|
|
53
|
-
|
|
53
|
+
getPerpMarketPublicKey,
|
|
54
54
|
getSerumFulfillmentConfigPublicKey,
|
|
55
55
|
getSerumSignerPublicKey,
|
|
56
|
+
getSpotMarketPublicKey,
|
|
56
57
|
getUserAccountPublicKey,
|
|
57
58
|
getUserAccountPublicKeySync,
|
|
58
59
|
getUserStatsAccountPublicKey,
|
|
@@ -64,7 +65,7 @@ import {
|
|
|
64
65
|
} from './accounts/types';
|
|
65
66
|
import { TxSender } from './tx/types';
|
|
66
67
|
import { wrapInTx } from './tx/utils';
|
|
67
|
-
import { QUOTE_SPOT_MARKET_INDEX } from './constants/numericConstants';
|
|
68
|
+
import { QUOTE_SPOT_MARKET_INDEX, ZERO } from './constants/numericConstants';
|
|
68
69
|
import { findDirectionToClose, positionIsAvailable } from './math/position';
|
|
69
70
|
import { getTokenAmount } from './math/spotBalance';
|
|
70
71
|
import { DEFAULT_USER_NAME, encodeName } from './userName';
|
|
@@ -101,7 +102,7 @@ export class ClearingHouse {
|
|
|
101
102
|
opts?: ConfirmOptions;
|
|
102
103
|
users = new Map<number, ClearingHouseUser>();
|
|
103
104
|
userStats?: ClearingHouseUserStats;
|
|
104
|
-
|
|
105
|
+
activeSubAccountId: number;
|
|
105
106
|
userAccountSubscriptionConfig: ClearingHouseUserAccountSubscriptionConfig;
|
|
106
107
|
accountSubscriber: ClearingHouseAccountSubscriber;
|
|
107
108
|
eventEmitter: StrictEventEmitter<EventEmitter, ClearingHouseAccountEvents>;
|
|
@@ -134,8 +135,8 @@ export class ClearingHouse {
|
|
|
134
135
|
);
|
|
135
136
|
|
|
136
137
|
this.authority = config.authority ?? this.wallet.publicKey;
|
|
137
|
-
const
|
|
138
|
-
this.
|
|
138
|
+
const subAccountIds = config.subAccountIds ?? [0];
|
|
139
|
+
this.activeSubAccountId = config.activeSubAccountId ?? subAccountIds[0];
|
|
139
140
|
this.userAccountSubscriptionConfig =
|
|
140
141
|
config.accountSubscription?.type === 'polling'
|
|
141
142
|
? {
|
|
@@ -145,7 +146,7 @@ export class ClearingHouse {
|
|
|
145
146
|
: {
|
|
146
147
|
type: 'websocket',
|
|
147
148
|
};
|
|
148
|
-
this.createUsers(
|
|
149
|
+
this.createUsers(subAccountIds, this.userAccountSubscriptionConfig);
|
|
149
150
|
if (config.userStats) {
|
|
150
151
|
this.userStats = new ClearingHouseUserStats({
|
|
151
152
|
clearingHouse: this,
|
|
@@ -201,23 +202,23 @@ export class ClearingHouse {
|
|
|
201
202
|
}
|
|
202
203
|
|
|
203
204
|
createUsers(
|
|
204
|
-
|
|
205
|
+
subAccountIds: number[],
|
|
205
206
|
accountSubscriptionConfig: ClearingHouseUserAccountSubscriptionConfig
|
|
206
207
|
): void {
|
|
207
|
-
for (const
|
|
208
|
-
const user = this.createUser(
|
|
209
|
-
this.users.set(
|
|
208
|
+
for (const subAccountId of subAccountIds) {
|
|
209
|
+
const user = this.createUser(subAccountId, accountSubscriptionConfig);
|
|
210
|
+
this.users.set(subAccountId, user);
|
|
210
211
|
}
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
createUser(
|
|
214
|
-
|
|
215
|
+
subAccountId: number,
|
|
215
216
|
accountSubscriptionConfig: ClearingHouseUserAccountSubscriptionConfig
|
|
216
217
|
): ClearingHouseUser {
|
|
217
218
|
const userAccountPublicKey = getUserAccountPublicKeySync(
|
|
218
219
|
this.program.programId,
|
|
219
220
|
this.authority,
|
|
220
|
-
|
|
221
|
+
subAccountId
|
|
221
222
|
);
|
|
222
223
|
|
|
223
224
|
return new ClearingHouseUser({
|
|
@@ -349,13 +350,13 @@ export class ClearingHouse {
|
|
|
349
350
|
/**
|
|
350
351
|
* Update the wallet to use for clearing house transactions and linked user account
|
|
351
352
|
* @param newWallet
|
|
352
|
-
* @param
|
|
353
|
-
* @param
|
|
353
|
+
* @param subAccountIds
|
|
354
|
+
* @param activeSubAccountId
|
|
354
355
|
*/
|
|
355
356
|
public async updateWallet(
|
|
356
357
|
newWallet: IWallet,
|
|
357
|
-
|
|
358
|
-
|
|
358
|
+
subAccountIds = [0],
|
|
359
|
+
activeSubAccountId = 0
|
|
359
360
|
): Promise<void> {
|
|
360
361
|
const newProvider = new AnchorProvider(
|
|
361
362
|
this.connection,
|
|
@@ -380,39 +381,46 @@ export class ClearingHouse {
|
|
|
380
381
|
await Promise.all(this.unsubscribeUsers());
|
|
381
382
|
}
|
|
382
383
|
this.users.clear();
|
|
383
|
-
this.createUsers(
|
|
384
|
+
this.createUsers(subAccountIds, this.userAccountSubscriptionConfig);
|
|
384
385
|
if (this.isSubscribed) {
|
|
385
386
|
await Promise.all(this.subscribeUsers());
|
|
386
387
|
}
|
|
387
388
|
|
|
388
|
-
this.
|
|
389
|
+
this.activeSubAccountId = activeSubAccountId;
|
|
389
390
|
this.userStatsAccountPublicKey = undefined;
|
|
390
391
|
}
|
|
391
392
|
|
|
392
|
-
public async switchActiveUser(
|
|
393
|
-
this.
|
|
393
|
+
public async switchActiveUser(subAccountId: number): Promise<void> {
|
|
394
|
+
this.activeSubAccountId = subAccountId;
|
|
394
395
|
}
|
|
395
396
|
|
|
396
|
-
public async addUser(
|
|
397
|
-
if (this.users.has(
|
|
397
|
+
public async addUser(subAccountId: number): Promise<void> {
|
|
398
|
+
if (this.users.has(subAccountId)) {
|
|
398
399
|
return;
|
|
399
400
|
}
|
|
400
401
|
|
|
401
|
-
const user = this.createUser(
|
|
402
|
+
const user = this.createUser(
|
|
403
|
+
subAccountId,
|
|
404
|
+
this.userAccountSubscriptionConfig
|
|
405
|
+
);
|
|
402
406
|
await user.subscribe();
|
|
403
|
-
this.users.set(
|
|
407
|
+
this.users.set(subAccountId, user);
|
|
404
408
|
}
|
|
405
409
|
|
|
406
410
|
public async initializeUserAccount(
|
|
407
|
-
|
|
411
|
+
subAccountId = 0,
|
|
408
412
|
name = DEFAULT_USER_NAME,
|
|
409
413
|
referrerInfo?: ReferrerInfo
|
|
410
414
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
411
415
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
412
|
-
await this.getInitializeUserInstructions(
|
|
416
|
+
await this.getInitializeUserInstructions(
|
|
417
|
+
subAccountId,
|
|
418
|
+
name,
|
|
419
|
+
referrerInfo
|
|
420
|
+
);
|
|
413
421
|
|
|
414
422
|
const tx = new Transaction();
|
|
415
|
-
if (
|
|
423
|
+
if (subAccountId === 0) {
|
|
416
424
|
// not the safest assumption, can explicitly check if user stats account exists if it causes problems
|
|
417
425
|
tx.add(await this.getInitializeUserStatsIx());
|
|
418
426
|
}
|
|
@@ -422,14 +430,14 @@ export class ClearingHouse {
|
|
|
422
430
|
}
|
|
423
431
|
|
|
424
432
|
async getInitializeUserInstructions(
|
|
425
|
-
|
|
433
|
+
subAccountId = 0,
|
|
426
434
|
name = DEFAULT_USER_NAME,
|
|
427
435
|
referrerInfo?: ReferrerInfo
|
|
428
436
|
): Promise<[PublicKey, TransactionInstruction]> {
|
|
429
437
|
const userAccountPublicKey = await getUserAccountPublicKey(
|
|
430
438
|
this.program.programId,
|
|
431
439
|
this.wallet.publicKey,
|
|
432
|
-
|
|
440
|
+
subAccountId
|
|
433
441
|
);
|
|
434
442
|
|
|
435
443
|
const remainingAccounts = new Array<AccountMeta>();
|
|
@@ -463,7 +471,7 @@ export class ClearingHouse {
|
|
|
463
471
|
|
|
464
472
|
const nameBuffer = encodeName(name);
|
|
465
473
|
const initializeUserAccountIx =
|
|
466
|
-
await this.program.instruction.initializeUser(
|
|
474
|
+
await this.program.instruction.initializeUser(subAccountId, nameBuffer, {
|
|
467
475
|
accounts: {
|
|
468
476
|
user: userAccountPublicKey,
|
|
469
477
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
@@ -494,12 +502,18 @@ export class ClearingHouse {
|
|
|
494
502
|
|
|
495
503
|
public async updateUserName(
|
|
496
504
|
name: string,
|
|
497
|
-
|
|
505
|
+
subAccountId = 0
|
|
498
506
|
): Promise<TransactionSignature> {
|
|
507
|
+
const userAccountPublicKey = getUserAccountPublicKeySync(
|
|
508
|
+
this.program.programId,
|
|
509
|
+
this.wallet.publicKey,
|
|
510
|
+
subAccountId
|
|
511
|
+
);
|
|
512
|
+
|
|
499
513
|
const nameBuffer = encodeName(name);
|
|
500
|
-
return await this.program.rpc.updateUserName(
|
|
514
|
+
return await this.program.rpc.updateUserName(subAccountId, nameBuffer, {
|
|
501
515
|
accounts: {
|
|
502
|
-
user:
|
|
516
|
+
user: userAccountPublicKey,
|
|
503
517
|
authority: this.wallet.publicKey,
|
|
504
518
|
},
|
|
505
519
|
});
|
|
@@ -507,10 +521,10 @@ export class ClearingHouse {
|
|
|
507
521
|
|
|
508
522
|
public async updateUserCustomMarginRatio(
|
|
509
523
|
marginRatio: number,
|
|
510
|
-
|
|
524
|
+
subAccountId = 0
|
|
511
525
|
): Promise<TransactionSignature> {
|
|
512
526
|
return await this.program.rpc.updateUserCustomMarginRatio(
|
|
513
|
-
|
|
527
|
+
subAccountId,
|
|
514
528
|
marginRatio,
|
|
515
529
|
{
|
|
516
530
|
accounts: {
|
|
@@ -523,9 +537,9 @@ export class ClearingHouse {
|
|
|
523
537
|
|
|
524
538
|
public async updateUserDelegate(
|
|
525
539
|
delegate: PublicKey,
|
|
526
|
-
|
|
540
|
+
subAccountId = 0
|
|
527
541
|
): Promise<TransactionSignature> {
|
|
528
|
-
return await this.program.rpc.updateUserDelegate(
|
|
542
|
+
return await this.program.rpc.updateUserDelegate(subAccountId, delegate, {
|
|
529
543
|
accounts: {
|
|
530
544
|
user: await this.getUserAccountPublicKey(),
|
|
531
545
|
authority: this.wallet.publicKey,
|
|
@@ -551,11 +565,11 @@ export class ClearingHouse {
|
|
|
551
565
|
);
|
|
552
566
|
}
|
|
553
567
|
|
|
554
|
-
public async deleteUser(
|
|
568
|
+
public async deleteUser(subAccountId = 0): Promise<TransactionSignature> {
|
|
555
569
|
const userAccountPublicKey = getUserAccountPublicKeySync(
|
|
556
570
|
this.program.programId,
|
|
557
571
|
this.wallet.publicKey,
|
|
558
|
-
|
|
572
|
+
subAccountId
|
|
559
573
|
);
|
|
560
574
|
|
|
561
575
|
const txSig = await this.program.rpc.deleteUser({
|
|
@@ -567,18 +581,18 @@ export class ClearingHouse {
|
|
|
567
581
|
},
|
|
568
582
|
});
|
|
569
583
|
|
|
570
|
-
await this.users.get(
|
|
571
|
-
this.users.delete(
|
|
584
|
+
await this.users.get(subAccountId)?.unsubscribe();
|
|
585
|
+
this.users.delete(subAccountId);
|
|
572
586
|
|
|
573
587
|
return txSig;
|
|
574
588
|
}
|
|
575
589
|
|
|
576
|
-
public getUser(
|
|
577
|
-
|
|
578
|
-
if (!this.users.has(
|
|
579
|
-
throw new Error(`Clearing House has no user for user id ${
|
|
590
|
+
public getUser(subAccountId?: number): ClearingHouseUser {
|
|
591
|
+
subAccountId = subAccountId ?? this.activeSubAccountId;
|
|
592
|
+
if (!this.users.has(subAccountId)) {
|
|
593
|
+
throw new Error(`Clearing House has no user for user id ${subAccountId}`);
|
|
580
594
|
}
|
|
581
|
-
return this.users.get(
|
|
595
|
+
return this.users.get(subAccountId);
|
|
582
596
|
}
|
|
583
597
|
|
|
584
598
|
public getUsers(): ClearingHouseUser[] {
|
|
@@ -606,14 +620,14 @@ export class ClearingHouse {
|
|
|
606
620
|
return this.getUser().userAccountPublicKey;
|
|
607
621
|
}
|
|
608
622
|
|
|
609
|
-
public getUserAccount(
|
|
610
|
-
return this.getUser(
|
|
623
|
+
public getUserAccount(subAccountId?: number): UserAccount | undefined {
|
|
624
|
+
return this.getUser(subAccountId).getUserAccount();
|
|
611
625
|
}
|
|
612
626
|
|
|
613
627
|
public getUserAccountAndSlot(
|
|
614
|
-
|
|
628
|
+
subAccountId?: number
|
|
615
629
|
): DataAndSlot<UserAccount> | undefined {
|
|
616
|
-
return this.getUser(
|
|
630
|
+
return this.getUser(subAccountId).getUserAccountAndSlot();
|
|
617
631
|
}
|
|
618
632
|
|
|
619
633
|
public getSpotPosition(marketIndex: number): SpotPosition | undefined {
|
|
@@ -626,7 +640,20 @@ export class ClearingHouse {
|
|
|
626
640
|
const spotMarket = this.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX);
|
|
627
641
|
const spotPosition = this.getSpotPosition(QUOTE_SPOT_MARKET_INDEX);
|
|
628
642
|
return getTokenAmount(
|
|
629
|
-
spotPosition.
|
|
643
|
+
spotPosition.scaledBalance,
|
|
644
|
+
spotMarket,
|
|
645
|
+
spotPosition.balanceType
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
public getTokenAmount(marketIndex: number): BN {
|
|
650
|
+
const spotPosition = this.getSpotPosition(marketIndex);
|
|
651
|
+
if (spotPosition === undefined) {
|
|
652
|
+
return ZERO;
|
|
653
|
+
}
|
|
654
|
+
const spotMarket = this.getSpotMarketAccount(marketIndex);
|
|
655
|
+
return getTokenAmount(
|
|
656
|
+
spotPosition.scaledBalance,
|
|
630
657
|
spotMarket,
|
|
631
658
|
spotPosition.balanceType
|
|
632
659
|
);
|
|
@@ -808,10 +835,17 @@ export class ClearingHouse {
|
|
|
808
835
|
amount: BN,
|
|
809
836
|
marketIndex: number,
|
|
810
837
|
collateralAccountPublicKey: PublicKey,
|
|
811
|
-
|
|
838
|
+
subAccountId?: number,
|
|
812
839
|
reduceOnly = false
|
|
813
840
|
): Promise<TransactionSignature> {
|
|
814
841
|
const tx = new Transaction();
|
|
842
|
+
tx.add(
|
|
843
|
+
ComputeBudgetProgram.requestUnits({
|
|
844
|
+
units: 600_000,
|
|
845
|
+
additionalFee: 0,
|
|
846
|
+
})
|
|
847
|
+
);
|
|
848
|
+
|
|
815
849
|
const additionalSigners: Array<Signer> = [];
|
|
816
850
|
|
|
817
851
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
@@ -840,7 +874,7 @@ export class ClearingHouse {
|
|
|
840
874
|
amount,
|
|
841
875
|
marketIndex,
|
|
842
876
|
collateralAccountPublicKey,
|
|
843
|
-
|
|
877
|
+
subAccountId,
|
|
844
878
|
reduceOnly,
|
|
845
879
|
true
|
|
846
880
|
);
|
|
@@ -872,15 +906,15 @@ export class ClearingHouse {
|
|
|
872
906
|
amount: BN,
|
|
873
907
|
marketIndex: number,
|
|
874
908
|
userTokenAccount: PublicKey,
|
|
875
|
-
|
|
909
|
+
subAccountId?: number,
|
|
876
910
|
reduceOnly = false,
|
|
877
911
|
userInitialized = true
|
|
878
912
|
): Promise<TransactionInstruction> {
|
|
879
|
-
const userAccountPublicKey =
|
|
913
|
+
const userAccountPublicKey = subAccountId
|
|
880
914
|
? await getUserAccountPublicKey(
|
|
881
915
|
this.program.programId,
|
|
882
916
|
this.authority,
|
|
883
|
-
|
|
917
|
+
subAccountId
|
|
884
918
|
)
|
|
885
919
|
: await this.getUserAccountPublicKey();
|
|
886
920
|
|
|
@@ -1000,22 +1034,26 @@ export class ClearingHouse {
|
|
|
1000
1034
|
* @param amount
|
|
1001
1035
|
* @param userTokenAccount
|
|
1002
1036
|
* @param marketIndex
|
|
1003
|
-
* @param
|
|
1037
|
+
* @param subAccountId
|
|
1004
1038
|
* @param name
|
|
1005
|
-
* @param
|
|
1039
|
+
* @param fromSubAccountId
|
|
1006
1040
|
* @returns
|
|
1007
1041
|
*/
|
|
1008
1042
|
public async initializeUserAccountAndDepositCollateral(
|
|
1009
1043
|
amount: BN,
|
|
1010
1044
|
userTokenAccount: PublicKey,
|
|
1011
1045
|
marketIndex = 0,
|
|
1012
|
-
|
|
1046
|
+
subAccountId = 0,
|
|
1013
1047
|
name = DEFAULT_USER_NAME,
|
|
1014
|
-
|
|
1048
|
+
fromSubAccountId?: number,
|
|
1015
1049
|
referrerInfo?: ReferrerInfo
|
|
1016
1050
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
1017
1051
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
1018
|
-
await this.getInitializeUserInstructions(
|
|
1052
|
+
await this.getInitializeUserInstructions(
|
|
1053
|
+
subAccountId,
|
|
1054
|
+
name,
|
|
1055
|
+
referrerInfo
|
|
1056
|
+
);
|
|
1019
1057
|
|
|
1020
1058
|
const additionalSigners: Array<Signer> = [];
|
|
1021
1059
|
|
|
@@ -1047,23 +1085,23 @@ export class ClearingHouse {
|
|
|
1047
1085
|
}
|
|
1048
1086
|
|
|
1049
1087
|
const depositCollateralIx =
|
|
1050
|
-
|
|
1088
|
+
fromSubAccountId != null
|
|
1051
1089
|
? await this.getTransferDepositIx(
|
|
1052
1090
|
amount,
|
|
1053
1091
|
marketIndex,
|
|
1054
|
-
|
|
1055
|
-
|
|
1092
|
+
fromSubAccountId,
|
|
1093
|
+
subAccountId
|
|
1056
1094
|
)
|
|
1057
1095
|
: await this.getDepositInstruction(
|
|
1058
1096
|
amount,
|
|
1059
1097
|
marketIndex,
|
|
1060
1098
|
userTokenAccount,
|
|
1061
|
-
|
|
1099
|
+
subAccountId,
|
|
1062
1100
|
false,
|
|
1063
1101
|
false
|
|
1064
1102
|
);
|
|
1065
1103
|
|
|
1066
|
-
if (
|
|
1104
|
+
if (subAccountId === 0) {
|
|
1067
1105
|
tx.add(await this.getInitializeUserStatsIx());
|
|
1068
1106
|
}
|
|
1069
1107
|
tx.add(initializeUserAccountIx).add(depositCollateralIx);
|
|
@@ -1091,7 +1129,7 @@ export class ClearingHouse {
|
|
|
1091
1129
|
}
|
|
1092
1130
|
|
|
1093
1131
|
public async initializeUserAccountForDevnet(
|
|
1094
|
-
|
|
1132
|
+
subAccountId = 0,
|
|
1095
1133
|
name = DEFAULT_USER_NAME,
|
|
1096
1134
|
marketIndex: number,
|
|
1097
1135
|
tokenFaucet: TokenFaucet,
|
|
@@ -1105,20 +1143,24 @@ export class ClearingHouse {
|
|
|
1105
1143
|
);
|
|
1106
1144
|
|
|
1107
1145
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
1108
|
-
await this.getInitializeUserInstructions(
|
|
1146
|
+
await this.getInitializeUserInstructions(
|
|
1147
|
+
subAccountId,
|
|
1148
|
+
name,
|
|
1149
|
+
referrerInfo
|
|
1150
|
+
);
|
|
1109
1151
|
|
|
1110
1152
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
1111
1153
|
amount,
|
|
1112
1154
|
marketIndex,
|
|
1113
1155
|
associateTokenPublicKey,
|
|
1114
|
-
|
|
1156
|
+
subAccountId,
|
|
1115
1157
|
false,
|
|
1116
1158
|
false
|
|
1117
1159
|
);
|
|
1118
1160
|
|
|
1119
1161
|
const tx = new Transaction().add(createAssociatedAccountIx).add(mintToIx);
|
|
1120
1162
|
|
|
1121
|
-
if (
|
|
1163
|
+
if (subAccountId === 0) {
|
|
1122
1164
|
tx.add(await this.getInitializeUserStatsIx());
|
|
1123
1165
|
}
|
|
1124
1166
|
tx.add(initializeUserAccountIx).add(depositCollateralIx);
|
|
@@ -1135,6 +1177,13 @@ export class ClearingHouse {
|
|
|
1135
1177
|
reduceOnly = false
|
|
1136
1178
|
): Promise<TransactionSignature> {
|
|
1137
1179
|
const tx = new Transaction();
|
|
1180
|
+
tx.add(
|
|
1181
|
+
ComputeBudgetProgram.requestUnits({
|
|
1182
|
+
units: 600_000,
|
|
1183
|
+
additionalFee: 0,
|
|
1184
|
+
})
|
|
1185
|
+
);
|
|
1186
|
+
|
|
1138
1187
|
const additionalSigners: Array<Signer> = [];
|
|
1139
1188
|
|
|
1140
1189
|
const spotMarketAccount = this.getSpotMarketAccount(marketIndex);
|
|
@@ -1241,16 +1290,16 @@ export class ClearingHouse {
|
|
|
1241
1290
|
public async transferDeposit(
|
|
1242
1291
|
amount: BN,
|
|
1243
1292
|
marketIndex: number,
|
|
1244
|
-
|
|
1245
|
-
|
|
1293
|
+
fromSubAccountId: number,
|
|
1294
|
+
toSubAccountId: number
|
|
1246
1295
|
): Promise<TransactionSignature> {
|
|
1247
1296
|
const { txSig } = await this.txSender.send(
|
|
1248
1297
|
wrapInTx(
|
|
1249
1298
|
await this.getTransferDepositIx(
|
|
1250
1299
|
amount,
|
|
1251
1300
|
marketIndex,
|
|
1252
|
-
|
|
1253
|
-
|
|
1301
|
+
fromSubAccountId,
|
|
1302
|
+
toSubAccountId
|
|
1254
1303
|
)
|
|
1255
1304
|
),
|
|
1256
1305
|
[],
|
|
@@ -1262,24 +1311,24 @@ export class ClearingHouse {
|
|
|
1262
1311
|
public async getTransferDepositIx(
|
|
1263
1312
|
amount: BN,
|
|
1264
1313
|
marketIndex: number,
|
|
1265
|
-
|
|
1266
|
-
|
|
1314
|
+
fromSubAccountId: number,
|
|
1315
|
+
toSubAccountId: number
|
|
1267
1316
|
): Promise<TransactionInstruction> {
|
|
1268
1317
|
const fromUser = await getUserAccountPublicKey(
|
|
1269
1318
|
this.program.programId,
|
|
1270
1319
|
this.wallet.publicKey,
|
|
1271
|
-
|
|
1320
|
+
fromSubAccountId
|
|
1272
1321
|
);
|
|
1273
1322
|
const toUser = await getUserAccountPublicKey(
|
|
1274
1323
|
this.program.programId,
|
|
1275
1324
|
this.wallet.publicKey,
|
|
1276
|
-
|
|
1325
|
+
toSubAccountId
|
|
1277
1326
|
);
|
|
1278
1327
|
|
|
1279
1328
|
let remainingAccounts;
|
|
1280
|
-
if (this.users.has(
|
|
1329
|
+
if (this.users.has(fromSubAccountId)) {
|
|
1281
1330
|
remainingAccounts = this.getRemainingAccounts({
|
|
1282
|
-
userAccounts: [this.users.get(
|
|
1331
|
+
userAccounts: [this.users.get(fromSubAccountId).getUserAccount()],
|
|
1283
1332
|
useMarketLastSlotCache: true,
|
|
1284
1333
|
writableSpotMarketIndexes: [marketIndex],
|
|
1285
1334
|
});
|
|
@@ -1287,7 +1336,7 @@ export class ClearingHouse {
|
|
|
1287
1336
|
const userAccountPublicKey = getUserAccountPublicKeySync(
|
|
1288
1337
|
this.program.programId,
|
|
1289
1338
|
this.authority,
|
|
1290
|
-
|
|
1339
|
+
fromSubAccountId
|
|
1291
1340
|
);
|
|
1292
1341
|
|
|
1293
1342
|
const fromUserAccount = (await this.program.account.user.fetch(
|
|
@@ -1331,6 +1380,7 @@ export class ClearingHouse {
|
|
|
1331
1380
|
accounts: {
|
|
1332
1381
|
state: await this.getStatePublicKey(),
|
|
1333
1382
|
spotMarket: spotMarket.pubkey,
|
|
1383
|
+
oracle: spotMarket.oracle,
|
|
1334
1384
|
},
|
|
1335
1385
|
});
|
|
1336
1386
|
}
|
|
@@ -1369,19 +1419,74 @@ export class ClearingHouse {
|
|
|
1369
1419
|
});
|
|
1370
1420
|
}
|
|
1371
1421
|
|
|
1372
|
-
public async
|
|
1422
|
+
public async removePerpLpShares(
|
|
1423
|
+
marketIndex: number,
|
|
1424
|
+
sharesToBurn?: BN
|
|
1425
|
+
): Promise<TransactionSignature> {
|
|
1426
|
+
const { txSig } = await this.txSender.send(
|
|
1427
|
+
wrapInTx(await this.getRemovePerpLpSharesIx(marketIndex, sharesToBurn)),
|
|
1428
|
+
[],
|
|
1429
|
+
this.opts
|
|
1430
|
+
);
|
|
1431
|
+
return txSig;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
public async removePerpLpSharesInExpiringMarket(
|
|
1373
1435
|
marketIndex: number,
|
|
1436
|
+
userAccountPublicKey: PublicKey,
|
|
1374
1437
|
sharesToBurn?: BN
|
|
1375
1438
|
): Promise<TransactionSignature> {
|
|
1376
1439
|
const { txSig } = await this.txSender.send(
|
|
1377
|
-
wrapInTx(
|
|
1440
|
+
wrapInTx(
|
|
1441
|
+
await this.getRemovePerpLpSharesInExpiringMarket(
|
|
1442
|
+
marketIndex,
|
|
1443
|
+
userAccountPublicKey,
|
|
1444
|
+
sharesToBurn
|
|
1445
|
+
)
|
|
1446
|
+
),
|
|
1378
1447
|
[],
|
|
1379
1448
|
this.opts
|
|
1380
1449
|
);
|
|
1381
1450
|
return txSig;
|
|
1382
1451
|
}
|
|
1383
1452
|
|
|
1384
|
-
public async
|
|
1453
|
+
public async getRemovePerpLpSharesInExpiringMarket(
|
|
1454
|
+
marketIndex: number,
|
|
1455
|
+
userAccountPublicKey: PublicKey,
|
|
1456
|
+
sharesToBurn?: BN
|
|
1457
|
+
): Promise<TransactionInstruction> {
|
|
1458
|
+
const userAccount = (await this.program.account.user.fetch(
|
|
1459
|
+
userAccountPublicKey
|
|
1460
|
+
)) as UserAccount;
|
|
1461
|
+
|
|
1462
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1463
|
+
userAccounts: [userAccount],
|
|
1464
|
+
useMarketLastSlotCache: true,
|
|
1465
|
+
writablePerpMarketIndexes: [marketIndex],
|
|
1466
|
+
});
|
|
1467
|
+
|
|
1468
|
+
if (sharesToBurn == undefined) {
|
|
1469
|
+
const perpPosition = userAccount.perpPositions.filter(
|
|
1470
|
+
(position) => position.marketIndex === marketIndex
|
|
1471
|
+
)[0];
|
|
1472
|
+
sharesToBurn = perpPosition.lpShares;
|
|
1473
|
+
console.log('burning lp shares:', sharesToBurn.toString());
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
return this.program.instruction.removePerpLpSharesInExpiringMarket(
|
|
1477
|
+
sharesToBurn,
|
|
1478
|
+
marketIndex,
|
|
1479
|
+
{
|
|
1480
|
+
accounts: {
|
|
1481
|
+
state: await this.getStatePublicKey(),
|
|
1482
|
+
user: userAccountPublicKey,
|
|
1483
|
+
},
|
|
1484
|
+
remainingAccounts: remainingAccounts,
|
|
1485
|
+
}
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
public async getRemovePerpLpSharesIx(
|
|
1385
1490
|
marketIndex: number,
|
|
1386
1491
|
sharesToBurn?: BN
|
|
1387
1492
|
): Promise<TransactionInstruction> {
|
|
@@ -1402,22 +1507,26 @@ export class ClearingHouse {
|
|
|
1402
1507
|
console.log('burning lp shares:', sharesToBurn.toString());
|
|
1403
1508
|
}
|
|
1404
1509
|
|
|
1405
|
-
return this.program.instruction.
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1510
|
+
return this.program.instruction.removePerpLpShares(
|
|
1511
|
+
sharesToBurn,
|
|
1512
|
+
marketIndex,
|
|
1513
|
+
{
|
|
1514
|
+
accounts: {
|
|
1515
|
+
state: await this.getStatePublicKey(),
|
|
1516
|
+
user: userAccountPublicKey,
|
|
1517
|
+
authority: this.wallet.publicKey,
|
|
1518
|
+
},
|
|
1519
|
+
remainingAccounts: remainingAccounts,
|
|
1520
|
+
}
|
|
1521
|
+
);
|
|
1413
1522
|
}
|
|
1414
1523
|
|
|
1415
|
-
public async
|
|
1524
|
+
public async addPerpLpShares(
|
|
1416
1525
|
amount: BN,
|
|
1417
1526
|
marketIndex: number
|
|
1418
1527
|
): Promise<TransactionSignature> {
|
|
1419
1528
|
const { txSig, slot } = await this.txSender.send(
|
|
1420
|
-
wrapInTx(await this.
|
|
1529
|
+
wrapInTx(await this.getAddPerpLpSharesIx(amount, marketIndex)),
|
|
1421
1530
|
[],
|
|
1422
1531
|
this.opts
|
|
1423
1532
|
);
|
|
@@ -1425,7 +1534,7 @@ export class ClearingHouse {
|
|
|
1425
1534
|
return txSig;
|
|
1426
1535
|
}
|
|
1427
1536
|
|
|
1428
|
-
public async
|
|
1537
|
+
public async getAddPerpLpSharesIx(
|
|
1429
1538
|
amount: BN,
|
|
1430
1539
|
marketIndex: number
|
|
1431
1540
|
): Promise<TransactionInstruction> {
|
|
@@ -1436,7 +1545,7 @@ export class ClearingHouse {
|
|
|
1436
1545
|
writablePerpMarketIndexes: [marketIndex],
|
|
1437
1546
|
});
|
|
1438
1547
|
|
|
1439
|
-
return this.program.instruction.
|
|
1548
|
+
return this.program.instruction.addPerpLpShares(amount, marketIndex, {
|
|
1440
1549
|
accounts: {
|
|
1441
1550
|
state: await this.getStatePublicKey(),
|
|
1442
1551
|
user: userAccountPublicKey,
|
|
@@ -1652,6 +1761,34 @@ export class ClearingHouse {
|
|
|
1652
1761
|
});
|
|
1653
1762
|
}
|
|
1654
1763
|
|
|
1764
|
+
public async settleExpiredMarketPoolsToRevenuePool(
|
|
1765
|
+
perpMarketIndex: number
|
|
1766
|
+
): Promise<TransactionSignature> {
|
|
1767
|
+
const perpMarketPublicKey = await getPerpMarketPublicKey(
|
|
1768
|
+
this.program.programId,
|
|
1769
|
+
perpMarketIndex
|
|
1770
|
+
);
|
|
1771
|
+
|
|
1772
|
+
const spotMarketPublicKey = await getSpotMarketPublicKey(
|
|
1773
|
+
this.program.programId,
|
|
1774
|
+
QUOTE_SPOT_MARKET_INDEX
|
|
1775
|
+
);
|
|
1776
|
+
|
|
1777
|
+
const ix =
|
|
1778
|
+
await this.program.instruction.settleExpiredMarketPoolsToRevenuePool({
|
|
1779
|
+
accounts: {
|
|
1780
|
+
state: await this.getStatePublicKey(),
|
|
1781
|
+
admin: this.wallet.publicKey,
|
|
1782
|
+
spotMarket: spotMarketPublicKey,
|
|
1783
|
+
perpMarket: perpMarketPublicKey,
|
|
1784
|
+
},
|
|
1785
|
+
});
|
|
1786
|
+
|
|
1787
|
+
const { txSig } = await this.txSender.send(wrapInTx(ix), [], this.opts);
|
|
1788
|
+
|
|
1789
|
+
return txSig;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1655
1792
|
public async cancelOrder(orderId?: number): Promise<TransactionSignature> {
|
|
1656
1793
|
const { txSig } = await this.txSender.send(
|
|
1657
1794
|
wrapInTx(await this.getCancelOrderIx(orderId)),
|
|
@@ -1716,6 +1853,48 @@ export class ClearingHouse {
|
|
|
1716
1853
|
});
|
|
1717
1854
|
}
|
|
1718
1855
|
|
|
1856
|
+
public async cancelOrders(
|
|
1857
|
+
marketType?: MarketType,
|
|
1858
|
+
marketIndex?: number,
|
|
1859
|
+
direction?: PositionDirection
|
|
1860
|
+
): Promise<TransactionSignature> {
|
|
1861
|
+
const { txSig } = await this.txSender.send(
|
|
1862
|
+
wrapInTx(
|
|
1863
|
+
await this.getCancelOrdersIx(marketType, marketIndex, direction)
|
|
1864
|
+
),
|
|
1865
|
+
[],
|
|
1866
|
+
this.opts
|
|
1867
|
+
);
|
|
1868
|
+
return txSig;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
public async getCancelOrdersIx(
|
|
1872
|
+
marketType: MarketType | null,
|
|
1873
|
+
marketIndex: number | null,
|
|
1874
|
+
direction: PositionDirection | null
|
|
1875
|
+
): Promise<TransactionInstruction> {
|
|
1876
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1877
|
+
|
|
1878
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
1879
|
+
userAccounts: [this.getUserAccount()],
|
|
1880
|
+
useMarketLastSlotCache: true,
|
|
1881
|
+
});
|
|
1882
|
+
|
|
1883
|
+
return await this.program.instruction.cancelOrders(
|
|
1884
|
+
marketType ?? null,
|
|
1885
|
+
marketIndex ?? null,
|
|
1886
|
+
direction ?? null,
|
|
1887
|
+
{
|
|
1888
|
+
accounts: {
|
|
1889
|
+
state: await this.getStatePublicKey(),
|
|
1890
|
+
user: userAccountPublicKey,
|
|
1891
|
+
authority: this.wallet.publicKey,
|
|
1892
|
+
},
|
|
1893
|
+
remainingAccounts,
|
|
1894
|
+
}
|
|
1895
|
+
);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1719
1898
|
public async fillOrder(
|
|
1720
1899
|
userAccountPublicKey: PublicKey,
|
|
1721
1900
|
user: UserAccount,
|
|
@@ -1931,90 +2110,11 @@ export class ClearingHouse {
|
|
|
1931
2110
|
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
1932
2111
|
|
|
1933
2112
|
if (fulfillmentConfig) {
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
remainingAccounts.push({
|
|
1940
|
-
pubkey: fulfillmentConfig.serumProgramId,
|
|
1941
|
-
isWritable: false,
|
|
1942
|
-
isSigner: false,
|
|
1943
|
-
});
|
|
1944
|
-
remainingAccounts.push({
|
|
1945
|
-
pubkey: fulfillmentConfig.serumMarket,
|
|
1946
|
-
isWritable: true,
|
|
1947
|
-
isSigner: false,
|
|
1948
|
-
});
|
|
1949
|
-
remainingAccounts.push({
|
|
1950
|
-
pubkey: fulfillmentConfig.serumRequestQueue,
|
|
1951
|
-
isWritable: true,
|
|
1952
|
-
isSigner: false,
|
|
1953
|
-
});
|
|
1954
|
-
remainingAccounts.push({
|
|
1955
|
-
pubkey: fulfillmentConfig.serumEventQueue,
|
|
1956
|
-
isWritable: true,
|
|
1957
|
-
isSigner: false,
|
|
1958
|
-
});
|
|
1959
|
-
remainingAccounts.push({
|
|
1960
|
-
pubkey: fulfillmentConfig.serumBids,
|
|
1961
|
-
isWritable: true,
|
|
1962
|
-
isSigner: false,
|
|
1963
|
-
});
|
|
1964
|
-
remainingAccounts.push({
|
|
1965
|
-
pubkey: fulfillmentConfig.serumAsks,
|
|
1966
|
-
isWritable: true,
|
|
1967
|
-
isSigner: false,
|
|
1968
|
-
});
|
|
1969
|
-
remainingAccounts.push({
|
|
1970
|
-
pubkey: fulfillmentConfig.serumBaseVault,
|
|
1971
|
-
isWritable: true,
|
|
1972
|
-
isSigner: false,
|
|
1973
|
-
});
|
|
1974
|
-
remainingAccounts.push({
|
|
1975
|
-
pubkey: fulfillmentConfig.serumQuoteVault,
|
|
1976
|
-
isWritable: true,
|
|
1977
|
-
isSigner: false,
|
|
1978
|
-
});
|
|
1979
|
-
remainingAccounts.push({
|
|
1980
|
-
pubkey: fulfillmentConfig.serumOpenOrders,
|
|
1981
|
-
isWritable: true,
|
|
1982
|
-
isSigner: false,
|
|
1983
|
-
});
|
|
1984
|
-
remainingAccounts.push({
|
|
1985
|
-
pubkey: getSerumSignerPublicKey(
|
|
1986
|
-
fulfillmentConfig.serumProgramId,
|
|
1987
|
-
fulfillmentConfig.serumMarket,
|
|
1988
|
-
fulfillmentConfig.serumSignerNonce
|
|
1989
|
-
),
|
|
1990
|
-
isWritable: false,
|
|
1991
|
-
isSigner: false,
|
|
1992
|
-
});
|
|
1993
|
-
remainingAccounts.push({
|
|
1994
|
-
pubkey: this.getSignerPublicKey(),
|
|
1995
|
-
isWritable: false,
|
|
1996
|
-
isSigner: false,
|
|
1997
|
-
});
|
|
1998
|
-
remainingAccounts.push({
|
|
1999
|
-
pubkey: TOKEN_PROGRAM_ID,
|
|
2000
|
-
isWritable: false,
|
|
2001
|
-
isSigner: false,
|
|
2002
|
-
});
|
|
2003
|
-
remainingAccounts.push({
|
|
2004
|
-
pubkey: this.getSpotMarketAccount(marketIndex).vault,
|
|
2005
|
-
isWritable: true,
|
|
2006
|
-
isSigner: false,
|
|
2007
|
-
});
|
|
2008
|
-
remainingAccounts.push({
|
|
2009
|
-
pubkey: this.getQuoteSpotMarketAccount().vault,
|
|
2010
|
-
isWritable: true,
|
|
2011
|
-
isSigner: false,
|
|
2012
|
-
});
|
|
2013
|
-
remainingAccounts.push({
|
|
2014
|
-
pubkey: this.getStateAccount().srmVault,
|
|
2015
|
-
isWritable: false,
|
|
2016
|
-
isSigner: false,
|
|
2017
|
-
});
|
|
2113
|
+
this.addSerumRemainingAccounts(
|
|
2114
|
+
marketIndex,
|
|
2115
|
+
remainingAccounts,
|
|
2116
|
+
fulfillmentConfig
|
|
2117
|
+
);
|
|
2018
2118
|
}
|
|
2019
2119
|
|
|
2020
2120
|
return await this.program.instruction.fillSpotOrder(
|
|
@@ -2035,6 +2135,97 @@ export class ClearingHouse {
|
|
|
2035
2135
|
);
|
|
2036
2136
|
}
|
|
2037
2137
|
|
|
2138
|
+
addSerumRemainingAccounts(
|
|
2139
|
+
marketIndex: number,
|
|
2140
|
+
remainingAccounts: AccountMeta[],
|
|
2141
|
+
fulfillmentConfig: SerumV3FulfillmentConfigAccount
|
|
2142
|
+
) {
|
|
2143
|
+
remainingAccounts.push({
|
|
2144
|
+
pubkey: fulfillmentConfig.pubkey,
|
|
2145
|
+
isWritable: false,
|
|
2146
|
+
isSigner: false,
|
|
2147
|
+
});
|
|
2148
|
+
remainingAccounts.push({
|
|
2149
|
+
pubkey: fulfillmentConfig.serumProgramId,
|
|
2150
|
+
isWritable: false,
|
|
2151
|
+
isSigner: false,
|
|
2152
|
+
});
|
|
2153
|
+
remainingAccounts.push({
|
|
2154
|
+
pubkey: fulfillmentConfig.serumMarket,
|
|
2155
|
+
isWritable: true,
|
|
2156
|
+
isSigner: false,
|
|
2157
|
+
});
|
|
2158
|
+
remainingAccounts.push({
|
|
2159
|
+
pubkey: fulfillmentConfig.serumRequestQueue,
|
|
2160
|
+
isWritable: true,
|
|
2161
|
+
isSigner: false,
|
|
2162
|
+
});
|
|
2163
|
+
remainingAccounts.push({
|
|
2164
|
+
pubkey: fulfillmentConfig.serumEventQueue,
|
|
2165
|
+
isWritable: true,
|
|
2166
|
+
isSigner: false,
|
|
2167
|
+
});
|
|
2168
|
+
remainingAccounts.push({
|
|
2169
|
+
pubkey: fulfillmentConfig.serumBids,
|
|
2170
|
+
isWritable: true,
|
|
2171
|
+
isSigner: false,
|
|
2172
|
+
});
|
|
2173
|
+
remainingAccounts.push({
|
|
2174
|
+
pubkey: fulfillmentConfig.serumAsks,
|
|
2175
|
+
isWritable: true,
|
|
2176
|
+
isSigner: false,
|
|
2177
|
+
});
|
|
2178
|
+
remainingAccounts.push({
|
|
2179
|
+
pubkey: fulfillmentConfig.serumBaseVault,
|
|
2180
|
+
isWritable: true,
|
|
2181
|
+
isSigner: false,
|
|
2182
|
+
});
|
|
2183
|
+
remainingAccounts.push({
|
|
2184
|
+
pubkey: fulfillmentConfig.serumQuoteVault,
|
|
2185
|
+
isWritable: true,
|
|
2186
|
+
isSigner: false,
|
|
2187
|
+
});
|
|
2188
|
+
remainingAccounts.push({
|
|
2189
|
+
pubkey: fulfillmentConfig.serumOpenOrders,
|
|
2190
|
+
isWritable: true,
|
|
2191
|
+
isSigner: false,
|
|
2192
|
+
});
|
|
2193
|
+
remainingAccounts.push({
|
|
2194
|
+
pubkey: getSerumSignerPublicKey(
|
|
2195
|
+
fulfillmentConfig.serumProgramId,
|
|
2196
|
+
fulfillmentConfig.serumMarket,
|
|
2197
|
+
fulfillmentConfig.serumSignerNonce
|
|
2198
|
+
),
|
|
2199
|
+
isWritable: false,
|
|
2200
|
+
isSigner: false,
|
|
2201
|
+
});
|
|
2202
|
+
remainingAccounts.push({
|
|
2203
|
+
pubkey: this.getSignerPublicKey(),
|
|
2204
|
+
isWritable: false,
|
|
2205
|
+
isSigner: false,
|
|
2206
|
+
});
|
|
2207
|
+
remainingAccounts.push({
|
|
2208
|
+
pubkey: TOKEN_PROGRAM_ID,
|
|
2209
|
+
isWritable: false,
|
|
2210
|
+
isSigner: false,
|
|
2211
|
+
});
|
|
2212
|
+
remainingAccounts.push({
|
|
2213
|
+
pubkey: this.getSpotMarketAccount(marketIndex).vault,
|
|
2214
|
+
isWritable: true,
|
|
2215
|
+
isSigner: false,
|
|
2216
|
+
});
|
|
2217
|
+
remainingAccounts.push({
|
|
2218
|
+
pubkey: this.getQuoteSpotMarketAccount().vault,
|
|
2219
|
+
isWritable: true,
|
|
2220
|
+
isSigner: false,
|
|
2221
|
+
});
|
|
2222
|
+
remainingAccounts.push({
|
|
2223
|
+
pubkey: this.getStateAccount().srmVault,
|
|
2224
|
+
isWritable: false,
|
|
2225
|
+
isSigner: false,
|
|
2226
|
+
});
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2038
2229
|
public async triggerOrder(
|
|
2039
2230
|
userAccountPublicKey: PublicKey,
|
|
2040
2231
|
user: UserAccount,
|
|
@@ -2226,6 +2417,171 @@ export class ClearingHouse {
|
|
|
2226
2417
|
);
|
|
2227
2418
|
}
|
|
2228
2419
|
|
|
2420
|
+
public async placeAndTakeSpotOrder(
|
|
2421
|
+
orderParams: OptionalOrderParams,
|
|
2422
|
+
fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
|
|
2423
|
+
makerInfo?: MakerInfo,
|
|
2424
|
+
referrerInfo?: ReferrerInfo
|
|
2425
|
+
): Promise<TransactionSignature> {
|
|
2426
|
+
const { txSig } = await this.txSender.send(
|
|
2427
|
+
wrapInTx(
|
|
2428
|
+
await this.getPlaceAndTakeSpotOrderIx(
|
|
2429
|
+
orderParams,
|
|
2430
|
+
fulfillmentConfig,
|
|
2431
|
+
makerInfo,
|
|
2432
|
+
referrerInfo
|
|
2433
|
+
)
|
|
2434
|
+
),
|
|
2435
|
+
[],
|
|
2436
|
+
this.opts
|
|
2437
|
+
);
|
|
2438
|
+
return txSig;
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
public async getPlaceAndTakeSpotOrderIx(
|
|
2442
|
+
orderParams: OptionalOrderParams,
|
|
2443
|
+
fulfillmentConfig?: SerumV3FulfillmentConfigAccount,
|
|
2444
|
+
makerInfo?: MakerInfo,
|
|
2445
|
+
referrerInfo?: ReferrerInfo
|
|
2446
|
+
): Promise<TransactionInstruction> {
|
|
2447
|
+
orderParams = this.getOrderParams(orderParams, MarketType.SPOT);
|
|
2448
|
+
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
2449
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2450
|
+
|
|
2451
|
+
const userAccounts = [this.getUserAccount()];
|
|
2452
|
+
if (makerInfo !== undefined) {
|
|
2453
|
+
userAccounts.push(makerInfo.makerUserAccount);
|
|
2454
|
+
}
|
|
2455
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2456
|
+
userAccounts,
|
|
2457
|
+
useMarketLastSlotCache: true,
|
|
2458
|
+
writableSpotMarketIndexes: [
|
|
2459
|
+
orderParams.marketIndex,
|
|
2460
|
+
QUOTE_SPOT_MARKET_INDEX,
|
|
2461
|
+
],
|
|
2462
|
+
});
|
|
2463
|
+
|
|
2464
|
+
let makerOrderId = null;
|
|
2465
|
+
if (makerInfo) {
|
|
2466
|
+
makerOrderId = makerInfo.order.orderId;
|
|
2467
|
+
remainingAccounts.push({
|
|
2468
|
+
pubkey: makerInfo.maker,
|
|
2469
|
+
isSigner: false,
|
|
2470
|
+
isWritable: true,
|
|
2471
|
+
});
|
|
2472
|
+
remainingAccounts.push({
|
|
2473
|
+
pubkey: makerInfo.makerStats,
|
|
2474
|
+
isSigner: false,
|
|
2475
|
+
isWritable: true,
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
if (referrerInfo) {
|
|
2480
|
+
remainingAccounts.push({
|
|
2481
|
+
pubkey: referrerInfo.referrer,
|
|
2482
|
+
isWritable: true,
|
|
2483
|
+
isSigner: false,
|
|
2484
|
+
});
|
|
2485
|
+
remainingAccounts.push({
|
|
2486
|
+
pubkey: referrerInfo.referrerStats,
|
|
2487
|
+
isWritable: true,
|
|
2488
|
+
isSigner: false,
|
|
2489
|
+
});
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
if (fulfillmentConfig) {
|
|
2493
|
+
this.addSerumRemainingAccounts(
|
|
2494
|
+
orderParams.marketIndex,
|
|
2495
|
+
remainingAccounts,
|
|
2496
|
+
fulfillmentConfig
|
|
2497
|
+
);
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
return await this.program.instruction.placeAndTakeSpotOrder(
|
|
2501
|
+
orderParams,
|
|
2502
|
+
fulfillmentConfig ? fulfillmentConfig.fulfillmentType : null,
|
|
2503
|
+
makerOrderId,
|
|
2504
|
+
{
|
|
2505
|
+
accounts: {
|
|
2506
|
+
state: await this.getStatePublicKey(),
|
|
2507
|
+
user: userAccountPublicKey,
|
|
2508
|
+
userStats: userStatsPublicKey,
|
|
2509
|
+
authority: this.wallet.publicKey,
|
|
2510
|
+
},
|
|
2511
|
+
remainingAccounts,
|
|
2512
|
+
}
|
|
2513
|
+
);
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
public async placeAndMakeSpotOrder(
|
|
2517
|
+
orderParams: OptionalOrderParams,
|
|
2518
|
+
takerInfo: TakerInfo,
|
|
2519
|
+
referrerInfo?: ReferrerInfo
|
|
2520
|
+
): Promise<TransactionSignature> {
|
|
2521
|
+
const { txSig } = await this.txSender.send(
|
|
2522
|
+
wrapInTx(
|
|
2523
|
+
await this.getPlaceAndMakeSpotOrderIx(
|
|
2524
|
+
orderParams,
|
|
2525
|
+
takerInfo,
|
|
2526
|
+
referrerInfo
|
|
2527
|
+
)
|
|
2528
|
+
),
|
|
2529
|
+
[],
|
|
2530
|
+
this.opts
|
|
2531
|
+
);
|
|
2532
|
+
|
|
2533
|
+
return txSig;
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
public async getPlaceAndMakeSpotOrderIx(
|
|
2537
|
+
orderParams: OptionalOrderParams,
|
|
2538
|
+
takerInfo: TakerInfo,
|
|
2539
|
+
referrerInfo?: ReferrerInfo
|
|
2540
|
+
): Promise<TransactionInstruction> {
|
|
2541
|
+
orderParams = this.getOrderParams(orderParams, MarketType.SPOT);
|
|
2542
|
+
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
2543
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
2544
|
+
|
|
2545
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2546
|
+
userAccounts: [this.getUserAccount(), takerInfo.takerUserAccount],
|
|
2547
|
+
useMarketLastSlotCache: true,
|
|
2548
|
+
writableSpotMarketIndexes: [
|
|
2549
|
+
orderParams.marketIndex,
|
|
2550
|
+
QUOTE_SPOT_MARKET_INDEX,
|
|
2551
|
+
],
|
|
2552
|
+
});
|
|
2553
|
+
|
|
2554
|
+
if (referrerInfo) {
|
|
2555
|
+
remainingAccounts.push({
|
|
2556
|
+
pubkey: referrerInfo.referrer,
|
|
2557
|
+
isWritable: true,
|
|
2558
|
+
isSigner: false,
|
|
2559
|
+
});
|
|
2560
|
+
remainingAccounts.push({
|
|
2561
|
+
pubkey: referrerInfo.referrerStats,
|
|
2562
|
+
isWritable: true,
|
|
2563
|
+
isSigner: false,
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2567
|
+
const takerOrderId = takerInfo.order.orderId;
|
|
2568
|
+
return await this.program.instruction.placeAndMakeSpotOrder(
|
|
2569
|
+
orderParams,
|
|
2570
|
+
takerOrderId,
|
|
2571
|
+
{
|
|
2572
|
+
accounts: {
|
|
2573
|
+
state: await this.getStatePublicKey(),
|
|
2574
|
+
user: userAccountPublicKey,
|
|
2575
|
+
userStats: userStatsPublicKey,
|
|
2576
|
+
taker: takerInfo.taker,
|
|
2577
|
+
takerStats: takerInfo.takerStats,
|
|
2578
|
+
authority: this.wallet.publicKey,
|
|
2579
|
+
},
|
|
2580
|
+
remainingAccounts,
|
|
2581
|
+
}
|
|
2582
|
+
);
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2229
2585
|
/**
|
|
2230
2586
|
* Close an entire position. If you want to reduce a position, use the {@link openPosition} method in the opposite direction of the current position.
|
|
2231
2587
|
* @param marketIndex
|
|
@@ -2321,46 +2677,6 @@ export class ClearingHouse {
|
|
|
2321
2677
|
});
|
|
2322
2678
|
}
|
|
2323
2679
|
|
|
2324
|
-
public async settleExpiredPosition(
|
|
2325
|
-
settleeUserAccountPublicKey: PublicKey,
|
|
2326
|
-
settleeUserAccount: UserAccount,
|
|
2327
|
-
marketIndex: number
|
|
2328
|
-
): Promise<TransactionSignature> {
|
|
2329
|
-
const { txSig } = await this.txSender.send(
|
|
2330
|
-
wrapInTx(
|
|
2331
|
-
await this.getSettleExpiredPositionIx(
|
|
2332
|
-
settleeUserAccountPublicKey,
|
|
2333
|
-
settleeUserAccount,
|
|
2334
|
-
marketIndex
|
|
2335
|
-
)
|
|
2336
|
-
),
|
|
2337
|
-
[],
|
|
2338
|
-
this.opts
|
|
2339
|
-
);
|
|
2340
|
-
return txSig;
|
|
2341
|
-
}
|
|
2342
|
-
|
|
2343
|
-
public async getSettleExpiredPositionIx(
|
|
2344
|
-
settleeUserAccountPublicKey: PublicKey,
|
|
2345
|
-
settleeUserAccount: UserAccount,
|
|
2346
|
-
marketIndex: number
|
|
2347
|
-
): Promise<TransactionInstruction> {
|
|
2348
|
-
const remainingAccounts = this.getRemainingAccounts({
|
|
2349
|
-
userAccounts: [settleeUserAccount],
|
|
2350
|
-
writablePerpMarketIndexes: [marketIndex],
|
|
2351
|
-
writableSpotMarketIndexes: [QUOTE_SPOT_MARKET_INDEX],
|
|
2352
|
-
});
|
|
2353
|
-
|
|
2354
|
-
return await this.program.instruction.settleExpiredPosition(marketIndex, {
|
|
2355
|
-
accounts: {
|
|
2356
|
-
state: await this.getStatePublicKey(),
|
|
2357
|
-
authority: this.wallet.publicKey,
|
|
2358
|
-
user: settleeUserAccountPublicKey,
|
|
2359
|
-
},
|
|
2360
|
-
remainingAccounts: remainingAccounts,
|
|
2361
|
-
});
|
|
2362
|
-
}
|
|
2363
|
-
|
|
2364
2680
|
public async liquidatePerp(
|
|
2365
2681
|
userAccountPublicKey: PublicKey,
|
|
2366
2682
|
userAccount: UserAccount,
|
|
@@ -2660,7 +2976,7 @@ export class ClearingHouse {
|
|
|
2660
2976
|
liquidator: liquidatorPublicKey,
|
|
2661
2977
|
liquidatorStats: liquidatorStatsPublicKey,
|
|
2662
2978
|
spotMarketVault: spotMarket.vault,
|
|
2663
|
-
insuranceFundVault: spotMarket.
|
|
2979
|
+
insuranceFundVault: spotMarket.insuranceFund.vault,
|
|
2664
2980
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2665
2981
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2666
2982
|
},
|
|
@@ -2717,7 +3033,7 @@ export class ClearingHouse {
|
|
|
2717
3033
|
liquidatorStats: liquidatorStatsPublicKey,
|
|
2718
3034
|
liquidator: liquidatorPublicKey,
|
|
2719
3035
|
spotMarketVault: spotMarket.vault,
|
|
2720
|
-
insuranceFundVault: spotMarket.
|
|
3036
|
+
insuranceFundVault: spotMarket.insuranceFund.vault,
|
|
2721
3037
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2722
3038
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2723
3039
|
},
|
|
@@ -2726,11 +3042,11 @@ export class ClearingHouse {
|
|
|
2726
3042
|
}
|
|
2727
3043
|
|
|
2728
3044
|
public async updateFundingRate(
|
|
2729
|
-
|
|
2730
|
-
|
|
3045
|
+
perpMarketIndex: number,
|
|
3046
|
+
oracle: PublicKey
|
|
2731
3047
|
): Promise<TransactionSignature> {
|
|
2732
3048
|
const { txSig } = await this.txSender.send(
|
|
2733
|
-
wrapInTx(await this.getUpdateFundingRateIx(
|
|
3049
|
+
wrapInTx(await this.getUpdateFundingRateIx(perpMarketIndex, oracle)),
|
|
2734
3050
|
[],
|
|
2735
3051
|
this.opts
|
|
2736
3052
|
);
|
|
@@ -2738,13 +3054,17 @@ export class ClearingHouse {
|
|
|
2738
3054
|
}
|
|
2739
3055
|
|
|
2740
3056
|
public async getUpdateFundingRateIx(
|
|
2741
|
-
|
|
2742
|
-
|
|
3057
|
+
perpMarketIndex: number,
|
|
3058
|
+
oracle: PublicKey
|
|
2743
3059
|
): Promise<TransactionInstruction> {
|
|
2744
|
-
|
|
3060
|
+
const perpMarketPublicKey = await getPerpMarketPublicKey(
|
|
3061
|
+
this.program.programId,
|
|
3062
|
+
perpMarketIndex
|
|
3063
|
+
);
|
|
3064
|
+
return await this.program.instruction.updateFundingRate(perpMarketIndex, {
|
|
2745
3065
|
accounts: {
|
|
2746
3066
|
state: await this.getStatePublicKey(),
|
|
2747
|
-
|
|
3067
|
+
perpMarket: perpMarketPublicKey,
|
|
2748
3068
|
oracle: oracle,
|
|
2749
3069
|
},
|
|
2750
3070
|
});
|
|
@@ -2793,7 +3113,7 @@ export class ClearingHouse {
|
|
|
2793
3113
|
this.eventEmitter.emit(eventName, data);
|
|
2794
3114
|
}
|
|
2795
3115
|
|
|
2796
|
-
public
|
|
3116
|
+
public getOracleDataForPerpMarket(marketIndex: number): OraclePriceData {
|
|
2797
3117
|
const oracleKey = this.getPerpMarketAccount(marketIndex).amm.oracle;
|
|
2798
3118
|
const oracleData = this.getOraclePriceDataAndSlot(oracleKey).data;
|
|
2799
3119
|
|
|
@@ -2870,7 +3190,7 @@ export class ClearingHouse {
|
|
|
2870
3190
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2871
3191
|
authority: this.wallet.publicKey,
|
|
2872
3192
|
spotMarketVault: spotMarket.vault,
|
|
2873
|
-
insuranceFundVault: spotMarket.
|
|
3193
|
+
insuranceFundVault: spotMarket.insuranceFund.vault,
|
|
2874
3194
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2875
3195
|
userTokenAccount: collateralAccountPublicKey,
|
|
2876
3196
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
@@ -2906,7 +3226,7 @@ export class ClearingHouse {
|
|
|
2906
3226
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2907
3227
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2908
3228
|
authority: this.wallet.publicKey,
|
|
2909
|
-
insuranceFundVault: spotMarketAccount.
|
|
3229
|
+
insuranceFundVault: spotMarketAccount.insuranceFund.vault,
|
|
2910
3230
|
},
|
|
2911
3231
|
remainingAccounts,
|
|
2912
3232
|
}
|
|
@@ -2938,7 +3258,7 @@ export class ClearingHouse {
|
|
|
2938
3258
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2939
3259
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2940
3260
|
authority: this.wallet.publicKey,
|
|
2941
|
-
insuranceFundVault: spotMarketAccount.
|
|
3261
|
+
insuranceFundVault: spotMarketAccount.insuranceFund.vault,
|
|
2942
3262
|
},
|
|
2943
3263
|
remainingAccounts,
|
|
2944
3264
|
}
|
|
@@ -2969,7 +3289,7 @@ export class ClearingHouse {
|
|
|
2969
3289
|
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2970
3290
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
2971
3291
|
authority: this.wallet.publicKey,
|
|
2972
|
-
insuranceFundVault: spotMarketAccount.
|
|
3292
|
+
insuranceFundVault: spotMarketAccount.insuranceFund.vault,
|
|
2973
3293
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2974
3294
|
userTokenAccount: collateralAccountPublicKey,
|
|
2975
3295
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
@@ -2995,7 +3315,7 @@ export class ClearingHouse {
|
|
|
2995
3315
|
spotMarket: spotMarketAccount.pubkey,
|
|
2996
3316
|
spotMarketVault: spotMarketAccount.vault,
|
|
2997
3317
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2998
|
-
insuranceFundVault: spotMarketAccount.
|
|
3318
|
+
insuranceFundVault: spotMarketAccount.insuranceFund.vault,
|
|
2999
3319
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
3000
3320
|
},
|
|
3001
3321
|
remainingAccounts,
|
|
@@ -3037,7 +3357,7 @@ export class ClearingHouse {
|
|
|
3037
3357
|
state: await this.getStatePublicKey(),
|
|
3038
3358
|
authority: this.wallet.publicKey,
|
|
3039
3359
|
spotMarketVault: spotMarket.vault,
|
|
3040
|
-
insuranceFundVault: spotMarket.
|
|
3360
|
+
insuranceFundVault: spotMarket.insuranceFund.vault,
|
|
3041
3361
|
clearingHouseSigner: this.getSignerPublicKey(),
|
|
3042
3362
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
3043
3363
|
},
|