@drift-labs/sdk 0.1.36-master.7 → 0.2.0-master.10

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 (254) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +6 -6
  2. package/lib/accounts/bulkAccountLoader.js +81 -95
  3. package/lib/accounts/bulkUserSubscription.js +13 -57
  4. package/lib/accounts/fetch.d.ts +4 -0
  5. package/lib/accounts/fetch.js +18 -0
  6. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +34 -38
  7. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +224 -224
  8. package/lib/accounts/pollingOracleSubscriber.d.ts +3 -3
  9. package/lib/accounts/pollingOracleSubscriber.js +37 -49
  10. package/lib/accounts/pollingTokenAccountSubscriber.d.ts +3 -3
  11. package/lib/accounts/pollingTokenAccountSubscriber.js +35 -50
  12. package/lib/accounts/pollingUserAccountSubscriber.d.ts +7 -13
  13. package/lib/accounts/pollingUserAccountSubscriber.js +71 -134
  14. package/lib/accounts/types.d.ts +34 -41
  15. package/lib/accounts/webSocketAccountSubscriber.d.ts +6 -4
  16. package/lib/accounts/webSocketAccountSubscriber.js +39 -35
  17. package/lib/accounts/webSocketClearingHouseAccountSubscriber.d.ts +33 -28
  18. package/lib/accounts/webSocketClearingHouseAccountSubscriber.js +153 -185
  19. package/lib/accounts/webSocketUserAccountSubscriber.d.ts +5 -11
  20. package/lib/accounts/webSocketUserAccountSubscriber.js +22 -67
  21. package/lib/addresses/marketAddresses.d.ts +4 -0
  22. package/lib/addresses/marketAddresses.js +15 -0
  23. package/lib/addresses/pda.d.ts +12 -0
  24. package/lib/addresses/pda.js +83 -0
  25. package/lib/admin.d.ts +12 -18
  26. package/lib/admin.js +398 -558
  27. package/lib/clearingHouse.d.ts +83 -109
  28. package/lib/clearingHouse.js +832 -893
  29. package/lib/clearingHouseConfig.d.ts +34 -0
  30. package/lib/clearingHouseConfig.js +2 -0
  31. package/lib/clearingHouseUser.d.ts +19 -22
  32. package/lib/clearingHouseUser.js +155 -141
  33. package/lib/clearingHouseUserConfig.d.ts +14 -0
  34. package/lib/clearingHouseUserConfig.js +2 -0
  35. package/lib/config.d.ts +12 -0
  36. package/lib/config.js +35 -4
  37. package/lib/constants/banks.d.ts +16 -0
  38. package/lib/constants/banks.js +41 -0
  39. package/lib/constants/markets.d.ts +8 -3
  40. package/lib/constants/markets.js +13 -206
  41. package/lib/constants/numericConstants.d.ts +17 -0
  42. package/lib/constants/numericConstants.js +23 -6
  43. package/lib/events/eventList.d.ts +22 -0
  44. package/lib/events/eventList.js +77 -0
  45. package/lib/events/eventSubscriber.d.ts +34 -0
  46. package/lib/events/eventSubscriber.js +126 -0
  47. package/lib/events/fetchLogs.d.ts +13 -0
  48. package/lib/events/fetchLogs.js +39 -0
  49. package/lib/events/pollingLogProvider.d.ts +15 -0
  50. package/lib/events/pollingLogProvider.js +53 -0
  51. package/lib/events/sort.d.ts +2 -0
  52. package/lib/events/sort.js +44 -0
  53. package/lib/events/txEventCache.d.ts +24 -0
  54. package/lib/events/txEventCache.js +71 -0
  55. package/lib/events/types.d.ts +49 -0
  56. package/lib/events/types.js +20 -0
  57. package/lib/events/webSocketLogProvider.d.ts +12 -0
  58. package/lib/events/webSocketLogProvider.js +30 -0
  59. package/lib/examples/makeTradeExample.js +26 -27
  60. package/lib/factory/bigNum.d.ts +118 -0
  61. package/lib/factory/bigNum.js +364 -0
  62. package/lib/factory/oracleClient.d.ts +1 -2
  63. package/lib/factory/oracleClient.js +6 -2
  64. package/lib/idl/clearing_house.json +2258 -2774
  65. package/lib/index.d.ts +14 -5
  66. package/lib/index.js +18 -5
  67. package/lib/math/amm.d.ts +24 -29
  68. package/lib/math/amm.js +209 -176
  69. package/lib/math/auction.d.ts +5 -0
  70. package/lib/math/auction.js +42 -0
  71. package/lib/math/bankBalance.d.ts +9 -0
  72. package/lib/math/bankBalance.js +75 -0
  73. package/lib/math/conversion.d.ts +0 -1
  74. package/lib/math/conversion.js +1 -5
  75. package/lib/math/funding.d.ts +6 -6
  76. package/lib/math/funding.js +158 -175
  77. package/lib/math/market.d.ts +6 -6
  78. package/lib/math/market.js +10 -9
  79. package/lib/math/orders.d.ts +6 -1
  80. package/lib/math/orders.js +38 -1
  81. package/lib/math/position.d.ts +7 -5
  82. package/lib/math/position.js +29 -27
  83. package/lib/math/repeg.d.ts +22 -0
  84. package/lib/math/repeg.js +128 -0
  85. package/lib/math/trade.d.ts +5 -4
  86. package/lib/math/trade.js +29 -24
  87. package/lib/mockUSDCFaucet.js +87 -116
  88. package/lib/oracles/oracleClientCache.d.ts +8 -0
  89. package/lib/oracles/oracleClientCache.js +19 -0
  90. package/lib/oracles/pythClient.d.ts +3 -5
  91. package/lib/oracles/pythClient.js +12 -31
  92. package/lib/oracles/quoteAssetOracleClient.d.ts +9 -0
  93. package/lib/oracles/quoteAssetOracleClient.js +21 -0
  94. package/lib/oracles/switchboardClient.d.ts +3 -5
  95. package/lib/oracles/switchboardClient.js +29 -50
  96. package/lib/oracles/types.d.ts +6 -1
  97. package/lib/orderParams.d.ts +14 -5
  98. package/lib/orderParams.js +8 -96
  99. package/lib/orders.d.ts +6 -7
  100. package/lib/orders.js +11 -89
  101. package/lib/slot/SlotSubscriber.d.ts +19 -0
  102. package/lib/slot/SlotSubscriber.js +26 -0
  103. package/lib/tx/retryTxSender.d.ts +2 -2
  104. package/lib/tx/retryTxSender.js +108 -123
  105. package/lib/tx/types.d.ts +5 -1
  106. package/lib/tx/utils.d.ts +1 -1
  107. package/lib/tx/utils.js +11 -2
  108. package/lib/types.d.ts +180 -110
  109. package/lib/types.js +54 -1
  110. package/lib/userName.d.ts +4 -0
  111. package/lib/userName.js +20 -0
  112. package/lib/util/computeUnits.js +10 -21
  113. package/lib/util/tps.js +11 -22
  114. package/lib/wallet.js +7 -20
  115. package/package.json +11 -4
  116. package/src/accounts/bulkAccountLoader.js +197 -0
  117. package/src/accounts/bulkAccountLoader.ts +21 -15
  118. package/src/accounts/bulkUserSubscription.js +33 -0
  119. package/src/accounts/bulkUserSubscription.ts +1 -45
  120. package/src/accounts/fetch.js +29 -0
  121. package/src/accounts/fetch.ts +33 -0
  122. package/src/accounts/pollingClearingHouseAccountSubscriber.js +311 -0
  123. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +249 -214
  124. package/src/accounts/pollingOracleSubscriber.js +93 -0
  125. package/src/accounts/pollingOracleSubscriber.ts +16 -8
  126. package/src/accounts/pollingTokenAccountSubscriber.js +90 -0
  127. package/src/accounts/pollingTokenAccountSubscriber.ts +11 -8
  128. package/src/accounts/pollingUserAccountSubscriber.js +132 -0
  129. package/src/accounts/pollingUserAccountSubscriber.ts +21 -86
  130. package/src/accounts/types.js +10 -0
  131. package/src/accounts/types.ts +41 -70
  132. package/src/accounts/utils.js +7 -0
  133. package/src/accounts/webSocketAccountSubscriber.js +93 -0
  134. package/src/accounts/webSocketAccountSubscriber.ts +33 -16
  135. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +233 -0
  136. package/src/accounts/webSocketClearingHouseAccountSubscriber.ts +190 -240
  137. package/src/accounts/webSocketUserAccountSubscriber.js +62 -0
  138. package/src/accounts/webSocketUserAccountSubscriber.ts +11 -71
  139. package/src/addresses/marketAddresses.js +26 -0
  140. package/src/addresses/marketAddresses.ts +18 -0
  141. package/{lib/addresses.js → src/addresses/pda.js} +45 -34
  142. package/src/addresses/pda.ts +118 -0
  143. package/src/admin.ts +247 -336
  144. package/src/assert/assert.js +9 -0
  145. package/src/clearingHouse.ts +1023 -1026
  146. package/src/clearingHouseConfig.ts +37 -0
  147. package/src/clearingHouseUser.ts +275 -185
  148. package/src/clearingHouseUserConfig.ts +18 -0
  149. package/src/config.ts +54 -1
  150. package/src/constants/banks.ts +50 -0
  151. package/src/constants/markets.ts +16 -207
  152. package/src/constants/numericConstants.ts +34 -5
  153. package/src/events/eventList.js +77 -0
  154. package/src/events/eventList.ts +94 -0
  155. package/src/events/eventSubscriber.js +139 -0
  156. package/src/events/eventSubscriber.ts +194 -0
  157. package/src/events/fetchLogs.js +50 -0
  158. package/src/events/fetchLogs.ts +80 -0
  159. package/src/events/pollingLogProvider.js +64 -0
  160. package/src/events/pollingLogProvider.ts +79 -0
  161. package/src/events/sort.js +44 -0
  162. package/src/events/sort.ts +65 -0
  163. package/src/events/txEventCache.js +71 -0
  164. package/src/events/txEventCache.ts +74 -0
  165. package/src/events/types.js +20 -0
  166. package/src/events/types.ts +98 -0
  167. package/src/events/webSocketLogProvider.js +41 -0
  168. package/src/events/webSocketLogProvider.ts +38 -0
  169. package/src/examples/makeTradeExample.js +80 -0
  170. package/src/examples/makeTradeExample.ts +20 -11
  171. package/src/factory/bigNum.js +364 -0
  172. package/src/factory/bigNum.ts +524 -0
  173. package/src/factory/oracleClient.js +20 -0
  174. package/src/factory/oracleClient.ts +7 -4
  175. package/src/idl/clearing_house.json +2258 -2774
  176. package/src/index.js +69 -0
  177. package/src/index.ts +14 -5
  178. package/src/math/amm.js +369 -0
  179. package/src/math/amm.ts +382 -243
  180. package/src/math/auction.js +42 -0
  181. package/src/math/auction.ts +43 -0
  182. package/src/math/bankBalance.js +75 -0
  183. package/src/math/bankBalance.ts +112 -0
  184. package/src/math/conversion.js +11 -0
  185. package/src/math/conversion.ts +1 -11
  186. package/src/math/funding.js +248 -0
  187. package/src/math/funding.ts +12 -9
  188. package/src/math/market.js +57 -0
  189. package/src/math/market.ts +37 -30
  190. package/src/math/oracles.js +26 -0
  191. package/src/math/orders.js +110 -0
  192. package/src/math/orders.ts +43 -1
  193. package/src/math/position.js +140 -0
  194. package/src/math/position.ts +52 -35
  195. package/src/math/repeg.js +128 -0
  196. package/src/math/repeg.ts +176 -0
  197. package/src/math/state.js +15 -0
  198. package/src/math/trade.js +253 -0
  199. package/src/math/trade.ts +55 -47
  200. package/src/math/utils.js +26 -0
  201. package/src/math/utils.js.map +1 -0
  202. package/src/mockUSDCFaucet.js +171 -0
  203. package/src/oracles/oracleClientCache.js +19 -0
  204. package/src/oracles/oracleClientCache.ts +20 -0
  205. package/src/oracles/pythClient.js +46 -0
  206. package/src/oracles/pythClient.ts +4 -11
  207. package/src/oracles/quoteAssetOracleClient.js +32 -0
  208. package/src/oracles/quoteAssetOracleClient.ts +25 -0
  209. package/src/oracles/switchboardClient.js +69 -0
  210. package/src/oracles/switchboardClient.ts +11 -24
  211. package/src/oracles/types.js +2 -0
  212. package/src/oracles/types.ts +7 -1
  213. package/src/orderParams.js +20 -0
  214. package/src/orderParams.ts +20 -141
  215. package/src/orders.js +134 -0
  216. package/src/orders.ts +25 -134
  217. package/src/slot/SlotSubscriber.js +39 -0
  218. package/src/slot/SlotSubscriber.ts +42 -0
  219. package/src/token/index.js +38 -0
  220. package/src/tx/retryTxSender.js +188 -0
  221. package/src/tx/retryTxSender.ts +6 -4
  222. package/src/tx/types.js +2 -0
  223. package/src/tx/types.ts +6 -1
  224. package/src/tx/utils.js +17 -0
  225. package/src/tx/utils.ts +22 -3
  226. package/src/types.js +114 -0
  227. package/src/types.ts +176 -124
  228. package/src/userName.js +20 -0
  229. package/src/userName.ts +20 -0
  230. package/src/util/promiseTimeout.js +14 -0
  231. package/src/util/tps.js +27 -0
  232. package/src/wallet.js +35 -0
  233. package/tests/bn/test.ts +255 -0
  234. package/tsconfig.json +12 -12
  235. package/lib/addresses.d.ts +0 -10
  236. package/lib/constants/accounts.d.ts +0 -15
  237. package/lib/constants/accounts.js +0 -18
  238. package/lib/factory/clearingHouse.d.ts +0 -35
  239. package/lib/factory/clearingHouse.js +0 -81
  240. package/lib/factory/clearingHouseUser.d.ts +0 -19
  241. package/lib/factory/clearingHouseUser.js +0 -34
  242. package/lib/math/insuranceFund.d.ts +0 -15
  243. package/lib/math/insuranceFund.js +0 -33
  244. package/lib/settlement.d.ts +0 -4
  245. package/lib/settlement.js +0 -10
  246. package/lib/tx/defaultTxSender.d.ts +0 -8
  247. package/lib/tx/defaultTxSender.js +0 -12
  248. package/src/addresses.ts +0 -82
  249. package/src/constants/accounts.ts +0 -26
  250. package/src/factory/clearingHouse.ts +0 -173
  251. package/src/factory/clearingHouseUser.ts +0 -73
  252. package/src/math/insuranceFund.ts +0 -29
  253. package/src/settlement.ts +0 -9
  254. package/src/tx/defaultTxSender.ts +0 -24
@@ -1,25 +1,18 @@
1
- import {
2
- getSwitchboardPid,
3
- SwitchboardDecimal,
4
- } from '@switchboard-xyz/switchboard-v2';
1
+ import { SwitchboardDecimal } from '@switchboard-xyz/switchboard-v2';
5
2
  import { Connection, Keypair, PublicKey } from '@solana/web3.js';
6
- import { DriftEnv } from '../config';
7
3
  import { BN, Program, Idl, AnchorProvider } from '@project-serum/anchor';
8
4
  import { MARK_PRICE_PRECISION, TEN } from '../constants/numericConstants';
9
5
  import { OracleClient, OraclePriceData } from './types';
10
6
  import { Wallet } from '../wallet';
11
7
  import switchboardV2Idl from '../idl/switchboard_v2.json';
12
8
 
13
- // cache switchboard program for every client object since itll always be the same
14
- const programMap = new Map<string, Program>();
9
+ let program: Program | undefined;
15
10
 
16
11
  export class SwitchboardClient implements OracleClient {
17
12
  connection: Connection;
18
- env: DriftEnv;
19
13
 
20
- public constructor(connection: Connection, env: DriftEnv) {
14
+ public constructor(connection: Connection) {
21
15
  this.connection = connection;
22
- this.env = env;
23
16
  }
24
17
 
25
18
  public async getOraclePriceData(
@@ -29,10 +22,8 @@ export class SwitchboardClient implements OracleClient {
29
22
  return this.getOraclePriceDataFromBuffer(accountInfo.data);
30
23
  }
31
24
 
32
- public async getOraclePriceDataFromBuffer(
33
- buffer: Buffer
34
- ): Promise<OraclePriceData> {
35
- const program = await this.getProgram();
25
+ public getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData {
26
+ const program = this.getProgram();
36
27
 
37
28
  const aggregatorAccountData =
38
29
  program.account.aggregatorAccountData.coder.accounts.decode(
@@ -61,23 +52,19 @@ export class SwitchboardClient implements OracleClient {
61
52
  };
62
53
  }
63
54
 
64
- public async getProgram(): Promise<Program> {
65
- if (programMap.has(this.env)) {
66
- return programMap.get(this.env);
55
+ public getProgram(): Program {
56
+ if (program) {
57
+ return program;
67
58
  }
68
59
 
69
- const program = await getSwitchboardProgram(this.env, this.connection);
70
- programMap.set(this.env, program);
60
+ program = getSwitchboardProgram(this.connection);
71
61
  return program;
72
62
  }
73
63
  }
74
64
 
75
- async function getSwitchboardProgram(
76
- env: DriftEnv,
77
- connection: Connection
78
- ): Promise<Program> {
65
+ function getSwitchboardProgram(connection: Connection): Program {
79
66
  const DEFAULT_KEYPAIR = Keypair.fromSeed(new Uint8Array(32).fill(1));
80
- const programId = getSwitchboardPid(env);
67
+ const programId = PublicKey.default;
81
68
  const wallet = new Wallet(DEFAULT_KEYPAIR);
82
69
  const provider = new AnchorProvider(connection, wallet, {});
83
70
 
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,5 +1,6 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import { PublicKey } from '@solana/web3.js';
3
+ import { OracleSource } from '../types';
3
4
 
4
5
  export type OraclePriceData = {
5
6
  price: BN;
@@ -10,7 +11,12 @@ export type OraclePriceData = {
10
11
  twapConfidence?: BN;
11
12
  };
12
13
 
14
+ export type OracleInfo = {
15
+ publicKey: PublicKey;
16
+ source: OracleSource;
17
+ };
18
+
13
19
  export interface OracleClient {
14
- getOraclePriceDataFromBuffer(buffer: Buffer): Promise<OraclePriceData>;
20
+ getOraclePriceDataFromBuffer(buffer: Buffer): OraclePriceData;
15
21
  getOraclePriceData(publicKey: PublicKey): Promise<OraclePriceData>;
16
22
  }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMarketOrderParams = exports.getTriggerLimitOrderParams = exports.getTriggerMarketOrderParams = exports.getLimitOrderParams = void 0;
4
+ const types_1 = require("./types");
5
+ function getLimitOrderParams(params) {
6
+ return Object.assign({}, params, { orderType: types_1.OrderType.LIMIT });
7
+ }
8
+ exports.getLimitOrderParams = getLimitOrderParams;
9
+ function getTriggerMarketOrderParams(params) {
10
+ return Object.assign({}, params, { orderType: types_1.OrderType.TRIGGER_MARKET });
11
+ }
12
+ exports.getTriggerMarketOrderParams = getTriggerMarketOrderParams;
13
+ function getTriggerLimitOrderParams(params) {
14
+ return Object.assign({}, params, { orderType: types_1.OrderType.TRIGGER_LIMIT });
15
+ }
16
+ exports.getTriggerLimitOrderParams = getTriggerLimitOrderParams;
17
+ function getMarketOrderParams(params) {
18
+ return Object.assign({}, params, { orderType: types_1.OrderType.MARKET });
19
+ }
20
+ exports.getMarketOrderParams = getMarketOrderParams;
@@ -1,154 +1,33 @@
1
- import {
2
- OrderParams,
3
- OrderTriggerCondition,
4
- OrderType,
5
- PositionDirection,
6
- } from './types';
1
+ import { OptionalOrderParams, OrderTriggerCondition, OrderType } from './types';
7
2
  import { BN } from '@project-serum/anchor';
8
- import { ZERO } from './constants/numericConstants';
9
3
 
10
4
  export function getLimitOrderParams(
11
- marketIndex: BN,
12
- direction: PositionDirection,
13
- baseAssetAmount: BN,
14
- price: BN,
15
- reduceOnly: boolean,
16
- discountToken = false,
17
- referrer = false,
18
- userOrderId = 0,
19
- postOnly = false,
20
- oraclePriceOffset = ZERO,
21
- immediateOrCancel = false
22
- ): OrderParams {
23
- return {
24
- orderType: OrderType.LIMIT,
25
- userOrderId,
26
- marketIndex,
27
- direction,
28
- quoteAssetAmount: ZERO,
29
- baseAssetAmount,
30
- price,
31
- reduceOnly,
32
- postOnly,
33
- immediateOrCancel,
34
- positionLimit: ZERO,
35
- padding0: true,
36
- padding1: ZERO,
37
- optionalAccounts: {
38
- discountToken,
39
- referrer,
40
- },
41
- triggerCondition: OrderTriggerCondition.ABOVE,
42
- triggerPrice: ZERO,
43
- oraclePriceOffset,
44
- };
5
+ params: Omit<OptionalOrderParams, 'orderType'> & { price: BN }
6
+ ): OptionalOrderParams {
7
+ return Object.assign({}, params, { orderType: OrderType.LIMIT });
45
8
  }
46
9
 
47
10
  export function getTriggerMarketOrderParams(
48
- marketIndex: BN,
49
- direction: PositionDirection,
50
- baseAssetAmount: BN,
51
- triggerPrice: BN,
52
- triggerCondition: OrderTriggerCondition,
53
- reduceOnly: boolean,
54
- discountToken = false,
55
- referrer = false,
56
- userOrderId = 0
57
- ): OrderParams {
58
- return {
59
- orderType: OrderType.TRIGGER_MARKET,
60
- userOrderId,
61
- marketIndex,
62
- direction,
63
- quoteAssetAmount: ZERO,
64
- baseAssetAmount,
65
- price: ZERO,
66
- reduceOnly,
67
- postOnly: false,
68
- immediateOrCancel: false,
69
- positionLimit: ZERO,
70
- padding0: true,
71
- padding1: ZERO,
72
- optionalAccounts: {
73
- discountToken,
74
- referrer,
75
- },
76
- triggerCondition,
77
- triggerPrice,
78
- oraclePriceOffset: ZERO,
79
- };
11
+ params: Omit<OptionalOrderParams, 'orderType'> & {
12
+ triggerCondition: OrderTriggerCondition;
13
+ triggerPrice: BN;
14
+ }
15
+ ): OptionalOrderParams {
16
+ return Object.assign({}, params, { orderType: OrderType.TRIGGER_MARKET });
80
17
  }
81
18
 
82
19
  export function getTriggerLimitOrderParams(
83
- marketIndex: BN,
84
- direction: PositionDirection,
85
- baseAssetAmount: BN,
86
- price: BN,
87
- triggerPrice: BN,
88
- triggerCondition: OrderTriggerCondition,
89
- reduceOnly: boolean,
90
- discountToken = false,
91
- referrer = false,
92
- userOrderId = 0
93
- ): OrderParams {
94
- return {
95
- orderType: OrderType.TRIGGER_LIMIT,
96
- userOrderId,
97
- marketIndex,
98
- direction,
99
- quoteAssetAmount: ZERO,
100
- baseAssetAmount,
101
- price,
102
- reduceOnly,
103
- postOnly: false,
104
- immediateOrCancel: false,
105
- positionLimit: ZERO,
106
- padding0: true,
107
- padding1: ZERO,
108
- optionalAccounts: {
109
- discountToken,
110
- referrer,
111
- },
112
- triggerCondition,
113
- triggerPrice,
114
- oraclePriceOffset: ZERO,
115
- };
20
+ params: Omit<OptionalOrderParams, 'orderType'> & {
21
+ triggerCondition: OrderTriggerCondition;
22
+ triggerPrice: BN;
23
+ price: BN;
24
+ }
25
+ ): OptionalOrderParams {
26
+ return Object.assign({}, params, { orderType: OrderType.TRIGGER_LIMIT });
116
27
  }
117
28
 
118
29
  export function getMarketOrderParams(
119
- marketIndex: BN,
120
- direction: PositionDirection,
121
- quoteAssetAmount: BN,
122
- baseAssetAmount: BN,
123
- reduceOnly: boolean,
124
- price = ZERO,
125
- discountToken = false,
126
- referrer = false
127
- ): OrderParams {
128
- if (baseAssetAmount.eq(ZERO) && quoteAssetAmount.eq(ZERO)) {
129
- throw Error('baseAssetAmount or quoteAssetAmount must be zero');
130
- }
131
-
132
- return {
133
- orderType: OrderType.MARKET,
134
- userOrderId: 0,
135
- marketIndex,
136
- direction,
137
- quoteAssetAmount,
138
- baseAssetAmount,
139
- price,
140
- reduceOnly,
141
- postOnly: false,
142
- immediateOrCancel: false,
143
- positionLimit: ZERO,
144
- padding0: true,
145
- padding1: ZERO,
146
- optionalAccounts: {
147
- discountToken,
148
- referrer,
149
- },
150
- triggerCondition: OrderTriggerCondition.ABOVE,
151
- triggerPrice: ZERO,
152
- oraclePriceOffset: ZERO,
153
- };
30
+ params: Omit<OptionalOrderParams, 'orderType'>
31
+ ): OptionalOrderParams {
32
+ return Object.assign({}, params, { orderType: OrderType.MARKET });
154
33
  }
package/src/orders.js ADDED
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute = exports.calculateNewStateAfterOrder = void 0;
4
+ const types_1 = require("./types");
5
+ const _1 = require(".");
6
+ const market_1 = require("./math/market");
7
+ const numericConstants_1 = require("./constants/numericConstants");
8
+ const amm_1 = require("./math/amm");
9
+ const position_1 = require("./math/position");
10
+ function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
11
+ if (types_1.isVariant(order.status, 'init')) {
12
+ return null;
13
+ }
14
+ const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(market, order);
15
+ if (baseAssetAmountToTrade.lt(market.amm.baseAssetAmountStepSize)) {
16
+ return null;
17
+ }
18
+ const userAccountAfter = Object.assign({}, userAccount);
19
+ const userPositionAfter = Object.assign({}, userPosition);
20
+ const currentPositionDirection = position_1.positionCurrentDirection(userPosition);
21
+ const increasePosition = userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) ||
22
+ isSameDirection(order.direction, currentPositionDirection);
23
+ if (increasePosition) {
24
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
25
+ const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(market, marketAfter);
26
+ userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
27
+ userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(quoteAssetAmountSwapped);
28
+ return [userAccountAfter, userPositionAfter, marketAfter];
29
+ }
30
+ else {
31
+ const reversePosition = baseAssetAmountToTrade.gt(userPosition.baseAssetAmount.abs());
32
+ if (reversePosition) {
33
+ const intermediateMarket = market_1.calculateNewMarketAfterTrade(userPosition.baseAssetAmount, position_1.findDirectionToClose(userPosition), market);
34
+ const { quoteAssetAmountSwapped: baseAssetValue } = calculateAmountSwapped(market, intermediateMarket);
35
+ let pnl;
36
+ if (types_1.isVariant(currentPositionDirection, 'long')) {
37
+ pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
38
+ }
39
+ else {
40
+ pnl = userPosition.quoteAssetAmount.sub(baseAssetValue);
41
+ }
42
+ userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
43
+ const baseAssetAmountLeft = baseAssetAmountToTrade.sub(userPosition.baseAssetAmount.abs());
44
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountLeft, order.direction, intermediateMarket);
45
+ const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(intermediateMarket, marketAfter);
46
+ userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
47
+ userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
48
+ return [userAccountAfter, userPositionAfter, marketAfter];
49
+ }
50
+ else {
51
+ const marketAfter = market_1.calculateNewMarketAfterTrade(baseAssetAmountToTrade, order.direction, market);
52
+ const { quoteAssetAmountSwapped: baseAssetValue, baseAssetAmountSwapped, } = calculateAmountSwapped(market, marketAfter);
53
+ const costBasisRealized = userPosition.quoteAssetAmount
54
+ .mul(baseAssetAmountSwapped.abs())
55
+ .div(userPosition.baseAssetAmount.abs());
56
+ let pnl;
57
+ if (types_1.isVariant(currentPositionDirection, 'long')) {
58
+ pnl = baseAssetValue.sub(costBasisRealized);
59
+ }
60
+ else {
61
+ pnl = costBasisRealized.sub(baseAssetValue);
62
+ }
63
+ userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
64
+ userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
65
+ userPositionAfter.quoteAssetAmount =
66
+ userPositionAfter.quoteAssetAmount.sub(costBasisRealized);
67
+ return [userAccountAfter, userPositionAfter, marketAfter];
68
+ }
69
+ }
70
+ }
71
+ exports.calculateNewStateAfterOrder = calculateNewStateAfterOrder;
72
+ function calculateAmountSwapped(marketBefore, marketAfter) {
73
+ return {
74
+ quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
75
+ .sub(marketAfter.amm.quoteAssetReserve)
76
+ .abs()
77
+ .mul(marketBefore.amm.pegMultiplier)
78
+ .div(numericConstants_1.PEG_PRECISION)
79
+ .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO),
80
+ baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(marketAfter.amm.baseAssetReserve),
81
+ };
82
+ }
83
+ function calculateBaseAssetAmountMarketCanExecute(market, order, oraclePriceData) {
84
+ if (types_1.isVariant(order.orderType, 'limit')) {
85
+ return calculateAmountToTradeForLimit(market, order, oraclePriceData);
86
+ }
87
+ else if (types_1.isVariant(order.orderType, 'triggerLimit')) {
88
+ return calculateAmountToTradeForTriggerLimit(market, order);
89
+ }
90
+ else if (types_1.isVariant(order.orderType, 'market')) {
91
+ return numericConstants_1.ZERO;
92
+ }
93
+ else {
94
+ return calculateAmountToTradeForTriggerMarket(market, order);
95
+ }
96
+ }
97
+ exports.calculateBaseAssetAmountMarketCanExecute = calculateBaseAssetAmountMarketCanExecute;
98
+ function calculateAmountToTradeForLimit(market, order, oraclePriceData) {
99
+ let limitPrice = order.price;
100
+ if (!order.oraclePriceOffset.eq(numericConstants_1.ZERO)) {
101
+ if (!oraclePriceData) {
102
+ throw Error('Cant calculate limit price for oracle offset oracle without OraclePriceData');
103
+ }
104
+ limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
105
+ }
106
+ const [maxAmountToTrade, direction] = amm_1.calculateMaxBaseAssetAmountToTrade(market.amm, limitPrice, order.direction);
107
+ const baseAssetAmount = _1.standardizeBaseAssetAmount(maxAmountToTrade, market.amm.baseAssetAmountStepSize);
108
+ // Check that directions are the same
109
+ const sameDirection = isSameDirection(direction, order.direction);
110
+ if (!sameDirection) {
111
+ return numericConstants_1.ZERO;
112
+ }
113
+ return baseAssetAmount.gt(order.baseAssetAmount)
114
+ ? order.baseAssetAmount
115
+ : baseAssetAmount;
116
+ }
117
+ exports.calculateAmountToTradeForLimit = calculateAmountToTradeForLimit;
118
+ function calculateAmountToTradeForTriggerLimit(market, order) {
119
+ if (!order.triggered) {
120
+ return numericConstants_1.ZERO;
121
+ }
122
+ return calculateAmountToTradeForLimit(market, order);
123
+ }
124
+ exports.calculateAmountToTradeForTriggerLimit = calculateAmountToTradeForTriggerLimit;
125
+ function isSameDirection(firstDirection, secondDirection) {
126
+ return ((types_1.isVariant(firstDirection, 'long') && types_1.isVariant(secondDirection, 'long')) ||
127
+ (types_1.isVariant(firstDirection, 'short') && types_1.isVariant(secondDirection, 'short')));
128
+ }
129
+ function calculateAmountToTradeForTriggerMarket(market, order) {
130
+ if (!order.triggered) {
131
+ return numericConstants_1.ZERO;
132
+ }
133
+ return order.baseAssetAmount;
134
+ }
package/src/orders.ts CHANGED
@@ -1,28 +1,15 @@
1
1
  import {
2
2
  isVariant,
3
- Market,
3
+ MarketAccount,
4
4
  Order,
5
5
  PositionDirection,
6
- SwapDirection,
7
6
  UserAccount,
8
7
  UserPosition,
9
8
  } from './types';
10
- import {
11
- BN,
12
- calculateAmmReservesAfterSwap,
13
- calculateBaseAssetValue,
14
- calculateSpreadReserves,
15
- ClearingHouseUser,
16
- isOrderRiskIncreasingInSameDirection,
17
- TEN_THOUSAND,
18
- } from '.';
19
- import {
20
- calculateMarkPrice,
21
- calculateNewMarketAfterTrade,
22
- } from './math/market';
9
+ import { BN, standardizeBaseAssetAmount } from '.';
10
+ import { calculateNewMarketAfterTrade } from './math/market';
23
11
  import {
24
12
  AMM_TO_QUOTE_PRECISION_RATIO,
25
- TWO,
26
13
  PEG_PRECISION,
27
14
  ZERO,
28
15
  } from './constants/numericConstants';
@@ -36,9 +23,9 @@ import { OraclePriceData } from '.';
36
23
  export function calculateNewStateAfterOrder(
37
24
  userAccount: UserAccount,
38
25
  userPosition: UserPosition,
39
- market: Market,
26
+ market: MarketAccount,
40
27
  order: Order
41
- ): [UserAccount, UserPosition, Market] | null {
28
+ ): [UserAccount, UserPosition, MarketAccount] | null {
42
29
  if (isVariant(order.status, 'init')) {
43
30
  return null;
44
31
  }
@@ -47,7 +34,7 @@ export function calculateNewStateAfterOrder(
47
34
  market,
48
35
  order
49
36
  );
50
- if (baseAssetAmountToTrade.lt(market.amm.minimumBaseAssetTradeSize)) {
37
+ if (baseAssetAmountToTrade.lt(market.amm.baseAssetAmountStepSize)) {
51
38
  return null;
52
39
  }
53
40
 
@@ -155,8 +142,8 @@ export function calculateNewStateAfterOrder(
155
142
  }
156
143
 
157
144
  function calculateAmountSwapped(
158
- marketBefore: Market,
159
- marketAfter: Market
145
+ marketBefore: MarketAccount,
146
+ marketAfter: MarketAccount
160
147
  ): { quoteAssetAmountSwapped: BN; baseAssetAmountSwapped: BN } {
161
148
  return {
162
149
  quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
@@ -172,7 +159,7 @@ function calculateAmountSwapped(
172
159
  }
173
160
 
174
161
  export function calculateBaseAssetAmountMarketCanExecute(
175
- market: Market,
162
+ market: MarketAccount,
176
163
  order: Order,
177
164
  oraclePriceData?: OraclePriceData
178
165
  ): BN {
@@ -181,7 +168,6 @@ export function calculateBaseAssetAmountMarketCanExecute(
181
168
  } else if (isVariant(order.orderType, 'triggerLimit')) {
182
169
  return calculateAmountToTradeForTriggerLimit(market, order);
183
170
  } else if (isVariant(order.orderType, 'market')) {
184
- // should never be a market order queued
185
171
  return ZERO;
186
172
  } else {
187
173
  return calculateAmountToTradeForTriggerMarket(market, order);
@@ -189,7 +175,7 @@ export function calculateBaseAssetAmountMarketCanExecute(
189
175
  }
190
176
 
191
177
  export function calculateAmountToTradeForLimit(
192
- market: Market,
178
+ market: MarketAccount,
193
179
  order: Order,
194
180
  oraclePriceData?: OraclePriceData
195
181
  ): BN {
@@ -200,21 +186,18 @@ export function calculateAmountToTradeForLimit(
200
186
  'Cant calculate limit price for oracle offset oracle without OraclePriceData'
201
187
  );
202
188
  }
203
- const floatingPrice = oraclePriceData.price.add(order.oraclePriceOffset);
204
- if (order.postOnly) {
205
- limitPrice = isVariant(order.direction, 'long')
206
- ? BN.min(order.price, floatingPrice)
207
- : BN.max(order.price, floatingPrice);
208
- } else {
209
- limitPrice = floatingPrice;
210
- }
189
+ limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
211
190
  }
212
191
 
213
192
  const [maxAmountToTrade, direction] = calculateMaxBaseAssetAmountToTrade(
214
193
  market.amm,
215
194
  limitPrice,
216
- order.direction,
217
- !order.postOnly
195
+ order.direction
196
+ );
197
+
198
+ const baseAssetAmount = standardizeBaseAssetAmount(
199
+ maxAmountToTrade,
200
+ market.amm.baseAssetAmountStepSize
218
201
  );
219
202
 
220
203
  // Check that directions are the same
@@ -223,23 +206,17 @@ export function calculateAmountToTradeForLimit(
223
206
  return ZERO;
224
207
  }
225
208
 
226
- return maxAmountToTrade.gt(order.baseAssetAmount)
209
+ return baseAssetAmount.gt(order.baseAssetAmount)
227
210
  ? order.baseAssetAmount
228
- : maxAmountToTrade;
211
+ : baseAssetAmount;
229
212
  }
230
213
 
231
214
  export function calculateAmountToTradeForTriggerLimit(
232
- market: Market,
215
+ market: MarketAccount,
233
216
  order: Order
234
217
  ): BN {
235
- if (order.baseAssetAmountFilled.eq(ZERO)) {
236
- const baseAssetAmount = calculateAmountToTradeForTriggerMarket(
237
- market,
238
- order
239
- );
240
- if (baseAssetAmount.eq(ZERO)) {
241
- return ZERO;
242
- }
218
+ if (!order.triggered) {
219
+ return ZERO;
243
220
  }
244
221
 
245
222
  return calculateAmountToTradeForLimit(market, order);
@@ -256,98 +233,12 @@ function isSameDirection(
256
233
  }
257
234
 
258
235
  function calculateAmountToTradeForTriggerMarket(
259
- market: Market,
236
+ market: MarketAccount,
260
237
  order: Order
261
238
  ): BN {
262
- return isTriggerConditionSatisfied(market, order)
263
- ? order.baseAssetAmount
264
- : ZERO;
265
- }
266
-
267
- function isTriggerConditionSatisfied(market: Market, order: Order): boolean {
268
- const markPrice = calculateMarkPrice(market);
269
- if (isVariant(order.triggerCondition, 'above')) {
270
- return markPrice.gt(order.triggerPrice);
271
- } else {
272
- return markPrice.lt(order.triggerPrice);
273
- }
274
- }
275
-
276
- export function calculateBaseAssetAmountUserCanExecute(
277
- market: Market,
278
- order: Order,
279
- user: ClearingHouseUser
280
- ): BN {
281
- const maxLeverage = user.getMaxLeverage(order.marketIndex, 'Initial');
282
- const freeCollateral = user.getFreeCollateral();
283
- let quoteAssetAmount: BN;
284
- if (isOrderRiskIncreasingInSameDirection(user, order)) {
285
- quoteAssetAmount = freeCollateral.mul(maxLeverage).div(TEN_THOUSAND);
286
- } else {
287
- const position =
288
- user.getUserPosition(order.marketIndex) ||
289
- user.getEmptyPosition(order.marketIndex);
290
- const positionValue = calculateBaseAssetValue(market, position);
291
- quoteAssetAmount = freeCollateral
292
- .mul(maxLeverage)
293
- .div(TEN_THOUSAND)
294
- .add(positionValue.mul(TWO));
295
- }
296
-
297
- if (quoteAssetAmount.lte(ZERO)) {
239
+ if (!order.triggered) {
298
240
  return ZERO;
299
241
  }
300
242
 
301
- const swapDirection = isVariant(order.direction, 'long')
302
- ? SwapDirection.ADD
303
- : SwapDirection.REMOVE;
304
-
305
- const useSpread = !order.postOnly;
306
- let amm: Parameters<typeof calculateAmmReservesAfterSwap>[0];
307
- if (useSpread) {
308
- const { baseAssetReserve, quoteAssetReserve } = calculateSpreadReserves(
309
- market.amm,
310
- order.direction
311
- );
312
- amm = {
313
- baseAssetReserve,
314
- quoteAssetReserve,
315
- sqrtK: market.amm.sqrtK,
316
- pegMultiplier: market.amm.pegMultiplier,
317
- };
318
- } else {
319
- amm = market.amm;
320
- }
321
-
322
- const baseAssetReservesBefore = amm.baseAssetReserve;
323
- const [_, baseAssetReservesAfter] = calculateAmmReservesAfterSwap(
324
- amm,
325
- 'quote',
326
- quoteAssetAmount,
327
- swapDirection
328
- );
329
-
330
- let baseAssetAmount = baseAssetReservesBefore
331
- .sub(baseAssetReservesAfter)
332
- .abs();
333
- if (order.reduceOnly) {
334
- const position =
335
- user.getUserPosition(order.marketIndex) ||
336
- user.getEmptyPosition(order.marketIndex);
337
- if (
338
- isVariant(order.direction, 'long') &&
339
- position.baseAssetAmount.gte(ZERO)
340
- ) {
341
- baseAssetAmount = ZERO;
342
- } else if (
343
- isVariant(order.direction, 'short') &&
344
- position.baseAssetAmount.lte(ZERO)
345
- ) {
346
- baseAssetAmount = ZERO;
347
- } else {
348
- BN.min(baseAssetAmount, position.baseAssetAmount.abs());
349
- }
350
- }
351
-
352
- return baseAssetAmount;
243
+ return order.baseAssetAmount;
353
244
  }