@drift-labs/sdk 0.2.0-master.11 → 0.2.0-master.14

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.
Files changed (114) hide show
  1. package/lib/accounts/fetch.d.ts +2 -1
  2. package/lib/accounts/fetch.js +9 -1
  3. package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
  4. package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
  5. package/lib/accounts/types.d.ts +14 -1
  6. package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
  7. package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
  8. package/lib/addresses/pda.d.ts +1 -0
  9. package/lib/addresses/pda.js +8 -1
  10. package/lib/admin.d.ts +2 -0
  11. package/lib/admin.js +18 -0
  12. package/lib/clearingHouse.d.ts +24 -3
  13. package/lib/clearingHouse.js +352 -51
  14. package/lib/clearingHouseConfig.d.ts +1 -0
  15. package/lib/clearingHouseUser.d.ts +15 -15
  16. package/lib/clearingHouseUser.js +185 -73
  17. package/lib/clearingHouseUserStats.d.ts +17 -0
  18. package/lib/clearingHouseUserStats.js +36 -0
  19. package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
  20. package/lib/clearingHouseUserStatsConfig.js +2 -0
  21. package/lib/config.js +1 -1
  22. package/lib/constants/banks.d.ts +2 -2
  23. package/lib/constants/banks.js +4 -3
  24. package/lib/constants/numericConstants.d.ts +2 -0
  25. package/lib/constants/numericConstants.js +3 -1
  26. package/lib/events/eventList.js +3 -0
  27. package/lib/events/types.d.ts +2 -1
  28. package/lib/factory/bigNum.d.ts +1 -0
  29. package/lib/factory/bigNum.js +37 -11
  30. package/lib/idl/clearing_house.json +692 -58
  31. package/lib/index.d.ts +1 -0
  32. package/lib/index.js +1 -0
  33. package/lib/math/amm.js +2 -2
  34. package/lib/math/bankBalance.d.ts +7 -1
  35. package/lib/math/bankBalance.js +76 -1
  36. package/lib/math/margin.d.ts +11 -0
  37. package/lib/math/margin.js +72 -0
  38. package/lib/math/market.d.ts +4 -1
  39. package/lib/math/market.js +35 -1
  40. package/lib/math/oracles.d.ts +3 -0
  41. package/lib/math/oracles.js +25 -5
  42. package/lib/math/position.d.ts +8 -0
  43. package/lib/math/position.js +43 -12
  44. package/lib/math/trade.js +2 -2
  45. package/lib/orders.d.ts +1 -2
  46. package/lib/orders.js +2 -77
  47. package/lib/tokenFaucet.d.ts +1 -0
  48. package/lib/tokenFaucet.js +23 -12
  49. package/lib/tx/retryTxSender.js +9 -2
  50. package/lib/types.d.ts +78 -10
  51. package/lib/types.js +12 -0
  52. package/lib/util/getTokenAddress.d.ts +2 -0
  53. package/lib/util/getTokenAddress.js +9 -0
  54. package/package.json +1 -1
  55. package/src/accounts/fetch.ts +27 -2
  56. package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
  57. package/src/accounts/types.ts +18 -0
  58. package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
  59. package/src/addresses/pda.ts +13 -0
  60. package/src/admin.ts +29 -1
  61. package/src/clearingHouse.ts +619 -62
  62. package/src/clearingHouseConfig.ts +1 -0
  63. package/src/clearingHouseUser.ts +317 -105
  64. package/src/clearingHouseUserStats.ts +53 -0
  65. package/src/clearingHouseUserStatsConfig.ts +18 -0
  66. package/src/config.ts +1 -1
  67. package/src/constants/banks.js +42 -0
  68. package/src/constants/banks.ts +6 -3
  69. package/src/constants/markets.js +42 -0
  70. package/src/constants/numericConstants.js +41 -0
  71. package/src/constants/numericConstants.ts +3 -0
  72. package/src/events/eventList.ts +3 -0
  73. package/src/events/types.ts +2 -0
  74. package/src/factory/bigNum.js +37 -11
  75. package/src/factory/bigNum.ts +43 -13
  76. package/src/idl/clearing_house.json +692 -58
  77. package/src/index.ts +1 -0
  78. package/src/math/amm.ts +8 -5
  79. package/src/math/bankBalance.ts +147 -1
  80. package/src/math/margin.ts +124 -0
  81. package/src/math/market.ts +66 -1
  82. package/src/math/oracles.ts +42 -5
  83. package/src/math/position.ts +60 -9
  84. package/src/math/trade.ts +2 -2
  85. package/src/orders.ts +4 -157
  86. package/src/tokenFaucet.js +189 -0
  87. package/src/tokenFaucet.ts +38 -15
  88. package/src/tx/retryTxSender.ts +11 -3
  89. package/src/types.js +12 -1
  90. package/src/types.ts +83 -10
  91. package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
  92. package/src/util/getTokenAddress.js +9 -0
  93. package/src/util/getTokenAddress.ts +18 -0
  94. package/tests/bn/test.ts +2 -0
  95. package/src/accounts/bulkAccountLoader.js +0 -197
  96. package/src/accounts/bulkUserSubscription.js +0 -33
  97. package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -311
  98. package/src/accounts/pollingOracleSubscriber.js +0 -93
  99. package/src/accounts/pollingTokenAccountSubscriber.js +0 -90
  100. package/src/accounts/pollingUserAccountSubscriber.js +0 -132
  101. package/src/accounts/types.js +0 -10
  102. package/src/accounts/utils.js +0 -7
  103. package/src/accounts/webSocketAccountSubscriber.js +0 -93
  104. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -233
  105. package/src/accounts/webSocketUserAccountSubscriber.js +0 -62
  106. package/src/addresses/pda.js +0 -104
  107. package/src/index.js +0 -100
  108. package/src/math/bankBalance.js +0 -75
  109. package/src/math/market.js +0 -57
  110. package/src/math/orders.js +0 -110
  111. package/src/math/position.js +0 -140
  112. package/src/mockUSDCFaucet.js +0 -280
  113. package/src/orders.js +0 -134
  114. package/src/tx/retryTxSender.js +0 -188
package/src/orders.ts CHANGED
@@ -1,163 +1,9 @@
1
- import {
2
- isVariant,
3
- MarketAccount,
4
- Order,
5
- PositionDirection,
6
- UserAccount,
7
- UserPosition,
8
- } from './types';
1
+ import { isVariant, MarketAccount, Order, PositionDirection } from './types';
9
2
  import { BN, standardizeBaseAssetAmount } from '.';
10
- import { calculateNewMarketAfterTrade } from './math/market';
11
- import {
12
- AMM_TO_QUOTE_PRECISION_RATIO,
13
- PEG_PRECISION,
14
- ZERO,
15
- } from './constants/numericConstants';
3
+ import { ZERO } from './constants/numericConstants';
16
4
  import { calculateMaxBaseAssetAmountToTrade } from './math/amm';
17
- import {
18
- findDirectionToClose,
19
- positionCurrentDirection,
20
- } from './math/position';
21
5
  import { OraclePriceData } from '.';
22
6
 
23
- export function calculateNewStateAfterOrder(
24
- userAccount: UserAccount,
25
- userPosition: UserPosition,
26
- market: MarketAccount,
27
- order: Order
28
- ): [UserAccount, UserPosition, MarketAccount] | null {
29
- if (isVariant(order.status, 'init')) {
30
- return null;
31
- }
32
-
33
- const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(
34
- market,
35
- order
36
- );
37
- if (baseAssetAmountToTrade.lt(market.amm.baseAssetAmountStepSize)) {
38
- return null;
39
- }
40
-
41
- const userAccountAfter = Object.assign({}, userAccount);
42
- const userPositionAfter = Object.assign({}, userPosition);
43
-
44
- const currentPositionDirection = positionCurrentDirection(userPosition);
45
- const increasePosition =
46
- userPosition.baseAssetAmount.eq(ZERO) ||
47
- isSameDirection(order.direction, currentPositionDirection);
48
-
49
- if (increasePosition) {
50
- const marketAfter = calculateNewMarketAfterTrade(
51
- baseAssetAmountToTrade,
52
- order.direction,
53
- market
54
- );
55
-
56
- const { quoteAssetAmountSwapped, baseAssetAmountSwapped } =
57
- calculateAmountSwapped(market, marketAfter);
58
-
59
- userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(
60
- baseAssetAmountSwapped
61
- );
62
- userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(
63
- quoteAssetAmountSwapped
64
- );
65
-
66
- return [userAccountAfter, userPositionAfter, marketAfter];
67
- } else {
68
- const reversePosition = baseAssetAmountToTrade.gt(
69
- userPosition.baseAssetAmount.abs()
70
- );
71
-
72
- if (reversePosition) {
73
- const intermediateMarket = calculateNewMarketAfterTrade(
74
- userPosition.baseAssetAmount,
75
- findDirectionToClose(userPosition),
76
- market
77
- );
78
-
79
- const { quoteAssetAmountSwapped: baseAssetValue } =
80
- calculateAmountSwapped(market, intermediateMarket);
81
-
82
- let pnl;
83
- if (isVariant(currentPositionDirection, 'long')) {
84
- pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
85
- } else {
86
- pnl = userPosition.quoteAssetAmount.sub(baseAssetValue);
87
- }
88
-
89
- userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
90
-
91
- const baseAssetAmountLeft = baseAssetAmountToTrade.sub(
92
- userPosition.baseAssetAmount.abs()
93
- );
94
-
95
- const marketAfter = calculateNewMarketAfterTrade(
96
- baseAssetAmountLeft,
97
- order.direction,
98
- intermediateMarket
99
- );
100
-
101
- const { quoteAssetAmountSwapped, baseAssetAmountSwapped } =
102
- calculateAmountSwapped(intermediateMarket, marketAfter);
103
-
104
- userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
105
- userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
106
-
107
- return [userAccountAfter, userPositionAfter, marketAfter];
108
- } else {
109
- const marketAfter = calculateNewMarketAfterTrade(
110
- baseAssetAmountToTrade,
111
- order.direction,
112
- market
113
- );
114
-
115
- const {
116
- quoteAssetAmountSwapped: baseAssetValue,
117
- baseAssetAmountSwapped,
118
- } = calculateAmountSwapped(market, marketAfter);
119
-
120
- const costBasisRealized = userPosition.quoteAssetAmount
121
- .mul(baseAssetAmountSwapped.abs())
122
- .div(userPosition.baseAssetAmount.abs());
123
-
124
- let pnl;
125
- if (isVariant(currentPositionDirection, 'long')) {
126
- pnl = baseAssetValue.sub(costBasisRealized);
127
- } else {
128
- pnl = costBasisRealized.sub(baseAssetValue);
129
- }
130
-
131
- userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
132
-
133
- userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(
134
- baseAssetAmountSwapped
135
- );
136
- userPositionAfter.quoteAssetAmount =
137
- userPositionAfter.quoteAssetAmount.sub(costBasisRealized);
138
-
139
- return [userAccountAfter, userPositionAfter, marketAfter];
140
- }
141
- }
142
- }
143
-
144
- function calculateAmountSwapped(
145
- marketBefore: MarketAccount,
146
- marketAfter: MarketAccount
147
- ): { quoteAssetAmountSwapped: BN; baseAssetAmountSwapped: BN } {
148
- return {
149
- quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
150
- .sub(marketAfter.amm.quoteAssetReserve)
151
- .abs()
152
- .mul(marketBefore.amm.pegMultiplier)
153
- .div(PEG_PRECISION)
154
- .div(AMM_TO_QUOTE_PRECISION_RATIO),
155
- baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(
156
- marketAfter.amm.baseAssetReserve
157
- ),
158
- };
159
- }
160
-
161
7
  export function calculateBaseAssetAmountMarketCanExecute(
162
8
  market: MarketAccount,
163
9
  order: Order,
@@ -192,7 +38,8 @@ export function calculateAmountToTradeForLimit(
192
38
  const [maxAmountToTrade, direction] = calculateMaxBaseAssetAmountToTrade(
193
39
  market.amm,
194
40
  limitPrice,
195
- order.direction
41
+ order.direction,
42
+ oraclePriceData
196
43
  );
197
44
 
198
45
  const baseAssetAmount = standardizeBaseAssetAmount(
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __importDefault = (this && this.__importDefault) || function (mod) {
31
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.TokenFaucet = void 0;
35
+ const anchor = __importStar(require("@project-serum/anchor"));
36
+ const anchor_1 = require("@project-serum/anchor");
37
+ const spl_token_1 = require("@solana/spl-token");
38
+ const web3_js_1 = require("@solana/web3.js");
39
+ const token_faucet_json_1 = __importDefault(require("./idl/token_faucet.json"));
40
+ class TokenFaucet {
41
+ constructor(connection, wallet, programId, mint, opts) {
42
+ this.connection = connection;
43
+ this.wallet = wallet;
44
+ this.opts = opts || anchor_1.AnchorProvider.defaultOptions();
45
+ const provider = new anchor_1.AnchorProvider(connection, wallet, this.opts);
46
+ this.provider = provider;
47
+ this.program = new anchor_1.Program(token_faucet_json_1.default, programId, provider);
48
+ this.mint = mint;
49
+ }
50
+ getFaucetConfigPublicKeyAndNonce() {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ return anchor.web3.PublicKey.findProgramAddress([
53
+ Buffer.from(anchor.utils.bytes.utf8.encode('faucet_config')),
54
+ this.mint.toBuffer(),
55
+ ], this.program.programId);
56
+ });
57
+ }
58
+ getMintAuthority() {
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ return (yield anchor.web3.PublicKey.findProgramAddress([
61
+ Buffer.from(anchor.utils.bytes.utf8.encode('mint_authority')),
62
+ this.mint.toBuffer(),
63
+ ], this.program.programId))[0];
64
+ });
65
+ }
66
+ getFaucetConfigPublicKey() {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ return (yield this.getFaucetConfigPublicKeyAndNonce())[0];
69
+ });
70
+ }
71
+ initialize() {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ const [faucetConfigPublicKey] = yield this.getFaucetConfigPublicKeyAndNonce();
74
+ return yield this.program.rpc.initialize({
75
+ accounts: {
76
+ faucetConfig: faucetConfigPublicKey,
77
+ admin: this.wallet.publicKey,
78
+ mintAccount: this.mint,
79
+ rent: web3_js_1.SYSVAR_RENT_PUBKEY,
80
+ systemProgram: anchor.web3.SystemProgram.programId,
81
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
82
+ },
83
+ });
84
+ });
85
+ }
86
+ fetchState() {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ return yield this.program.account.faucetConfig.fetch(yield this.getFaucetConfigPublicKey());
89
+ });
90
+ }
91
+ mintToUserIx(userTokenAccount, amount) {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ return this.program.instruction.mintToUser(amount, {
94
+ accounts: {
95
+ faucetConfig: yield this.getFaucetConfigPublicKey(),
96
+ mintAccount: this.mint,
97
+ userTokenAccount,
98
+ mintAuthority: yield this.getMintAuthority(),
99
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
100
+ },
101
+ });
102
+ });
103
+ }
104
+ mintToUser(userTokenAccount, amount) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ const mintIx = yield this.mintToUserIx(userTokenAccount, amount);
107
+ const tx = new web3_js_1.Transaction().add(mintIx);
108
+ const txSig = yield this.program.provider.sendAndConfirm(tx, [], this.opts);
109
+ return txSig;
110
+ });
111
+ }
112
+ transferMintAuthority() {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ return yield this.program.rpc.transferMintAuthority({
115
+ accounts: {
116
+ faucetConfig: yield this.getFaucetConfigPublicKey(),
117
+ mintAccount: this.mint,
118
+ mintAuthority: yield this.getMintAuthority(),
119
+ tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
120
+ admin: this.wallet.publicKey,
121
+ },
122
+ });
123
+ });
124
+ }
125
+ createAssociatedTokenAccountAndMintTo(userPublicKey, amount) {
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ const tx = new web3_js_1.Transaction();
128
+ const [associatedTokenPublicKey, createAssociatedAccountIx, mintToTx] = yield this.createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount);
129
+ let associatedTokenAccountExists = false;
130
+ try {
131
+ const assosciatedTokenAccount = yield this.connection.getAccountInfo(associatedTokenPublicKey);
132
+ associatedTokenAccountExists = !!assosciatedTokenAccount;
133
+ }
134
+ catch (e) {
135
+ // token account doesn't exist
136
+ associatedTokenAccountExists = false;
137
+ }
138
+ const skipAccountCreation = associatedTokenAccountExists;
139
+ if (!skipAccountCreation)
140
+ tx.add(createAssociatedAccountIx);
141
+ tx.add(mintToTx);
142
+ const txSig = yield this.program.provider.sendAndConfirm(tx, [], this.opts);
143
+ return [associatedTokenPublicKey, txSig];
144
+ });
145
+ }
146
+ createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount) {
147
+ return __awaiter(this, void 0, void 0, function* () {
148
+ const state = yield this.fetchState();
149
+ const associateTokenPublicKey = yield this.getAssosciatedMockUSDMintAddress({ userPubKey: userPublicKey });
150
+ const createAssociatedAccountIx = spl_token_1.Token.createAssociatedTokenAccountInstruction(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, state.mint, associateTokenPublicKey, userPublicKey, this.wallet.publicKey);
151
+ const mintToIx = yield this.mintToUserIx(associateTokenPublicKey, amount);
152
+ return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
153
+ });
154
+ }
155
+ getAssosciatedMockUSDMintAddress(props) {
156
+ return __awaiter(this, void 0, void 0, function* () {
157
+ const state = yield this.fetchState();
158
+ return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, state.mint, props.userPubKey);
159
+ });
160
+ }
161
+ getTokenAccountInfo(props) {
162
+ return __awaiter(this, void 0, void 0, function* () {
163
+ const assosciatedKey = yield this.getAssosciatedMockUSDMintAddress(props);
164
+ const state = yield this.fetchState();
165
+ const token = new spl_token_1.Token(this.connection, state.mint, spl_token_1.TOKEN_PROGRAM_ID,
166
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
167
+ // @ts-ignore
168
+ this.provider.payer);
169
+ return yield token.getAccountInfo(assosciatedKey);
170
+ });
171
+ }
172
+ subscribeToTokenAccount(props) {
173
+ return __awaiter(this, void 0, void 0, function* () {
174
+ try {
175
+ const tokenAccountKey = yield this.getAssosciatedMockUSDMintAddress(props);
176
+ props.callback(yield this.getTokenAccountInfo(props));
177
+ // Couldn't find a way to do it using anchor framework subscription, someone on serum discord recommended this way
178
+ this.connection.onAccountChange(tokenAccountKey, (_accountInfo /* accountInfo is a buffer which we don't know how to deserialize */) => __awaiter(this, void 0, void 0, function* () {
179
+ props.callback(yield this.getTokenAccountInfo(props));
180
+ }));
181
+ return true;
182
+ }
183
+ catch (e) {
184
+ return false;
185
+ }
186
+ });
187
+ }
188
+ }
189
+ exports.TokenFaucet = TokenFaucet;
@@ -92,11 +92,8 @@ export class TokenFaucet {
92
92
  );
93
93
  }
94
94
 
95
- public async mintToUser(
96
- userTokenAccount: PublicKey,
97
- amount: BN
98
- ): Promise<TransactionSignature> {
99
- return await this.program.rpc.mintToUser(amount, {
95
+ private async mintToUserIx(userTokenAccount: PublicKey, amount: BN) {
96
+ return this.program.instruction.mintToUser(amount, {
100
97
  accounts: {
101
98
  faucetConfig: await this.getFaucetConfigPublicKey(),
102
99
  mintAccount: this.mint,
@@ -107,6 +104,19 @@ export class TokenFaucet {
107
104
  });
108
105
  }
109
106
 
107
+ public async mintToUser(
108
+ userTokenAccount: PublicKey,
109
+ amount: BN
110
+ ): Promise<TransactionSignature> {
111
+ const mintIx = await this.mintToUserIx(userTokenAccount, amount);
112
+
113
+ const tx = new Transaction().add(mintIx);
114
+
115
+ const txSig = await this.program.provider.sendAndConfirm(tx, [], this.opts);
116
+
117
+ return txSig;
118
+ }
119
+
110
120
  public async transferMintAuthority(): Promise<TransactionSignature> {
111
121
  return await this.program.rpc.transferMintAuthority({
112
122
  accounts: {
@@ -123,12 +133,33 @@ export class TokenFaucet {
123
133
  userPublicKey: PublicKey,
124
134
  amount: BN
125
135
  ): Promise<[PublicKey, TransactionSignature]> {
136
+ const tx = new Transaction();
137
+
126
138
  const [associatedTokenPublicKey, createAssociatedAccountIx, mintToTx] =
127
139
  await this.createAssociatedTokenAccountAndMintToInstructions(
128
140
  userPublicKey,
129
141
  amount
130
142
  );
131
- const tx = new Transaction().add(createAssociatedAccountIx).add(mintToTx);
143
+
144
+ let associatedTokenAccountExists = false;
145
+
146
+ try {
147
+ const assosciatedTokenAccount = await this.connection.getAccountInfo(
148
+ associatedTokenPublicKey
149
+ );
150
+
151
+ associatedTokenAccountExists = !!assosciatedTokenAccount;
152
+ } catch (e) {
153
+ // token account doesn't exist
154
+ associatedTokenAccountExists = false;
155
+ }
156
+
157
+ const skipAccountCreation = associatedTokenAccountExists;
158
+
159
+ if (!skipAccountCreation) tx.add(createAssociatedAccountIx);
160
+
161
+ tx.add(mintToTx);
162
+
132
163
  const txSig = await this.program.provider.sendAndConfirm(tx, [], this.opts);
133
164
  return [associatedTokenPublicKey, txSig];
134
165
  }
@@ -153,15 +184,7 @@ export class TokenFaucet {
153
184
  this.wallet.publicKey
154
185
  );
155
186
 
156
- const mintToIx = await this.program.instruction.mintToUser(amount, {
157
- accounts: {
158
- faucetConfig: await this.getFaucetConfigPublicKey(),
159
- mintAccount: state.mint,
160
- userTokenAccount: associateTokenPublicKey,
161
- mintAuthority: state.mintAuthority,
162
- tokenProgram: TOKEN_PROGRAM_ID,
163
- },
164
- });
187
+ const mintToIx = await this.mintToUserIx(associateTokenPublicKey, amount);
165
188
 
166
189
  return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
167
190
  }
@@ -56,9 +56,17 @@ export class RetryTxSender implements TxSender {
56
56
  const rawTransaction = tx.serialize();
57
57
  const startTime = this.getTimestamp();
58
58
 
59
- const txid: TransactionSignature =
60
- await this.provider.connection.sendRawTransaction(rawTransaction, opts);
61
- this.sendToAdditionalConnections(rawTransaction, opts);
59
+ let txid: TransactionSignature;
60
+ try {
61
+ txid = await this.provider.connection.sendRawTransaction(
62
+ rawTransaction,
63
+ opts
64
+ );
65
+ this.sendToAdditionalConnections(rawTransaction, opts);
66
+ } catch (e) {
67
+ console.error(e);
68
+ throw e;
69
+ }
62
70
 
63
71
  let done = false;
64
72
  const resolveReference: ResolveReference = {
package/src/types.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DefaultOrderParams = exports.TradeSide = exports.isOneOfVariant = exports.isVariant = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.BankBalanceType = exports.SwapDirection = void 0;
3
+ exports.DefaultOrderParams = exports.LiquidationType = exports.TradeSide = exports.isOneOfVariant = exports.isVariant = exports.OrderTriggerCondition = exports.OrderActionExplanation = exports.OrderAction = exports.OrderDiscountTier = exports.OrderStatus = exports.OrderType = exports.OracleSource = exports.DepositDirection = exports.PositionDirection = exports.BankBalanceType = exports.SwapDirection = void 0;
4
4
  const _1 = require(".");
5
5
  // # Utility Types / Enums / Constants
6
6
  class SwapDirection {
@@ -91,6 +91,17 @@ var TradeSide;
91
91
  TradeSide[TradeSide["Buy"] = 1] = "Buy";
92
92
  TradeSide[TradeSide["Sell"] = 2] = "Sell";
93
93
  })(TradeSide = exports.TradeSide || (exports.TradeSide = {}));
94
+ class LiquidationType {
95
+ }
96
+ exports.LiquidationType = LiquidationType;
97
+ LiquidationType.LIQUIDATE_PERP = { liquidatePerp: {} };
98
+ LiquidationType.LIQUIDATE_BORROW = { liquidateBorrow: {} };
99
+ LiquidationType.LIQUIDATE_BORROW_FOR_PERP_PNL = {
100
+ liquidateBorrowForPerpPnl: {},
101
+ };
102
+ LiquidationType.LIQUIDATE_PERP_PNL_FOR_DEPOSIT = {
103
+ liquidatePerpPnlForDeposit: {},
104
+ };
94
105
  exports.DefaultOrderParams = {
95
106
  orderType: OrderType.MARKET,
96
107
  userOrderId: 0,
package/src/types.ts CHANGED
@@ -67,6 +67,12 @@ export class OrderActionExplanation {
67
67
  static readonly MARKET_ORDER_FILLED_TO_LIMIT_PRICE = {
68
68
  marketOrderFilledToLimitPrice: {},
69
69
  };
70
+ static readonly CANCELED_FOR_LIQUIDATION = {
71
+ canceledForLiquidation: {},
72
+ };
73
+ static readonly MARKET_ORDER_AUCTION_EXPIRED = {
74
+ marketOrderAuctionExpired: {},
75
+ };
70
76
  }
71
77
 
72
78
  export class OrderTriggerCondition {
@@ -166,10 +172,13 @@ export type LiquidationRecord = {
166
172
  liquidationType: LiquidationType;
167
173
  marginRequirement: BN;
168
174
  totalCollateral: BN;
175
+ liquidationId: number;
169
176
  liquidatePerp: LiquidatePerpRecord;
170
177
  liquidateBorrow: LiquidateBorrowRecord;
171
178
  liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
172
179
  liquidatePerpPnlForDeposit: LiquidatePerpPnlForDepositRecord;
180
+ perpBankruptcy: PerpBankruptcyRecord;
181
+ borrowBankruptcy: BorrowBankruptcyRecord;
173
182
  };
174
183
 
175
184
  export class LiquidationType {
@@ -181,6 +190,12 @@ export class LiquidationType {
181
190
  static readonly LIQUIDATE_PERP_PNL_FOR_DEPOSIT = {
182
191
  liquidatePerpPnlForDeposit: {},
183
192
  };
193
+ static readonly PERP_BANKRUPTCY = {
194
+ perpBankruptcy: {},
195
+ };
196
+ static readonly BORROW_BANKRUPTCY = {
197
+ borrowBankruptcy: {},
198
+ };
184
199
  }
185
200
 
186
201
  export type LiquidatePerpRecord = {
@@ -224,14 +239,37 @@ export type LiquidatePerpPnlForDepositRecord = {
224
239
  assetTransfer: BN;
225
240
  };
226
241
 
242
+ export type PerpBankruptcyRecord = {
243
+ marketIndex: BN;
244
+ pnl: BN;
245
+ cumulativeFundingRateDelta: BN;
246
+ };
247
+
248
+ export type BorrowBankruptcyRecord = {
249
+ bankIndex: BN;
250
+ borrowAmount: BN;
251
+ cumulativeDepositInterestDelta: BN;
252
+ };
253
+
254
+ export type SettlePnlRecord = {
255
+ ts: BN;
256
+ user: PublicKey;
257
+ marketIndex: BN;
258
+ pnl: BN;
259
+ baseAssetAmount: BN;
260
+ quoteAssetAmountAfter: BN;
261
+ quoteEntryamount: BN;
262
+ settlePrice: BN;
263
+ };
264
+
227
265
  export type OrderRecord = {
228
266
  ts: BN;
229
267
  taker: PublicKey;
230
268
  maker: PublicKey;
231
269
  takerOrder: Order;
232
270
  makerOrder: Order;
233
- takerUnsettledPnl: BN;
234
- makerUnsettledPnl: BN;
271
+ takerPnl: BN;
272
+ makerPnl: BN;
235
273
  action: OrderAction;
236
274
  actionExplanation: OrderActionExplanation;
237
275
  filler: PublicKey;
@@ -291,6 +329,10 @@ export type MarketAccount = {
291
329
  nextFillRecordId: BN;
292
330
  pnlPool: PoolBalance;
293
331
  liquidationFee: BN;
332
+ imfFactor: BN;
333
+ unsettledImfFactor: BN;
334
+ unsettledInitialAssetWeight: number;
335
+ unsettledMaintenanceAssetWeight: number;
294
336
  };
295
337
 
296
338
  export type BankAccount = {
@@ -315,6 +357,12 @@ export type BankAccount = {
315
357
  initialLiabilityWeight: BN;
316
358
  maintenanceLiabilityWeight: BN;
317
359
  liquidationFee: BN;
360
+ imfFactor: BN;
361
+
362
+ withdrawGuardThreshold: BN;
363
+ depositTokenTwap: BN;
364
+ borrowTokenTwap: BN;
365
+ utilizationTwap: BN;
318
366
  };
319
367
 
320
368
  export type PoolBalance = {
@@ -328,8 +376,10 @@ export type AMM = {
328
376
  lastFundingRate: BN;
329
377
  lastFundingRateTs: BN;
330
378
  lastMarkPriceTwap: BN;
379
+ lastMarkPriceTwap5min: BN;
331
380
  lastMarkPriceTwapTs: BN;
332
381
  lastOraclePriceTwap: BN;
382
+ lastOraclePriceTwap5min: BN;
333
383
  lastOraclePriceTwapTs: BN;
334
384
  lastOracleMarkSpreadPct: BN;
335
385
  lastOracleConfPct: BN;
@@ -340,11 +390,16 @@ export type AMM = {
340
390
  pegMultiplier: BN;
341
391
  cumulativeFundingRateLong: BN;
342
392
  cumulativeFundingRateShort: BN;
393
+ cumulativeFundingRateLp: BN;
343
394
  cumulativeRepegRebateLong: BN;
344
395
  cumulativeRepegRebateShort: BN;
345
396
  totalFeeMinusDistributions: BN;
346
397
  totalFeeWithdrawn: BN;
347
398
  totalFee: BN;
399
+ cumulativeFundingPaymentPerLp: BN;
400
+ cumulativeFeePerLp: BN;
401
+ cumulativeNetBaseAssetAmountPerLp: BN;
402
+ userLpShares: BN;
348
403
  minimumQuoteAssetTradeSize: BN;
349
404
  baseAssetAmountStepSize: BN;
350
405
  maxBaseAssetAmountRatio: number;
@@ -366,6 +421,8 @@ export type AMM = {
366
421
  longSpread: BN;
367
422
  shortSpread: BN;
368
423
  maxSpread: number;
424
+ marketPosition: UserPosition;
425
+ marketPositionPerLp: UserPosition;
369
426
  };
370
427
 
371
428
  // # User Account Types
@@ -376,18 +433,23 @@ export type UserPosition = {
376
433
  quoteAssetAmount: BN;
377
434
  quoteEntryAmount: BN;
378
435
  openOrders: BN;
379
- unsettledPnl: BN;
380
436
  openBids: BN;
381
437
  openAsks: BN;
438
+ realizedPnl: BN;
439
+ lpShares: BN;
440
+ lastFeePerLp: BN;
441
+ lastNetBaseAssetAmountPerLp: BN;
442
+ lastNetQuoteAssetAmountPerLp: BN;
382
443
  };
383
444
 
384
- export type UserAccount = {
385
- authority: PublicKey;
386
- name: number[];
387
- userId: number;
388
- bankBalances: UserBankBalance[];
389
- collateral: BN;
390
- cumulativeDeposits: BN;
445
+ export type UserStatsAccount = {
446
+ numberOfUsers: number;
447
+ makerVolume30D: BN;
448
+ takerVolume30D: BN;
449
+ fillerVolume30D: BN;
450
+ lastMakerVolume30DTs: BN;
451
+ lastTakerVolume30DTs: BN;
452
+ lastFillerVolume30DTs: BN;
391
453
  fees: {
392
454
  totalFeePaid: BN;
393
455
  totalFeeRebate: BN;
@@ -395,9 +457,18 @@ export type UserAccount = {
395
457
  totalReferralReward: BN;
396
458
  totalRefereeDiscount: BN;
397
459
  };
460
+ };
461
+
462
+ export type UserAccount = {
463
+ authority: PublicKey;
464
+ name: number[];
465
+ userId: number;
466
+ bankBalances: UserBankBalance[];
398
467
  positions: UserPosition[];
399
468
  orders: Order[];
400
469
  beingLiquidated: boolean;
470
+ bankrupt: boolean;
471
+ nextLiquidationId: number;
401
472
  };
402
473
 
403
474
  export type UserBankBalance = {
@@ -493,11 +564,13 @@ export const DefaultOrderParams = {
493
564
 
494
565
  export type MakerInfo = {
495
566
  maker: PublicKey;
567
+ makerStats: PublicKey;
496
568
  order: Order;
497
569
  };
498
570
 
499
571
  export type TakerInfo = {
500
572
  taker: PublicKey;
573
+ takerStats: PublicKey;
501
574
  order: Order;
502
575
  };
503
576