@drift-labs/sdk 0.2.0-master.11 → 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.
Files changed (72) hide show
  1. package/lib/clearingHouse.d.ts +7 -2
  2. package/lib/clearingHouse.js +157 -37
  3. package/lib/clearingHouseUser.d.ts +10 -15
  4. package/lib/clearingHouseUser.js +92 -74
  5. package/lib/config.js +1 -1
  6. package/lib/constants/banks.d.ts +2 -2
  7. package/lib/constants/banks.js +4 -3
  8. package/lib/constants/numericConstants.d.ts +2 -0
  9. package/lib/constants/numericConstants.js +3 -1
  10. package/lib/events/eventList.js +3 -0
  11. package/lib/events/types.d.ts +2 -1
  12. package/lib/factory/bigNum.d.ts +1 -0
  13. package/lib/factory/bigNum.js +37 -11
  14. package/lib/idl/clearing_house.json +97 -19
  15. package/lib/index.d.ts +1 -0
  16. package/lib/index.js +1 -0
  17. package/lib/math/bankBalance.d.ts +3 -1
  18. package/lib/math/bankBalance.js +54 -1
  19. package/lib/math/margin.d.ts +11 -0
  20. package/lib/math/margin.js +72 -0
  21. package/lib/math/market.d.ts +4 -1
  22. package/lib/math/market.js +35 -1
  23. package/lib/math/position.d.ts +8 -0
  24. package/lib/math/position.js +42 -12
  25. package/lib/orders.d.ts +1 -2
  26. package/lib/orders.js +2 -77
  27. package/lib/tokenFaucet.d.ts +1 -0
  28. package/lib/tokenFaucet.js +23 -12
  29. package/lib/tx/retryTxSender.js +9 -2
  30. package/lib/types.d.ts +24 -3
  31. package/lib/types.js +6 -0
  32. package/lib/util/getTokenAddress.d.ts +2 -0
  33. package/lib/util/getTokenAddress.js +9 -0
  34. package/package.json +1 -1
  35. package/src/clearingHouse.ts +301 -47
  36. package/src/clearingHouseConfig.js +2 -0
  37. package/src/clearingHouseUser.ts +213 -104
  38. package/src/clearingHouseUserConfig.js +2 -0
  39. package/src/config.ts +1 -1
  40. package/src/constants/banks.js +42 -0
  41. package/src/constants/banks.ts +6 -3
  42. package/src/constants/markets.js +42 -0
  43. package/src/constants/numericConstants.js +41 -0
  44. package/src/constants/numericConstants.ts +3 -0
  45. package/src/events/eventList.ts +3 -0
  46. package/src/events/types.ts +2 -0
  47. package/src/factory/bigNum.js +37 -11
  48. package/src/factory/bigNum.ts +43 -13
  49. package/src/idl/clearing_house.json +97 -19
  50. package/src/index.js +67 -98
  51. package/src/index.ts +1 -0
  52. package/src/math/bankBalance.ts +98 -1
  53. package/src/math/margin.ts +124 -0
  54. package/src/math/market.ts +66 -1
  55. package/src/math/position.ts +59 -9
  56. package/src/orders.ts +4 -157
  57. package/src/tokenFaucet.js +189 -0
  58. package/src/tokenFaucet.ts +38 -15
  59. package/src/tx/retryTxSender.ts +11 -3
  60. package/src/types.js +12 -1
  61. package/src/types.ts +25 -3
  62. package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
  63. package/src/util/getTokenAddress.js +9 -0
  64. package/src/util/getTokenAddress.ts +18 -0
  65. package/tests/bn/test.ts +2 -0
  66. package/src/addresses/pda.js +0 -104
  67. package/src/math/bankBalance.js +0 -75
  68. package/src/math/market.js +0 -57
  69. package/src/math/orders.js +0 -110
  70. package/src/math/position.js +0 -140
  71. package/src/orders.js +0 -134
  72. 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,6 +172,7 @@ 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;
@@ -224,14 +231,24 @@ export type LiquidatePerpPnlForDepositRecord = {
224
231
  assetTransfer: BN;
225
232
  };
226
233
 
234
+ export type SettlePnlRecord = {
235
+ ts: BN;
236
+ marketIndex: BN;
237
+ pnl: BN;
238
+ baseAssetAmount: BN;
239
+ quoteAssetAmountAfter: BN;
240
+ quoteEntryamount: BN;
241
+ oraclePrice: BN;
242
+ };
243
+
227
244
  export type OrderRecord = {
228
245
  ts: BN;
229
246
  taker: PublicKey;
230
247
  maker: PublicKey;
231
248
  takerOrder: Order;
232
249
  makerOrder: Order;
233
- takerUnsettledPnl: BN;
234
- makerUnsettledPnl: BN;
250
+ takerPnl: BN;
251
+ makerPnl: BN;
235
252
  action: OrderAction;
236
253
  actionExplanation: OrderActionExplanation;
237
254
  filler: PublicKey;
@@ -291,6 +308,10 @@ export type MarketAccount = {
291
308
  nextFillRecordId: BN;
292
309
  pnlPool: PoolBalance;
293
310
  liquidationFee: BN;
311
+ imfFactor: BN;
312
+ unsettledImfFactor: BN;
313
+ unsettledInitialAssetWeight: number;
314
+ unsettledMaintenanceAssetWeight: number;
294
315
  };
295
316
 
296
317
  export type BankAccount = {
@@ -315,6 +336,7 @@ export type BankAccount = {
315
336
  initialLiabilityWeight: BN;
316
337
  maintenanceLiabilityWeight: BN;
317
338
  liquidationFee: BN;
339
+ imfFactor: BN;
318
340
  };
319
341
 
320
342
  export type PoolBalance = {
@@ -376,7 +398,6 @@ export type UserPosition = {
376
398
  quoteAssetAmount: BN;
377
399
  quoteEntryAmount: BN;
378
400
  openOrders: BN;
379
- unsettledPnl: BN;
380
401
  openBids: BN;
381
402
  openAsks: BN;
382
403
  };
@@ -398,6 +419,7 @@ export type UserAccount = {
398
419
  positions: UserPosition[];
399
420
  orders: Order[];
400
421
  beingLiquidated: boolean;
422
+ nextLiquidationId: number;
401
423
  };
402
424
 
403
425
  export type UserBankBalance = {
@@ -9,21 +9,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.fetchUserAccounts = void 0;
13
- const pda_1 = require("../addresses/pda");
14
- function fetchUserAccounts(connection, program, authority, limit = 8) {
12
+ exports.findComputeUnitConsumption = void 0;
13
+ function findComputeUnitConsumption(programId, connection, txSignature, commitment = 'confirmed') {
15
14
  return __awaiter(this, void 0, void 0, function* () {
16
- const userAccountPublicKeys = new Array();
17
- for (let i = 0; i < limit; i++) {
18
- userAccountPublicKeys.push(yield pda_1.getUserAccountPublicKey(program.programId, authority, i));
19
- }
20
- const accountInfos = yield connection.getMultipleAccountsInfo(userAccountPublicKeys, 'confirmed');
21
- return accountInfos.map((accountInfo) => {
22
- if (!accountInfo) {
23
- return undefined;
15
+ const tx = yield connection.getTransaction(txSignature, { commitment });
16
+ const computeUnits = [];
17
+ const regex = new RegExp(`Program ${programId.toString()} consumed ([0-9]{0,6}) of ([0-9]{0,7}) compute units`);
18
+ tx.meta.logMessages.forEach((logMessage) => {
19
+ const match = logMessage.match(regex);
20
+ if (match && match[1]) {
21
+ computeUnits.push(match[1]);
24
22
  }
25
- return program.account.user.coder.accounts.decode('User', accountInfo.data);
26
23
  });
24
+ return computeUnits;
27
25
  });
28
26
  }
29
- exports.fetchUserAccounts = fetchUserAccounts;
27
+ exports.findComputeUnitConsumption = findComputeUnitConsumption;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTokenAddress = void 0;
4
+ const spl_token_1 = require("@solana/spl-token");
5
+ const web3_js_1 = require("@solana/web3.js");
6
+ const getTokenAddress = (mintAddress, userPubKey) => {
7
+ return spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, new web3_js_1.PublicKey(mintAddress), new web3_js_1.PublicKey(userPubKey));
8
+ };
9
+ exports.getTokenAddress = getTokenAddress;
@@ -0,0 +1,18 @@
1
+ import {
2
+ Token,
3
+ ASSOCIATED_TOKEN_PROGRAM_ID,
4
+ TOKEN_PROGRAM_ID,
5
+ } from '@solana/spl-token';
6
+ import { PublicKey } from '@solana/web3.js';
7
+
8
+ export const getTokenAddress = (
9
+ mintAddress: string,
10
+ userPubKey: string
11
+ ): Promise<PublicKey> => {
12
+ return Token.getAssociatedTokenAddress(
13
+ ASSOCIATED_TOKEN_PROGRAM_ID,
14
+ TOKEN_PROGRAM_ID,
15
+ new PublicKey(mintAddress),
16
+ new PublicKey(userPubKey)
17
+ );
18
+ };
package/tests/bn/test.ts CHANGED
@@ -125,6 +125,8 @@ describe('BigNum Tests', () => {
125
125
  expect(BigNum.fromPrint('1234567').toMillified(5)).to.equal('1.2345M');
126
126
  expect(BigNum.fromPrint('12345678').toMillified(5)).to.equal('12.345M');
127
127
  expect(BigNum.fromPrint('123456789').toMillified(5)).to.equal('123.45M');
128
+
129
+ expect(BigNum.from(-95, 2).print()).to.equal('-0.95');
128
130
  });
129
131
 
130
132
  it('can initialise from string values correctly', () => {