@drift-labs/sdk 0.2.0-master.19 → 0.2.0-master.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accounts/types.d.ts +0 -1
- package/lib/clearingHouse.d.ts +13 -13
- package/lib/clearingHouse.js +98 -37
- package/lib/clearingHouseUser.d.ts +9 -1
- package/lib/clearingHouseUser.js +64 -45
- package/lib/clearingHouseUserStats.d.ts +2 -1
- package/lib/clearingHouseUserStats.js +13 -0
- package/lib/config.js +1 -1
- package/lib/events/types.d.ts +2 -1
- package/lib/events/types.js +1 -0
- package/lib/idl/clearing_house.json +200 -129
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/lib/math/amm.d.ts +1 -0
- package/lib/math/amm.js +13 -1
- package/lib/math/market.d.ts +1 -1
- package/lib/math/market.js +5 -5
- package/lib/math/orders.d.ts +4 -0
- package/lib/math/orders.js +45 -2
- package/lib/types.d.ts +28 -7
- package/my-script/.env +7 -0
- package/my-script/getUserStats.ts +124 -0
- package/my-script/multiConnections.ts +137 -0
- package/my-script/test-regex.ts +11 -0
- package/my-script/utils.ts +52 -0
- package/my-script/ww18NdhuLSQPCrHSx7V68eZJpe2y311heWeXJfSmP3Q.json +1 -0
- package/my-script/ww2z7N9TG1PLLUQGQF2VKzCFaPtQ5FBhRfeEAuy6c5C.json +1 -0
- package/my-script/ww3StJtTubhwssqAhvSSAc5ifCgKjzmF8hz7Gt2DmSa.json +1 -0
- package/package.json +1 -1
- package/src/clearingHouse.ts +132 -42
- package/src/clearingHouseUser.ts +78 -91
- package/src/clearingHouseUserStats.ts +23 -1
- package/src/config.ts +1 -1
- package/src/events/types.ts +3 -0
- package/src/idl/clearing_house.json +200 -129
- package/src/index.ts +0 -1
- package/src/math/amm.ts +27 -1
- package/src/math/market.ts +6 -6
- package/src/math/orders.ts +114 -2
- package/src/types.ts +30 -7
- package/lib/orders.d.ts +0 -7
- package/lib/orders.js +0 -59
- package/src/addresses/marketAddresses.js +0 -26
- package/src/assert/assert.js +0 -9
- package/src/constants/banks.js +0 -42
- package/src/constants/markets.js +0 -42
- package/src/constants/numericConstants.js +0 -41
- package/src/events/eventList.js +0 -77
- package/src/events/eventSubscriber.js +0 -139
- package/src/events/fetchLogs.js +0 -50
- package/src/events/pollingLogProvider.js +0 -64
- package/src/events/sort.js +0 -44
- package/src/events/txEventCache.js +0 -71
- package/src/events/types.js +0 -20
- package/src/events/webSocketLogProvider.js +0 -41
- package/src/examples/makeTradeExample.js +0 -80
- package/src/factory/bigNum.js +0 -390
- package/src/factory/oracleClient.js +0 -20
- package/src/math/amm.js +0 -369
- package/src/math/auction.js +0 -42
- package/src/math/conversion.js +0 -11
- package/src/math/funding.js +0 -248
- package/src/math/oracles.js +0 -26
- package/src/math/repeg.js +0 -128
- package/src/math/state.js +0 -15
- package/src/math/trade.js +0 -253
- package/src/math/utils.js +0 -26
- package/src/math/utils.js.map +0 -1
- package/src/oracles/oracleClientCache.js +0 -19
- package/src/oracles/pythClient.js +0 -46
- package/src/oracles/quoteAssetOracleClient.js +0 -32
- package/src/oracles/switchboardClient.js +0 -69
- package/src/oracles/types.js +0 -2
- package/src/orderParams.js +0 -20
- package/src/orders.ts +0 -91
- package/src/slot/SlotSubscriber.js +0 -39
- package/src/token/index.js +0 -38
- package/src/tokenFaucet.js +0 -189
- package/src/tx/types.js +0 -2
- package/src/tx/utils.js +0 -17
- package/src/userName.js +0 -20
- package/src/util/computeUnits.js +0 -27
- package/src/util/getTokenAddress.js +0 -9
- package/src/util/promiseTimeout.js +0 -14
- package/src/util/tps.js +0 -27
- package/src/wallet.js +0 -35
package/src/clearingHouse.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
OptionalOrderParams,
|
|
16
16
|
DefaultOrderParams,
|
|
17
17
|
OrderType,
|
|
18
|
+
ReferrerInfo,
|
|
18
19
|
} from './types';
|
|
19
20
|
import * as anchor from '@project-serum/anchor';
|
|
20
21
|
import clearingHouseIDL from './idl/clearing_house.json';
|
|
@@ -51,7 +52,11 @@ import {
|
|
|
51
52
|
} from './accounts/types';
|
|
52
53
|
import { TxSender } from './tx/types';
|
|
53
54
|
import { wrapInTx } from './tx/utils';
|
|
54
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
ONE,
|
|
57
|
+
QUOTE_ASSET_BANK_INDEX,
|
|
58
|
+
ZERO,
|
|
59
|
+
} from './constants/numericConstants';
|
|
55
60
|
import { findDirectionToClose, positionIsAvailable } from './math/position';
|
|
56
61
|
import { getTokenAmount } from './math/bankBalance';
|
|
57
62
|
import { DEFAULT_USER_NAME, encodeName } from './userName';
|
|
@@ -219,11 +224,13 @@ export class ClearingHouse {
|
|
|
219
224
|
* Forces the accountSubscriber to fetch account updates from rpc
|
|
220
225
|
*/
|
|
221
226
|
public async fetchAccounts(): Promise<void> {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
+
const promises = [...this.users.values()]
|
|
228
|
+
.map((user) => user.fetchAccounts())
|
|
229
|
+
.concat(this.accountSubscriber.fetch());
|
|
230
|
+
if (this.userStats) {
|
|
231
|
+
promises.concat(this.userStats.fetchAccounts());
|
|
232
|
+
}
|
|
233
|
+
await Promise.all(promises);
|
|
227
234
|
}
|
|
228
235
|
|
|
229
236
|
public async unsubscribe(): Promise<void> {
|
|
@@ -341,10 +348,11 @@ export class ClearingHouse {
|
|
|
341
348
|
|
|
342
349
|
public async initializeUserAccount(
|
|
343
350
|
userId = 0,
|
|
344
|
-
name = DEFAULT_USER_NAME
|
|
351
|
+
name = DEFAULT_USER_NAME,
|
|
352
|
+
referrerInfo?: ReferrerInfo
|
|
345
353
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
346
354
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
347
|
-
await this.getInitializeUserInstructions(userId, name);
|
|
355
|
+
await this.getInitializeUserInstructions(userId, name, referrerInfo);
|
|
348
356
|
|
|
349
357
|
const tx = new Transaction();
|
|
350
358
|
if (userId === 0) {
|
|
@@ -358,7 +366,8 @@ export class ClearingHouse {
|
|
|
358
366
|
|
|
359
367
|
async getInitializeUserInstructions(
|
|
360
368
|
userId = 0,
|
|
361
|
-
name = DEFAULT_USER_NAME
|
|
369
|
+
name = DEFAULT_USER_NAME,
|
|
370
|
+
referrerInfo?: ReferrerInfo
|
|
362
371
|
): Promise<[PublicKey, TransactionInstruction]> {
|
|
363
372
|
const userAccountPublicKey = await getUserAccountPublicKey(
|
|
364
373
|
this.program.programId,
|
|
@@ -366,6 +375,20 @@ export class ClearingHouse {
|
|
|
366
375
|
userId
|
|
367
376
|
);
|
|
368
377
|
|
|
378
|
+
const remainingAccounts = new Array<AccountMeta>();
|
|
379
|
+
if (referrerInfo !== undefined) {
|
|
380
|
+
remainingAccounts.push({
|
|
381
|
+
pubkey: referrerInfo.referrer,
|
|
382
|
+
isWritable: true,
|
|
383
|
+
isSigner: false,
|
|
384
|
+
});
|
|
385
|
+
remainingAccounts.push({
|
|
386
|
+
pubkey: referrerInfo.referrerStats,
|
|
387
|
+
isWritable: true,
|
|
388
|
+
isSigner: false,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
|
|
369
392
|
const nameBuffer = encodeName(name);
|
|
370
393
|
const initializeUserAccountIx =
|
|
371
394
|
await this.program.instruction.initializeUser(userId, nameBuffer, {
|
|
@@ -378,6 +401,7 @@ export class ClearingHouse {
|
|
|
378
401
|
systemProgram: anchor.web3.SystemProgram.programId,
|
|
379
402
|
state: await this.getStatePublicKey(),
|
|
380
403
|
},
|
|
404
|
+
remainingAccounts,
|
|
381
405
|
});
|
|
382
406
|
|
|
383
407
|
return [userAccountPublicKey, initializeUserAccountIx];
|
|
@@ -711,6 +735,7 @@ export class ClearingHouse {
|
|
|
711
735
|
bank: bank.pubkey,
|
|
712
736
|
bankVault: bank.vault,
|
|
713
737
|
user: userAccountPublicKey,
|
|
738
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
714
739
|
userTokenAccount: userTokenAccount,
|
|
715
740
|
authority: this.wallet.publicKey,
|
|
716
741
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
@@ -842,10 +867,11 @@ export class ClearingHouse {
|
|
|
842
867
|
bankIndex = new BN(0),
|
|
843
868
|
userId = 0,
|
|
844
869
|
name = DEFAULT_USER_NAME,
|
|
845
|
-
fromUserId?: number
|
|
870
|
+
fromUserId?: number,
|
|
871
|
+
referrerInfo?: ReferrerInfo
|
|
846
872
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
847
873
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
848
|
-
await this.getInitializeUserInstructions(userId, name);
|
|
874
|
+
await this.getInitializeUserInstructions(userId, name, referrerInfo);
|
|
849
875
|
|
|
850
876
|
const additionalSigners: Array<Signer> = [];
|
|
851
877
|
|
|
@@ -920,7 +946,8 @@ export class ClearingHouse {
|
|
|
920
946
|
name = DEFAULT_USER_NAME,
|
|
921
947
|
bankIndex: BN,
|
|
922
948
|
tokenFaucet: TokenFaucet,
|
|
923
|
-
amount: BN
|
|
949
|
+
amount: BN,
|
|
950
|
+
referrerInfo?: ReferrerInfo
|
|
924
951
|
): Promise<[TransactionSignature, PublicKey]> {
|
|
925
952
|
const [associateTokenPublicKey, createAssociatedAccountIx, mintToIx] =
|
|
926
953
|
await tokenFaucet.createAssociatedTokenAccountAndMintToInstructions(
|
|
@@ -929,7 +956,7 @@ export class ClearingHouse {
|
|
|
929
956
|
);
|
|
930
957
|
|
|
931
958
|
const [userAccountPublicKey, initializeUserAccountIx] =
|
|
932
|
-
await this.getInitializeUserInstructions(userId, name);
|
|
959
|
+
await this.getInitializeUserInstructions(userId, name, referrerInfo);
|
|
933
960
|
|
|
934
961
|
const depositCollateralIx = await this.getDepositInstruction(
|
|
935
962
|
amount,
|
|
@@ -1038,6 +1065,7 @@ export class ClearingHouse {
|
|
|
1038
1065
|
bankVault: bank.vault,
|
|
1039
1066
|
bankVaultAuthority: bank.vaultAuthority,
|
|
1040
1067
|
user: userAccountPublicKey,
|
|
1068
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
1041
1069
|
userTokenAccount: userTokenAccount,
|
|
1042
1070
|
authority: this.wallet.publicKey,
|
|
1043
1071
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
@@ -1089,6 +1117,7 @@ export class ClearingHouse {
|
|
|
1089
1117
|
authority: this.wallet.publicKey,
|
|
1090
1118
|
fromUser,
|
|
1091
1119
|
toUser,
|
|
1120
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
1092
1121
|
state: await this.getStatePublicKey(),
|
|
1093
1122
|
},
|
|
1094
1123
|
remainingAccounts,
|
|
@@ -1401,11 +1430,18 @@ export class ClearingHouse {
|
|
|
1401
1430
|
userAccountPublicKey: PublicKey,
|
|
1402
1431
|
user: UserAccount,
|
|
1403
1432
|
order?: Order,
|
|
1404
|
-
makerInfo?: MakerInfo
|
|
1433
|
+
makerInfo?: MakerInfo,
|
|
1434
|
+
referrerInfo?: ReferrerInfo
|
|
1405
1435
|
): Promise<TransactionSignature> {
|
|
1406
1436
|
const { txSig } = await this.txSender.send(
|
|
1407
1437
|
wrapInTx(
|
|
1408
|
-
await this.getFillOrderIx(
|
|
1438
|
+
await this.getFillOrderIx(
|
|
1439
|
+
userAccountPublicKey,
|
|
1440
|
+
user,
|
|
1441
|
+
order,
|
|
1442
|
+
makerInfo,
|
|
1443
|
+
referrerInfo
|
|
1444
|
+
)
|
|
1409
1445
|
),
|
|
1410
1446
|
[],
|
|
1411
1447
|
this.opts
|
|
@@ -1417,7 +1453,8 @@ export class ClearingHouse {
|
|
|
1417
1453
|
userAccountPublicKey: PublicKey,
|
|
1418
1454
|
userAccount: UserAccount,
|
|
1419
1455
|
order: Order,
|
|
1420
|
-
makerInfo?: MakerInfo
|
|
1456
|
+
makerInfo?: MakerInfo,
|
|
1457
|
+
referrerInfo?: ReferrerInfo
|
|
1421
1458
|
): Promise<TransactionInstruction> {
|
|
1422
1459
|
const userStatsPublicKey = getUserStatsAccountPublicKey(
|
|
1423
1460
|
this.program.programId,
|
|
@@ -1427,7 +1464,11 @@ export class ClearingHouse {
|
|
|
1427
1464
|
const fillerPublicKey = await this.getUserAccountPublicKey();
|
|
1428
1465
|
const fillerStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1429
1466
|
|
|
1430
|
-
const marketIndex = order
|
|
1467
|
+
const marketIndex = order
|
|
1468
|
+
? order.marketIndex
|
|
1469
|
+
: userAccount.orders.find((order) =>
|
|
1470
|
+
order.orderId.eq(userAccount.nextOrderId.sub(ONE))
|
|
1471
|
+
).marketIndex;
|
|
1431
1472
|
const marketAccount = this.getMarketAccount(marketIndex);
|
|
1432
1473
|
|
|
1433
1474
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
@@ -1502,6 +1543,19 @@ export class ClearingHouse {
|
|
|
1502
1543
|
});
|
|
1503
1544
|
}
|
|
1504
1545
|
|
|
1546
|
+
if (referrerInfo) {
|
|
1547
|
+
remainingAccounts.push({
|
|
1548
|
+
pubkey: referrerInfo.referrer,
|
|
1549
|
+
isWritable: true,
|
|
1550
|
+
isSigner: false,
|
|
1551
|
+
});
|
|
1552
|
+
remainingAccounts.push({
|
|
1553
|
+
pubkey: referrerInfo.referrerStats,
|
|
1554
|
+
isWritable: true,
|
|
1555
|
+
isSigner: false,
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1505
1559
|
const orderId = order.orderId;
|
|
1506
1560
|
const makerOrderId = makerInfo ? makerInfo.order.orderId : null;
|
|
1507
1561
|
|
|
@@ -1614,10 +1668,13 @@ export class ClearingHouse {
|
|
|
1614
1668
|
|
|
1615
1669
|
public async placeAndTake(
|
|
1616
1670
|
orderParams: OptionalOrderParams,
|
|
1617
|
-
makerInfo?: MakerInfo
|
|
1671
|
+
makerInfo?: MakerInfo,
|
|
1672
|
+
referrerInfo?: ReferrerInfo
|
|
1618
1673
|
): Promise<TransactionSignature> {
|
|
1619
1674
|
const { txSig, slot } = await this.txSender.send(
|
|
1620
|
-
wrapInTx(
|
|
1675
|
+
wrapInTx(
|
|
1676
|
+
await this.getPlaceAndTakeIx(orderParams, makerInfo, referrerInfo)
|
|
1677
|
+
),
|
|
1621
1678
|
[],
|
|
1622
1679
|
this.opts
|
|
1623
1680
|
);
|
|
@@ -1627,7 +1684,8 @@ export class ClearingHouse {
|
|
|
1627
1684
|
|
|
1628
1685
|
public async getPlaceAndTakeIx(
|
|
1629
1686
|
orderParams: OptionalOrderParams,
|
|
1630
|
-
makerInfo?: MakerInfo
|
|
1687
|
+
makerInfo?: MakerInfo,
|
|
1688
|
+
referrerInfo?: ReferrerInfo
|
|
1631
1689
|
): Promise<TransactionInstruction> {
|
|
1632
1690
|
orderParams = this.getOrderParams(orderParams);
|
|
1633
1691
|
const userStatsPublicKey = await this.getUserStatsAccountPublicKey();
|
|
@@ -1653,6 +1711,19 @@ export class ClearingHouse {
|
|
|
1653
1711
|
});
|
|
1654
1712
|
}
|
|
1655
1713
|
|
|
1714
|
+
if (referrerInfo) {
|
|
1715
|
+
remainingAccounts.push({
|
|
1716
|
+
pubkey: referrerInfo.referrer,
|
|
1717
|
+
isWritable: true,
|
|
1718
|
+
isSigner: false,
|
|
1719
|
+
});
|
|
1720
|
+
remainingAccounts.push({
|
|
1721
|
+
pubkey: referrerInfo.referrerStats,
|
|
1722
|
+
isWritable: true,
|
|
1723
|
+
isSigner: false,
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1656
1727
|
return await this.program.instruction.placeAndTake(
|
|
1657
1728
|
orderParams,
|
|
1658
1729
|
makerOrderId,
|
|
@@ -1670,10 +1741,13 @@ export class ClearingHouse {
|
|
|
1670
1741
|
|
|
1671
1742
|
public async placeAndMake(
|
|
1672
1743
|
orderParams: OptionalOrderParams,
|
|
1673
|
-
takerInfo: TakerInfo
|
|
1744
|
+
takerInfo: TakerInfo,
|
|
1745
|
+
referrerInfo?: ReferrerInfo
|
|
1674
1746
|
): Promise<TransactionSignature> {
|
|
1675
1747
|
const { txSig, slot } = await this.txSender.send(
|
|
1676
|
-
wrapInTx(
|
|
1748
|
+
wrapInTx(
|
|
1749
|
+
await this.getPlaceAndMakeIx(orderParams, takerInfo, referrerInfo)
|
|
1750
|
+
),
|
|
1677
1751
|
[],
|
|
1678
1752
|
this.opts
|
|
1679
1753
|
);
|
|
@@ -1685,16 +1759,32 @@ export class ClearingHouse {
|
|
|
1685
1759
|
|
|
1686
1760
|
public async getPlaceAndMakeIx(
|
|
1687
1761
|
orderParams: OptionalOrderParams,
|
|
1688
|
-
takerInfo: TakerInfo
|
|
1762
|
+
takerInfo: TakerInfo,
|
|
1763
|
+
referrerInfo?: ReferrerInfo
|
|
1689
1764
|
): Promise<TransactionInstruction> {
|
|
1690
1765
|
orderParams = this.getOrderParams(orderParams);
|
|
1691
1766
|
const userStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1692
1767
|
const userAccountPublicKey = await this.getUserAccountPublicKey();
|
|
1693
1768
|
|
|
1694
|
-
|
|
1769
|
+
// todo merge this with getRemainingAccounts
|
|
1770
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1771
|
+
counterPartyUserAccount: takerInfo.takerUserAccount,
|
|
1695
1772
|
writableMarketIndex: orderParams.marketIndex,
|
|
1696
1773
|
});
|
|
1697
1774
|
|
|
1775
|
+
if (referrerInfo) {
|
|
1776
|
+
remainingAccounts.push({
|
|
1777
|
+
pubkey: referrerInfo.referrer,
|
|
1778
|
+
isWritable: true,
|
|
1779
|
+
isSigner: false,
|
|
1780
|
+
});
|
|
1781
|
+
remainingAccounts.push({
|
|
1782
|
+
pubkey: referrerInfo.referrerStats,
|
|
1783
|
+
isWritable: true,
|
|
1784
|
+
isSigner: false,
|
|
1785
|
+
});
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1698
1788
|
const takerOrderId = takerInfo!.order!.orderId;
|
|
1699
1789
|
return await this.program.instruction.placeAndMake(
|
|
1700
1790
|
orderParams,
|
|
@@ -1758,7 +1848,7 @@ export class ClearingHouse {
|
|
|
1758
1848
|
const tx = new Transaction()
|
|
1759
1849
|
.add(
|
|
1760
1850
|
ComputeBudgetProgram.requestUnits({
|
|
1761
|
-
units:
|
|
1851
|
+
units: 1_000_000,
|
|
1762
1852
|
additionalFee: 0,
|
|
1763
1853
|
})
|
|
1764
1854
|
)
|
|
@@ -1899,9 +1989,9 @@ export class ClearingHouse {
|
|
|
1899
1989
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1900
1990
|
const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
|
|
1901
1991
|
|
|
1902
|
-
const remainingAccounts = this.
|
|
1992
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
1903
1993
|
writableMarketIndex: marketIndex,
|
|
1904
|
-
userAccount,
|
|
1994
|
+
counterPartyUserAccount: userAccount,
|
|
1905
1995
|
});
|
|
1906
1996
|
|
|
1907
1997
|
return await this.program.instruction.liquidatePerp(
|
|
@@ -1953,8 +2043,8 @@ export class ClearingHouse {
|
|
|
1953
2043
|
): Promise<TransactionInstruction> {
|
|
1954
2044
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
1955
2045
|
|
|
1956
|
-
const remainingAccounts = this.
|
|
1957
|
-
userAccount,
|
|
2046
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2047
|
+
counterPartyUserAccount: userAccount,
|
|
1958
2048
|
writableBankIndexes: [liabilityBankIndex, assetBankIndex],
|
|
1959
2049
|
});
|
|
1960
2050
|
|
|
@@ -2006,8 +2096,8 @@ export class ClearingHouse {
|
|
|
2006
2096
|
): Promise<TransactionInstruction> {
|
|
2007
2097
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2008
2098
|
|
|
2009
|
-
const remainingAccounts = this.
|
|
2010
|
-
userAccount,
|
|
2099
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2100
|
+
counterPartyUserAccount: userAccount,
|
|
2011
2101
|
writableMarketIndex: perpMarketIndex,
|
|
2012
2102
|
writableBankIndexes: [liabilityBankIndex],
|
|
2013
2103
|
});
|
|
@@ -2060,8 +2150,8 @@ export class ClearingHouse {
|
|
|
2060
2150
|
): Promise<TransactionInstruction> {
|
|
2061
2151
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2062
2152
|
|
|
2063
|
-
const remainingAccounts = this.
|
|
2064
|
-
userAccount,
|
|
2153
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2154
|
+
counterPartyUserAccount: userAccount,
|
|
2065
2155
|
writableMarketIndex: perpMarketIndex,
|
|
2066
2156
|
writableBankIndexes: [assetBankIndex],
|
|
2067
2157
|
});
|
|
@@ -2108,9 +2198,9 @@ export class ClearingHouse {
|
|
|
2108
2198
|
): Promise<TransactionInstruction> {
|
|
2109
2199
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2110
2200
|
|
|
2111
|
-
const remainingAccounts = this.
|
|
2201
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2112
2202
|
writableMarketIndex: marketIndex,
|
|
2113
|
-
userAccount,
|
|
2203
|
+
counterPartyUserAccount: userAccount,
|
|
2114
2204
|
});
|
|
2115
2205
|
|
|
2116
2206
|
return await this.program.instruction.resolvePerpBankruptcy(marketIndex, {
|
|
@@ -2150,9 +2240,9 @@ export class ClearingHouse {
|
|
|
2150
2240
|
): Promise<TransactionInstruction> {
|
|
2151
2241
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2152
2242
|
|
|
2153
|
-
const remainingAccounts = this.
|
|
2243
|
+
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2154
2244
|
writableBankIndexes: [bankIndex],
|
|
2155
|
-
userAccount,
|
|
2245
|
+
counterPartyUserAccount: userAccount,
|
|
2156
2246
|
});
|
|
2157
2247
|
|
|
2158
2248
|
return await this.program.instruction.resolveBorrowBankruptcy(bankIndex, {
|
|
@@ -2166,17 +2256,17 @@ export class ClearingHouse {
|
|
|
2166
2256
|
});
|
|
2167
2257
|
}
|
|
2168
2258
|
|
|
2169
|
-
|
|
2170
|
-
|
|
2259
|
+
getRemainingAccountsWithCounterparty(params: {
|
|
2260
|
+
counterPartyUserAccount: UserAccount;
|
|
2171
2261
|
writableMarketIndex?: BN;
|
|
2172
2262
|
writableBankIndexes?: BN[];
|
|
2173
2263
|
}): AccountMeta[] {
|
|
2174
|
-
const
|
|
2264
|
+
const counterPartyUserAccount = params.counterPartyUserAccount;
|
|
2175
2265
|
|
|
2176
2266
|
const oracleAccountMap = new Map<string, AccountMeta>();
|
|
2177
2267
|
const bankAccountMap = new Map<number, AccountMeta>();
|
|
2178
2268
|
const marketAccountMap = new Map<number, AccountMeta>();
|
|
2179
|
-
for (const bankBalance of
|
|
2269
|
+
for (const bankBalance of counterPartyUserAccount.bankBalances) {
|
|
2180
2270
|
if (!bankBalance.balance.eq(ZERO)) {
|
|
2181
2271
|
const bankAccount = this.getBankAccount(bankBalance.bankIndex);
|
|
2182
2272
|
bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
|
|
@@ -2194,7 +2284,7 @@ export class ClearingHouse {
|
|
|
2194
2284
|
}
|
|
2195
2285
|
}
|
|
2196
2286
|
}
|
|
2197
|
-
for (const position of
|
|
2287
|
+
for (const position of counterPartyUserAccount.positions) {
|
|
2198
2288
|
if (!positionIsAvailable(position)) {
|
|
2199
2289
|
const market = this.getMarketAccount(position.marketIndex);
|
|
2200
2290
|
marketAccountMap.set(position.marketIndex.toNumber(), {
|
package/src/clearingHouseUser.ts
CHANGED
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
calculateBaseAssetValue,
|
|
34
34
|
calculatePositionFundingPNL,
|
|
35
35
|
calculatePositionPNL,
|
|
36
|
-
|
|
36
|
+
calculateUnrealizedAssetWeight,
|
|
37
37
|
calculateMarketMarginRatio,
|
|
38
38
|
PositionDirection,
|
|
39
39
|
calculateTradeSlippage,
|
|
@@ -144,6 +144,11 @@ export class ClearingHouseUser {
|
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
public getClonedPosition(position: UserPosition): UserPosition {
|
|
148
|
+
const clonedPosition = Object.assign({}, position);
|
|
149
|
+
return clonedPosition;
|
|
150
|
+
}
|
|
151
|
+
|
|
147
152
|
/**
|
|
148
153
|
* @param orderId
|
|
149
154
|
* @returns Order
|
|
@@ -180,8 +185,10 @@ export class ClearingHouseUser {
|
|
|
180
185
|
* calculates the market position if the lp position was settled
|
|
181
186
|
* @returns : userPosition
|
|
182
187
|
*/
|
|
183
|
-
public getSettledLPPosition(marketIndex: BN): [UserPosition, BN] {
|
|
184
|
-
const
|
|
188
|
+
public getSettledLPPosition(marketIndex: BN): [UserPosition, BN, BN] {
|
|
189
|
+
const _position = this.getUserPosition(marketIndex);
|
|
190
|
+
const position = this.getClonedPosition(_position);
|
|
191
|
+
|
|
185
192
|
const market = this.clearingHouse.getMarketAccount(position.marketIndex);
|
|
186
193
|
const nShares = position.lpShares;
|
|
187
194
|
|
|
@@ -265,7 +272,7 @@ export class ClearingHouseUser {
|
|
|
265
272
|
position.lastCumulativeFundingRate = ZERO;
|
|
266
273
|
}
|
|
267
274
|
|
|
268
|
-
return [position, pnl];
|
|
275
|
+
return [position, remainderBaa, pnl];
|
|
269
276
|
}
|
|
270
277
|
|
|
271
278
|
/**
|
|
@@ -289,51 +296,55 @@ export class ClearingHouseUser {
|
|
|
289
296
|
return freeCollateral.gte(ZERO) ? freeCollateral : ZERO;
|
|
290
297
|
}
|
|
291
298
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
299
|
+
/**
|
|
300
|
+
* @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
|
|
301
|
+
*/
|
|
302
|
+
public getMarginRequirement(type: MarginCategory): BN {
|
|
303
|
+
return this.getUserAccount()
|
|
304
|
+
.positions.reduce((marginRequirement, marketPosition) => {
|
|
295
305
|
const market = this.clearingHouse.getMarketAccount(
|
|
296
306
|
marketPosition.marketIndex
|
|
297
307
|
);
|
|
298
|
-
const worstCaseBaseAssetAmount =
|
|
299
|
-
calculateWorstCaseBaseAssetAmount(marketPosition);
|
|
300
308
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
.
|
|
309
|
+
if (marketPosition.lpShares.gt(ZERO)) {
|
|
310
|
+
// is an lp
|
|
311
|
+
// clone so we dont mutate the position
|
|
312
|
+
marketPosition = this.getClonedPosition(marketPosition);
|
|
305
313
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
market
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
314
|
+
// settle position
|
|
315
|
+
const [settledPosition, dustBaa, _] = this.getSettledLPPosition(
|
|
316
|
+
market.marketIndex
|
|
317
|
+
);
|
|
318
|
+
marketPosition.baseAssetAmount =
|
|
319
|
+
settledPosition.baseAssetAmount.add(dustBaa);
|
|
320
|
+
marketPosition.quoteAssetAmount = settledPosition.quoteAssetAmount;
|
|
321
|
+
|
|
322
|
+
// open orders
|
|
323
|
+
let openAsks;
|
|
324
|
+
if (market.amm.maxBaseAssetReserve > market.amm.baseAssetReserve) {
|
|
325
|
+
openAsks = market.amm.maxBaseAssetReserve
|
|
326
|
+
.sub(market.amm.baseAssetReserve)
|
|
327
|
+
.mul(marketPosition.lpShares)
|
|
328
|
+
.div(market.amm.sqrtK)
|
|
329
|
+
.mul(new BN(-1));
|
|
330
|
+
} else {
|
|
331
|
+
openAsks = ZERO;
|
|
332
|
+
}
|
|
319
333
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
334
|
+
let openBids;
|
|
335
|
+
if (market.amm.minBaseAssetReserve < market.amm.baseAssetReserve) {
|
|
336
|
+
openBids = market.amm.baseAssetReserve
|
|
337
|
+
.sub(market.amm.minBaseAssetReserve)
|
|
338
|
+
.mul(marketPosition.lpShares)
|
|
339
|
+
.div(market.amm.sqrtK);
|
|
340
|
+
} else {
|
|
341
|
+
openBids = ZERO;
|
|
342
|
+
}
|
|
324
343
|
|
|
325
|
-
|
|
326
|
-
|
|
344
|
+
marketPosition.openAsks = marketPosition.openAsks.add(openAsks);
|
|
345
|
+
marketPosition.openBids = marketPosition.openBids.add(openBids);
|
|
346
|
+
}
|
|
327
347
|
|
|
328
|
-
/**
|
|
329
|
-
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
|
|
330
|
-
*/
|
|
331
|
-
public getMaintenanceMarginRequirement(): BN {
|
|
332
|
-
return this.getUserAccount()
|
|
333
|
-
.positions.reduce((marginRequirement, marketPosition) => {
|
|
334
|
-
const market = this.clearingHouse.getMarketAccount(
|
|
335
|
-
marketPosition.marketIndex
|
|
336
|
-
);
|
|
337
348
|
const worstCaseBaseAssetAmount =
|
|
338
349
|
calculateWorstCaseBaseAssetAmount(marketPosition);
|
|
339
350
|
|
|
@@ -349,14 +360,28 @@ export class ClearingHouseUser {
|
|
|
349
360
|
calculateMarketMarginRatio(
|
|
350
361
|
market,
|
|
351
362
|
worstCaseBaseAssetAmount.abs(),
|
|
352
|
-
|
|
363
|
+
type
|
|
353
364
|
)
|
|
354
365
|
)
|
|
355
366
|
)
|
|
356
367
|
.div(MARGIN_PRECISION)
|
|
357
368
|
);
|
|
358
369
|
}, ZERO)
|
|
359
|
-
.add(this.getBankLiabilityValue(undefined,
|
|
370
|
+
.add(this.getBankLiabilityValue(undefined, type));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* @returns The initial margin requirement in USDC. : QUOTE_PRECISION
|
|
375
|
+
*/
|
|
376
|
+
public getInitialMarginRequirement(): BN {
|
|
377
|
+
return this.getMarginRequirement('Initial');
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
|
|
382
|
+
*/
|
|
383
|
+
public getMaintenanceMarginRequirement(): BN {
|
|
384
|
+
return this.getMarginRequirement('Maintenance');
|
|
360
385
|
}
|
|
361
386
|
|
|
362
387
|
/**
|
|
@@ -372,11 +397,11 @@ export class ClearingHouseUser {
|
|
|
372
397
|
.positions.filter((pos) =>
|
|
373
398
|
marketIndex ? pos.marketIndex === marketIndex : true
|
|
374
399
|
)
|
|
375
|
-
.reduce((
|
|
400
|
+
.reduce((unrealizedPnl, marketPosition) => {
|
|
376
401
|
const market = this.clearingHouse.getMarketAccount(
|
|
377
402
|
marketPosition.marketIndex
|
|
378
403
|
);
|
|
379
|
-
let
|
|
404
|
+
let positionUnrealizedPnl = calculatePositionPNL(
|
|
380
405
|
market,
|
|
381
406
|
marketPosition,
|
|
382
407
|
withFunding,
|
|
@@ -384,12 +409,12 @@ export class ClearingHouseUser {
|
|
|
384
409
|
);
|
|
385
410
|
|
|
386
411
|
if (withWeightMarginCategory !== undefined) {
|
|
387
|
-
if (
|
|
388
|
-
|
|
412
|
+
if (positionUnrealizedPnl.gt(ZERO)) {
|
|
413
|
+
positionUnrealizedPnl = positionUnrealizedPnl
|
|
389
414
|
.mul(
|
|
390
|
-
|
|
415
|
+
calculateUnrealizedAssetWeight(
|
|
391
416
|
market,
|
|
392
|
-
|
|
417
|
+
positionUnrealizedPnl,
|
|
393
418
|
withWeightMarginCategory
|
|
394
419
|
)
|
|
395
420
|
)
|
|
@@ -397,7 +422,7 @@ export class ClearingHouseUser {
|
|
|
397
422
|
}
|
|
398
423
|
}
|
|
399
424
|
|
|
400
|
-
return
|
|
425
|
+
return unrealizedPnl.add(positionUnrealizedPnl);
|
|
401
426
|
}, ZERO);
|
|
402
427
|
}
|
|
403
428
|
|
|
@@ -528,47 +553,9 @@ export class ClearingHouseUser {
|
|
|
528
553
|
* @returns : Precision QUOTE_PRECISION
|
|
529
554
|
*/
|
|
530
555
|
public getTotalCollateral(marginCategory: MarginCategory = 'Initial'): BN {
|
|
531
|
-
return this.
|
|
532
|
-
.
|
|
533
|
-
|
|
534
|
-
bankBalance.balance.eq(ZERO) ||
|
|
535
|
-
isVariant(bankBalance.balanceType, 'borrow')
|
|
536
|
-
) {
|
|
537
|
-
return totalAssetValue;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
541
|
-
const bankAccount: BankAccount = this.clearingHouse.getBankAccount(
|
|
542
|
-
bankBalance.bankIndex
|
|
543
|
-
);
|
|
544
|
-
|
|
545
|
-
const tokenAmount = getTokenAmount(
|
|
546
|
-
bankBalance.balance,
|
|
547
|
-
bankAccount,
|
|
548
|
-
bankBalance.balanceType
|
|
549
|
-
);
|
|
550
|
-
|
|
551
|
-
const weight = calculateAssetWeight(
|
|
552
|
-
tokenAmount,
|
|
553
|
-
bankAccount,
|
|
554
|
-
marginCategory
|
|
555
|
-
);
|
|
556
|
-
|
|
557
|
-
return totalAssetValue.add(
|
|
558
|
-
tokenAmount
|
|
559
|
-
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
560
|
-
.mul(weight)
|
|
561
|
-
.div(BANK_WEIGHT_PRECISION)
|
|
562
|
-
.div(MARK_PRICE_PRECISION)
|
|
563
|
-
// Adjust for decimals of bank account
|
|
564
|
-
.div(
|
|
565
|
-
new BN(10).pow(
|
|
566
|
-
new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
|
|
567
|
-
)
|
|
568
|
-
)
|
|
569
|
-
);
|
|
570
|
-
}, ZERO)
|
|
571
|
-
.add(this.getUnrealizedPNL(true, undefined, marginCategory));
|
|
556
|
+
return this.getBankAssetValue(undefined, marginCategory).add(
|
|
557
|
+
this.getUnrealizedPNL(true, undefined, marginCategory)
|
|
558
|
+
);
|
|
572
559
|
}
|
|
573
560
|
|
|
574
561
|
/**
|
|
@@ -4,7 +4,11 @@ import { DataAndSlot, UserStatsAccountSubscriber } from './accounts/types';
|
|
|
4
4
|
import { ClearingHouseUserStatsConfig } from './clearingHouseUserStatsConfig';
|
|
5
5
|
import { PollingUserStatsAccountSubscriber } from './accounts/pollingUserStatsAccountSubscriber';
|
|
6
6
|
import { WebSocketUserStatsAccountSubscriber } from './accounts/webSocketUserStatsAccountSubsriber';
|
|
7
|
-
import { UserStatsAccount } from './types';
|
|
7
|
+
import { ReferrerInfo, UserStatsAccount } from './types';
|
|
8
|
+
import {
|
|
9
|
+
getUserAccountPublicKeySync,
|
|
10
|
+
getUserStatsAccountPublicKey,
|
|
11
|
+
} from './addresses/pda';
|
|
8
12
|
|
|
9
13
|
export class ClearingHouseUserStats {
|
|
10
14
|
clearingHouse: ClearingHouse;
|
|
@@ -50,4 +54,22 @@ export class ClearingHouseUserStats {
|
|
|
50
54
|
public getAccount(): UserStatsAccount {
|
|
51
55
|
return this.accountSubscriber.getUserStatsAccountAndSlot().data;
|
|
52
56
|
}
|
|
57
|
+
|
|
58
|
+
public getReferrerInfo(): ReferrerInfo | undefined {
|
|
59
|
+
if (this.getAccount().referrer.equals(PublicKey.default)) {
|
|
60
|
+
return undefined;
|
|
61
|
+
} else {
|
|
62
|
+
return {
|
|
63
|
+
referrer: getUserAccountPublicKeySync(
|
|
64
|
+
this.clearingHouse.program.programId,
|
|
65
|
+
this.getAccount().referrer,
|
|
66
|
+
0
|
|
67
|
+
),
|
|
68
|
+
referrerStats: getUserStatsAccountPublicKey(
|
|
69
|
+
this.clearingHouse.program.programId,
|
|
70
|
+
this.getAccount().referrer
|
|
71
|
+
),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
53
75
|
}
|