@drift-labs/sdk 0.2.0-master.1 → 0.2.0-master.12
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/types.d.ts +1 -0
- package/lib/admin.d.ts +8 -5
- package/lib/admin.js +43 -11
- package/lib/clearingHouse.d.ts +35 -20
- package/lib/clearingHouse.js +497 -154
- package/lib/clearingHouseUser.d.ts +12 -17
- package/lib/clearingHouseUser.js +97 -88
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -2
- package/lib/constants/banks.js +12 -4
- package/lib/constants/numericConstants.d.ts +4 -0
- package/lib/constants/numericConstants.js +5 -1
- package/lib/events/eventList.js +3 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/factory/bigNum.d.ts +9 -2
- package/lib/factory/bigNum.js +50 -16
- package/lib/idl/clearing_house.json +858 -177
- package/lib/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/lib/index.d.ts +4 -2
- package/lib/index.js +8 -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/bankBalance.d.ts +3 -1
- package/lib/math/bankBalance.js +54 -1
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +72 -0
- package/lib/math/market.d.ts +4 -1
- package/lib/math/market.js +35 -1
- package/lib/math/orders.d.ts +2 -2
- package/lib/math/orders.js +18 -11
- package/lib/math/position.d.ts +8 -0
- package/lib/math/position.js +44 -12
- 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 +2 -4
- package/lib/orders.js +7 -161
- package/lib/slot/SlotSubscriber.d.ts +7 -0
- package/lib/slot/SlotSubscriber.js +3 -0
- package/lib/{mockUSDCFaucet.d.ts → tokenFaucet.d.ts} +8 -5
- package/lib/{mockUSDCFaucet.js → tokenFaucet.js} +63 -51
- package/lib/tx/retryTxSender.js +9 -2
- package/lib/tx/utils.js +1 -1
- package/lib/types.d.ts +159 -15
- package/lib/types.js +59 -1
- package/lib/util/computeUnits.js +1 -1
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +3 -3
- package/src/accounts/bulkAccountLoader.js +197 -0
- package/src/accounts/bulkUserSubscription.js +33 -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/admin.ts +66 -14
- package/src/assert/assert.js +9 -0
- package/src/clearingHouse.ts +836 -254
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseUser.ts +219 -121
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +14 -4
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +5 -0
- package/src/events/eventList.js +77 -0
- package/src/events/eventList.ts +3 -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/types.ts +2 -0
- package/src/events/webSocketLogProvider.js +41 -0
- package/src/examples/makeTradeExample.js +80 -0
- package/src/factory/bigNum.js +390 -0
- package/src/factory/bigNum.ts +65 -18
- package/src/factory/oracleClient.js +20 -0
- package/src/idl/clearing_house.json +858 -177
- package/src/idl/{mock_usdc_faucet.json → token_faucet.json} +46 -23
- package/src/index.js +69 -0
- package/src/index.ts +4 -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.ts +98 -1
- package/src/math/conversion.js +11 -0
- package/src/math/funding.js +248 -0
- package/src/math/margin.ts +124 -0
- package/src/math/market.ts +66 -1
- package/src/math/oracles.js +26 -0
- package/src/math/orders.ts +17 -13
- package/src/math/position.ts +63 -9
- 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.ts +10 -287
- package/src/slot/SlotSubscriber.js +39 -0
- package/src/slot/SlotSubscriber.ts +11 -1
- package/src/token/index.js +38 -0
- package/src/tokenFaucet.js +189 -0
- package/src/{mockUSDCFaucet.ts → tokenFaucet.ts} +82 -70
- package/src/tx/retryTxSender.ts +11 -3
- 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 +125 -0
- package/src/types.ts +155 -17
- package/src/userName.js +20 -0
- package/src/util/computeUnits.js +21 -11
- package/src/util/computeUnits.ts +1 -1
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/src/util/promiseTimeout.js +14 -0
- package/src/util/tps.js +27 -0
- package/src/wallet.js +35 -0
- package/tests/bn/test.ts +2 -0
- 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,8 +43,8 @@ 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
|
+
const banks_1 = require("./constants/banks");
|
|
47
48
|
/**
|
|
48
49
|
* # ClearingHouse
|
|
49
50
|
* This class is the main way to interact with Drift Protocol. It allows you to subscribe to the various accounts where the Market's state is stored, as well as: opening positions, liquidating, settling funding, depositing & withdrawing, and more.
|
|
@@ -284,8 +285,7 @@ class ClearingHouse {
|
|
|
284
285
|
marketAccountMap.set(marketIndexNum, {
|
|
285
286
|
pubkey: marketAccount.pubkey,
|
|
286
287
|
isSigner: false,
|
|
287
|
-
|
|
288
|
-
isWritable: true,
|
|
288
|
+
isWritable: false,
|
|
289
289
|
});
|
|
290
290
|
oracleAccountMap.set(marketAccount.pubkey.toString(), {
|
|
291
291
|
pubkey: marketAccount.amm.oracle,
|
|
@@ -294,6 +294,19 @@ class ClearingHouse {
|
|
|
294
294
|
});
|
|
295
295
|
}
|
|
296
296
|
}
|
|
297
|
+
if (params.readableMarketIndex) {
|
|
298
|
+
const marketAccount = this.getMarketAccount(params.readableMarketIndex.toNumber());
|
|
299
|
+
marketAccountMap.set(params.readableMarketIndex.toNumber(), {
|
|
300
|
+
pubkey: marketAccount.pubkey,
|
|
301
|
+
isSigner: false,
|
|
302
|
+
isWritable: true,
|
|
303
|
+
});
|
|
304
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
305
|
+
pubkey: marketAccount.amm.oracle,
|
|
306
|
+
isSigner: false,
|
|
307
|
+
isWritable: false,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
297
310
|
if (params.writableMarketIndex) {
|
|
298
311
|
const marketAccount = this.getMarketAccount(params.writableMarketIndex.toNumber());
|
|
299
312
|
marketAccountMap.set(params.writableMarketIndex.toNumber(), {
|
|
@@ -355,9 +368,27 @@ class ClearingHouse {
|
|
|
355
368
|
return (_a = this.getUserAccount()) === null || _a === void 0 ? void 0 : _a.orders.find((order) => order.userOrderId === userOrderId);
|
|
356
369
|
}
|
|
357
370
|
async deposit(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly = false) {
|
|
371
|
+
const tx = new web3_js_1.Transaction();
|
|
372
|
+
const additionalSigners = [];
|
|
373
|
+
const bank = this.getBankAccount(bankIndex);
|
|
374
|
+
const isSolBank = bank.mint.equals(banks_1.WRAPPED_SOL_MINT);
|
|
375
|
+
const authority = this.wallet.publicKey;
|
|
376
|
+
const createWSOLTokenAccount = isSolBank && collateralAccountPublicKey.equals(authority);
|
|
377
|
+
if (createWSOLTokenAccount) {
|
|
378
|
+
const { ixs, signers, pubkey } = await this.getWrappedSolAccountCreationIxs(amount);
|
|
379
|
+
collateralAccountPublicKey = pubkey;
|
|
380
|
+
ixs.forEach((ix) => {
|
|
381
|
+
tx.add(ix);
|
|
382
|
+
});
|
|
383
|
+
signers.forEach((signer) => additionalSigners.push(signer));
|
|
384
|
+
}
|
|
358
385
|
const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, collateralAccountPublicKey, userId, reduceOnly, true);
|
|
359
|
-
|
|
360
|
-
|
|
386
|
+
tx.add(depositCollateralIx);
|
|
387
|
+
// Close the wrapped sol account at the end of the transaction
|
|
388
|
+
if (createWSOLTokenAccount) {
|
|
389
|
+
tx.add(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, collateralAccountPublicKey, authority, authority, []));
|
|
390
|
+
}
|
|
391
|
+
const { txSig } = await this.txSender.send(tx, additionalSigners, this.opts);
|
|
361
392
|
return txSig;
|
|
362
393
|
}
|
|
363
394
|
async getDepositInstruction(amount, bankIndex, userTokenAccount, userId, reduceOnly = false, userInitialized = true) {
|
|
@@ -371,13 +402,19 @@ class ClearingHouse {
|
|
|
371
402
|
});
|
|
372
403
|
}
|
|
373
404
|
else {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
405
|
+
const bankAccount = this.getBankAccount(bankIndex);
|
|
406
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
407
|
+
remainingAccounts.push({
|
|
408
|
+
pubkey: bankAccount.oracle,
|
|
377
409
|
isSigner: false,
|
|
378
|
-
isWritable:
|
|
379
|
-
}
|
|
380
|
-
|
|
410
|
+
isWritable: false,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
remainingAccounts.push({
|
|
414
|
+
pubkey: bankAccount.pubkey,
|
|
415
|
+
isSigner: false,
|
|
416
|
+
isWritable: true,
|
|
417
|
+
});
|
|
381
418
|
}
|
|
382
419
|
const bank = this.getBankAccount(bankIndex);
|
|
383
420
|
return await this.program.instruction.deposit(bankIndex, amount, reduceOnly, {
|
|
@@ -393,30 +430,99 @@ class ClearingHouse {
|
|
|
393
430
|
remainingAccounts,
|
|
394
431
|
});
|
|
395
432
|
}
|
|
433
|
+
async checkIfAccountExists(account) {
|
|
434
|
+
try {
|
|
435
|
+
const accountInfo = await this.connection.getAccountInfo(account);
|
|
436
|
+
return accountInfo && true;
|
|
437
|
+
}
|
|
438
|
+
catch (e) {
|
|
439
|
+
// Doesn't already exist
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
async getSolWithdrawalIxs(bankIndex, amount) {
|
|
444
|
+
const result = {
|
|
445
|
+
ixs: [],
|
|
446
|
+
signers: [],
|
|
447
|
+
pubkey: web3_js_1.PublicKey.default,
|
|
448
|
+
};
|
|
449
|
+
// Create a temporary wrapped SOL account to store the SOL that we're withdrawing
|
|
450
|
+
const authority = this.wallet.publicKey;
|
|
451
|
+
const { ixs, signers, pubkey } = await this.getWrappedSolAccountCreationIxs(amount);
|
|
452
|
+
result.pubkey = pubkey;
|
|
453
|
+
ixs.forEach((ix) => {
|
|
454
|
+
result.ixs.push(ix);
|
|
455
|
+
});
|
|
456
|
+
signers.forEach((ix) => {
|
|
457
|
+
result.signers.push(ix);
|
|
458
|
+
});
|
|
459
|
+
const withdrawIx = await this.getWithdrawIx(amount, bankIndex, pubkey, true);
|
|
460
|
+
result.ixs.push(withdrawIx);
|
|
461
|
+
result.ixs.push(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, pubkey, authority, authority, []));
|
|
462
|
+
return result;
|
|
463
|
+
}
|
|
464
|
+
async getWrappedSolAccountCreationIxs(amount) {
|
|
465
|
+
const wrappedSolAccount = new web3_js_1.Keypair();
|
|
466
|
+
const result = {
|
|
467
|
+
ixs: [],
|
|
468
|
+
signers: [],
|
|
469
|
+
pubkey: wrappedSolAccount.publicKey,
|
|
470
|
+
};
|
|
471
|
+
const rentSpaceLamports = new anchor_1.BN(web3_js_1.LAMPORTS_PER_SOL / 100);
|
|
472
|
+
const depositAmountLamports = amount.add(rentSpaceLamports);
|
|
473
|
+
const authority = this.wallet.publicKey;
|
|
474
|
+
result.ixs.push(web3_js_1.SystemProgram.createAccount({
|
|
475
|
+
fromPubkey: authority,
|
|
476
|
+
newAccountPubkey: wrappedSolAccount.publicKey,
|
|
477
|
+
lamports: depositAmountLamports.toNumber(),
|
|
478
|
+
space: 165,
|
|
479
|
+
programId: spl_token_1.TOKEN_PROGRAM_ID,
|
|
480
|
+
}));
|
|
481
|
+
result.ixs.push(spl_token_1.Token.createInitAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, banks_1.WRAPPED_SOL_MINT, wrappedSolAccount.publicKey, authority));
|
|
482
|
+
result.signers.push(wrappedSolAccount);
|
|
483
|
+
return result;
|
|
484
|
+
}
|
|
396
485
|
/**
|
|
397
486
|
* Creates the Clearing House User account for a user, and deposits some initial collateral
|
|
398
|
-
* @param userId
|
|
399
|
-
* @param name
|
|
400
487
|
* @param amount
|
|
401
488
|
* @param userTokenAccount
|
|
489
|
+
* @param bankIndex
|
|
490
|
+
* @param userId
|
|
491
|
+
* @param name
|
|
402
492
|
* @param fromUserId
|
|
403
493
|
* @returns
|
|
404
494
|
*/
|
|
405
495
|
async initializeUserAccountAndDepositCollateral(amount, userTokenAccount, bankIndex = new anchor_1.BN(0), userId = 0, name = userName_1.DEFAULT_USER_NAME, fromUserId) {
|
|
406
496
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
|
|
497
|
+
const additionalSigners = [];
|
|
498
|
+
const bank = this.getBankAccount(bankIndex);
|
|
499
|
+
const isSolBank = bank.mint.equals(banks_1.WRAPPED_SOL_MINT);
|
|
500
|
+
const tx = new web3_js_1.Transaction();
|
|
501
|
+
const authority = this.wallet.publicKey;
|
|
502
|
+
const createWSOLTokenAccount = isSolBank && userTokenAccount.equals(authority);
|
|
503
|
+
if (createWSOLTokenAccount) {
|
|
504
|
+
const { ixs: startIxs, signers, pubkey, } = await this.getWrappedSolAccountCreationIxs(amount);
|
|
505
|
+
userTokenAccount = pubkey;
|
|
506
|
+
startIxs.forEach((ix) => {
|
|
507
|
+
tx.add(ix);
|
|
508
|
+
});
|
|
509
|
+
signers.forEach((signer) => additionalSigners.push(signer));
|
|
510
|
+
}
|
|
407
511
|
const depositCollateralIx = fromUserId != null
|
|
408
512
|
? await this.getTransferDepositIx(amount, bankIndex, fromUserId, userId)
|
|
409
513
|
: await this.getDepositInstruction(amount, bankIndex, userTokenAccount, userId, false, false);
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
514
|
+
tx.add(initializeUserAccountIx).add(depositCollateralIx);
|
|
515
|
+
// Close the wrapped sol account at the end of the transaction
|
|
516
|
+
if (createWSOLTokenAccount) {
|
|
517
|
+
tx.add(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, userTokenAccount, authority, authority, []));
|
|
518
|
+
}
|
|
519
|
+
const { txSig } = await this.txSender.send(tx, additionalSigners, this.opts);
|
|
414
520
|
return [txSig, userAccountPublicKey];
|
|
415
521
|
}
|
|
416
|
-
async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME,
|
|
417
|
-
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await
|
|
522
|
+
async initializeUserAccountForDevnet(userId = 0, name = userName_1.DEFAULT_USER_NAME, bankIndex, tokenFaucet, amount) {
|
|
523
|
+
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] = await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(this.wallet.publicKey, amount);
|
|
418
524
|
const [userAccountPublicKey, initializeUserAccountIx] = await this.getInitializeUserInstructions(userId, name);
|
|
419
|
-
const depositCollateralIx = await this.getDepositInstruction(amount,
|
|
525
|
+
const depositCollateralIx = await this.getDepositInstruction(amount, bankIndex, associateTokenPublicKey, userId, false, false);
|
|
420
526
|
const tx = new web3_js_1.Transaction()
|
|
421
527
|
.add(createAssociatedAccountIx)
|
|
422
528
|
.add(mintToIx)
|
|
@@ -426,7 +532,27 @@ class ClearingHouse {
|
|
|
426
532
|
return [txSig, userAccountPublicKey];
|
|
427
533
|
}
|
|
428
534
|
async withdraw(amount, bankIndex, userTokenAccount, reduceOnly = false) {
|
|
429
|
-
const
|
|
535
|
+
const tx = new web3_js_1.Transaction();
|
|
536
|
+
const additionalSigners = [];
|
|
537
|
+
const bank = this.getBankAccount(bankIndex);
|
|
538
|
+
const isSolBank = bank.mint.equals(banks_1.WRAPPED_SOL_MINT);
|
|
539
|
+
const authority = this.wallet.publicKey;
|
|
540
|
+
const createWSOLTokenAccount = isSolBank && userTokenAccount.equals(authority);
|
|
541
|
+
if (createWSOLTokenAccount) {
|
|
542
|
+
const { ixs, signers, pubkey } = await this.getWrappedSolAccountCreationIxs(amount);
|
|
543
|
+
userTokenAccount = pubkey;
|
|
544
|
+
ixs.forEach((ix) => {
|
|
545
|
+
tx.add(ix);
|
|
546
|
+
});
|
|
547
|
+
signers.forEach((signer) => additionalSigners.push(signer));
|
|
548
|
+
}
|
|
549
|
+
const withdrawCollateral = await this.getWithdrawIx(amount, bank.bankIndex, userTokenAccount, reduceOnly);
|
|
550
|
+
tx.add(withdrawCollateral);
|
|
551
|
+
// Close the wrapped sol account at the end of the transaction
|
|
552
|
+
if (createWSOLTokenAccount) {
|
|
553
|
+
tx.add(spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, userTokenAccount, authority, authority, []));
|
|
554
|
+
}
|
|
555
|
+
const { txSig } = await this.txSender.send(tx, additionalSigners, this.opts);
|
|
430
556
|
return txSig;
|
|
431
557
|
}
|
|
432
558
|
async getWithdrawIx(amount, bankIndex, userTokenAccount, reduceOnly = false) {
|
|
@@ -482,45 +608,37 @@ class ClearingHouse {
|
|
|
482
608
|
});
|
|
483
609
|
}
|
|
484
610
|
async openPosition(direction, amount, marketIndex, limitPrice) {
|
|
485
|
-
return await this.placeAndTake(
|
|
611
|
+
return await this.placeAndTake({
|
|
612
|
+
orderType: types_1.OrderType.MARKET,
|
|
613
|
+
marketIndex,
|
|
614
|
+
direction,
|
|
615
|
+
baseAssetAmount: amount,
|
|
616
|
+
price: limitPrice,
|
|
617
|
+
});
|
|
486
618
|
}
|
|
487
619
|
async placeOrder(orderParams) {
|
|
488
620
|
const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceOrderIx(orderParams)), [], this.opts);
|
|
489
621
|
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
490
622
|
return txSig;
|
|
491
623
|
}
|
|
624
|
+
getOrderParams(optionalOrderParams) {
|
|
625
|
+
return Object.assign({}, types_1.DefaultOrderParams, optionalOrderParams);
|
|
626
|
+
}
|
|
492
627
|
async getPlaceOrderIx(orderParams) {
|
|
628
|
+
orderParams = this.getOrderParams(orderParams);
|
|
493
629
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
494
|
-
const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
|
|
495
|
-
.oracle;
|
|
496
630
|
const remainingAccounts = this.getRemainingAccounts({
|
|
497
|
-
|
|
631
|
+
readableMarketIndex: orderParams.marketIndex,
|
|
498
632
|
});
|
|
499
633
|
return await this.program.instruction.placeOrder(orderParams, {
|
|
500
634
|
accounts: {
|
|
501
635
|
state: await this.getStatePublicKey(),
|
|
502
636
|
user: userAccountPublicKey,
|
|
503
637
|
authority: this.wallet.publicKey,
|
|
504
|
-
oracle: priceOracle,
|
|
505
638
|
},
|
|
506
639
|
remainingAccounts,
|
|
507
640
|
});
|
|
508
641
|
}
|
|
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
642
|
async updateAMMs(marketIndexes) {
|
|
525
643
|
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateAMMsIx(marketIndexes)), [], this.opts);
|
|
526
644
|
return txSig;
|
|
@@ -561,15 +679,12 @@ class ClearingHouse {
|
|
|
561
679
|
}
|
|
562
680
|
async getCancelOrderIx(orderId) {
|
|
563
681
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
564
|
-
const order = this.getOrder(orderId);
|
|
565
|
-
const oracle = this.getMarketAccount(order.marketIndex).amm.oracle;
|
|
566
682
|
const remainingAccounts = this.getRemainingAccounts({});
|
|
567
|
-
return await this.program.instruction.cancelOrder(orderId, {
|
|
683
|
+
return await this.program.instruction.cancelOrder(orderId !== null && orderId !== void 0 ? orderId : null, {
|
|
568
684
|
accounts: {
|
|
569
685
|
state: await this.getStatePublicKey(),
|
|
570
686
|
user: userAccountPublicKey,
|
|
571
687
|
authority: this.wallet.publicKey,
|
|
572
|
-
oracle,
|
|
573
688
|
},
|
|
574
689
|
remainingAccounts,
|
|
575
690
|
});
|
|
@@ -593,117 +708,150 @@ class ClearingHouse {
|
|
|
593
708
|
remainingAccounts,
|
|
594
709
|
});
|
|
595
710
|
}
|
|
596
|
-
async
|
|
597
|
-
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.
|
|
711
|
+
async fillOrder(userAccountPublicKey, user, order, makerInfo) {
|
|
712
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getFillOrderIx(userAccountPublicKey, user, order, makerInfo)), [], this.opts);
|
|
598
713
|
return txSig;
|
|
599
714
|
}
|
|
600
|
-
async
|
|
601
|
-
const
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
715
|
+
async getFillOrderIx(userAccountPublicKey, userAccount, order, makerInfo) {
|
|
716
|
+
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
717
|
+
const marketIndex = order.marketIndex;
|
|
718
|
+
const marketAccount = this.getMarketAccount(marketIndex);
|
|
719
|
+
const oracleAccountMap = new Map();
|
|
720
|
+
const bankAccountMap = new Map();
|
|
721
|
+
const marketAccountMap = new Map();
|
|
722
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
723
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
724
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
725
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
726
|
+
pubkey: bankAccount.pubkey,
|
|
727
|
+
isSigner: false,
|
|
728
|
+
isWritable: false,
|
|
729
|
+
});
|
|
730
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
731
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
732
|
+
pubkey: bankAccount.oracle,
|
|
733
|
+
isSigner: false,
|
|
734
|
+
isWritable: false,
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
}
|
|
610
738
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
739
|
+
for (const position of userAccount.positions) {
|
|
740
|
+
if (!(0, position_1.positionIsAvailable)(position) &&
|
|
741
|
+
!position.marketIndex.eq(order.marketIndex)) {
|
|
742
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
743
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
744
|
+
pubkey: market.pubkey,
|
|
745
|
+
isWritable: false,
|
|
746
|
+
isSigner: false,
|
|
747
|
+
});
|
|
748
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
749
|
+
pubkey: market.amm.oracle,
|
|
750
|
+
isWritable: false,
|
|
751
|
+
isSigner: false,
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
marketAccountMap.set(marketIndex.toNumber(), {
|
|
756
|
+
pubkey: marketAccount.pubkey,
|
|
757
|
+
isWritable: true,
|
|
758
|
+
isSigner: false,
|
|
618
759
|
});
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
760
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
761
|
+
pubkey: marketAccount.amm.oracle,
|
|
762
|
+
isWritable: false,
|
|
763
|
+
isSigner: false,
|
|
764
|
+
});
|
|
765
|
+
const remainingAccounts = [
|
|
766
|
+
...oracleAccountMap.values(),
|
|
767
|
+
...bankAccountMap.values(),
|
|
768
|
+
...marketAccountMap.values(),
|
|
769
|
+
];
|
|
770
|
+
if (makerInfo) {
|
|
629
771
|
remainingAccounts.push({
|
|
630
|
-
pubkey:
|
|
631
|
-
isWritable:
|
|
772
|
+
pubkey: makerInfo.maker,
|
|
773
|
+
isWritable: true,
|
|
632
774
|
isSigner: false,
|
|
633
775
|
});
|
|
634
776
|
}
|
|
635
|
-
|
|
777
|
+
const orderId = order.orderId;
|
|
778
|
+
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
779
|
+
return await this.program.instruction.fillOrder(orderId, makerOrderId, {
|
|
636
780
|
accounts: {
|
|
637
781
|
state: await this.getStatePublicKey(),
|
|
782
|
+
filler: fillerPublicKey,
|
|
638
783
|
user: userAccountPublicKey,
|
|
639
784
|
authority: this.wallet.publicKey,
|
|
640
785
|
},
|
|
641
786
|
remainingAccounts,
|
|
642
787
|
});
|
|
643
788
|
}
|
|
644
|
-
async
|
|
645
|
-
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.
|
|
789
|
+
async triggerOrder(userAccountPublicKey, user, order) {
|
|
790
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getTriggerOrderIx(userAccountPublicKey, user, order)), [], this.opts);
|
|
646
791
|
return txSig;
|
|
647
792
|
}
|
|
648
|
-
async
|
|
793
|
+
async getTriggerOrderIx(userAccountPublicKey, userAccount, order) {
|
|
649
794
|
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
650
795
|
const marketIndex = order.marketIndex;
|
|
651
796
|
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
|
-
];
|
|
797
|
+
const oracleAccountMap = new Map();
|
|
798
|
+
const bankAccountMap = new Map();
|
|
799
|
+
const marketAccountMap = new Map();
|
|
800
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
801
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
802
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
803
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
804
|
+
pubkey: bankAccount.pubkey,
|
|
805
|
+
isSigner: false,
|
|
806
|
+
isWritable: false,
|
|
807
|
+
});
|
|
808
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
809
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
810
|
+
pubkey: bankAccount.oracle,
|
|
811
|
+
isSigner: false,
|
|
812
|
+
isWritable: false,
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
674
817
|
for (const position of userAccount.positions) {
|
|
675
818
|
if (!(0, position_1.positionIsAvailable)(position) &&
|
|
676
819
|
!position.marketIndex.eq(order.marketIndex)) {
|
|
677
820
|
const market = this.getMarketAccount(position.marketIndex);
|
|
678
|
-
|
|
821
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
679
822
|
pubkey: market.pubkey,
|
|
680
823
|
isWritable: false,
|
|
681
824
|
isSigner: false,
|
|
682
825
|
});
|
|
683
|
-
|
|
826
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
684
827
|
pubkey: market.amm.oracle,
|
|
685
828
|
isWritable: false,
|
|
686
829
|
isSigner: false,
|
|
687
830
|
});
|
|
688
831
|
}
|
|
689
832
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
833
|
+
marketAccountMap.set(marketIndex.toNumber(), {
|
|
834
|
+
pubkey: marketAccount.pubkey,
|
|
835
|
+
isWritable: true,
|
|
836
|
+
isSigner: false,
|
|
837
|
+
});
|
|
838
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
839
|
+
pubkey: marketAccount.amm.oracle,
|
|
840
|
+
isWritable: false,
|
|
841
|
+
isSigner: false,
|
|
842
|
+
});
|
|
843
|
+
const remainingAccounts = [
|
|
844
|
+
...oracleAccountMap.values(),
|
|
845
|
+
...bankAccountMap.values(),
|
|
846
|
+
...marketAccountMap.values(),
|
|
847
|
+
];
|
|
698
848
|
const orderId = order.orderId;
|
|
699
|
-
|
|
700
|
-
return await this.program.instruction.fillOrder(orderId, makerOrderId, {
|
|
849
|
+
return await this.program.instruction.triggerOrder(orderId, {
|
|
701
850
|
accounts: {
|
|
702
851
|
state: await this.getStatePublicKey(),
|
|
703
852
|
filler: fillerPublicKey,
|
|
704
853
|
user: userAccountPublicKey,
|
|
705
854
|
authority: this.wallet.publicKey,
|
|
706
|
-
oracle: oracle,
|
|
707
855
|
},
|
|
708
856
|
remainingAccounts,
|
|
709
857
|
});
|
|
@@ -714,9 +862,8 @@ class ClearingHouse {
|
|
|
714
862
|
return txSig;
|
|
715
863
|
}
|
|
716
864
|
async getPlaceAndTakeIx(orderParams, makerInfo) {
|
|
865
|
+
orderParams = this.getOrderParams(orderParams);
|
|
717
866
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
718
|
-
const priceOracle = this.getMarketAccount(orderParams.marketIndex).amm
|
|
719
|
-
.oracle;
|
|
720
867
|
const remainingAccounts = this.getRemainingAccounts({
|
|
721
868
|
writableMarketIndex: orderParams.marketIndex,
|
|
722
869
|
writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
|
|
@@ -735,7 +882,34 @@ class ClearingHouse {
|
|
|
735
882
|
state: await this.getStatePublicKey(),
|
|
736
883
|
user: userAccountPublicKey,
|
|
737
884
|
authority: this.wallet.publicKey,
|
|
738
|
-
|
|
885
|
+
},
|
|
886
|
+
remainingAccounts,
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
async placeAndMake(orderParams, takerInfo) {
|
|
890
|
+
const { txSig, slot } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getPlaceAndMakeIx(orderParams, takerInfo)), [], this.opts);
|
|
891
|
+
this.marketLastSlotCache.set(orderParams.marketIndex.toNumber(), slot);
|
|
892
|
+
return txSig;
|
|
893
|
+
}
|
|
894
|
+
async getPlaceAndMakeIx(orderParams, takerInfo) {
|
|
895
|
+
orderParams = this.getOrderParams(orderParams);
|
|
896
|
+
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
897
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
898
|
+
writableMarketIndex: orderParams.marketIndex,
|
|
899
|
+
writableBankIndex: numericConstants_1.QUOTE_ASSET_BANK_INDEX,
|
|
900
|
+
});
|
|
901
|
+
const takerOrderId = takerInfo.order.orderId;
|
|
902
|
+
remainingAccounts.push({
|
|
903
|
+
pubkey: takerInfo.taker,
|
|
904
|
+
isSigner: false,
|
|
905
|
+
isWritable: true,
|
|
906
|
+
});
|
|
907
|
+
return await this.program.instruction.placeAndMake(orderParams, takerOrderId, {
|
|
908
|
+
accounts: {
|
|
909
|
+
state: await this.getStatePublicKey(),
|
|
910
|
+
user: userAccountPublicKey,
|
|
911
|
+
taker: takerInfo.taker,
|
|
912
|
+
authority: this.wallet.publicKey,
|
|
739
913
|
},
|
|
740
914
|
remainingAccounts,
|
|
741
915
|
});
|
|
@@ -750,7 +924,13 @@ class ClearingHouse {
|
|
|
750
924
|
if (!userPosition) {
|
|
751
925
|
throw Error(`No position in market ${marketIndex.toString()}`);
|
|
752
926
|
}
|
|
753
|
-
return await this.placeAndTake(
|
|
927
|
+
return await this.placeAndTake({
|
|
928
|
+
orderType: types_1.OrderType.MARKET,
|
|
929
|
+
marketIndex,
|
|
930
|
+
direction: (0, position_1.findDirectionToClose)(userPosition),
|
|
931
|
+
baseAssetAmount: userPosition.baseAssetAmount,
|
|
932
|
+
reduceOnly: true,
|
|
933
|
+
});
|
|
754
934
|
}
|
|
755
935
|
async settlePNLs(users, marketIndex) {
|
|
756
936
|
const ixs = [];
|
|
@@ -774,7 +954,7 @@ class ClearingHouse {
|
|
|
774
954
|
const market = this.getMarketAccount(position.marketIndex);
|
|
775
955
|
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
776
956
|
pubkey: market.pubkey,
|
|
777
|
-
isWritable:
|
|
957
|
+
isWritable: false,
|
|
778
958
|
isSigner: false,
|
|
779
959
|
});
|
|
780
960
|
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
@@ -831,54 +1011,217 @@ class ClearingHouse {
|
|
|
831
1011
|
remainingAccounts: remainingAccounts,
|
|
832
1012
|
});
|
|
833
1013
|
}
|
|
834
|
-
async
|
|
835
|
-
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.
|
|
1014
|
+
async liquidatePerp(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
|
|
1015
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount)), [], this.opts);
|
|
836
1016
|
return txSig;
|
|
837
1017
|
}
|
|
838
|
-
async
|
|
839
|
-
const
|
|
840
|
-
const
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
1018
|
+
async getLiquidatePerpIx(userAccountPublicKey, userAccount, marketIndex, maxBaseAssetAmount) {
|
|
1019
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1020
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1021
|
+
writableMarketIndex: marketIndex,
|
|
1022
|
+
userAccount,
|
|
1023
|
+
});
|
|
1024
|
+
return await this.program.instruction.liquidatePerp(marketIndex, maxBaseAssetAmount, {
|
|
1025
|
+
accounts: {
|
|
1026
|
+
state: await this.getStatePublicKey(),
|
|
1027
|
+
authority: this.wallet.publicKey,
|
|
1028
|
+
user: userAccountPublicKey,
|
|
1029
|
+
liquidator: liquidatorPublicKey,
|
|
846
1030
|
},
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
1031
|
+
remainingAccounts: remainingAccounts,
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
async liquidateBorrow(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
1035
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
|
|
1036
|
+
return txSig;
|
|
1037
|
+
}
|
|
1038
|
+
async getLiquidateBorrowIx(userAccountPublicKey, userAccount, assetBankIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
1039
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1040
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1041
|
+
userAccount,
|
|
1042
|
+
writableBankIndexes: [liabilityBankIndex, assetBankIndex],
|
|
1043
|
+
});
|
|
1044
|
+
return await this.program.instruction.liquidateBorrow(assetBankIndex, liabilityBankIndex, maxLiabilityTransfer, {
|
|
1045
|
+
accounts: {
|
|
1046
|
+
state: await this.getStatePublicKey(),
|
|
1047
|
+
authority: this.wallet.publicKey,
|
|
1048
|
+
user: userAccountPublicKey,
|
|
1049
|
+
liquidator: liquidatorPublicKey,
|
|
1050
|
+
},
|
|
1051
|
+
remainingAccounts: remainingAccounts,
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
async liquidateBorrowForPerpPnl(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
1055
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer)), [], this.opts);
|
|
1056
|
+
return txSig;
|
|
1057
|
+
}
|
|
1058
|
+
async getLiquidateBorrowForPerpPnlIx(userAccountPublicKey, userAccount, perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer) {
|
|
1059
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1060
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1061
|
+
userAccount,
|
|
1062
|
+
writableMarketIndex: perpMarketIndex,
|
|
1063
|
+
writableBankIndexes: [liabilityBankIndex],
|
|
1064
|
+
});
|
|
1065
|
+
return await this.program.instruction.liquidateBorrowForPerpPnl(perpMarketIndex, liabilityBankIndex, maxLiabilityTransfer, {
|
|
1066
|
+
accounts: {
|
|
1067
|
+
state: await this.getStatePublicKey(),
|
|
1068
|
+
authority: this.wallet.publicKey,
|
|
1069
|
+
user: userAccountPublicKey,
|
|
1070
|
+
liquidator: liquidatorPublicKey,
|
|
1071
|
+
},
|
|
1072
|
+
remainingAccounts: remainingAccounts,
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
async liquidatePerpPnlForDeposit(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
|
|
1076
|
+
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer)), [], this.opts);
|
|
1077
|
+
return txSig;
|
|
1078
|
+
}
|
|
1079
|
+
async getLiquidatePerpPnlForDepositIx(userAccountPublicKey, userAccount, perpMarketIndex, assetBankIndex, maxPnlTransfer) {
|
|
1080
|
+
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1081
|
+
const remainingAccounts = this.getRemainingAccountsForLiquidation({
|
|
1082
|
+
userAccount,
|
|
1083
|
+
writableMarketIndex: perpMarketIndex,
|
|
1084
|
+
writableBankIndexes: [assetBankIndex],
|
|
1085
|
+
});
|
|
1086
|
+
return await this.program.instruction.liquidatePerpPnlForDeposit(perpMarketIndex, assetBankIndex, maxPnlTransfer, {
|
|
1087
|
+
accounts: {
|
|
1088
|
+
state: await this.getStatePublicKey(),
|
|
1089
|
+
authority: this.wallet.publicKey,
|
|
1090
|
+
user: userAccountPublicKey,
|
|
1091
|
+
liquidator: liquidatorPublicKey,
|
|
1092
|
+
},
|
|
1093
|
+
remainingAccounts: remainingAccounts,
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
getRemainingAccountsForLiquidation(params) {
|
|
1097
|
+
const liquidateeUserAccount = params.userAccount;
|
|
1098
|
+
const oracleAccountMap = new Map();
|
|
1099
|
+
const bankAccountMap = new Map();
|
|
1100
|
+
const marketAccountMap = new Map();
|
|
1101
|
+
for (const bankBalance of liquidateeUserAccount.bankBalances) {
|
|
1102
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
1103
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1104
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1105
|
+
pubkey: bankAccount.pubkey,
|
|
1106
|
+
isSigner: false,
|
|
1107
|
+
isWritable: false,
|
|
1108
|
+
});
|
|
1109
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
1110
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1111
|
+
pubkey: bankAccount.oracle,
|
|
1112
|
+
isSigner: false,
|
|
1113
|
+
isWritable: false,
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
850
1118
|
for (const position of liquidateeUserAccount.positions) {
|
|
851
1119
|
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
852
1120
|
const market = this.getMarketAccount(position.marketIndex);
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
isWritable: true,
|
|
1121
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1122
|
+
pubkey: market.pubkey,
|
|
1123
|
+
isWritable: false,
|
|
857
1124
|
isSigner: false,
|
|
858
1125
|
});
|
|
859
|
-
|
|
1126
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
860
1127
|
pubkey: market.amm.oracle,
|
|
861
1128
|
isWritable: false,
|
|
862
1129
|
isSigner: false,
|
|
863
1130
|
});
|
|
864
1131
|
}
|
|
865
1132
|
}
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1133
|
+
const userAccountAndSlot = this.getUserAccountAndSlot();
|
|
1134
|
+
if (!userAccountAndSlot) {
|
|
1135
|
+
throw Error('No user account found. Most likely user account does not exist or failed to fetch account');
|
|
1136
|
+
}
|
|
1137
|
+
const { data: userAccount, slot: lastUserPositionsSlot } = userAccountAndSlot;
|
|
1138
|
+
for (const [marketIndexNum, slot] of this.marketLastSlotCache.entries()) {
|
|
1139
|
+
// if cache has more recent slot than user positions account slot, add market to remaining accounts
|
|
1140
|
+
// otherwise remove from slot
|
|
1141
|
+
if (slot > lastUserPositionsSlot) {
|
|
1142
|
+
const marketAccount = this.getMarketAccount(marketIndexNum);
|
|
1143
|
+
marketAccountMap.set(marketIndexNum, {
|
|
1144
|
+
pubkey: marketAccount.pubkey,
|
|
1145
|
+
isSigner: false,
|
|
1146
|
+
isWritable: false,
|
|
1147
|
+
});
|
|
1148
|
+
oracleAccountMap.set(marketAccount.amm.oracle.toString(), {
|
|
1149
|
+
pubkey: marketAccount.amm.oracle,
|
|
1150
|
+
isSigner: false,
|
|
1151
|
+
isWritable: false,
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
else {
|
|
1155
|
+
this.marketLastSlotCache.delete(marketIndexNum);
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
for (const bankBalance of userAccount.bankBalances) {
|
|
1159
|
+
if (!bankBalance.balance.eq(numericConstants_1.ZERO)) {
|
|
1160
|
+
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
1161
|
+
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
1162
|
+
pubkey: bankAccount.pubkey,
|
|
1163
|
+
isSigner: false,
|
|
1164
|
+
isWritable: false,
|
|
1165
|
+
});
|
|
1166
|
+
if (!bankAccount.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
1167
|
+
oracleAccountMap.set(bankAccount.oracle.toString(), {
|
|
1168
|
+
pubkey: bankAccount.oracle,
|
|
1169
|
+
isSigner: false,
|
|
1170
|
+
isWritable: false,
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
for (const position of userAccount.positions) {
|
|
1176
|
+
if (!(0, position_1.positionIsAvailable)(position)) {
|
|
1177
|
+
const market = this.getMarketAccount(position.marketIndex);
|
|
1178
|
+
marketAccountMap.set(position.marketIndex.toNumber(), {
|
|
1179
|
+
pubkey: market.pubkey,
|
|
1180
|
+
isWritable: false,
|
|
1181
|
+
isSigner: false,
|
|
1182
|
+
});
|
|
1183
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1184
|
+
pubkey: market.amm.oracle,
|
|
1185
|
+
isWritable: false,
|
|
1186
|
+
isSigner: false,
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
if (params.writableMarketIndex) {
|
|
1191
|
+
const market = this.getMarketAccount(params.writableMarketIndex);
|
|
1192
|
+
marketAccountMap.set(market.marketIndex.toNumber(), {
|
|
1193
|
+
pubkey: market.pubkey,
|
|
1194
|
+
isSigner: false,
|
|
1195
|
+
isWritable: true,
|
|
1196
|
+
});
|
|
1197
|
+
oracleAccountMap.set(market.amm.oracle.toString(), {
|
|
1198
|
+
pubkey: market.amm.oracle,
|
|
1199
|
+
isSigner: false,
|
|
1200
|
+
isWritable: false,
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
if (params.writableBankIndexes) {
|
|
1204
|
+
for (const writableBankIndex of params.writableBankIndexes) {
|
|
1205
|
+
const bank = this.getBankAccount(writableBankIndex);
|
|
1206
|
+
bankAccountMap.set(bank.bankIndex.toNumber(), {
|
|
1207
|
+
pubkey: bank.pubkey,
|
|
1208
|
+
isSigner: false,
|
|
1209
|
+
isWritable: true,
|
|
1210
|
+
});
|
|
1211
|
+
if (!bank.oracle.equals(web3_js_1.PublicKey.default)) {
|
|
1212
|
+
oracleAccountMap.set(bank.oracle.toString(), {
|
|
1213
|
+
pubkey: bank.oracle,
|
|
1214
|
+
isSigner: false,
|
|
1215
|
+
isWritable: false,
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
return [
|
|
1221
|
+
...oracleAccountMap.values(),
|
|
1222
|
+
...bankAccountMap.values(),
|
|
1223
|
+
...marketAccountMap.values(),
|
|
1224
|
+
];
|
|
882
1225
|
}
|
|
883
1226
|
async updateFundingRate(oracle, marketIndex) {
|
|
884
1227
|
const { txSig } = await this.txSender.send((0, utils_1.wrapInTx)(await this.getUpdateFundingRateIx(oracle, marketIndex)), [], this.opts);
|