@drift-labs/sdk 0.2.0-master.22 → 0.2.0-master.25
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/addresses/pda.d.ts +4 -0
- package/lib/addresses/pda.js +27 -1
- package/lib/admin.d.ts +3 -0
- package/lib/admin.js +36 -10
- package/lib/clearingHouse.d.ts +11 -2
- package/lib/clearingHouse.js +140 -5
- package/lib/clearingHouseUser.d.ts +3 -1
- package/lib/clearingHouseUser.js +11 -9
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -0
- package/lib/constants/banks.js +9 -0
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +4 -1
- package/lib/events/eventSubscriber.d.ts +4 -2
- package/lib/events/eventSubscriber.js +16 -9
- package/lib/events/fetchLogs.d.ts +10 -1
- package/lib/events/fetchLogs.js +27 -7
- package/lib/events/pollingLogProvider.d.ts +2 -1
- package/lib/events/pollingLogProvider.js +6 -2
- package/lib/events/sort.js +7 -10
- package/lib/events/types.d.ts +4 -2
- package/lib/events/types.js +2 -0
- package/lib/examples/makeTradeExample.js +13 -1
- package/lib/idl/clearing_house.json +1081 -173
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/math/amm.d.ts +3 -1
- package/lib/math/amm.js +41 -3
- package/lib/math/insurance.d.ts +4 -0
- package/lib/math/insurance.js +27 -0
- package/lib/math/margin.d.ts +1 -1
- package/lib/math/margin.js +5 -7
- package/lib/math/position.js +1 -1
- package/lib/types.d.ts +79 -24
- package/lib/types.js +7 -4
- package/package.json +1 -1
- package/src/addresses/pda.ts +56 -0
- package/src/admin.ts +64 -18
- package/src/clearingHouse.ts +230 -10
- package/src/clearingHouseUser.ts +16 -11
- package/src/config.ts +1 -1
- package/src/constants/banks.ts +16 -0
- package/src/constants/numericConstants.ts +4 -0
- package/src/events/eventSubscriber.ts +20 -12
- package/src/events/fetchLogs.ts +35 -8
- package/src/events/pollingLogProvider.ts +10 -2
- package/src/events/sort.ts +10 -14
- package/src/events/types.ts +7 -1
- package/src/examples/makeTradeExample.ts +20 -1
- package/src/idl/clearing_house.json +1081 -173
- package/src/index.ts +2 -0
- package/src/math/amm.ts +67 -2
- package/src/math/insurance.ts +35 -0
- package/src/math/margin.ts +3 -10
- package/src/math/position.ts +2 -2
- package/src/types.ts +83 -24
- package/src/events/eventSubscriber.js +0 -139
- package/src/events/sort.js +0 -44
package/src/clearingHouse.ts
CHANGED
|
@@ -39,7 +39,9 @@ import { TokenFaucet } from './tokenFaucet';
|
|
|
39
39
|
import { EventEmitter } from 'events';
|
|
40
40
|
import StrictEventEmitter from 'strict-event-emitter-types';
|
|
41
41
|
import {
|
|
42
|
+
getClearingHouseSignerPublicKey,
|
|
42
43
|
getClearingHouseStateAccountPublicKey,
|
|
44
|
+
getInsuranceFundStakeAccountPublicKey,
|
|
43
45
|
getMarketPublicKey,
|
|
44
46
|
getUserAccountPublicKey,
|
|
45
47
|
getUserAccountPublicKeySync,
|
|
@@ -259,6 +261,17 @@ export class ClearingHouse {
|
|
|
259
261
|
return this.statePublicKey;
|
|
260
262
|
}
|
|
261
263
|
|
|
264
|
+
signerPublicKey?: PublicKey;
|
|
265
|
+
public getSignerPublicKey(): PublicKey {
|
|
266
|
+
if (this.signerPublicKey) {
|
|
267
|
+
return this.signerPublicKey;
|
|
268
|
+
}
|
|
269
|
+
this.signerPublicKey = getClearingHouseSignerPublicKey(
|
|
270
|
+
this.program.programId
|
|
271
|
+
);
|
|
272
|
+
return this.signerPublicKey;
|
|
273
|
+
}
|
|
274
|
+
|
|
262
275
|
public getStateAccount(): StateAccount {
|
|
263
276
|
return this.accountSubscriber.getStateAccountAndSlot().data;
|
|
264
277
|
}
|
|
@@ -1063,7 +1076,7 @@ export class ClearingHouse {
|
|
|
1063
1076
|
state: await this.getStatePublicKey(),
|
|
1064
1077
|
bank: bank.pubkey,
|
|
1065
1078
|
bankVault: bank.vault,
|
|
1066
|
-
|
|
1079
|
+
clearingHouseSigner: this.getSignerPublicKey(),
|
|
1067
1080
|
user: userAccountPublicKey,
|
|
1068
1081
|
userStats: this.getUserStatsAccountPublicKey(),
|
|
1069
1082
|
userTokenAccount: userTokenAccount,
|
|
@@ -2175,6 +2188,7 @@ export class ClearingHouse {
|
|
|
2175
2188
|
public async resolvePerpBankruptcy(
|
|
2176
2189
|
userAccountPublicKey: PublicKey,
|
|
2177
2190
|
userAccount: UserAccount,
|
|
2191
|
+
bankIndex: BN,
|
|
2178
2192
|
marketIndex: BN
|
|
2179
2193
|
): Promise<TransactionSignature> {
|
|
2180
2194
|
const { txSig } = await this.txSender.send(
|
|
@@ -2182,6 +2196,7 @@ export class ClearingHouse {
|
|
|
2182
2196
|
await this.getResolvePerpBankruptcyIx(
|
|
2183
2197
|
userAccountPublicKey,
|
|
2184
2198
|
userAccount,
|
|
2199
|
+
bankIndex,
|
|
2185
2200
|
marketIndex
|
|
2186
2201
|
)
|
|
2187
2202
|
),
|
|
@@ -2194,24 +2209,36 @@ export class ClearingHouse {
|
|
|
2194
2209
|
public async getResolvePerpBankruptcyIx(
|
|
2195
2210
|
userAccountPublicKey: PublicKey,
|
|
2196
2211
|
userAccount: UserAccount,
|
|
2212
|
+
bankIndex: BN,
|
|
2197
2213
|
marketIndex: BN
|
|
2198
2214
|
): Promise<TransactionInstruction> {
|
|
2199
2215
|
const liquidatorPublicKey = await this.getUserAccountPublicKey();
|
|
2200
2216
|
|
|
2201
2217
|
const remainingAccounts = this.getRemainingAccountsWithCounterparty({
|
|
2202
2218
|
writableMarketIndex: marketIndex,
|
|
2219
|
+
writableBankIndexes: [bankIndex],
|
|
2203
2220
|
counterPartyUserAccount: userAccount,
|
|
2204
2221
|
});
|
|
2205
2222
|
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2223
|
+
const bank = this.getBankAccount(bankIndex);
|
|
2224
|
+
|
|
2225
|
+
return await this.program.instruction.resolvePerpBankruptcy(
|
|
2226
|
+
bankIndex,
|
|
2227
|
+
marketIndex,
|
|
2228
|
+
{
|
|
2229
|
+
accounts: {
|
|
2230
|
+
state: await this.getStatePublicKey(),
|
|
2231
|
+
authority: this.wallet.publicKey,
|
|
2232
|
+
user: userAccountPublicKey,
|
|
2233
|
+
liquidator: liquidatorPublicKey,
|
|
2234
|
+
bankVault: bank.vault,
|
|
2235
|
+
insuranceFundVault: bank.insuranceFundVault,
|
|
2236
|
+
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2237
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2238
|
+
},
|
|
2239
|
+
remainingAccounts: remainingAccounts,
|
|
2240
|
+
}
|
|
2241
|
+
);
|
|
2215
2242
|
}
|
|
2216
2243
|
|
|
2217
2244
|
public async resolveBorrowBankruptcy(
|
|
@@ -2245,12 +2272,18 @@ export class ClearingHouse {
|
|
|
2245
2272
|
counterPartyUserAccount: userAccount,
|
|
2246
2273
|
});
|
|
2247
2274
|
|
|
2275
|
+
const bank = this.getBankAccount(bankIndex);
|
|
2276
|
+
|
|
2248
2277
|
return await this.program.instruction.resolveBorrowBankruptcy(bankIndex, {
|
|
2249
2278
|
accounts: {
|
|
2250
2279
|
state: await this.getStatePublicKey(),
|
|
2251
2280
|
authority: this.wallet.publicKey,
|
|
2252
2281
|
user: userAccountPublicKey,
|
|
2253
2282
|
liquidator: liquidatorPublicKey,
|
|
2283
|
+
bankVault: bank.vault,
|
|
2284
|
+
insuranceFundVault: bank.insuranceFundVault,
|
|
2285
|
+
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2286
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2254
2287
|
},
|
|
2255
2288
|
remainingAccounts: remainingAccounts,
|
|
2256
2289
|
});
|
|
@@ -2480,4 +2513,191 @@ export class ClearingHouse {
|
|
|
2480
2513
|
|
|
2481
2514
|
return oracleData;
|
|
2482
2515
|
}
|
|
2516
|
+
|
|
2517
|
+
public async initializeInsuranceFundStake(
|
|
2518
|
+
bankIndex: BN
|
|
2519
|
+
): Promise<TransactionSignature> {
|
|
2520
|
+
const { txSig } = await this.txSender.send(
|
|
2521
|
+
wrapInTx(await this.getInitializeInsuranceFundStakeIx(bankIndex)),
|
|
2522
|
+
[],
|
|
2523
|
+
this.opts
|
|
2524
|
+
);
|
|
2525
|
+
return txSig;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
public async getInitializeInsuranceFundStakeIx(
|
|
2529
|
+
bankIndex: BN
|
|
2530
|
+
): Promise<TransactionInstruction> {
|
|
2531
|
+
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2532
|
+
this.program.programId,
|
|
2533
|
+
this.wallet.publicKey,
|
|
2534
|
+
bankIndex
|
|
2535
|
+
);
|
|
2536
|
+
|
|
2537
|
+
return await this.program.instruction.initializeInsuranceFundStake(
|
|
2538
|
+
bankIndex,
|
|
2539
|
+
{
|
|
2540
|
+
accounts: {
|
|
2541
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2542
|
+
bank: this.getBankAccount(bankIndex).pubkey,
|
|
2543
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
2544
|
+
authority: this.wallet.publicKey,
|
|
2545
|
+
payer: this.wallet.publicKey,
|
|
2546
|
+
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
|
2547
|
+
systemProgram: anchor.web3.SystemProgram.programId,
|
|
2548
|
+
state: await this.getStatePublicKey(),
|
|
2549
|
+
},
|
|
2550
|
+
}
|
|
2551
|
+
);
|
|
2552
|
+
}
|
|
2553
|
+
|
|
2554
|
+
public async addInsuranceFundStake(
|
|
2555
|
+
bankIndex: BN,
|
|
2556
|
+
amount: BN,
|
|
2557
|
+
collateralAccountPublicKey: PublicKey
|
|
2558
|
+
): Promise<TransactionSignature> {
|
|
2559
|
+
const bank = this.getBankAccount(bankIndex);
|
|
2560
|
+
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2561
|
+
this.program.programId,
|
|
2562
|
+
this.wallet.publicKey,
|
|
2563
|
+
bankIndex
|
|
2564
|
+
);
|
|
2565
|
+
|
|
2566
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2567
|
+
writableBankIndex: bankIndex,
|
|
2568
|
+
});
|
|
2569
|
+
|
|
2570
|
+
return await this.program.rpc.addInsuranceFundStake(bankIndex, amount, {
|
|
2571
|
+
accounts: {
|
|
2572
|
+
state: await this.getStatePublicKey(),
|
|
2573
|
+
bank: bank.pubkey,
|
|
2574
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2575
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
2576
|
+
authority: this.wallet.publicKey,
|
|
2577
|
+
insuranceFundVault: bank.insuranceFundVault,
|
|
2578
|
+
userTokenAccount: collateralAccountPublicKey,
|
|
2579
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2580
|
+
},
|
|
2581
|
+
remainingAccounts,
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
public async requestRemoveInsuranceFundStake(
|
|
2586
|
+
bankIndex: BN,
|
|
2587
|
+
amount: BN
|
|
2588
|
+
): Promise<TransactionSignature> {
|
|
2589
|
+
const bank = this.getBankAccount(bankIndex);
|
|
2590
|
+
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2591
|
+
this.program.programId,
|
|
2592
|
+
this.wallet.publicKey,
|
|
2593
|
+
bankIndex
|
|
2594
|
+
);
|
|
2595
|
+
|
|
2596
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2597
|
+
writableBankIndex: bankIndex,
|
|
2598
|
+
});
|
|
2599
|
+
|
|
2600
|
+
return await this.program.rpc.requestRemoveInsuranceFundStake(
|
|
2601
|
+
bankIndex,
|
|
2602
|
+
amount,
|
|
2603
|
+
{
|
|
2604
|
+
accounts: {
|
|
2605
|
+
state: await this.getStatePublicKey(),
|
|
2606
|
+
bank: bank.pubkey,
|
|
2607
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2608
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
2609
|
+
authority: this.wallet.publicKey,
|
|
2610
|
+
insuranceFundVault: bank.insuranceFundVault,
|
|
2611
|
+
// userTokenAccount: collateralAccountPublicKey,
|
|
2612
|
+
// tokenProgram: TOKEN_PROGRAM_ID,
|
|
2613
|
+
},
|
|
2614
|
+
remainingAccounts,
|
|
2615
|
+
}
|
|
2616
|
+
);
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2619
|
+
public async cancelRequestRemoveInsuranceFundStake(
|
|
2620
|
+
bankIndex: BN
|
|
2621
|
+
): Promise<TransactionSignature> {
|
|
2622
|
+
const bank = this.getBankAccount(bankIndex);
|
|
2623
|
+
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2624
|
+
this.program.programId,
|
|
2625
|
+
this.wallet.publicKey,
|
|
2626
|
+
bankIndex
|
|
2627
|
+
);
|
|
2628
|
+
|
|
2629
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2630
|
+
writableBankIndex: bankIndex,
|
|
2631
|
+
});
|
|
2632
|
+
|
|
2633
|
+
return await this.program.rpc.cancelRequestRemoveInsuranceFundStake(
|
|
2634
|
+
bankIndex,
|
|
2635
|
+
{
|
|
2636
|
+
accounts: {
|
|
2637
|
+
state: await this.getStatePublicKey(),
|
|
2638
|
+
bank: bank.pubkey,
|
|
2639
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2640
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
2641
|
+
authority: this.wallet.publicKey,
|
|
2642
|
+
insuranceFundVault: bank.insuranceFundVault,
|
|
2643
|
+
// userTokenAccount: collateralAccountPublicKey,
|
|
2644
|
+
// tokenProgram: TOKEN_PROGRAM_ID,
|
|
2645
|
+
},
|
|
2646
|
+
remainingAccounts,
|
|
2647
|
+
}
|
|
2648
|
+
);
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
public async removeInsuranceFundStake(
|
|
2652
|
+
bankIndex: BN,
|
|
2653
|
+
collateralAccountPublicKey: PublicKey
|
|
2654
|
+
): Promise<TransactionSignature> {
|
|
2655
|
+
const bank = this.getBankAccount(bankIndex);
|
|
2656
|
+
const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
|
|
2657
|
+
this.program.programId,
|
|
2658
|
+
this.wallet.publicKey,
|
|
2659
|
+
bankIndex
|
|
2660
|
+
);
|
|
2661
|
+
|
|
2662
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2663
|
+
writableBankIndex: bankIndex,
|
|
2664
|
+
});
|
|
2665
|
+
|
|
2666
|
+
return await this.program.rpc.removeInsuranceFundStake(bankIndex, {
|
|
2667
|
+
accounts: {
|
|
2668
|
+
state: await this.getStatePublicKey(),
|
|
2669
|
+
bank: bank.pubkey,
|
|
2670
|
+
insuranceFundStake: ifStakeAccountPublicKey,
|
|
2671
|
+
userStats: this.getUserStatsAccountPublicKey(),
|
|
2672
|
+
authority: this.wallet.publicKey,
|
|
2673
|
+
insuranceFundVault: bank.insuranceFundVault,
|
|
2674
|
+
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2675
|
+
userTokenAccount: collateralAccountPublicKey,
|
|
2676
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2677
|
+
},
|
|
2678
|
+
remainingAccounts,
|
|
2679
|
+
});
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
public async settleRevenueToInsuranceFund(
|
|
2683
|
+
bankIndex: BN
|
|
2684
|
+
): Promise<TransactionSignature> {
|
|
2685
|
+
const bank = this.getBankAccount(bankIndex);
|
|
2686
|
+
|
|
2687
|
+
const remainingAccounts = this.getRemainingAccounts({
|
|
2688
|
+
writableBankIndex: bankIndex,
|
|
2689
|
+
});
|
|
2690
|
+
|
|
2691
|
+
return await this.program.rpc.settleRevenueToInsuranceFund(bankIndex, {
|
|
2692
|
+
accounts: {
|
|
2693
|
+
state: await this.getStatePublicKey(),
|
|
2694
|
+
bank: bank.pubkey,
|
|
2695
|
+
bankVault: bank.vault,
|
|
2696
|
+
clearingHouseSigner: this.getSignerPublicKey(),
|
|
2697
|
+
insuranceFundVault: bank.insuranceFundVault,
|
|
2698
|
+
tokenProgram: TOKEN_PROGRAM_ID,
|
|
2699
|
+
},
|
|
2700
|
+
remainingAccounts,
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2483
2703
|
}
|
package/src/clearingHouseUser.ts
CHANGED
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
calculateLiabilityWeight,
|
|
47
47
|
} from './math/bankBalance';
|
|
48
48
|
import {
|
|
49
|
-
|
|
49
|
+
calculateBaseAssetValueWithOracle,
|
|
50
50
|
calculateWorstCaseBaseAssetAmount,
|
|
51
51
|
} from './math/margin';
|
|
52
52
|
import { OraclePriceData } from './oracles/types';
|
|
@@ -183,7 +183,9 @@ export class ClearingHouseUser {
|
|
|
183
183
|
|
|
184
184
|
/**
|
|
185
185
|
* calculates the market position if the lp position was settled
|
|
186
|
-
* @returns : userPosition
|
|
186
|
+
* @returns : the settled userPosition
|
|
187
|
+
* @returns : the dust base asset amount (ie, < stepsize)
|
|
188
|
+
* @returns : pnl from settle
|
|
187
189
|
*/
|
|
188
190
|
public getSettledLPPosition(marketIndex: BN): [UserPosition, BN, BN] {
|
|
189
191
|
const _position = this.getUserPosition(marketIndex);
|
|
@@ -224,9 +226,6 @@ export class ClearingHouseUser {
|
|
|
224
226
|
|
|
225
227
|
const reaminderPerLP = remainderBaa.mul(AMM_RESERVE_PRECISION).div(nShares);
|
|
226
228
|
|
|
227
|
-
position.baseAssetAmount = position.baseAssetAmount.add(standardizedBaa);
|
|
228
|
-
position.quoteAssetAmount = position.quoteAssetAmount.add(deltaQaa);
|
|
229
|
-
|
|
230
229
|
position.lastNetBaseAssetAmountPerLp =
|
|
231
230
|
market.amm.marketPositionPerLp.baseAssetAmount.sub(reaminderPerLP);
|
|
232
231
|
|
|
@@ -254,7 +253,7 @@ export class ClearingHouseUser {
|
|
|
254
253
|
.mul(deltaBaa.abs())
|
|
255
254
|
.div(position.baseAssetAmount.abs())
|
|
256
255
|
);
|
|
257
|
-
pnl = position.quoteEntryAmount.sub(newQuoteEntry);
|
|
256
|
+
pnl = position.quoteEntryAmount.sub(newQuoteEntry).add(deltaQaa);
|
|
258
257
|
} else {
|
|
259
258
|
newQuoteEntry = deltaQaa.sub(
|
|
260
259
|
deltaQaa.mul(position.baseAssetAmount.abs()).div(deltaBaa.abs())
|
|
@@ -262,6 +261,8 @@ export class ClearingHouseUser {
|
|
|
262
261
|
pnl = position.quoteEntryAmount.add(deltaQaa.sub(newQuoteEntry));
|
|
263
262
|
}
|
|
264
263
|
position.quoteEntryAmount = newQuoteEntry;
|
|
264
|
+
position.baseAssetAmount = position.baseAssetAmount.add(standardizedBaa);
|
|
265
|
+
position.quoteAssetAmount = position.quoteAssetAmount.add(deltaQaa);
|
|
265
266
|
|
|
266
267
|
if (position.baseAssetAmount.gt(ZERO)) {
|
|
267
268
|
position.lastCumulativeFundingRate = market.amm.cumulativeFundingRateLong;
|
|
@@ -568,7 +569,7 @@ export class ClearingHouseUser {
|
|
|
568
569
|
const market = this.clearingHouse.getMarketAccount(
|
|
569
570
|
marketPosition.marketIndex
|
|
570
571
|
);
|
|
571
|
-
const posVal =
|
|
572
|
+
const posVal = calculateBaseAssetValueWithOracle(
|
|
572
573
|
market,
|
|
573
574
|
marketPosition,
|
|
574
575
|
this.getOracleDataForMarket(market.marketIndex)
|
|
@@ -593,7 +594,11 @@ export class ClearingHouseUser {
|
|
|
593
594
|
const market = this.clearingHouse.getMarketAccount(
|
|
594
595
|
userPosition.marketIndex
|
|
595
596
|
);
|
|
596
|
-
return
|
|
597
|
+
return calculateBaseAssetValueWithOracle(
|
|
598
|
+
market,
|
|
599
|
+
userPosition,
|
|
600
|
+
oraclePriceData
|
|
601
|
+
);
|
|
597
602
|
}
|
|
598
603
|
|
|
599
604
|
public getPositionSide(
|
|
@@ -644,7 +649,7 @@ export class ClearingHouseUser {
|
|
|
644
649
|
oraclePriceData
|
|
645
650
|
);
|
|
646
651
|
} else {
|
|
647
|
-
baseAssetValue =
|
|
652
|
+
baseAssetValue = calculateBaseAssetValueWithOracle(
|
|
648
653
|
market,
|
|
649
654
|
position,
|
|
650
655
|
oraclePriceData
|
|
@@ -818,7 +823,7 @@ export class ClearingHouseUser {
|
|
|
818
823
|
proposedMarketPosition.marketIndex
|
|
819
824
|
);
|
|
820
825
|
|
|
821
|
-
const proposedMarketPositionValue =
|
|
826
|
+
const proposedMarketPositionValue = calculateBaseAssetValueWithOracle(
|
|
822
827
|
market,
|
|
823
828
|
proposedMarketPosition,
|
|
824
829
|
this.getOracleDataForMarket(market.marketIndex)
|
|
@@ -835,7 +840,7 @@ export class ClearingHouseUser {
|
|
|
835
840
|
const market = this.clearingHouse.getMarketAccount(
|
|
836
841
|
position.marketIndex
|
|
837
842
|
);
|
|
838
|
-
const positionValue =
|
|
843
|
+
const positionValue = calculateBaseAssetValueWithOracle(
|
|
839
844
|
market,
|
|
840
845
|
position,
|
|
841
846
|
this.getOracleDataForMarket(market.marketIndex)
|
package/src/config.ts
CHANGED
|
@@ -28,7 +28,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
|
|
|
28
28
|
devnet: {
|
|
29
29
|
ENV: 'devnet',
|
|
30
30
|
PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
|
|
31
|
-
CLEARING_HOUSE_PROGRAM_ID: '
|
|
31
|
+
CLEARING_HOUSE_PROGRAM_ID: '3v1iEjbSSLSSYyt1pmx4UB5rqJGurmz71RibXF7X6UF3',
|
|
32
32
|
USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
|
|
33
33
|
MARKETS: DevnetMarkets,
|
|
34
34
|
BANKS: DevnetBanks,
|
package/src/constants/banks.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
2
|
import { BN, DriftEnv, OracleSource } from '../';
|
|
3
|
+
import {
|
|
4
|
+
BANK_BALANCE_PRECISION,
|
|
5
|
+
BANK_BALANCE_PRECISION_EXP,
|
|
6
|
+
LAMPORTS_EXP,
|
|
7
|
+
LAMPORTS_PRECISION,
|
|
8
|
+
} from './numericConstants';
|
|
3
9
|
|
|
4
10
|
export type BankConfig = {
|
|
5
11
|
symbol: string;
|
|
@@ -7,6 +13,8 @@ export type BankConfig = {
|
|
|
7
13
|
oracle: PublicKey;
|
|
8
14
|
mint: PublicKey;
|
|
9
15
|
oracleSource: OracleSource;
|
|
16
|
+
precision: BN;
|
|
17
|
+
precisionExp: BN;
|
|
10
18
|
};
|
|
11
19
|
|
|
12
20
|
export const WRAPPED_SOL_MINT = new PublicKey(
|
|
@@ -20,6 +28,8 @@ export const DevnetBanks: BankConfig[] = [
|
|
|
20
28
|
oracle: PublicKey.default,
|
|
21
29
|
oracleSource: OracleSource.QUOTE_ASSET,
|
|
22
30
|
mint: new PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
|
|
31
|
+
precision: BANK_BALANCE_PRECISION,
|
|
32
|
+
precisionExp: BANK_BALANCE_PRECISION_EXP,
|
|
23
33
|
},
|
|
24
34
|
{
|
|
25
35
|
symbol: 'SOL',
|
|
@@ -27,6 +37,8 @@ export const DevnetBanks: BankConfig[] = [
|
|
|
27
37
|
oracle: new PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
|
|
28
38
|
oracleSource: OracleSource.PYTH,
|
|
29
39
|
mint: new PublicKey(WRAPPED_SOL_MINT),
|
|
40
|
+
precision: LAMPORTS_PRECISION,
|
|
41
|
+
precisionExp: LAMPORTS_EXP,
|
|
30
42
|
},
|
|
31
43
|
{
|
|
32
44
|
symbol: 'BTC',
|
|
@@ -34,6 +46,8 @@ export const DevnetBanks: BankConfig[] = [
|
|
|
34
46
|
oracle: new PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
|
|
35
47
|
oracleSource: OracleSource.PYTH,
|
|
36
48
|
mint: new PublicKey('3BZPwbcqB5kKScF3TEXxwNfx5ipV13kbRVDvfVp5c6fv'),
|
|
49
|
+
precision: BANK_BALANCE_PRECISION,
|
|
50
|
+
precisionExp: BANK_BALANCE_PRECISION_EXP,
|
|
37
51
|
},
|
|
38
52
|
];
|
|
39
53
|
|
|
@@ -44,6 +58,8 @@ export const MainnetBanks: BankConfig[] = [
|
|
|
44
58
|
oracle: PublicKey.default,
|
|
45
59
|
oracleSource: OracleSource.QUOTE_ASSET,
|
|
46
60
|
mint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
61
|
+
precision: BANK_BALANCE_PRECISION,
|
|
62
|
+
precisionExp: BANK_BALANCE_PRECISION_EXP,
|
|
47
63
|
},
|
|
48
64
|
];
|
|
49
65
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LAMPORTS_PER_SOL } from '@solana/web3.js';
|
|
1
2
|
import { BN } from '../';
|
|
2
3
|
|
|
3
4
|
export const ZERO = new BN(0);
|
|
@@ -66,3 +67,6 @@ export const BID_ASK_SPREAD_PRECISION = new BN(1000000);
|
|
|
66
67
|
export const ONE_YEAR = new BN(31536000);
|
|
67
68
|
|
|
68
69
|
export const QUOTE_ASSET_BANK_INDEX = new BN(0);
|
|
70
|
+
|
|
71
|
+
export const LAMPORTS_PRECISION = new BN(LAMPORTS_PER_SOL);
|
|
72
|
+
export const LAMPORTS_EXP = new BN(Math.log10(LAMPORTS_PER_SOL));
|
|
@@ -25,6 +25,8 @@ export class EventSubscriber {
|
|
|
25
25
|
private awaitTxResolver = new Map<string, () => void>();
|
|
26
26
|
private logProvider: LogProvider;
|
|
27
27
|
public eventEmitter: StrictEventEmitter<EventEmitter, EventSubscriberEvents>;
|
|
28
|
+
private lastSeenSlot: number;
|
|
29
|
+
public lastSeenTxSig: string;
|
|
28
30
|
|
|
29
31
|
public constructor(
|
|
30
32
|
private connection: Connection,
|
|
@@ -62,19 +64,22 @@ export class EventSubscriber {
|
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
public subscribe(): boolean {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
public async subscribe(): Promise<boolean> {
|
|
68
|
+
try {
|
|
69
|
+
if (this.logProvider.isSubscribed()) {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
this.logProvider.subscribe((txSig, slot, logs) => {
|
|
74
|
+
this.handleTxLogs(txSig, slot, logs);
|
|
75
|
+
}, true);
|
|
76
|
+
|
|
77
|
+
return true;
|
|
78
|
+
} catch (e) {
|
|
71
79
|
console.error('Error fetching previous txs in event subscriber');
|
|
72
80
|
console.error(e);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return this.logProvider.subscribe((txSig, slot, logs) => {
|
|
76
|
-
this.handleTxLogs(txSig, slot, logs);
|
|
77
|
-
});
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
private handleTxLogs(
|
|
@@ -98,11 +103,14 @@ export class EventSubscriber {
|
|
|
98
103
|
this.awaitTxResolver.delete(txSig);
|
|
99
104
|
}
|
|
100
105
|
|
|
106
|
+
if (slot > this.lastSeenSlot) {
|
|
107
|
+
this.lastSeenTxSig = txSig;
|
|
108
|
+
}
|
|
101
109
|
this.txEventCache.add(txSig, wrappedEvents);
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
|
|
105
|
-
if (!this.options.untilTx) {
|
|
112
|
+
public async fetchPreviousTx(fetchMax?: boolean): Promise<void> {
|
|
113
|
+
if (!this.options.untilTx && !fetchMax) {
|
|
106
114
|
return;
|
|
107
115
|
}
|
|
108
116
|
|
package/src/events/fetchLogs.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
import { Program } from '@project-serum/anchor';
|
|
1
2
|
import {
|
|
2
3
|
Connection,
|
|
3
4
|
Finality,
|
|
4
5
|
PublicKey,
|
|
5
6
|
TransactionSignature,
|
|
6
7
|
} from '@solana/web3.js';
|
|
8
|
+
import { WrappedEvents } from './types';
|
|
7
9
|
|
|
8
10
|
type Log = { txSig: TransactionSignature; slot: number; logs: string[] };
|
|
9
11
|
type FetchLogsResponse = {
|
|
10
12
|
earliestTx: string;
|
|
11
13
|
mostRecentTx: string;
|
|
14
|
+
earliestSlot: number;
|
|
15
|
+
mostRecentSlot: number;
|
|
12
16
|
transactionLogs: Log[];
|
|
13
17
|
};
|
|
14
18
|
|
|
@@ -17,19 +21,21 @@ export async function fetchLogs(
|
|
|
17
21
|
programId: PublicKey,
|
|
18
22
|
finality: Finality,
|
|
19
23
|
beforeTx?: TransactionSignature,
|
|
20
|
-
untilTx?: TransactionSignature
|
|
21
|
-
|
|
24
|
+
untilTx?: TransactionSignature,
|
|
25
|
+
limit?: number
|
|
26
|
+
): Promise<FetchLogsResponse> {
|
|
22
27
|
const signatures = await connection.getSignaturesForAddress(
|
|
23
28
|
programId,
|
|
24
29
|
{
|
|
25
30
|
before: beforeTx,
|
|
26
31
|
until: untilTx,
|
|
32
|
+
limit,
|
|
27
33
|
},
|
|
28
34
|
finality
|
|
29
35
|
);
|
|
30
36
|
|
|
31
37
|
const sortedSignatures = signatures.sort((a, b) =>
|
|
32
|
-
a.slot < b.slot ? -1 : 1
|
|
38
|
+
a.slot === b.slot ? 0 : a.slot < b.slot ? -1 : 1
|
|
33
39
|
);
|
|
34
40
|
|
|
35
41
|
const filteredSignatures = sortedSignatures.filter(
|
|
@@ -61,14 +67,15 @@ export async function fetchLogs(
|
|
|
61
67
|
)
|
|
62
68
|
).flat();
|
|
63
69
|
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
filteredSignatures[filteredSignatures.length - 1].signature;
|
|
70
|
+
const earliest = filteredSignatures[0];
|
|
71
|
+
const mostRecent = filteredSignatures[filteredSignatures.length - 1];
|
|
67
72
|
|
|
68
73
|
return {
|
|
69
74
|
transactionLogs: transactionLogs,
|
|
70
|
-
earliestTx:
|
|
71
|
-
mostRecentTx:
|
|
75
|
+
earliestTx: earliest.signature,
|
|
76
|
+
mostRecentTx: mostRecent.signature,
|
|
77
|
+
earliestSlot: earliest.slot,
|
|
78
|
+
mostRecentSlot: mostRecent.slot,
|
|
72
79
|
};
|
|
73
80
|
}
|
|
74
81
|
|
|
@@ -78,3 +85,23 @@ function chunk<T>(array: readonly T[], size: number): T[][] {
|
|
|
78
85
|
.map((_, index) => index * size)
|
|
79
86
|
.map((begin) => array.slice(begin, begin + size));
|
|
80
87
|
}
|
|
88
|
+
|
|
89
|
+
export class LogParser {
|
|
90
|
+
private program: Program;
|
|
91
|
+
|
|
92
|
+
constructor(program: Program) {
|
|
93
|
+
this.program = program;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public parseEventsFromLogs(event: Log): WrappedEvents {
|
|
97
|
+
const records: WrappedEvents = [];
|
|
98
|
+
// @ts-ignore
|
|
99
|
+
this.program._events._eventParser.parseLogs(event.logs, (eventLog) => {
|
|
100
|
+
eventLog.data.txSig = event.txSig;
|
|
101
|
+
eventLog.data.slot = event.slot;
|
|
102
|
+
eventLog.data.eventType = eventLog.name;
|
|
103
|
+
records.push(eventLog.data);
|
|
104
|
+
});
|
|
105
|
+
return records;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -13,6 +13,7 @@ export class PollingLogProvider implements LogProvider {
|
|
|
13
13
|
private intervalId: NodeJS.Timer;
|
|
14
14
|
private mostRecentSeenTx?: TransactionSignature;
|
|
15
15
|
private mutex: number;
|
|
16
|
+
private firstFetch = true;
|
|
16
17
|
|
|
17
18
|
public constructor(
|
|
18
19
|
private connection: Connection,
|
|
@@ -23,7 +24,10 @@ export class PollingLogProvider implements LogProvider {
|
|
|
23
24
|
this.finality = commitment === 'finalized' ? 'finalized' : 'confirmed';
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
public subscribe(
|
|
27
|
+
public subscribe(
|
|
28
|
+
callback: logProviderCallback,
|
|
29
|
+
skipHistory?: boolean
|
|
30
|
+
): boolean {
|
|
27
31
|
if (this.intervalId) {
|
|
28
32
|
return true;
|
|
29
33
|
}
|
|
@@ -40,9 +44,13 @@ export class PollingLogProvider implements LogProvider {
|
|
|
40
44
|
this.programId,
|
|
41
45
|
this.finality,
|
|
42
46
|
undefined,
|
|
43
|
-
this.mostRecentSeenTx
|
|
47
|
+
this.mostRecentSeenTx,
|
|
48
|
+
// If skipping history, only fetch one log back, not the maximum amount available
|
|
49
|
+
skipHistory && this.firstFetch ? 1 : undefined
|
|
44
50
|
);
|
|
45
51
|
|
|
52
|
+
this.firstFetch = false;
|
|
53
|
+
|
|
46
54
|
if (response === undefined) {
|
|
47
55
|
return;
|
|
48
56
|
}
|