@drift-labs/sdk 0.2.0-master.0 → 0.2.0-master.11
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/admin.d.ts +8 -5
- package/lib/admin.js +43 -11
- package/lib/clearingHouse.d.ts +28 -18
- package/lib/clearingHouse.js +366 -143
- package/lib/clearingHouseUser.d.ts +2 -2
- package/lib/clearingHouseUser.js +8 -17
- package/lib/config.js +1 -1
- package/lib/constants/banks.js +9 -2
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/factory/bigNum.d.ts +8 -2
- package/lib/factory/bigNum.js +14 -6
- package/lib/idl/clearing_house.json +805 -202
- package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/lib/index.d.ts +3 -2
- package/lib/index.js +7 -2
- package/lib/math/amm.d.ts +6 -1
- package/lib/math/amm.js +124 -41
- package/lib/math/auction.js +4 -1
- package/lib/math/orders.d.ts +2 -2
- package/lib/math/orders.js +18 -11
- package/lib/math/position.js +3 -1
- package/lib/math/repeg.js +1 -1
- package/lib/math/trade.d.ts +1 -1
- package/lib/math/trade.js +7 -10
- package/lib/orderParams.d.ts +14 -5
- package/lib/orderParams.js +8 -96
- package/lib/orders.d.ts +1 -2
- package/lib/orders.js +6 -85
- package/lib/slot/SlotSubscriber.d.ts +7 -0
- package/lib/slot/SlotSubscriber.js +3 -0
- package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +7 -5
- package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +41 -40
- package/lib/tx/utils.js +1 -1
- package/lib/types.d.ts +137 -14
- package/lib/types.js +53 -1
- package/lib/util/computeUnits.js +1 -1
- package/package.json +3 -3
- package/src/accounts/bulkAccountLoader.js +197 -0
- package/src/accounts/bulkUserSubscription.js +33 -0
- package/src/accounts/fetch.js +29 -0
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
- package/src/accounts/pollingOracleSubscriber.js +93 -0
- package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
- package/src/accounts/pollingUserAccountSubscriber.js +132 -0
- package/src/accounts/types.js +10 -0
- package/src/accounts/utils.js +7 -0
- package/src/accounts/webSocketAccountSubscriber.js +93 -0
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
- package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
- package/src/addresses/marketAddresses.js +26 -0
- package/src/addresses/pda.js +104 -0
- package/src/admin.ts +66 -14
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +558 -230
- package/src/clearingHouseUser.ts +12 -23
- package/src/config.ts +1 -1
- package/src/constants/banks.ts +9 -2
- package/src/constants/numericConstants.ts +2 -0
- package/src/events/eventList.js +77 -0
- package/src/events/eventSubscriber.js +139 -0
- package/src/events/fetchLogs.js +50 -0
- package/src/events/pollingLogProvider.js +64 -0
- package/src/events/sort.js +44 -0
- package/src/events/txEventCache.js +71 -0
- package/src/events/types.js +20 -0
- package/src/events/webSocketLogProvider.js +41 -0
- package/src/examples/makeTradeExample.js +80 -0
- package/src/factory/bigNum.js +364 -0
- package/src/factory/bigNum.ts +26 -9
- package/src/factory/oracleClient.js +20 -0
- package/src/idl/clearing_house.json +805 -202
- package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/src/index.js +100 -0
- package/src/index.ts +3 -2
- package/src/math/amm.js +369 -0
- package/src/math/amm.ts +207 -52
- package/src/math/auction.js +42 -0
- package/src/math/auction.ts +5 -1
- package/src/math/bankBalance.js +75 -0
- package/src/math/conversion.js +11 -0
- package/src/math/funding.js +248 -0
- package/src/math/market.js +57 -0
- package/src/math/oracles.js +26 -0
- package/src/math/orders.js +110 -0
- package/src/math/orders.ts +17 -13
- package/src/math/position.js +140 -0
- package/src/math/position.ts +5 -1
- package/src/math/repeg.js +128 -0
- package/src/math/repeg.ts +2 -1
- package/src/math/state.js +15 -0
- package/src/math/trade.js +253 -0
- package/src/math/trade.ts +23 -25
- package/src/math/utils.js +0 -1
- package/src/mockUSDCFaucet.js +280 -0
- package/src/oracles/oracleClientCache.js +19 -0
- package/src/oracles/pythClient.js +46 -0
- package/src/oracles/quoteAssetOracleClient.js +32 -0
- package/src/oracles/switchboardClient.js +69 -0
- package/src/oracles/types.js +2 -0
- package/src/orderParams.js +20 -0
- package/src/orderParams.ts +20 -141
- package/src/orders.js +134 -0
- package/src/orders.ts +7 -131
- package/src/slot/SlotSubscriber.js +39 -0
- package/src/slot/SlotSubscriber.ts +11 -1
- package/src/token/index.js +38 -0
- package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +48 -59
- package/src/tx/retryTxSender.js +188 -0
- package/src/tx/types.js +2 -0
- package/src/tx/utils.js +17 -0
- package/src/tx/utils.ts +1 -1
- package/src/types.js +114 -0
- package/src/types.ts +132 -16
- package/src/userName.js +20 -0
- package/src/util/computeUnits.ts +1 -1
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/src/wallet.js +35 -0
- package/src/util/computeUnits.js +0 -17
- package/src/util/computeUnits.js.map +0 -1
package/lib/clearingHouse.js
CHANGED
|
@@ -29,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.ClearingHouse = void 0;
|
|
30
30
|
const anchor_1 = require("@project-serum/anchor");
|
|
31
31
|
const spl_token_1 = require("@solana/spl-token");
|
|
32
|
+
const types_1 = require("./types");
|
|
32
33
|
const anchor = __importStar(require("@project-serum/anchor"));
|
|
33
34
|
const clearing_house_json_1 = __importDefault(require("./idl/clearing_house.json"));
|
|
34
35
|
const web3_js_1 = require("@solana/web3.js");
|
|
@@ -42,7 +43,6 @@ const pollingClearingHouseAccountSubscriber_1 = require("./accounts/pollingClear
|
|
|
42
43
|
const webSocketClearingHouseAccountSubscriber_1 = require("./accounts/webSocketClearingHouseAccountSubscriber");
|
|
43
44
|
const retryTxSender_1 = require("./tx/retryTxSender");
|
|
44
45
|
const clearingHouseUser_1 = require("./clearingHouseUser");
|
|
45
|
-
const orderParams_1 = require("./orderParams");
|
|
46
46
|
const config_1 = require("./config");
|
|
47
47
|
/**
|
|
48
48
|
* # ClearingHouse
|
|
@@ -371,13 +371,19 @@ class ClearingHouse {
|
|
|
371
371
|
});
|
|
372
372
|
}
|
|
373
373
|
else {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
374
|
+
const bankAccount = this.getBankAccount(bankIndex);
|
|
375
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
376
|
+
remainingAccounts.push({
|
|
377
|
+
pubkey: bankAccount.oracle,
|
|
377
378
|
isSigner: false,
|
|
378
|
-
isWritable:
|
|
379
|
-
}
|
|
380
|
-
|
|
379
|
+
isWritable: false,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
remainingAccounts.push({
|
|
383
|
+
pubkey: bankAccount.pubkey,
|
|
384
|
+
isSigner: false,
|
|
385
|
+
isWritable: true,
|
|
386
|
+
});
|
|
381
387
|
}
|
|
382
388
|
const bank = this.getBankAccount(bankIndex);
|
|
383
389
|
return await this.program.instruction.deposit(bankIndex, amount, reduceOnly, {
|
|
@@ -413,10 +419,10 @@ class ClearingHouse {
|
|
|
413
419
|
const { txSig } = await this.txSender.send(tx, []);
|
|
414
420
|
return [txSig, userAccountPublicKey];
|
|
415
421
|
}
|
|
416
|
-
async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME,
|
|
417
|
-
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await
|
|
422
|
+
async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME, bankIndex, tokenFaucet, amount) {
|
|
423
|
+
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
|
|
418
424
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
|
|
419
|
-
const depositCollateralIx = await this.getDepositInstruction(amount,
|
|
425
|
+
const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, associateTokenPublicKey, userId, false, false);
|
|
420
426
|
const tx = new web3_js_1.Transaction()
|
|
421
427
|
.add(createAssociatedAccountIx)
|
|
422
428
|
.add(mintToIx)
|
|
@@ -482,17 +488,25 @@ class ClearingHouse {
|
|
|
482
488
|
});
|
|
483
489
|
}
|
|
484
490
|
async openPosition(direction, amount, marketIndex, limitPrice) {
|
|
485
|
-
return await this.placeAndTake(
|
|
491
|
+
return await this.placeAndTake({
|
|
492
|
+
orderType: types_1.OrderType.MARKET,
|
|
493
|
+
marketIndex,
|
|
494
|
+
direction,
|
|
495
|
+
baseAssetAmount: amount,
|
|
496
|
+
price: limitPrice,
|
|
497
|
+
});
|
|
486
498
|
}
|
|
487
499
|
async placeOrder(orderParams) {
|
|
488
500
|
const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceOrderIx(orderParams)), [], this.opts);
|
|
489
501
|
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
490
502
|
return txSig;
|
|
491
503
|
}
|
|
504
|
+
getOrderParams(optionalOrderParams) {
|
|
505
|
+
return Object.assign({}, types_1.DefaultOrderParams, optionalOrderParams);
|
|
506
|
+
}
|
|
492
507
|
async getPlaceOrderIx(orderParams) {
|
|
508
|
+
orderParams = this.getOrderParams(orderParams);
|
|
493
509
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
494
|
-
const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
|
|
495
|
-
.oracle;
|
|
496
510
|
const remainingAccounts = this.getRemainingAccounts({
|
|
497
511
|
writableMarketIndex: orderParams.marketIndex,
|
|
498
512
|
});
|
|
@@ -501,26 +515,10 @@ class ClearingHouse {
|
|
|
501
515
|
state: await this.getStatePublicKey(),
|
|
502
516
|
user: userAccountPublicKey,
|
|
503
517
|
authority: this.wallet.publicKey,
|
|
504
|
-
oracle: priceOracle,
|
|
505
518
|
},
|
|
506
519
|
remainingAccounts,
|
|
507
520
|
});
|
|
508
521
|
}
|
|
509
|
-
async expireOrders(userAccountPublicKey) {
|
|
510
|
-
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getExpireOrdersIx(userAccountPublicKey)), [], this.opts);
|
|
511
|
-
return txSig;
|
|
512
|
-
}
|
|
513
|
-
async getExpireOrdersIx(userAccountPublicKey) {
|
|
514
|
-
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
515
|
-
return await this.program.instruction.expireOrders({
|
|
516
|
-
accounts: {
|
|
517
|
-
state: await this.getStatePublicKey(),
|
|
518
|
-
filler: fillerPublicKey,
|
|
519
|
-
user: userAccountPublicKey,
|
|
520
|
-
authority: this.wallet.publicKey,
|
|
521
|
-
},
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
522
|
async updateAMMs(marketIndexes) {
|
|
525
523
|
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateAMMsIx(marketIndexes)), [], this.opts);
|
|
526
524
|
return txSig;
|
|
@@ -561,15 +559,12 @@ class ClearingHouse {
|
|
|
561
559
|
}
|
|
562
560
|
async getCancelOrderIx(orderId) {
|
|
563
561
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
564
|
-
const order = this.getOrder(orderId);
|
|
565
|
-
const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
|
|
566
562
|
const remainingAccounts = this.getRemainingAccounts({});
|
|
567
|
-
return await this.program.instruction.cancelOrder(orderId, {
|
|
563
|
+
return await this.program.instruction.cancelOrder(orderId !== null && orderId !== void 0 ? orderId : null, {
|
|
568
564
|
accounts: {
|
|
569
565
|
state: await this.getStatePublicKey(),
|
|
570
566
|
user: userAccountPublicKey,
|
|
571
567
|
authority: this.wallet.publicKey,
|
|
572
|
-
oracle,
|
|
573
568
|
},
|
|
574
569
|
remainingAccounts,
|
|
575
570
|
});
|
|
@@ -593,117 +588,150 @@ class ClearingHouse {
|
|
|
593
588
|
remainingAccounts,
|
|
594
589
|
});
|
|
595
590
|
}
|
|
596
|
-
async
|
|
597
|
-
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.
|
|
591
|
+
async fillOrder(userAccountPublicKey, user, order, makerInfo) {
|
|
592
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getFillOrderIx(userAccountPublicKey, user, order, makerInfo)), [], this.opts);
|
|
598
593
|
return txSig;
|
|
599
594
|
}
|
|
600
|
-
async
|
|
601
|
-
const
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
return await this.program.instruction.cancelAllOrders(bestEffort, {
|
|
612
|
-
accounts: {
|
|
613
|
-
state: await this.getStatePublicKey(),
|
|
614
|
-
user: userAccountPublicKey,
|
|
615
|
-
authority: this.wallet.publicKey,
|
|
616
|
-
},
|
|
617
|
-
remainingAccounts,
|
|
595
|
+
async getFillOrderIx(userAccountPublicKey, userAccount, order, makerInfo) {
|
|
596
|
+
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
597
|
+
const marketIndex = order.marketIndex;
|
|
598
|
+
const marketAccount = this.getMarketAccount(marketIndex);
|
|
599
|
+
const oracleAccountMap = new Map();
|
|
600
|
+
const bankAccountMap = new Map();
|
|
601
|
+
const marketAccountMap = new Map();
|
|
602
|
+
marketAccountMap.set(marketIndex.toNumber(), {
|
|
603
|
+
pubkey: marketAccount.pubkey,
|
|
604
|
+
isWritable: true,
|
|
605
|
+
isSigner: false,
|
|
618
606
|
});
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
607
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
608
|
+
pubkey: marketAccount.amm.oracle,
|
|
609
|
+
isWritable: false,
|
|
610
|
+
isSigner: false,
|
|
611
|
+
});
|
|
612
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
613
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
614
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
615
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
616
|
+
pubkey: bankAccount.pubkey,
|
|
617
|
+
isSigner: false,
|
|
618
|
+
isWritable: true,
|
|
619
|
+
});
|
|
620
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
621
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
622
|
+
pubkey: bankAccount.oracle,
|
|
623
|
+
isSigner: false,
|
|
624
|
+
isWritable: false,
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
for (const position of userAccount.positions) {
|
|
630
|
+
if (!(0, position_1.positionIsAvailable)(position) &&
|
|
631
|
+
!position.marketIndex.eq(order.marketIndex)) {
|
|
632
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
633
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
634
|
+
pubkey: market.pubkey,
|
|
635
|
+
isWritable: true,
|
|
636
|
+
isSigner: false,
|
|
637
|
+
});
|
|
638
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
639
|
+
pubkey: market.amm.oracle,
|
|
640
|
+
isWritable: false,
|
|
641
|
+
isSigner: false,
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
const remainingAccounts = [
|
|
646
|
+
...oracleAccountMap.values(),
|
|
647
|
+
...bankAccountMap.values(),
|
|
648
|
+
...marketAccountMap.values(),
|
|
649
|
+
];
|
|
650
|
+
if (makerInfo) {
|
|
629
651
|
remainingAccounts.push({
|
|
630
|
-
pubkey:
|
|
631
|
-
isWritable:
|
|
652
|
+
pubkey: makerInfo.maker,
|
|
653
|
+
isWritable: true,
|
|
632
654
|
isSigner: false,
|
|
633
655
|
});
|
|
634
656
|
}
|
|
635
|
-
|
|
657
|
+
const orderId = order.orderId;
|
|
658
|
+
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
659
|
+
return await this.program.instruction.fillOrder(orderId, makerOrderId, {
|
|
636
660
|
accounts: {
|
|
637
661
|
state: await this.getStatePublicKey(),
|
|
662
|
+
filler: fillerPublicKey,
|
|
638
663
|
user: userAccountPublicKey,
|
|
639
664
|
authority: this.wallet.publicKey,
|
|
640
665
|
},
|
|
641
666
|
remainingAccounts,
|
|
642
667
|
});
|
|
643
668
|
}
|
|
644
|
-
async
|
|
645
|
-
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.
|
|
669
|
+
async triggerOrder(userAccountPublicKey, user, order) {
|
|
670
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getTriggerOrderIx(userAccountPublicKey, user, order)), [], this.opts);
|
|
646
671
|
return txSig;
|
|
647
672
|
}
|
|
648
|
-
async
|
|
673
|
+
async getTriggerOrderIx(userAccountPublicKey, userAccount, order) {
|
|
649
674
|
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
650
675
|
const marketIndex = order.marketIndex;
|
|
651
676
|
const marketAccount = this.getMarketAccount(marketIndex);
|
|
652
|
-
const
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
677
|
+
const oracleAccountMap = new Map();
|
|
678
|
+
const bankAccountMap = new Map();
|
|
679
|
+
const marketAccountMap = new Map();
|
|
680
|
+
marketAccountMap.set(marketIndex.toNumber(), {
|
|
681
|
+
pubkey: marketAccount.pubkey,
|
|
682
|
+
isWritable: true,
|
|
683
|
+
isSigner: false,
|
|
684
|
+
});
|
|
685
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
686
|
+
pubkey: marketAccount.amm.oracle,
|
|
687
|
+
isWritable: false,
|
|
688
|
+
isSigner: false,
|
|
689
|
+
});
|
|
690
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
691
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
692
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
693
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
694
|
+
pubkey: bankAccount.pubkey,
|
|
695
|
+
isSigner: false,
|
|
696
|
+
isWritable: true,
|
|
697
|
+
});
|
|
698
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
699
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
700
|
+
pubkey: bankAccount.oracle,
|
|
701
|
+
isSigner: false,
|
|
702
|
+
isWritable: false,
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
674
707
|
for (const position of userAccount.positions) {
|
|
675
708
|
if (!(0, position_1.positionIsAvailable)(position) &&
|
|
676
709
|
!position.marketIndex.eq(order.marketIndex)) {
|
|
677
710
|
const market = this.getMarketAccount(position.marketIndex);
|
|
678
|
-
|
|
711
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
679
712
|
pubkey: market.pubkey,
|
|
680
|
-
isWritable:
|
|
713
|
+
isWritable: true,
|
|
681
714
|
isSigner: false,
|
|
682
715
|
});
|
|
683
|
-
|
|
716
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
684
717
|
pubkey: market.amm.oracle,
|
|
685
718
|
isWritable: false,
|
|
686
719
|
isSigner: false,
|
|
687
720
|
});
|
|
688
721
|
}
|
|
689
722
|
}
|
|
690
|
-
const remainingAccounts =
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
isSigner: false,
|
|
696
|
-
});
|
|
697
|
-
}
|
|
723
|
+
const remainingAccounts = [
|
|
724
|
+
...oracleAccountMap.values(),
|
|
725
|
+
...bankAccountMap.values(),
|
|
726
|
+
...marketAccountMap.values(),
|
|
727
|
+
];
|
|
698
728
|
const orderId = order.orderId;
|
|
699
|
-
|
|
700
|
-
return await this.program.instruction.fillOrder(orderId, makerOrderId, {
|
|
729
|
+
return await this.program.instruction.triggerOrder(orderId, {
|
|
701
730
|
accounts: {
|
|
702
731
|
state: await this.getStatePublicKey(),
|
|
703
732
|
filler: fillerPublicKey,
|
|
704
733
|
user: userAccountPublicKey,
|
|
705
734
|
authority: this.wallet.publicKey,
|
|
706
|
-
oracle: oracle,
|
|
707
735
|
},
|
|
708
736
|
remainingAccounts,
|
|
709
737
|
});
|
|
@@ -714,9 +742,8 @@ class ClearingHouse {
|
|
|
714
742
|
return txSig;
|
|
715
743
|
}
|
|
716
744
|
async getPlaceAndTakeIx(orderParams, makerInfo) {
|
|
745
|
+
orderParams = this.getOrderParams(orderParams);
|
|
717
746
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
718
|
-
const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
|
|
719
|
-
.oracle;
|
|
720
747
|
const remainingAccounts = this.getRemainingAccounts({
|
|
721
748
|
writableMarketIndex: orderParams.marketIndex,
|
|
722
749
|
writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
|
|
@@ -735,7 +762,34 @@ class ClearingHouse {
|
|
|
735
762
|
state: await this.getStatePublicKey(),
|
|
736
763
|
user: userAccountPublicKey,
|
|
737
764
|
authority: this.wallet.publicKey,
|
|
738
|
-
|
|
765
|
+
},
|
|
766
|
+
remainingAccounts,
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
async placeAndMake(orderParams, takerInfo) {
|
|
770
|
+
const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceAndMakeIx(orderParams, takerInfo)), [], this.opts);
|
|
771
|
+
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
772
|
+
return txSig;
|
|
773
|
+
}
|
|
774
|
+
async getPlaceAndMakeIx(orderParams, takerInfo) {
|
|
775
|
+
orderParams = this.getOrderParams(orderParams);
|
|
776
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
777
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
778
|
+
writableMarketIndex: orderParams.marketIndex,
|
|
779
|
+
writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
|
|
780
|
+
});
|
|
781
|
+
const takerOrderId = takerInfo.order.orderId;
|
|
782
|
+
remainingAccounts.push({
|
|
783
|
+
pubkey: takerInfo.taker,
|
|
784
|
+
isSigner: false,
|
|
785
|
+
isWritable: true,
|
|
786
|
+
});
|
|
787
|
+
return await this.program.instruction.placeAndMake(orderParams, takerOrderId, {
|
|
788
|
+
accounts: {
|
|
789
|
+
state: await this.getStatePublicKey(),
|
|
790
|
+
user: userAccountPublicKey,
|
|
791
|
+
taker: takerInfo.taker,
|
|
792
|
+
authority: this.wallet.publicKey,
|
|
739
793
|
},
|
|
740
794
|
remainingAccounts,
|
|
741
795
|
});
|
|
@@ -750,7 +804,13 @@ class ClearingHouse {
|
|
|
750
804
|
if (!userPosition) {
|
|
751
805
|
throw Error(`No position in market ${marketIndex.toString()}`);
|
|
752
806
|
}
|
|
753
|
-
return await this.placeAndTake(
|
|
807
|
+
return await this.placeAndTake({
|
|
808
|
+
orderType: types_1.OrderType.MARKET,
|
|
809
|
+
marketIndex,
|
|
810
|
+
direction: (0, position_1.findDirectionToClose)(userPosition),
|
|
811
|
+
baseAssetAmount: userPosition.baseAssetAmount,
|
|
812
|
+
reduceOnly: true,
|
|
813
|
+
});
|
|
754
814
|
}
|
|
755
815
|
async settlePNLs(users, marketIndex) {
|
|
756
816
|
const ixs = [];
|
|
@@ -831,54 +891,217 @@ class ClearingHouse {
|
|
|
831
891
|
remainingAccounts: remainingAccounts,
|
|
832
892
|
});
|
|
833
893
|
}
|
|
834
|
-
async
|
|
835
|
-
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.
|
|
894
|
+
async liquidatePerp(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
|
|
895
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount)), [], this.opts);
|
|
836
896
|
return txSig;
|
|
837
897
|
}
|
|
838
|
-
async
|
|
839
|
-
const
|
|
840
|
-
const
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
898
|
+
async getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
|
|
899
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
900
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
901
|
+
writableMarketIndex: marketIndex,
|
|
902
|
+
userAccount,
|
|
903
|
+
});
|
|
904
|
+
return await this.program.instruction.liquidatePerp(marketIndex, maxBaseAssetAmount, {
|
|
905
|
+
accounts: {
|
|
906
|
+
state: await this.getStatePublicKey(),
|
|
907
|
+
authority: this.wallet.publicKey,
|
|
908
|
+
user: userAccountPublicKey,
|
|
909
|
+
liquidator: liquidatorPublicKey,
|
|
846
910
|
},
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
911
|
+
remainingAccounts: remainingAccounts,
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
async liquidateBorrow(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
915
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
|
|
916
|
+
return txSig;
|
|
917
|
+
}
|
|
918
|
+
async getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
919
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
920
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
921
|
+
userAccount,
|
|
922
|
+
writableBankIndexes: [liabilityBankIndex, assetBankIndex],
|
|
923
|
+
});
|
|
924
|
+
return await this.program.instruction.liquidateBorrow(assetBankIndex, liabilityBankIndex, maxLiabilityTransfer, {
|
|
925
|
+
accounts: {
|
|
926
|
+
state: await this.getStatePublicKey(),
|
|
927
|
+
authority: this.wallet.publicKey,
|
|
928
|
+
user: userAccountPublicKey,
|
|
929
|
+
liquidator: liquidatorPublicKey,
|
|
930
|
+
},
|
|
931
|
+
remainingAccounts: remainingAccounts,
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
async liquidateBorrowForPerpPnl(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
935
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
|
|
936
|
+
return txSig;
|
|
937
|
+
}
|
|
938
|
+
async getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
939
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
940
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
941
|
+
userAccount,
|
|
942
|
+
writableMarketIndex: perpMarketIndex,
|
|
943
|
+
writableBankIndexes: [liabilityBankIndex],
|
|
944
|
+
});
|
|
945
|
+
return await this.program.instruction.liquidateBorrowForPerpPnl(perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer, {
|
|
946
|
+
accounts: {
|
|
947
|
+
state: await this.getStatePublicKey(),
|
|
948
|
+
authority: this.wallet.publicKey,
|
|
949
|
+
user: userAccountPublicKey,
|
|
950
|
+
liquidator: liquidatorPublicKey,
|
|
951
|
+
},
|
|
952
|
+
remainingAccounts: remainingAccounts,
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
async liquidatePerpPnlForDeposit(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
|
|
956
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer)), [], this.opts);
|
|
957
|
+
return txSig;
|
|
958
|
+
}
|
|
959
|
+
async getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
|
|
960
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
961
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
962
|
+
userAccount,
|
|
963
|
+
writableMarketIndex: perpMarketIndex,
|
|
964
|
+
writableBankIndexes: [assetBankIndex],
|
|
965
|
+
});
|
|
966
|
+
return await this.program.instruction.liquidatePerpPnlForDeposit(perpMarketIndex, assetBankIndex, maxPnlTransfer, {
|
|
967
|
+
accounts: {
|
|
968
|
+
state: await this.getStatePublicKey(),
|
|
969
|
+
authority: this.wallet.publicKey,
|
|
970
|
+
user: userAccountPublicKey,
|
|
971
|
+
liquidator: liquidatorPublicKey,
|
|
972
|
+
},
|
|
973
|
+
remainingAccounts: remainingAccounts,
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
getRemainingAccountsForLiquidation(params) {
|
|
977
|
+
const liquidateeUserAccount = params.userAccount;
|
|
978
|
+
const oracleAccountMap = new Map();
|
|
979
|
+
const bankAccountMap = new Map();
|
|
980
|
+
const marketAccountMap = new Map();
|
|
981
|
+
for (const bankBalance of liquidateeUserAccount.bankBalances) {
|
|
982
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
983
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
984
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
985
|
+
pubkey: bankAccount.pubkey,
|
|
986
|
+
isSigner: false,
|
|
987
|
+
isWritable: false,
|
|
988
|
+
});
|
|
989
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
990
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
991
|
+
pubkey: bankAccount.oracle,
|
|
992
|
+
isSigner: false,
|
|
993
|
+
isWritable: false,
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
}
|
|
850
998
|
for (const position of liquidateeUserAccount.positions) {
|
|
851
999
|
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
852
1000
|
const market = this.getMarketAccount(position.marketIndex);
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
isWritable: true,
|
|
1001
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1002
|
+
pubkey: market.pubkey,
|
|
1003
|
+
isWritable: false,
|
|
857
1004
|
isSigner: false,
|
|
858
1005
|
});
|
|
859
|
-
|
|
1006
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
860
1007
|
pubkey: market.amm.oracle,
|
|
861
1008
|
isWritable: false,
|
|
862
1009
|
isSigner: false,
|
|
863
1010
|
});
|
|
864
1011
|
}
|
|
865
1012
|
}
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1013
|
+
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
1014
|
+
if (!userAccountAndSlot) {
|
|
1015
|
+
throw Error('No user account found. Most likely user account does not exist or failed to fetch account');
|
|
1016
|
+
}
|
|
1017
|
+
const { data: userAccount, slot: lastUserPositionsSlot } = userAccountAndSlot;
|
|
1018
|
+
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
1019
|
+
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1020
|
+
// otherwise remove from slot
|
|
1021
|
+
if (slot > lastUserPositionsSlot) {
|
|
1022
|
+
const marketAccount = this.getMarketAccount(marketIndexNum);
|
|
1023
|
+
marketAccountMap.set(marketIndexNum, {
|
|
1024
|
+
pubkey: marketAccount.pubkey,
|
|
1025
|
+
isSigner: false,
|
|
1026
|
+
isWritable: false,
|
|
1027
|
+
});
|
|
1028
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
1029
|
+
pubkey: marketAccount.amm.oracle,
|
|
1030
|
+
isSigner: false,
|
|
1031
|
+
isWritable: false,
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
else {
|
|
1035
|
+
this.marketLastSlotCache.delete(marketIndexNum);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
1039
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
1040
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1041
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1042
|
+
pubkey: bankAccount.pubkey,
|
|
1043
|
+
isSigner: false,
|
|
1044
|
+
isWritable: false,
|
|
1045
|
+
});
|
|
1046
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
1047
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1048
|
+
pubkey: bankAccount.oracle,
|
|
1049
|
+
isSigner: false,
|
|
1050
|
+
isWritable: false,
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
for (const position of userAccount.positions) {
|
|
1056
|
+
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
1057
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
1058
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1059
|
+
pubkey: market.pubkey,
|
|
1060
|
+
isWritable: false,
|
|
1061
|
+
isSigner: false,
|
|
1062
|
+
});
|
|
1063
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1064
|
+
pubkey: market.amm.oracle,
|
|
1065
|
+
isWritable: false,
|
|
1066
|
+
isSigner: false,
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
if (params.writableMarketIndex) {
|
|
1071
|
+
const market = this.getMarketAccount(params.writableMarketIndex);
|
|
1072
|
+
marketAccountMap.set(market.marketIndex.toNumber(), {
|
|
1073
|
+
pubkey: market.pubkey,
|
|
1074
|
+
isSigner: false,
|
|
1075
|
+
isWritable: true,
|
|
1076
|
+
});
|
|
1077
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1078
|
+
pubkey: market.amm.oracle,
|
|
1079
|
+
isSigner: false,
|
|
1080
|
+
isWritable: false,
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
if (params.writableBankIndexes) {
|
|
1084
|
+
for (const writableBankIndex of params.writableBankIndexes) {
|
|
1085
|
+
const bank = this.getBankAccount(writableBankIndex);
|
|
1086
|
+
bankAccountMap.set(bank.bankIndex.toNumber(), {
|
|
1087
|
+
pubkey: bank.pubkey,
|
|
1088
|
+
isSigner: false,
|
|
1089
|
+
isWritable: true,
|
|
1090
|
+
});
|
|
1091
|
+
if (!bank.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
1092
|
+
oracleAccountMap.set(bank.oracle.toString(), {
|
|
1093
|
+
pubkey: bank.oracle,
|
|
1094
|
+
isSigner: false,
|
|
1095
|
+
isWritable: false,
|
|
1096
|
+
});
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
return [
|
|
1101
|
+
...oracleAccountMap.values(),
|
|
1102
|
+
...bankAccountMap.values(),
|
|
1103
|
+
...marketAccountMap.values(),
|
|
1104
|
+
];
|
|
882
1105
|
}
|
|
883
1106
|
async updateFundingRate(oracle, marketIndex) {
|
|
884
1107
|
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateFundingRateIx(oracle, marketIndex)), [], this.opts);
|