@glamsystems/glam-sdk 0.1.19 → 0.1.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/README.md +3 -37
- package/index.cjs.js +1596 -220
- package/index.esm.js +1543 -218
- package/package.json +2 -4
- package/src/client/drift.d.ts +75 -59
- package/src/client/kamino.d.ts +36 -12
- package/src/client/meteora.d.ts +1 -1
- package/src/client/price.d.ts +4 -7
- package/src/client.d.ts +3 -1
- package/src/constants.d.ts +4 -0
- package/src/index.d.ts +3 -0
- package/src/react/glam.d.ts +2 -2
- package/src/utils/driftOrderParams.d.ts +28 -0
- package/src/utils/driftTypes.d.ts +1422 -0
- package/src/utils/driftUser.d.ts +2 -0
- package/src/utils/helpers.d.ts +1 -0
- package/src/utils/priorityfee.d.ts +1 -1
- package/target/idl/glam_protocol.json +8 -2
- package/target/types/glam_protocol.d.ts +8 -2
- package/target/types/glam_protocol.ts +8 -2
package/index.esm.js
CHANGED
|
@@ -5,7 +5,6 @@ import { getExtensionData, ExtensionType, TOKEN_PROGRAM_ID, getAssociatedTokenAd
|
|
|
5
5
|
import { unpack } from '@solana/spl-token-metadata';
|
|
6
6
|
import DLMM, { binIdToBinArrayIndex, deriveBinArray, Strategy } from '@meteora-ag/dlmm';
|
|
7
7
|
import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
|
|
8
|
-
import { getUserAccountPublicKeySync, getUserStatsAccountPublicKey, decodeUser, MarketType, getDriftStateAccountPublicKey } from '@drift-labs/sdk';
|
|
9
8
|
import { Marinade } from '@marinade.finance/marinade-ts-sdk';
|
|
10
9
|
import { getStakePoolAccount } from '@solana/spl-stake-pool';
|
|
11
10
|
import * as borsh from '@coral-xyz/borsh';
|
|
@@ -3230,6 +3229,7 @@ var instructions = [
|
|
|
3230
3229
|
},
|
|
3231
3230
|
{
|
|
3232
3231
|
name: "glam_vault",
|
|
3232
|
+
writable: true,
|
|
3233
3233
|
pda: {
|
|
3234
3234
|
seeds: [
|
|
3235
3235
|
{
|
|
@@ -9194,16 +9194,21 @@ var errors = [
|
|
|
9194
9194
|
},
|
|
9195
9195
|
{
|
|
9196
9196
|
code: 50004,
|
|
9197
|
+
name: "InvalidPlatformFeeForSwap",
|
|
9198
|
+
msg: "Invalid platform fee"
|
|
9199
|
+
},
|
|
9200
|
+
{
|
|
9201
|
+
code: 50005,
|
|
9197
9202
|
name: "InvalidTokenAccount",
|
|
9198
9203
|
msg: "Invalid token account"
|
|
9199
9204
|
},
|
|
9200
9205
|
{
|
|
9201
|
-
code:
|
|
9206
|
+
code: 50006,
|
|
9202
9207
|
name: "InvalidVoteSide",
|
|
9203
9208
|
msg: "Invalid vote side"
|
|
9204
9209
|
},
|
|
9205
9210
|
{
|
|
9206
|
-
code:
|
|
9211
|
+
code: 50007,
|
|
9207
9212
|
name: "MultipleStakeAccountsDisallowed",
|
|
9208
9213
|
msg: "Multiple stake accounts disallowed"
|
|
9209
9214
|
},
|
|
@@ -12427,9 +12432,12 @@ const MEMO_PROGRAM = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"
|
|
|
12427
12432
|
* Stake pools
|
|
12428
12433
|
*/ const JITO_STAKE_POOL = new PublicKey("Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb");
|
|
12429
12434
|
const JUPSOL_STAKE_POOL = new PublicKey("8VpRhuxa7sUUepdY3kQiTmX9rS5vx4WgaXiAnXq4KCtr");
|
|
12435
|
+
/**
|
|
12436
|
+
* Referrers
|
|
12437
|
+
*/ const GLAM_REFERRER = new PublicKey("GLAMrG37ZqioqvzBNQGCfCUueDz3tsr7MwMFyRk9PS89");
|
|
12430
12438
|
|
|
12431
12439
|
const GlamIntegrations = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Integration")?.type?.variants?.map((v)=>v.name) ?? [];
|
|
12432
|
-
const GlamPermissions = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Permission")?.type?.variants?.map((v)=>v.name) ?? [];
|
|
12440
|
+
const GlamPermissions = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Permission")?.type?.variants?.map((v)=>v.name).filter((v)=>!v.startsWith("__")) ?? [];
|
|
12433
12441
|
const GLAM_PROGRAM_ID_DEFAULT = new PublicKey(GlamProtocolIdlJson.address);
|
|
12434
12442
|
class StateIdlModel {
|
|
12435
12443
|
constructor(data){
|
|
@@ -12904,6 +12912,13 @@ const getErrorFromRPCResponse = (rpcResponse)=>{
|
|
|
12904
12912
|
throw Error(error.toString());
|
|
12905
12913
|
}
|
|
12906
12914
|
};
|
|
12915
|
+
const setsAreEqual = (a, b)=>{
|
|
12916
|
+
if (a.size !== b.size) return false;
|
|
12917
|
+
for (let item of a){
|
|
12918
|
+
if (!b.has(item)) return false;
|
|
12919
|
+
}
|
|
12920
|
+
return true;
|
|
12921
|
+
};
|
|
12907
12922
|
|
|
12908
12923
|
const ASSETS_MAINNET = new Map([
|
|
12909
12924
|
[
|
|
@@ -13573,7 +13588,901 @@ class BaseClient {
|
|
|
13573
13588
|
}
|
|
13574
13589
|
}
|
|
13575
13590
|
|
|
13576
|
-
const
|
|
13591
|
+
const ZERO = new BN(0);
|
|
13592
|
+
// # Utility Types / Enums / Constants
|
|
13593
|
+
var ExchangeStatus = /*#__PURE__*/ function(ExchangeStatus) {
|
|
13594
|
+
ExchangeStatus[ExchangeStatus["ACTIVE"] = 0] = "ACTIVE";
|
|
13595
|
+
ExchangeStatus[ExchangeStatus["DEPOSIT_PAUSED"] = 1] = "DEPOSIT_PAUSED";
|
|
13596
|
+
ExchangeStatus[ExchangeStatus["WITHDRAW_PAUSED"] = 2] = "WITHDRAW_PAUSED";
|
|
13597
|
+
ExchangeStatus[ExchangeStatus["AMM_PAUSED"] = 4] = "AMM_PAUSED";
|
|
13598
|
+
ExchangeStatus[ExchangeStatus["FILL_PAUSED"] = 8] = "FILL_PAUSED";
|
|
13599
|
+
ExchangeStatus[ExchangeStatus["LIQ_PAUSED"] = 16] = "LIQ_PAUSED";
|
|
13600
|
+
ExchangeStatus[ExchangeStatus["FUNDING_PAUSED"] = 32] = "FUNDING_PAUSED";
|
|
13601
|
+
ExchangeStatus[ExchangeStatus["SETTLE_PNL_PAUSED"] = 64] = "SETTLE_PNL_PAUSED";
|
|
13602
|
+
ExchangeStatus[ExchangeStatus["AMM_IMMEDIATE_FILL_PAUSED"] = 128] = "AMM_IMMEDIATE_FILL_PAUSED";
|
|
13603
|
+
ExchangeStatus[ExchangeStatus["PAUSED"] = 255] = "PAUSED";
|
|
13604
|
+
return ExchangeStatus;
|
|
13605
|
+
}({});
|
|
13606
|
+
class MarketStatus {
|
|
13607
|
+
}
|
|
13608
|
+
MarketStatus.INITIALIZED = {
|
|
13609
|
+
initialized: {}
|
|
13610
|
+
};
|
|
13611
|
+
MarketStatus.ACTIVE = {
|
|
13612
|
+
active: {}
|
|
13613
|
+
};
|
|
13614
|
+
MarketStatus.FUNDING_PAUSED = {
|
|
13615
|
+
fundingPaused: {}
|
|
13616
|
+
};
|
|
13617
|
+
MarketStatus.AMM_PAUSED = {
|
|
13618
|
+
ammPaused: {}
|
|
13619
|
+
};
|
|
13620
|
+
MarketStatus.FILL_PAUSED = {
|
|
13621
|
+
fillPaused: {}
|
|
13622
|
+
};
|
|
13623
|
+
MarketStatus.WITHDRAW_PAUSED = {
|
|
13624
|
+
withdrawPaused: {}
|
|
13625
|
+
};
|
|
13626
|
+
MarketStatus.REDUCE_ONLY = {
|
|
13627
|
+
reduceOnly: {}
|
|
13628
|
+
};
|
|
13629
|
+
MarketStatus.SETTLEMENT = {
|
|
13630
|
+
settlement: {}
|
|
13631
|
+
};
|
|
13632
|
+
MarketStatus.DELISTED = {
|
|
13633
|
+
delisted: {}
|
|
13634
|
+
};
|
|
13635
|
+
var PerpOperation = /*#__PURE__*/ function(PerpOperation) {
|
|
13636
|
+
PerpOperation[PerpOperation["UPDATE_FUNDING"] = 1] = "UPDATE_FUNDING";
|
|
13637
|
+
PerpOperation[PerpOperation["AMM_FILL"] = 2] = "AMM_FILL";
|
|
13638
|
+
PerpOperation[PerpOperation["FILL"] = 4] = "FILL";
|
|
13639
|
+
PerpOperation[PerpOperation["SETTLE_PNL"] = 8] = "SETTLE_PNL";
|
|
13640
|
+
PerpOperation[PerpOperation["SETTLE_PNL_WITH_POSITION"] = 16] = "SETTLE_PNL_WITH_POSITION";
|
|
13641
|
+
PerpOperation[PerpOperation["LIQUIDATION"] = 32] = "LIQUIDATION";
|
|
13642
|
+
return PerpOperation;
|
|
13643
|
+
}({});
|
|
13644
|
+
var SpotOperation = /*#__PURE__*/ function(SpotOperation) {
|
|
13645
|
+
SpotOperation[SpotOperation["UPDATE_CUMULATIVE_INTEREST"] = 1] = "UPDATE_CUMULATIVE_INTEREST";
|
|
13646
|
+
SpotOperation[SpotOperation["FILL"] = 2] = "FILL";
|
|
13647
|
+
SpotOperation[SpotOperation["DEPOSIT"] = 4] = "DEPOSIT";
|
|
13648
|
+
SpotOperation[SpotOperation["WITHDRAW"] = 8] = "WITHDRAW";
|
|
13649
|
+
SpotOperation[SpotOperation["LIQUIDATION"] = 16] = "LIQUIDATION";
|
|
13650
|
+
return SpotOperation;
|
|
13651
|
+
}({});
|
|
13652
|
+
var InsuranceFundOperation = /*#__PURE__*/ function(InsuranceFundOperation) {
|
|
13653
|
+
InsuranceFundOperation[InsuranceFundOperation["INIT"] = 1] = "INIT";
|
|
13654
|
+
InsuranceFundOperation[InsuranceFundOperation["ADD"] = 2] = "ADD";
|
|
13655
|
+
InsuranceFundOperation[InsuranceFundOperation["REQUEST_REMOVE"] = 4] = "REQUEST_REMOVE";
|
|
13656
|
+
InsuranceFundOperation[InsuranceFundOperation["REMOVE"] = 8] = "REMOVE";
|
|
13657
|
+
return InsuranceFundOperation;
|
|
13658
|
+
}({});
|
|
13659
|
+
var UserStatus = /*#__PURE__*/ function(UserStatus) {
|
|
13660
|
+
UserStatus[UserStatus["BEING_LIQUIDATED"] = 1] = "BEING_LIQUIDATED";
|
|
13661
|
+
UserStatus[UserStatus["BANKRUPT"] = 2] = "BANKRUPT";
|
|
13662
|
+
UserStatus[UserStatus["REDUCE_ONLY"] = 4] = "REDUCE_ONLY";
|
|
13663
|
+
UserStatus[UserStatus["ADVANCED_LP"] = 8] = "ADVANCED_LP";
|
|
13664
|
+
UserStatus[UserStatus["PROTECTED_MAKER"] = 16] = "PROTECTED_MAKER";
|
|
13665
|
+
return UserStatus;
|
|
13666
|
+
}({});
|
|
13667
|
+
class MarginMode {
|
|
13668
|
+
}
|
|
13669
|
+
MarginMode.DEFAULT = {
|
|
13670
|
+
default: {}
|
|
13671
|
+
};
|
|
13672
|
+
MarginMode.HIGH_LEVERAGE = {
|
|
13673
|
+
highLeverage: {}
|
|
13674
|
+
};
|
|
13675
|
+
class ContractType {
|
|
13676
|
+
}
|
|
13677
|
+
ContractType.PERPETUAL = {
|
|
13678
|
+
perpetual: {}
|
|
13679
|
+
};
|
|
13680
|
+
ContractType.FUTURE = {
|
|
13681
|
+
future: {}
|
|
13682
|
+
};
|
|
13683
|
+
ContractType.PREDICTION = {
|
|
13684
|
+
prediction: {}
|
|
13685
|
+
};
|
|
13686
|
+
class ContractTier {
|
|
13687
|
+
}
|
|
13688
|
+
ContractTier.A = {
|
|
13689
|
+
a: {}
|
|
13690
|
+
};
|
|
13691
|
+
ContractTier.B = {
|
|
13692
|
+
b: {}
|
|
13693
|
+
};
|
|
13694
|
+
ContractTier.C = {
|
|
13695
|
+
c: {}
|
|
13696
|
+
};
|
|
13697
|
+
ContractTier.SPECULATIVE = {
|
|
13698
|
+
speculative: {}
|
|
13699
|
+
};
|
|
13700
|
+
ContractTier.HIGHLY_SPECULATIVE = {
|
|
13701
|
+
highlySpeculative: {}
|
|
13702
|
+
};
|
|
13703
|
+
ContractTier.ISOLATED = {
|
|
13704
|
+
isolated: {}
|
|
13705
|
+
};
|
|
13706
|
+
class AssetTier {
|
|
13707
|
+
}
|
|
13708
|
+
AssetTier.COLLATERAL = {
|
|
13709
|
+
collateral: {}
|
|
13710
|
+
};
|
|
13711
|
+
AssetTier.PROTECTED = {
|
|
13712
|
+
protected: {}
|
|
13713
|
+
};
|
|
13714
|
+
AssetTier.CROSS = {
|
|
13715
|
+
cross: {}
|
|
13716
|
+
};
|
|
13717
|
+
AssetTier.ISOLATED = {
|
|
13718
|
+
isolated: {}
|
|
13719
|
+
};
|
|
13720
|
+
AssetTier.UNLISTED = {
|
|
13721
|
+
unlisted: {}
|
|
13722
|
+
};
|
|
13723
|
+
class SwapDirection {
|
|
13724
|
+
}
|
|
13725
|
+
SwapDirection.ADD = {
|
|
13726
|
+
add: {}
|
|
13727
|
+
};
|
|
13728
|
+
SwapDirection.REMOVE = {
|
|
13729
|
+
remove: {}
|
|
13730
|
+
};
|
|
13731
|
+
class SpotBalanceType {
|
|
13732
|
+
}
|
|
13733
|
+
SpotBalanceType.DEPOSIT = {
|
|
13734
|
+
deposit: {}
|
|
13735
|
+
};
|
|
13736
|
+
SpotBalanceType.BORROW = {
|
|
13737
|
+
borrow: {}
|
|
13738
|
+
};
|
|
13739
|
+
class PositionDirection {
|
|
13740
|
+
}
|
|
13741
|
+
PositionDirection.LONG = {
|
|
13742
|
+
long: {}
|
|
13743
|
+
};
|
|
13744
|
+
PositionDirection.SHORT = {
|
|
13745
|
+
short: {}
|
|
13746
|
+
};
|
|
13747
|
+
class DepositDirection {
|
|
13748
|
+
}
|
|
13749
|
+
DepositDirection.DEPOSIT = {
|
|
13750
|
+
deposit: {}
|
|
13751
|
+
};
|
|
13752
|
+
DepositDirection.WITHDRAW = {
|
|
13753
|
+
withdraw: {}
|
|
13754
|
+
};
|
|
13755
|
+
class OracleSource {
|
|
13756
|
+
static get(n) {
|
|
13757
|
+
const name = Object.entries(OracleSourceNum).find(([, v])=>v === n)?.[0];
|
|
13758
|
+
const source = Object.entries(OracleSource).find(([key, _])=>key.toLocaleLowerCase() === name?.toLocaleLowerCase())?.[1];
|
|
13759
|
+
if (!source) {
|
|
13760
|
+
throw new Error(`Invalid oracle source enum value: ${n}`);
|
|
13761
|
+
}
|
|
13762
|
+
return source;
|
|
13763
|
+
}
|
|
13764
|
+
}
|
|
13765
|
+
OracleSource.PYTH = {
|
|
13766
|
+
pyth: {}
|
|
13767
|
+
};
|
|
13768
|
+
OracleSource.PYTH_1K = {
|
|
13769
|
+
pyth1K: {}
|
|
13770
|
+
};
|
|
13771
|
+
OracleSource.PYTH_1M = {
|
|
13772
|
+
pyth1M: {}
|
|
13773
|
+
};
|
|
13774
|
+
OracleSource.PYTH_PULL = {
|
|
13775
|
+
pythPull: {}
|
|
13776
|
+
};
|
|
13777
|
+
OracleSource.PYTH_1K_PULL = {
|
|
13778
|
+
pyth1KPull: {}
|
|
13779
|
+
};
|
|
13780
|
+
OracleSource.PYTH_1M_PULL = {
|
|
13781
|
+
pyth1MPull: {}
|
|
13782
|
+
};
|
|
13783
|
+
OracleSource.SWITCHBOARD = {
|
|
13784
|
+
switchboard: {}
|
|
13785
|
+
};
|
|
13786
|
+
OracleSource.QUOTE_ASSET = {
|
|
13787
|
+
quoteAsset: {}
|
|
13788
|
+
};
|
|
13789
|
+
OracleSource.PYTH_STABLE_COIN = {
|
|
13790
|
+
pythStableCoin: {}
|
|
13791
|
+
};
|
|
13792
|
+
OracleSource.PYTH_STABLE_COIN_PULL = {
|
|
13793
|
+
pythStableCoinPull: {}
|
|
13794
|
+
};
|
|
13795
|
+
OracleSource.Prelaunch = {
|
|
13796
|
+
prelaunch: {}
|
|
13797
|
+
};
|
|
13798
|
+
OracleSource.SWITCHBOARD_ON_DEMAND = {
|
|
13799
|
+
switchboardOnDemand: {}
|
|
13800
|
+
};
|
|
13801
|
+
OracleSource.PYTH_LAZER = {
|
|
13802
|
+
pythLazer: {}
|
|
13803
|
+
};
|
|
13804
|
+
OracleSource.PYTH_LAZER_1K = {
|
|
13805
|
+
pythLazer1K: {}
|
|
13806
|
+
};
|
|
13807
|
+
OracleSource.PYTH_LAZER_1M = {
|
|
13808
|
+
pythLazer1M: {}
|
|
13809
|
+
};
|
|
13810
|
+
OracleSource.PYTH_LAZER_STABLE_COIN = {
|
|
13811
|
+
pythLazerStableCoin: {}
|
|
13812
|
+
};
|
|
13813
|
+
class OracleSourceNum {
|
|
13814
|
+
}
|
|
13815
|
+
OracleSourceNum.PYTH = 0;
|
|
13816
|
+
OracleSourceNum.PYTH_1K = 1;
|
|
13817
|
+
OracleSourceNum.PYTH_1M = 2;
|
|
13818
|
+
OracleSourceNum.PYTH_PULL = 3;
|
|
13819
|
+
OracleSourceNum.PYTH_1K_PULL = 4;
|
|
13820
|
+
OracleSourceNum.PYTH_1M_PULL = 5;
|
|
13821
|
+
OracleSourceNum.SWITCHBOARD = 6;
|
|
13822
|
+
OracleSourceNum.QUOTE_ASSET = 7;
|
|
13823
|
+
OracleSourceNum.PYTH_STABLE_COIN = 8;
|
|
13824
|
+
OracleSourceNum.PYTH_STABLE_COIN_PULL = 9;
|
|
13825
|
+
OracleSourceNum.PRELAUNCH = 10;
|
|
13826
|
+
OracleSourceNum.SWITCHBOARD_ON_DEMAND = 11;
|
|
13827
|
+
OracleSourceNum.PYTH_LAZER = 12;
|
|
13828
|
+
OracleSourceNum.PYTH_LAZER_1K = 13;
|
|
13829
|
+
OracleSourceNum.PYTH_LAZER_1M = 14;
|
|
13830
|
+
OracleSourceNum.PYTH_LAZER_STABLE_COIN = 15;
|
|
13831
|
+
class OrderType {
|
|
13832
|
+
}
|
|
13833
|
+
OrderType.LIMIT = {
|
|
13834
|
+
limit: {}
|
|
13835
|
+
};
|
|
13836
|
+
OrderType.TRIGGER_MARKET = {
|
|
13837
|
+
triggerMarket: {}
|
|
13838
|
+
};
|
|
13839
|
+
OrderType.TRIGGER_LIMIT = {
|
|
13840
|
+
triggerLimit: {}
|
|
13841
|
+
};
|
|
13842
|
+
OrderType.MARKET = {
|
|
13843
|
+
market: {}
|
|
13844
|
+
};
|
|
13845
|
+
OrderType.ORACLE = {
|
|
13846
|
+
oracle: {}
|
|
13847
|
+
};
|
|
13848
|
+
class MarketType {
|
|
13849
|
+
}
|
|
13850
|
+
MarketType.SPOT = {
|
|
13851
|
+
spot: {}
|
|
13852
|
+
};
|
|
13853
|
+
MarketType.PERP = {
|
|
13854
|
+
perp: {}
|
|
13855
|
+
};
|
|
13856
|
+
class OrderStatus {
|
|
13857
|
+
}
|
|
13858
|
+
OrderStatus.INIT = {
|
|
13859
|
+
init: {}
|
|
13860
|
+
};
|
|
13861
|
+
OrderStatus.OPEN = {
|
|
13862
|
+
open: {}
|
|
13863
|
+
};
|
|
13864
|
+
OrderStatus.FILLED = {
|
|
13865
|
+
filled: {}
|
|
13866
|
+
};
|
|
13867
|
+
OrderStatus.CANCELED = {
|
|
13868
|
+
canceled: {}
|
|
13869
|
+
};
|
|
13870
|
+
class OrderAction {
|
|
13871
|
+
}
|
|
13872
|
+
OrderAction.PLACE = {
|
|
13873
|
+
place: {}
|
|
13874
|
+
};
|
|
13875
|
+
OrderAction.CANCEL = {
|
|
13876
|
+
cancel: {}
|
|
13877
|
+
};
|
|
13878
|
+
OrderAction.EXPIRE = {
|
|
13879
|
+
expire: {}
|
|
13880
|
+
};
|
|
13881
|
+
OrderAction.FILL = {
|
|
13882
|
+
fill: {}
|
|
13883
|
+
};
|
|
13884
|
+
OrderAction.TRIGGER = {
|
|
13885
|
+
trigger: {}
|
|
13886
|
+
};
|
|
13887
|
+
class OrderActionExplanation {
|
|
13888
|
+
}
|
|
13889
|
+
OrderActionExplanation.NONE = {
|
|
13890
|
+
none: {}
|
|
13891
|
+
};
|
|
13892
|
+
OrderActionExplanation.INSUFFICIENT_FREE_COLLATERAL = {
|
|
13893
|
+
insufficientFreeCollateral: {}
|
|
13894
|
+
};
|
|
13895
|
+
OrderActionExplanation.ORACLE_PRICE_BREACHED_LIMIT_PRICE = {
|
|
13896
|
+
oraclePriceBreachedLimitPrice: {}
|
|
13897
|
+
};
|
|
13898
|
+
OrderActionExplanation.MARKET_ORDER_FILLED_TO_LIMIT_PRICE = {
|
|
13899
|
+
marketOrderFilledToLimitPrice: {}
|
|
13900
|
+
};
|
|
13901
|
+
OrderActionExplanation.ORDER_EXPIRED = {
|
|
13902
|
+
orderExpired: {}
|
|
13903
|
+
};
|
|
13904
|
+
OrderActionExplanation.LIQUIDATION = {
|
|
13905
|
+
liquidation: {}
|
|
13906
|
+
};
|
|
13907
|
+
OrderActionExplanation.ORDER_FILLED_WITH_AMM = {
|
|
13908
|
+
orderFilledWithAmm: {}
|
|
13909
|
+
};
|
|
13910
|
+
OrderActionExplanation.ORDER_FILLED_WITH_AMM_JIT = {
|
|
13911
|
+
orderFilledWithAmmJit: {}
|
|
13912
|
+
};
|
|
13913
|
+
OrderActionExplanation.ORDER_FILLED_WITH_AMM_JIT_LP_SPLIT = {
|
|
13914
|
+
orderFilledWithAmmJitLpSplit: {}
|
|
13915
|
+
};
|
|
13916
|
+
OrderActionExplanation.ORDER_FILLED_WITH_LP_JIT = {
|
|
13917
|
+
orderFilledWithLpJit: {}
|
|
13918
|
+
};
|
|
13919
|
+
OrderActionExplanation.ORDER_FILLED_WITH_MATCH = {
|
|
13920
|
+
orderFilledWithMatch: {}
|
|
13921
|
+
};
|
|
13922
|
+
OrderActionExplanation.ORDER_FILLED_WITH_MATCH_JIT = {
|
|
13923
|
+
orderFilledWithMatchJit: {}
|
|
13924
|
+
};
|
|
13925
|
+
OrderActionExplanation.MARKET_EXPIRED = {
|
|
13926
|
+
marketExpired: {}
|
|
13927
|
+
};
|
|
13928
|
+
OrderActionExplanation.RISK_INCREASING_ORDER = {
|
|
13929
|
+
riskingIncreasingOrder: {}
|
|
13930
|
+
};
|
|
13931
|
+
OrderActionExplanation.ORDER_FILLED_WITH_SERUM = {
|
|
13932
|
+
orderFillWithSerum: {}
|
|
13933
|
+
};
|
|
13934
|
+
OrderActionExplanation.ORDER_FILLED_WITH_OPENBOOK_V2 = {
|
|
13935
|
+
orderFilledWithOpenbookV2: {}
|
|
13936
|
+
};
|
|
13937
|
+
OrderActionExplanation.ORDER_FILLED_WITH_PHOENIX = {
|
|
13938
|
+
orderFillWithPhoenix: {}
|
|
13939
|
+
};
|
|
13940
|
+
OrderActionExplanation.REDUCE_ONLY_ORDER_INCREASED_POSITION = {
|
|
13941
|
+
reduceOnlyOrderIncreasedPosition: {}
|
|
13942
|
+
};
|
|
13943
|
+
OrderActionExplanation.DERISK_LP = {
|
|
13944
|
+
deriskLp: {}
|
|
13945
|
+
};
|
|
13946
|
+
OrderActionExplanation.TRANSFER_PERP_POSITION = {
|
|
13947
|
+
transferPerpPosition: {}
|
|
13948
|
+
};
|
|
13949
|
+
class OrderTriggerCondition {
|
|
13950
|
+
}
|
|
13951
|
+
OrderTriggerCondition.ABOVE = {
|
|
13952
|
+
above: {}
|
|
13953
|
+
};
|
|
13954
|
+
OrderTriggerCondition.BELOW = {
|
|
13955
|
+
below: {}
|
|
13956
|
+
};
|
|
13957
|
+
OrderTriggerCondition.TRIGGERED_ABOVE = {
|
|
13958
|
+
triggeredAbove: {}
|
|
13959
|
+
} // above condition has been triggered
|
|
13960
|
+
;
|
|
13961
|
+
OrderTriggerCondition.TRIGGERED_BELOW = {
|
|
13962
|
+
triggeredBelow: {}
|
|
13963
|
+
} // below condition has been triggered
|
|
13964
|
+
;
|
|
13965
|
+
class SpotFulfillmentType {
|
|
13966
|
+
}
|
|
13967
|
+
SpotFulfillmentType.EXTERNAL = {
|
|
13968
|
+
external: {}
|
|
13969
|
+
};
|
|
13970
|
+
SpotFulfillmentType.MATCH = {
|
|
13971
|
+
match: {}
|
|
13972
|
+
};
|
|
13973
|
+
class SpotFulfillmentStatus {
|
|
13974
|
+
}
|
|
13975
|
+
SpotFulfillmentStatus.ENABLED = {
|
|
13976
|
+
enabled: {}
|
|
13977
|
+
};
|
|
13978
|
+
SpotFulfillmentStatus.DISABLED = {
|
|
13979
|
+
disabled: {}
|
|
13980
|
+
};
|
|
13981
|
+
class DepositExplanation {
|
|
13982
|
+
}
|
|
13983
|
+
DepositExplanation.NONE = {
|
|
13984
|
+
none: {}
|
|
13985
|
+
};
|
|
13986
|
+
DepositExplanation.TRANSFER = {
|
|
13987
|
+
transfer: {}
|
|
13988
|
+
};
|
|
13989
|
+
DepositExplanation.BORROW = {
|
|
13990
|
+
borrow: {}
|
|
13991
|
+
};
|
|
13992
|
+
DepositExplanation.REPAY_BORROW = {
|
|
13993
|
+
repayBorrow: {}
|
|
13994
|
+
};
|
|
13995
|
+
class SettlePnlExplanation {
|
|
13996
|
+
}
|
|
13997
|
+
SettlePnlExplanation.NONE = {
|
|
13998
|
+
none: {}
|
|
13999
|
+
};
|
|
14000
|
+
SettlePnlExplanation.EXPIRED_POSITION = {
|
|
14001
|
+
expiredPosition: {}
|
|
14002
|
+
};
|
|
14003
|
+
class SpotFulfillmentConfigStatus {
|
|
14004
|
+
}
|
|
14005
|
+
SpotFulfillmentConfigStatus.ENABLED = {
|
|
14006
|
+
enabled: {}
|
|
14007
|
+
};
|
|
14008
|
+
SpotFulfillmentConfigStatus.DISABLED = {
|
|
14009
|
+
disabled: {}
|
|
14010
|
+
};
|
|
14011
|
+
class StakeAction {
|
|
14012
|
+
}
|
|
14013
|
+
StakeAction.STAKE = {
|
|
14014
|
+
stake: {}
|
|
14015
|
+
};
|
|
14016
|
+
StakeAction.UNSTAKE_REQUEST = {
|
|
14017
|
+
unstakeRequest: {}
|
|
14018
|
+
};
|
|
14019
|
+
StakeAction.UNSTAKE_CANCEL_REQUEST = {
|
|
14020
|
+
unstakeCancelRequest: {}
|
|
14021
|
+
};
|
|
14022
|
+
StakeAction.UNSTAKE = {
|
|
14023
|
+
unstake: {}
|
|
14024
|
+
};
|
|
14025
|
+
StakeAction.UNSTAKE_TRANSFER = {
|
|
14026
|
+
unstakeTransfer: {}
|
|
14027
|
+
};
|
|
14028
|
+
StakeAction.STAKE_TRANSFER = {
|
|
14029
|
+
stakeTransfer: {}
|
|
14030
|
+
};
|
|
14031
|
+
class SettlePnlMode {
|
|
14032
|
+
}
|
|
14033
|
+
SettlePnlMode.TRY_SETTLE = {
|
|
14034
|
+
trySettle: {}
|
|
14035
|
+
};
|
|
14036
|
+
SettlePnlMode.MUST_SETTLE = {
|
|
14037
|
+
mustSettle: {}
|
|
14038
|
+
};
|
|
14039
|
+
function isVariant(object, type) {
|
|
14040
|
+
return object.hasOwnProperty(type);
|
|
14041
|
+
}
|
|
14042
|
+
function isOneOfVariant(object, types) {
|
|
14043
|
+
return types.reduce((result, type)=>{
|
|
14044
|
+
return result || object.hasOwnProperty(type);
|
|
14045
|
+
}, false);
|
|
14046
|
+
}
|
|
14047
|
+
function getVariant(object) {
|
|
14048
|
+
return Object.keys(object)[0];
|
|
14049
|
+
}
|
|
14050
|
+
var TradeSide = /*#__PURE__*/ function(TradeSide) {
|
|
14051
|
+
TradeSide[TradeSide["None"] = 0] = "None";
|
|
14052
|
+
TradeSide[TradeSide["Buy"] = 1] = "Buy";
|
|
14053
|
+
TradeSide[TradeSide["Sell"] = 2] = "Sell";
|
|
14054
|
+
return TradeSide;
|
|
14055
|
+
}({});
|
|
14056
|
+
class LPAction {
|
|
14057
|
+
}
|
|
14058
|
+
LPAction.ADD_LIQUIDITY = {
|
|
14059
|
+
addLiquidity: {}
|
|
14060
|
+
};
|
|
14061
|
+
LPAction.REMOVE_LIQUIDITY = {
|
|
14062
|
+
removeLiquidity: {}
|
|
14063
|
+
};
|
|
14064
|
+
LPAction.SETTLE_LIQUIDITY = {
|
|
14065
|
+
settleLiquidity: {}
|
|
14066
|
+
};
|
|
14067
|
+
LPAction.REMOVE_LIQUIDITY_DERISK = {
|
|
14068
|
+
removeLiquidityDerisk: {}
|
|
14069
|
+
};
|
|
14070
|
+
class LiquidationType {
|
|
14071
|
+
}
|
|
14072
|
+
LiquidationType.LIQUIDATE_PERP = {
|
|
14073
|
+
liquidatePerp: {}
|
|
14074
|
+
};
|
|
14075
|
+
LiquidationType.LIQUIDATE_BORROW_FOR_PERP_PNL = {
|
|
14076
|
+
liquidateBorrowForPerpPnl: {}
|
|
14077
|
+
};
|
|
14078
|
+
LiquidationType.LIQUIDATE_PERP_PNL_FOR_DEPOSIT = {
|
|
14079
|
+
liquidatePerpPnlForDeposit: {}
|
|
14080
|
+
};
|
|
14081
|
+
LiquidationType.PERP_BANKRUPTCY = {
|
|
14082
|
+
perpBankruptcy: {}
|
|
14083
|
+
};
|
|
14084
|
+
LiquidationType.SPOT_BANKRUPTCY = {
|
|
14085
|
+
spotBankruptcy: {}
|
|
14086
|
+
};
|
|
14087
|
+
LiquidationType.LIQUIDATE_SPOT = {
|
|
14088
|
+
liquidateSpot: {}
|
|
14089
|
+
};
|
|
14090
|
+
class PostOnlyParams {
|
|
14091
|
+
}
|
|
14092
|
+
PostOnlyParams.NONE = {
|
|
14093
|
+
none: {}
|
|
14094
|
+
};
|
|
14095
|
+
PostOnlyParams.MUST_POST_ONLY = {
|
|
14096
|
+
mustPostOnly: {}
|
|
14097
|
+
} // Tx fails if order can't be post only
|
|
14098
|
+
;
|
|
14099
|
+
PostOnlyParams.TRY_POST_ONLY = {
|
|
14100
|
+
tryPostOnly: {}
|
|
14101
|
+
} // Tx succeeds and order not placed if can't be post only
|
|
14102
|
+
;
|
|
14103
|
+
PostOnlyParams.SLIDE = {
|
|
14104
|
+
slide: {}
|
|
14105
|
+
} // Modify price to be post only if can't be post only
|
|
14106
|
+
;
|
|
14107
|
+
var ModifyOrderPolicy = /*#__PURE__*/ function(ModifyOrderPolicy) {
|
|
14108
|
+
ModifyOrderPolicy[ModifyOrderPolicy["MustModify"] = 1] = "MustModify";
|
|
14109
|
+
ModifyOrderPolicy[ModifyOrderPolicy["ExcludePreviousFill"] = 2] = "ExcludePreviousFill";
|
|
14110
|
+
return ModifyOrderPolicy;
|
|
14111
|
+
}({});
|
|
14112
|
+
const DefaultOrderParams = {
|
|
14113
|
+
orderType: OrderType.MARKET,
|
|
14114
|
+
marketType: MarketType.PERP,
|
|
14115
|
+
userOrderId: 0,
|
|
14116
|
+
direction: PositionDirection.LONG,
|
|
14117
|
+
baseAssetAmount: ZERO,
|
|
14118
|
+
price: ZERO,
|
|
14119
|
+
marketIndex: 0,
|
|
14120
|
+
reduceOnly: false,
|
|
14121
|
+
postOnly: PostOnlyParams.NONE,
|
|
14122
|
+
immediateOrCancel: false,
|
|
14123
|
+
triggerPrice: null,
|
|
14124
|
+
triggerCondition: OrderTriggerCondition.ABOVE,
|
|
14125
|
+
oraclePriceOffset: null,
|
|
14126
|
+
auctionDuration: null,
|
|
14127
|
+
maxTs: null,
|
|
14128
|
+
auctionStartPrice: null,
|
|
14129
|
+
auctionEndPrice: null
|
|
14130
|
+
};
|
|
14131
|
+
var ReferrerStatus = /*#__PURE__*/ function(ReferrerStatus) {
|
|
14132
|
+
ReferrerStatus[ReferrerStatus["IsReferrer"] = 1] = "IsReferrer";
|
|
14133
|
+
ReferrerStatus[ReferrerStatus["IsReferred"] = 2] = "IsReferred";
|
|
14134
|
+
return ReferrerStatus;
|
|
14135
|
+
}({});
|
|
14136
|
+
var FuelOverflowStatus = /*#__PURE__*/ function(FuelOverflowStatus) {
|
|
14137
|
+
FuelOverflowStatus[FuelOverflowStatus["Exists"] = 1] = "Exists";
|
|
14138
|
+
return FuelOverflowStatus;
|
|
14139
|
+
}({});
|
|
14140
|
+
var PlaceAndTakeOrderSuccessCondition = /*#__PURE__*/ function(PlaceAndTakeOrderSuccessCondition) {
|
|
14141
|
+
PlaceAndTakeOrderSuccessCondition[PlaceAndTakeOrderSuccessCondition["PartialFill"] = 1] = "PartialFill";
|
|
14142
|
+
PlaceAndTakeOrderSuccessCondition[PlaceAndTakeOrderSuccessCondition["FullFill"] = 2] = "FullFill";
|
|
14143
|
+
return PlaceAndTakeOrderSuccessCondition;
|
|
14144
|
+
}({});
|
|
14145
|
+
class SwapReduceOnly {
|
|
14146
|
+
}
|
|
14147
|
+
SwapReduceOnly.In = {
|
|
14148
|
+
in: {}
|
|
14149
|
+
};
|
|
14150
|
+
SwapReduceOnly.Out = {
|
|
14151
|
+
out: {}
|
|
14152
|
+
};
|
|
14153
|
+
|
|
14154
|
+
function readUnsignedBigInt64LE(buffer, offset) {
|
|
14155
|
+
return new BN(buffer.subarray(offset, offset + 8), 10, "le");
|
|
14156
|
+
}
|
|
14157
|
+
function readSignedBigInt64LE(buffer, offset) {
|
|
14158
|
+
const unsignedValue = new BN(buffer.subarray(offset, offset + 8), 10, "le");
|
|
14159
|
+
if (unsignedValue.testn(63)) {
|
|
14160
|
+
const inverted = unsignedValue.notn(64).addn(1);
|
|
14161
|
+
return inverted.neg();
|
|
14162
|
+
} else {
|
|
14163
|
+
return unsignedValue;
|
|
14164
|
+
}
|
|
14165
|
+
}
|
|
14166
|
+
function decodeUser(buffer) {
|
|
14167
|
+
let offset = 8;
|
|
14168
|
+
const authority = new PublicKey(buffer.slice(offset, offset + 32));
|
|
14169
|
+
offset += 32;
|
|
14170
|
+
const delegate = new PublicKey(buffer.slice(offset, offset + 32));
|
|
14171
|
+
offset += 32;
|
|
14172
|
+
const name = [];
|
|
14173
|
+
for(let i = 0; i < 32; i++){
|
|
14174
|
+
name.push(buffer.readUint8(offset + i));
|
|
14175
|
+
}
|
|
14176
|
+
offset += 32;
|
|
14177
|
+
const spotPositions = [];
|
|
14178
|
+
for(let i = 0; i < 8; i++){
|
|
14179
|
+
const scaledBalance = readUnsignedBigInt64LE(buffer, offset);
|
|
14180
|
+
const openOrders = buffer.readUInt8(offset + 35);
|
|
14181
|
+
if (scaledBalance.eq(ZERO) && openOrders === 0) {
|
|
14182
|
+
offset += 40;
|
|
14183
|
+
continue;
|
|
14184
|
+
}
|
|
14185
|
+
offset += 8;
|
|
14186
|
+
const openBids = readSignedBigInt64LE(buffer, offset);
|
|
14187
|
+
offset += 8;
|
|
14188
|
+
const openAsks = readSignedBigInt64LE(buffer, offset);
|
|
14189
|
+
offset += 8;
|
|
14190
|
+
const cumulativeDeposits = readSignedBigInt64LE(buffer, offset);
|
|
14191
|
+
offset += 8;
|
|
14192
|
+
const marketIndex = buffer.readUInt16LE(offset);
|
|
14193
|
+
offset += 2;
|
|
14194
|
+
const balanceTypeNum = buffer.readUInt8(offset);
|
|
14195
|
+
let balanceType;
|
|
14196
|
+
if (balanceTypeNum === 0) {
|
|
14197
|
+
balanceType = SpotBalanceType.DEPOSIT;
|
|
14198
|
+
} else {
|
|
14199
|
+
balanceType = SpotBalanceType.BORROW;
|
|
14200
|
+
}
|
|
14201
|
+
offset += 6;
|
|
14202
|
+
spotPositions.push({
|
|
14203
|
+
scaledBalance,
|
|
14204
|
+
openBids,
|
|
14205
|
+
openAsks,
|
|
14206
|
+
cumulativeDeposits,
|
|
14207
|
+
marketIndex,
|
|
14208
|
+
balanceType,
|
|
14209
|
+
openOrders
|
|
14210
|
+
});
|
|
14211
|
+
}
|
|
14212
|
+
const perpPositions = [];
|
|
14213
|
+
for(let i = 0; i < 8; i++){
|
|
14214
|
+
const baseAssetAmount = readSignedBigInt64LE(buffer, offset + 8);
|
|
14215
|
+
const quoteAssetAmount = readSignedBigInt64LE(buffer, offset + 16);
|
|
14216
|
+
const lpShares = readUnsignedBigInt64LE(buffer, offset + 64);
|
|
14217
|
+
const openOrders = buffer.readUInt8(offset + 94);
|
|
14218
|
+
if (baseAssetAmount.eq(ZERO) && openOrders === 0 && quoteAssetAmount.eq(ZERO) && lpShares.eq(ZERO)) {
|
|
14219
|
+
offset += 96;
|
|
14220
|
+
continue;
|
|
14221
|
+
}
|
|
14222
|
+
const lastCumulativeFundingRate = readSignedBigInt64LE(buffer, offset);
|
|
14223
|
+
offset += 24;
|
|
14224
|
+
const quoteBreakEvenAmount = readSignedBigInt64LE(buffer, offset);
|
|
14225
|
+
offset += 8;
|
|
14226
|
+
const quoteEntryAmount = readSignedBigInt64LE(buffer, offset);
|
|
14227
|
+
offset += 8;
|
|
14228
|
+
const openBids = readSignedBigInt64LE(buffer, offset);
|
|
14229
|
+
offset += 8;
|
|
14230
|
+
const openAsks = readSignedBigInt64LE(buffer, offset);
|
|
14231
|
+
offset += 8;
|
|
14232
|
+
const settledPnl = readSignedBigInt64LE(buffer, offset);
|
|
14233
|
+
offset += 16;
|
|
14234
|
+
const lastBaseAssetAmountPerLp = readSignedBigInt64LE(buffer, offset);
|
|
14235
|
+
offset += 8;
|
|
14236
|
+
const lastQuoteAssetAmountPerLp = readSignedBigInt64LE(buffer, offset);
|
|
14237
|
+
offset += 8;
|
|
14238
|
+
const remainderBaseAssetAmount = buffer.readInt32LE(offset);
|
|
14239
|
+
offset += 4;
|
|
14240
|
+
const marketIndex = buffer.readUInt16LE(offset);
|
|
14241
|
+
offset += 3;
|
|
14242
|
+
const perLpBase = buffer.readUInt8(offset);
|
|
14243
|
+
offset += 1;
|
|
14244
|
+
perpPositions.push({
|
|
14245
|
+
lastCumulativeFundingRate,
|
|
14246
|
+
baseAssetAmount,
|
|
14247
|
+
quoteAssetAmount,
|
|
14248
|
+
quoteBreakEvenAmount,
|
|
14249
|
+
quoteEntryAmount,
|
|
14250
|
+
openBids,
|
|
14251
|
+
openAsks,
|
|
14252
|
+
settledPnl,
|
|
14253
|
+
lpShares,
|
|
14254
|
+
lastBaseAssetAmountPerLp,
|
|
14255
|
+
lastQuoteAssetAmountPerLp,
|
|
14256
|
+
remainderBaseAssetAmount,
|
|
14257
|
+
marketIndex,
|
|
14258
|
+
openOrders,
|
|
14259
|
+
perLpBase
|
|
14260
|
+
});
|
|
14261
|
+
}
|
|
14262
|
+
const orders = [];
|
|
14263
|
+
for(let i = 0; i < 32; i++){
|
|
14264
|
+
// skip order if it's not open
|
|
14265
|
+
if (buffer.readUint8(offset + 82) !== 1) {
|
|
14266
|
+
offset += 96;
|
|
14267
|
+
continue;
|
|
14268
|
+
}
|
|
14269
|
+
const slot = readUnsignedBigInt64LE(buffer, offset);
|
|
14270
|
+
offset += 8;
|
|
14271
|
+
const price = readUnsignedBigInt64LE(buffer, offset);
|
|
14272
|
+
offset += 8;
|
|
14273
|
+
const baseAssetAmount = readUnsignedBigInt64LE(buffer, offset);
|
|
14274
|
+
offset += 8;
|
|
14275
|
+
const baseAssetAmountFilled = readUnsignedBigInt64LE(buffer, offset);
|
|
14276
|
+
offset += 8;
|
|
14277
|
+
const quoteAssetAmountFilled = readUnsignedBigInt64LE(buffer, offset);
|
|
14278
|
+
offset += 8;
|
|
14279
|
+
const triggerPrice = readUnsignedBigInt64LE(buffer, offset);
|
|
14280
|
+
offset += 8;
|
|
14281
|
+
const auctionStartPrice = readSignedBigInt64LE(buffer, offset);
|
|
14282
|
+
offset += 8;
|
|
14283
|
+
const auctionEndPrice = readSignedBigInt64LE(buffer, offset);
|
|
14284
|
+
offset += 8;
|
|
14285
|
+
const maxTs = readSignedBigInt64LE(buffer, offset);
|
|
14286
|
+
offset += 8;
|
|
14287
|
+
const oraclePriceOffset = buffer.readInt32LE(offset);
|
|
14288
|
+
offset += 4;
|
|
14289
|
+
const orderId = buffer.readUInt32LE(offset);
|
|
14290
|
+
offset += 4;
|
|
14291
|
+
const marketIndex = buffer.readUInt16LE(offset);
|
|
14292
|
+
offset += 2;
|
|
14293
|
+
const orderStatusNum = buffer.readUInt8(offset);
|
|
14294
|
+
let status = OrderStatus.INIT;
|
|
14295
|
+
if (orderStatusNum === 0) {
|
|
14296
|
+
status = OrderStatus.INIT;
|
|
14297
|
+
} else if (orderStatusNum === 1) {
|
|
14298
|
+
status = OrderStatus.OPEN;
|
|
14299
|
+
} else if (orderStatusNum === 2) {
|
|
14300
|
+
status = OrderStatus.FILLED;
|
|
14301
|
+
} else if (orderStatusNum === 3) {
|
|
14302
|
+
status = OrderStatus.CANCELED;
|
|
14303
|
+
}
|
|
14304
|
+
offset += 1;
|
|
14305
|
+
const orderTypeNum = buffer.readUInt8(offset);
|
|
14306
|
+
let orderType = OrderType.MARKET;
|
|
14307
|
+
if (orderTypeNum === 0) {
|
|
14308
|
+
orderType = OrderType.MARKET;
|
|
14309
|
+
} else if (orderTypeNum === 1) {
|
|
14310
|
+
orderType = OrderType.LIMIT;
|
|
14311
|
+
} else if (orderTypeNum === 2) {
|
|
14312
|
+
orderType = OrderType.TRIGGER_MARKET;
|
|
14313
|
+
} else if (orderTypeNum === 3) {
|
|
14314
|
+
orderType = OrderType.TRIGGER_LIMIT;
|
|
14315
|
+
} else if (orderTypeNum === 4) {
|
|
14316
|
+
orderType = OrderType.ORACLE;
|
|
14317
|
+
}
|
|
14318
|
+
offset += 1;
|
|
14319
|
+
const marketTypeNum = buffer.readUInt8(offset);
|
|
14320
|
+
let marketType;
|
|
14321
|
+
if (marketTypeNum === 0) {
|
|
14322
|
+
marketType = MarketType.SPOT;
|
|
14323
|
+
} else {
|
|
14324
|
+
marketType = MarketType.PERP;
|
|
14325
|
+
}
|
|
14326
|
+
offset += 1;
|
|
14327
|
+
const userOrderId = buffer.readUint8(offset);
|
|
14328
|
+
offset += 1;
|
|
14329
|
+
const existingPositionDirectionNum = buffer.readUInt8(offset);
|
|
14330
|
+
let existingPositionDirection;
|
|
14331
|
+
if (existingPositionDirectionNum === 0) {
|
|
14332
|
+
existingPositionDirection = PositionDirection.LONG;
|
|
14333
|
+
} else {
|
|
14334
|
+
existingPositionDirection = PositionDirection.SHORT;
|
|
14335
|
+
}
|
|
14336
|
+
offset += 1;
|
|
14337
|
+
const positionDirectionNum = buffer.readUInt8(offset);
|
|
14338
|
+
let direction;
|
|
14339
|
+
if (positionDirectionNum === 0) {
|
|
14340
|
+
direction = PositionDirection.LONG;
|
|
14341
|
+
} else {
|
|
14342
|
+
direction = PositionDirection.SHORT;
|
|
14343
|
+
}
|
|
14344
|
+
offset += 1;
|
|
14345
|
+
const reduceOnly = buffer.readUInt8(offset) === 1;
|
|
14346
|
+
offset += 1;
|
|
14347
|
+
const postOnly = buffer.readUInt8(offset) === 1;
|
|
14348
|
+
offset += 1;
|
|
14349
|
+
const immediateOrCancel = buffer.readUInt8(offset) === 1;
|
|
14350
|
+
offset += 1;
|
|
14351
|
+
const triggerConditionNum = buffer.readUInt8(offset);
|
|
14352
|
+
let triggerCondition = OrderTriggerCondition.ABOVE;
|
|
14353
|
+
if (triggerConditionNum === 0) {
|
|
14354
|
+
triggerCondition = OrderTriggerCondition.ABOVE;
|
|
14355
|
+
} else if (triggerConditionNum === 1) {
|
|
14356
|
+
triggerCondition = OrderTriggerCondition.BELOW;
|
|
14357
|
+
} else if (triggerConditionNum === 2) {
|
|
14358
|
+
triggerCondition = OrderTriggerCondition.TRIGGERED_ABOVE;
|
|
14359
|
+
} else if (triggerConditionNum === 3) {
|
|
14360
|
+
triggerCondition = OrderTriggerCondition.TRIGGERED_BELOW;
|
|
14361
|
+
}
|
|
14362
|
+
offset += 1;
|
|
14363
|
+
const auctionDuration = buffer.readUInt8(offset);
|
|
14364
|
+
offset += 1;
|
|
14365
|
+
const postedSlotTail = buffer.readUint8(offset);
|
|
14366
|
+
offset += 1;
|
|
14367
|
+
const bitFlags = buffer.readUint8(offset);
|
|
14368
|
+
offset += 1;
|
|
14369
|
+
offset += 1; // padding
|
|
14370
|
+
orders.push({
|
|
14371
|
+
slot,
|
|
14372
|
+
price,
|
|
14373
|
+
baseAssetAmount,
|
|
14374
|
+
quoteAssetAmount: undefined,
|
|
14375
|
+
baseAssetAmountFilled,
|
|
14376
|
+
quoteAssetAmountFilled,
|
|
14377
|
+
triggerPrice,
|
|
14378
|
+
auctionStartPrice,
|
|
14379
|
+
auctionEndPrice,
|
|
14380
|
+
maxTs,
|
|
14381
|
+
oraclePriceOffset,
|
|
14382
|
+
orderId,
|
|
14383
|
+
marketIndex,
|
|
14384
|
+
status,
|
|
14385
|
+
orderType,
|
|
14386
|
+
marketType,
|
|
14387
|
+
userOrderId,
|
|
14388
|
+
existingPositionDirection,
|
|
14389
|
+
direction,
|
|
14390
|
+
reduceOnly,
|
|
14391
|
+
postOnly,
|
|
14392
|
+
immediateOrCancel,
|
|
14393
|
+
triggerCondition,
|
|
14394
|
+
auctionDuration,
|
|
14395
|
+
bitFlags,
|
|
14396
|
+
postedSlotTail
|
|
14397
|
+
});
|
|
14398
|
+
}
|
|
14399
|
+
const lastAddPerpLpSharesTs = readSignedBigInt64LE(buffer, offset);
|
|
14400
|
+
offset += 8;
|
|
14401
|
+
const totalDeposits = readUnsignedBigInt64LE(buffer, offset);
|
|
14402
|
+
offset += 8;
|
|
14403
|
+
const totalWithdraws = readUnsignedBigInt64LE(buffer, offset);
|
|
14404
|
+
offset += 8;
|
|
14405
|
+
const totalSocialLoss = readUnsignedBigInt64LE(buffer, offset);
|
|
14406
|
+
offset += 8;
|
|
14407
|
+
const settledPerpPnl = readSignedBigInt64LE(buffer, offset);
|
|
14408
|
+
offset += 8;
|
|
14409
|
+
const cumulativeSpotFees = readSignedBigInt64LE(buffer, offset);
|
|
14410
|
+
offset += 8;
|
|
14411
|
+
const cumulativePerpFunding = readSignedBigInt64LE(buffer, offset);
|
|
14412
|
+
offset += 8;
|
|
14413
|
+
const liquidationMarginFreed = readUnsignedBigInt64LE(buffer, offset);
|
|
14414
|
+
offset += 8;
|
|
14415
|
+
const lastActiveSlot = readUnsignedBigInt64LE(buffer, offset);
|
|
14416
|
+
offset += 8;
|
|
14417
|
+
const nextOrderId = buffer.readUInt32LE(offset);
|
|
14418
|
+
offset += 4;
|
|
14419
|
+
const maxMarginRatio = buffer.readUInt32LE(offset);
|
|
14420
|
+
offset += 4;
|
|
14421
|
+
const nextLiquidationId = buffer.readUInt16LE(offset);
|
|
14422
|
+
offset += 2;
|
|
14423
|
+
const subAccountId = buffer.readUInt16LE(offset);
|
|
14424
|
+
offset += 2;
|
|
14425
|
+
const status = buffer.readUInt8(offset);
|
|
14426
|
+
offset += 1;
|
|
14427
|
+
const isMarginTradingEnabled = buffer.readUInt8(offset) === 1;
|
|
14428
|
+
offset += 1;
|
|
14429
|
+
const idle = buffer.readUInt8(offset) === 1;
|
|
14430
|
+
offset += 1;
|
|
14431
|
+
const openOrders = buffer.readUInt8(offset);
|
|
14432
|
+
offset += 1;
|
|
14433
|
+
const hasOpenOrder = buffer.readUInt8(offset) === 1;
|
|
14434
|
+
offset += 1;
|
|
14435
|
+
const openAuctions = buffer.readUInt8(offset);
|
|
14436
|
+
offset += 1;
|
|
14437
|
+
const hasOpenAuction = buffer.readUInt8(offset) === 1;
|
|
14438
|
+
offset += 1;
|
|
14439
|
+
let marginMode;
|
|
14440
|
+
const marginModeNum = buffer.readUInt8(offset);
|
|
14441
|
+
if (marginModeNum === 0) {
|
|
14442
|
+
marginMode = MarginMode.DEFAULT;
|
|
14443
|
+
} else {
|
|
14444
|
+
marginMode = MarginMode.HIGH_LEVERAGE;
|
|
14445
|
+
}
|
|
14446
|
+
offset += 1;
|
|
14447
|
+
const poolId = buffer.readUint8(offset);
|
|
14448
|
+
offset += 1;
|
|
14449
|
+
offset += 3; // padding
|
|
14450
|
+
const lastFuelBonusUpdateTs = buffer.readUint32LE(offset);
|
|
14451
|
+
offset += 4;
|
|
14452
|
+
return {
|
|
14453
|
+
authority,
|
|
14454
|
+
delegate,
|
|
14455
|
+
name,
|
|
14456
|
+
spotPositions,
|
|
14457
|
+
perpPositions,
|
|
14458
|
+
orders,
|
|
14459
|
+
lastAddPerpLpSharesTs,
|
|
14460
|
+
totalDeposits,
|
|
14461
|
+
totalWithdraws,
|
|
14462
|
+
totalSocialLoss,
|
|
14463
|
+
settledPerpPnl,
|
|
14464
|
+
cumulativeSpotFees,
|
|
14465
|
+
cumulativePerpFunding,
|
|
14466
|
+
liquidationMarginFreed,
|
|
14467
|
+
lastActiveSlot,
|
|
14468
|
+
nextOrderId,
|
|
14469
|
+
maxMarginRatio,
|
|
14470
|
+
nextLiquidationId,
|
|
14471
|
+
subAccountId,
|
|
14472
|
+
status,
|
|
14473
|
+
isMarginTradingEnabled,
|
|
14474
|
+
idle,
|
|
14475
|
+
openOrders,
|
|
14476
|
+
hasOpenOrder,
|
|
14477
|
+
openAuctions,
|
|
14478
|
+
hasOpenAuction,
|
|
14479
|
+
marginMode,
|
|
14480
|
+
poolId,
|
|
14481
|
+
lastFuelBonusUpdateTs
|
|
14482
|
+
};
|
|
14483
|
+
}
|
|
14484
|
+
|
|
14485
|
+
const DRIFT_SIGNER = new PublicKey("JCNCMFXo5M5qwUPg2Utu1u6YWp3MbygxqBsBeXXJfrw");
|
|
13577
14486
|
const DRIFT_MARGIN_PRECISION = 10000;
|
|
13578
14487
|
class DriftClient {
|
|
13579
14488
|
/*
|
|
@@ -13598,83 +14507,268 @@ class DriftClient {
|
|
|
13598
14507
|
const tx = await this.deleteUserTx(new PublicKey(statePda), subAccountId, txOptions);
|
|
13599
14508
|
return await this.base.sendAndConfirm(tx);
|
|
13600
14509
|
}
|
|
13601
|
-
async deposit(statePda, amount, marketIndex = 1, subAccountId = 0,
|
|
13602
|
-
const tx = await this.depositTx(new PublicKey(statePda), amount, marketIndex, subAccountId,
|
|
14510
|
+
async deposit(statePda, amount, marketIndex = 1, subAccountId = 0, txOptions = {}) {
|
|
14511
|
+
const tx = await this.depositTx(new PublicKey(statePda), amount, marketIndex, subAccountId, txOptions);
|
|
13603
14512
|
return await this.base.sendAndConfirm(tx);
|
|
13604
14513
|
}
|
|
13605
|
-
async withdraw(statePda, amount, marketIndex = 1, subAccountId = 0,
|
|
13606
|
-
const tx = await this.withdrawTx(new PublicKey(statePda), amount, marketIndex, subAccountId,
|
|
14514
|
+
async withdraw(statePda, amount, marketIndex = 1, subAccountId = 0, txOptions = {}) {
|
|
14515
|
+
const tx = await this.withdrawTx(new PublicKey(statePda), amount, marketIndex, subAccountId, txOptions);
|
|
13607
14516
|
return await this.base.sendAndConfirm(tx);
|
|
13608
14517
|
}
|
|
13609
|
-
async placeOrder(statePda, orderParams, subAccountId = 0,
|
|
13610
|
-
const tx = await this.placeOrderTx(new PublicKey(statePda), orderParams, subAccountId,
|
|
14518
|
+
async placeOrder(statePda, orderParams, subAccountId = 0, txOptions = {}) {
|
|
14519
|
+
const tx = await this.placeOrderTx(new PublicKey(statePda), orderParams, subAccountId, txOptions);
|
|
13611
14520
|
return await this.base.sendAndConfirm(tx);
|
|
13612
14521
|
}
|
|
13613
|
-
async modifyOrder(statePda, modifyOrderParams, subAccountId = 0,
|
|
13614
|
-
const tx = await this.modifyOrderTx(new PublicKey(statePda), modifyOrderParams, subAccountId,
|
|
14522
|
+
async modifyOrder(statePda, modifyOrderParams, subAccountId = 0, txOptions = {}) {
|
|
14523
|
+
const tx = await this.modifyOrderTx(new PublicKey(statePda), modifyOrderParams, subAccountId, txOptions);
|
|
13615
14524
|
return await this.base.sendAndConfirm(tx);
|
|
13616
14525
|
}
|
|
13617
|
-
async cancelOrders(statePda, marketType, marketIndex, direction, subAccountId = 0,
|
|
13618
|
-
const tx = await this.cancelOrdersTx(new PublicKey(statePda), marketType, marketIndex, direction, subAccountId,
|
|
14526
|
+
async cancelOrders(statePda, marketType, marketIndex, direction, subAccountId = 0, txOptions = {}) {
|
|
14527
|
+
const tx = await this.cancelOrdersTx(new PublicKey(statePda), marketType, marketIndex, direction, subAccountId, txOptions);
|
|
13619
14528
|
return await this.base.sendAndConfirm(tx);
|
|
13620
14529
|
}
|
|
13621
|
-
async cancelOrdersByIds(statePda, orderIds, subAccountId = 0,
|
|
13622
|
-
const tx = await this.cancelOrdersByIdsTx(new PublicKey(statePda), orderIds, subAccountId,
|
|
14530
|
+
async cancelOrdersByIds(statePda, orderIds, subAccountId = 0, txOptions = {}) {
|
|
14531
|
+
const tx = await this.cancelOrdersByIdsTx(new PublicKey(statePda), orderIds, subAccountId, txOptions);
|
|
13623
14532
|
return await this.base.sendAndConfirm(tx);
|
|
13624
14533
|
}
|
|
13625
|
-
async settlePnl(statePda, marketIndex, subAccountId = 0,
|
|
13626
|
-
const tx = await this.settlePnlTx(new PublicKey(statePda), marketIndex, subAccountId,
|
|
14534
|
+
async settlePnl(statePda, marketIndex, subAccountId = 0, txOptions = {}) {
|
|
14535
|
+
const tx = await this.settlePnlTx(new PublicKey(statePda), marketIndex, subAccountId, txOptions);
|
|
13627
14536
|
return await this.base.sendAndConfirm(tx);
|
|
13628
14537
|
}
|
|
13629
|
-
async priceDrift(statePda,
|
|
13630
|
-
const tx = await this.priceDriftTx(new PublicKey(statePda),
|
|
14538
|
+
async priceDrift(statePda, priceDenom, txOptions = {}) {
|
|
14539
|
+
const tx = await this.priceDriftTx(new PublicKey(statePda), priceDenom, txOptions);
|
|
13631
14540
|
return await this.base.sendAndConfirm(tx);
|
|
13632
14541
|
}
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
|
|
14542
|
+
getGlamReferrerPdas() {
|
|
14543
|
+
return {
|
|
14544
|
+
user: this.getUserPda(GLAM_REFERRER, 0),
|
|
14545
|
+
userStats: this.getUserStatsPda(GLAM_REFERRER)
|
|
14546
|
+
};
|
|
14547
|
+
}
|
|
14548
|
+
parsePerpMarket(data) {
|
|
14549
|
+
const marketPda = new PublicKey(data.subarray(8, 40));
|
|
14550
|
+
const oracle = new PublicKey(data.subarray(40, 72));
|
|
14551
|
+
const name = this.charsToName(data.subarray(1000, 1032));
|
|
14552
|
+
const oralceEnum = data.subarray(926, 927).readUint8();
|
|
14553
|
+
const oracleSource = OracleSource.get(oralceEnum);
|
|
14554
|
+
const marketIndex = data.subarray(1160, 1162).readUint16LE();
|
|
14555
|
+
return {
|
|
14556
|
+
name,
|
|
14557
|
+
marketPda,
|
|
14558
|
+
marketIndex,
|
|
14559
|
+
oracle,
|
|
14560
|
+
oracleSource
|
|
14561
|
+
};
|
|
14562
|
+
}
|
|
14563
|
+
parseSpotMarket(data) {
|
|
14564
|
+
const marketPda = new PublicKey(data.subarray(8, 40));
|
|
14565
|
+
const oracle = new PublicKey(data.subarray(40, 72));
|
|
14566
|
+
const mint = new PublicKey(data.subarray(72, 104));
|
|
14567
|
+
const vault = new PublicKey(data.subarray(104, 136));
|
|
14568
|
+
const name = this.charsToName(data.subarray(136, 168));
|
|
14569
|
+
const cumulativeDepositInterest = new BN(data.subarray(464, 480), "le");
|
|
14570
|
+
const cumulativeBorrowInterest = new BN(data.subarray(480, 496), "le");
|
|
14571
|
+
const decimals = data.subarray(680, 684).readUint32LE();
|
|
14572
|
+
const marketIndex = data.subarray(684, 686).readUint16LE();
|
|
14573
|
+
const oralceEnum = data.subarray(687, 688).readUint8();
|
|
14574
|
+
const oracleSource = OracleSource.get(oralceEnum);
|
|
14575
|
+
const tokenProgram = data.subarray(734, 735).readUint8() == 0 ? TOKEN_PROGRAM_ID : TOKEN_2022_PROGRAM_ID;
|
|
14576
|
+
return {
|
|
14577
|
+
name,
|
|
14578
|
+
marketIndex,
|
|
14579
|
+
marketPda,
|
|
14580
|
+
oracle,
|
|
14581
|
+
oracleSource,
|
|
14582
|
+
vault,
|
|
14583
|
+
mint,
|
|
14584
|
+
decimals,
|
|
14585
|
+
tokenProgram,
|
|
14586
|
+
cumulativeDepositInterest,
|
|
14587
|
+
cumulativeBorrowInterest
|
|
14588
|
+
};
|
|
14589
|
+
}
|
|
14590
|
+
async calcSpotBalance(marketIndex, scaledBalance, scaledBalanceType) {
|
|
14591
|
+
const { decimals, cumulativeDepositInterest, cumulativeBorrowInterest } = await this.fetchAndParseSpotMarket(marketIndex);
|
|
14592
|
+
const precisionAdjustment = new BN(10 ** (19 - decimals));
|
|
14593
|
+
let interest = cumulativeDepositInterest;
|
|
14594
|
+
if (scaledBalanceType === SpotBalanceType.BORROW) {
|
|
14595
|
+
interest = cumulativeBorrowInterest;
|
|
14596
|
+
}
|
|
14597
|
+
const balance = scaledBalance.mul(interest).div(precisionAdjustment);
|
|
14598
|
+
const amount = scaledBalanceType === SpotBalanceType.BORROW ? balance.neg().toNumber() : balance.toNumber();
|
|
14599
|
+
const uiAmount = amount / 10 ** decimals;
|
|
14600
|
+
return {
|
|
14601
|
+
amount,
|
|
14602
|
+
uiAmount
|
|
14603
|
+
};
|
|
14604
|
+
}
|
|
14605
|
+
getDriftUserPdas(statePda, subAccountId = 0) {
|
|
13636
14606
|
const vault = this.base.getVaultPda(new PublicKey(statePda));
|
|
13637
|
-
return
|
|
13638
|
-
|
|
13639
|
-
|
|
13640
|
-
|
|
14607
|
+
return {
|
|
14608
|
+
user: this.getUserPda(vault, subAccountId),
|
|
14609
|
+
userStats: this.getUserStatsPda(vault)
|
|
14610
|
+
};
|
|
13641
14611
|
}
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
14612
|
+
get driftStatePda() {
|
|
14613
|
+
return PublicKey.findProgramAddressSync([
|
|
14614
|
+
Buffer.from("drift_state")
|
|
14615
|
+
], DRIFT_PROGRAM_ID)[0];
|
|
14616
|
+
}
|
|
14617
|
+
async fetchAndParseSpotMarket(marketIndex) {
|
|
14618
|
+
const markets = await this.fetchAndParseSpotMarkets([
|
|
14619
|
+
marketIndex
|
|
14620
|
+
]);
|
|
14621
|
+
if (!markets || markets.length === 0) {
|
|
14622
|
+
throw new Error(`Spot market not found at index ${marketIndex}`);
|
|
13646
14623
|
}
|
|
13647
|
-
|
|
13648
|
-
|
|
14624
|
+
return markets[0];
|
|
14625
|
+
}
|
|
14626
|
+
async fetchAndParseSpotMarkets(marketIndexes) {
|
|
14627
|
+
const indexesToFetch = marketIndexes.filter((marketIndex)=>!this.spotMarkets.has(marketIndex));
|
|
14628
|
+
if (indexesToFetch.length > 0) {
|
|
14629
|
+
console.log("Fetching spot markets:", indexesToFetch);
|
|
14630
|
+
const marketPdas = indexesToFetch.map((marketIndex)=>this.getMarketPda(MarketType.SPOT, marketIndex));
|
|
14631
|
+
const accounts = await this.base.provider.connection.getMultipleAccountsInfo(marketPdas);
|
|
14632
|
+
accounts.forEach((account)=>{
|
|
14633
|
+
if (account) {
|
|
14634
|
+
const spotMarket = this.parseSpotMarket(account.data);
|
|
14635
|
+
this.spotMarkets.set(spotMarket.marketIndex, spotMarket);
|
|
14636
|
+
}
|
|
14637
|
+
});
|
|
14638
|
+
}
|
|
14639
|
+
// At this point this.spotMarkets has all the requested markets
|
|
14640
|
+
return marketIndexes.map((marketIndex)=>this.spotMarkets.get(marketIndex)).filter((m)=>m);
|
|
13649
14641
|
}
|
|
13650
|
-
async
|
|
13651
|
-
const
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
if (!
|
|
13655
|
-
throw new Error(
|
|
14642
|
+
async fetchAndParsePerpMarket(marketIndex) {
|
|
14643
|
+
const markets = await this.fetchAndParsePerpMarkets([
|
|
14644
|
+
marketIndex
|
|
14645
|
+
]);
|
|
14646
|
+
if (!markets || markets.length === 0) {
|
|
14647
|
+
throw new Error(`Perp market not found at index ${marketIndex}`);
|
|
13656
14648
|
}
|
|
13657
|
-
return
|
|
14649
|
+
return markets[0];
|
|
14650
|
+
}
|
|
14651
|
+
async fetchAndParsePerpMarkets(marketIndexes) {
|
|
14652
|
+
const indexesToFetch = marketIndexes.filter((marketIndex)=>!this.perpMarkets.has(marketIndex));
|
|
14653
|
+
if (indexesToFetch.length > 0) {
|
|
14654
|
+
console.log("Fetching perp markets:", indexesToFetch);
|
|
14655
|
+
const marketPdas = marketIndexes.map((marketIndex)=>this.getMarketPda(MarketType.PERP, marketIndex));
|
|
14656
|
+
const accounts = await this.base.provider.connection.getMultipleAccountsInfo(marketPdas);
|
|
14657
|
+
accounts.forEach((account)=>{
|
|
14658
|
+
if (account) {
|
|
14659
|
+
const perpMarket = this.parsePerpMarket(account.data);
|
|
14660
|
+
this.perpMarkets.set(perpMarket.marketIndex, perpMarket);
|
|
14661
|
+
}
|
|
14662
|
+
});
|
|
14663
|
+
} else {
|
|
14664
|
+
console.log("Requested perp markets already cached:", marketIndexes);
|
|
14665
|
+
}
|
|
14666
|
+
return marketIndexes.map((marketIndex)=>this.perpMarkets.get(marketIndex)).filter((m)=>m);
|
|
13658
14667
|
}
|
|
13659
|
-
async
|
|
13660
|
-
const
|
|
14668
|
+
async fetchMarketConfigs() {
|
|
14669
|
+
// const response = await fetch(
|
|
14670
|
+
// "https://api.glam.systems/v0/drift/market_configs/",
|
|
14671
|
+
// );
|
|
14672
|
+
// if (!response.ok) {
|
|
14673
|
+
// throw new Error(`Failed to fetch market configs: ${response.status}`);
|
|
14674
|
+
// }
|
|
14675
|
+
// const data = await response.json();
|
|
14676
|
+
// const { orderConstants, perp, spot } = data;
|
|
14677
|
+
// // Transform perp market from API to `PerpMarket` type
|
|
14678
|
+
// const perpMarkets = perp.map((m: any) => ({
|
|
14679
|
+
// marketIndex: m.marketIndex,
|
|
14680
|
+
// marketPda: m.marketPDA,
|
|
14681
|
+
// oracle: new PublicKey(m.oracle),
|
|
14682
|
+
// }));
|
|
14683
|
+
// // Transform spot market from API to `SpotMarket` type
|
|
14684
|
+
// const spotMarkets = spot.map((m: any) => ({
|
|
14685
|
+
// marketIndex: m.marketIndex,
|
|
14686
|
+
// marketPda: m.marketPDA,
|
|
14687
|
+
// oracle: new PublicKey(m.oracle),
|
|
14688
|
+
// mint: new PublicKey(m.mint),
|
|
14689
|
+
// vault: new PublicKey(m.vaultPDA),
|
|
14690
|
+
// decimals: m.decimals,
|
|
14691
|
+
// }));
|
|
14692
|
+
if (!this.marketConfigs) {
|
|
14693
|
+
const perpMarkets = await this.fetchAndParsePerpMarkets(Array.from(Array(100).keys()));
|
|
14694
|
+
const spotMarkets = await this.fetchAndParseSpotMarkets(Array.from(Array(100).keys()));
|
|
14695
|
+
this.marketConfigs = {
|
|
14696
|
+
orderConstants: {
|
|
14697
|
+
perpBaseScale: 9,
|
|
14698
|
+
quoteScale: 6
|
|
14699
|
+
},
|
|
14700
|
+
perpMarkets,
|
|
14701
|
+
spotMarkets
|
|
14702
|
+
};
|
|
14703
|
+
}
|
|
14704
|
+
return this.marketConfigs;
|
|
14705
|
+
}
|
|
14706
|
+
// public async fetchGlamDriftUser(
|
|
14707
|
+
// glamState: PublicKey | string,
|
|
14708
|
+
// subAccountId: number = 0,
|
|
14709
|
+
// ): Promise<GlamDriftUser> {
|
|
14710
|
+
// const vault = this.base.getVaultPda(new PublicKey(glamState));
|
|
14711
|
+
// const response = await fetch(
|
|
14712
|
+
// `https://api.glam.systems/v0/drift/user?authority=${vault.toBase58()}&accountId=${subAccountId}`,
|
|
14713
|
+
// );
|
|
14714
|
+
// const data = await response.json();
|
|
14715
|
+
// if (!data) {
|
|
14716
|
+
// throw new Error("Failed to fetch drift user.");
|
|
14717
|
+
// }
|
|
14718
|
+
// return data as GlamDriftUser;
|
|
14719
|
+
// }
|
|
14720
|
+
charsToName(chars) {
|
|
14721
|
+
return String.fromCharCode(...chars).replace(/\0/g, "").trim();
|
|
14722
|
+
}
|
|
14723
|
+
async fetchDriftUser(statePda, subAccountId = 0) {
|
|
14724
|
+
const { user } = this.getDriftUserPdas(new PublicKey(statePda), subAccountId);
|
|
14725
|
+
const accountInfo = await this.base.provider.connection.getAccountInfo(user);
|
|
14726
|
+
if (!accountInfo) {
|
|
14727
|
+
return null;
|
|
14728
|
+
}
|
|
14729
|
+
const { delegate, name, spotPositions, marginMode, perpPositions, isMarginTradingEnabled, maxMarginRatio, orders } = decodeUser(accountInfo.data);
|
|
14730
|
+
// Prefetch market configs
|
|
14731
|
+
const marketConfigs = await this.fetchMarketConfigs();
|
|
14732
|
+
const spotPositionsExt = await Promise.all(spotPositions.map(async (p)=>{
|
|
14733
|
+
const { amount, uiAmount } = await this.calcSpotBalance(p.marketIndex, p.scaledBalance, p.balanceType);
|
|
14734
|
+
const spotMarket = marketConfigs.spotMarkets.find((m)=>m.marketIndex === p.marketIndex);
|
|
14735
|
+
return {
|
|
14736
|
+
...p,
|
|
14737
|
+
amount,
|
|
14738
|
+
uiAmount,
|
|
14739
|
+
mint: spotMarket.mint,
|
|
14740
|
+
decimals: spotMarket.decimals,
|
|
14741
|
+
marketName: spotMarket.name
|
|
14742
|
+
};
|
|
14743
|
+
}));
|
|
13661
14744
|
return {
|
|
13662
|
-
|
|
13663
|
-
|
|
14745
|
+
delegate,
|
|
14746
|
+
name: this.charsToName(name),
|
|
14747
|
+
spotPositions: spotPositionsExt,
|
|
14748
|
+
perpPositions,
|
|
14749
|
+
orders,
|
|
14750
|
+
marginMode,
|
|
14751
|
+
subAccountId,
|
|
14752
|
+
isMarginTradingEnabled,
|
|
14753
|
+
maxMarginRatio
|
|
13664
14754
|
};
|
|
13665
14755
|
}
|
|
14756
|
+
// async getPositions(statePda: PublicKey | string, subAccountId: number = 0) {
|
|
14757
|
+
// const driftUser = await this.fetchDriftUser(
|
|
14758
|
+
// new PublicKey(statePda),
|
|
14759
|
+
// subAccountId,
|
|
14760
|
+
// );
|
|
14761
|
+
// if (!driftUser) {
|
|
14762
|
+
// return { spotPositions: [], perpPositions: [] };
|
|
14763
|
+
// }
|
|
14764
|
+
// const marketConfigs = await this.fetchMarketConfigs();
|
|
14765
|
+
// const { spotPositions, perpPositions } = driftUser;
|
|
14766
|
+
// return { spotPositions, perpPositions };
|
|
14767
|
+
// }
|
|
13666
14768
|
async fetchPolicyConfig(glamState) {
|
|
13667
|
-
|
|
13668
|
-
if (glamState && glamState.id) {
|
|
13669
|
-
const [driftUserAddress] = this.getUser(glamState.id);
|
|
13670
|
-
const connection = this.base.provider.connection;
|
|
13671
|
-
const info = await connection.getAccountInfo(driftUserAddress, connection.commitment);
|
|
13672
|
-
if (info) {
|
|
13673
|
-
driftUserAccount = decodeUser(info.data);
|
|
13674
|
-
}
|
|
13675
|
-
}
|
|
14769
|
+
const driftUserAccount = glamState && glamState.id && await this.fetchDriftUser(glamState.id);
|
|
13676
14770
|
let delegate = driftUserAccount?.delegate;
|
|
13677
|
-
if (delegate && delegate.equals(
|
|
14771
|
+
if (delegate && delegate.equals(PublicKey.default)) {
|
|
13678
14772
|
delegate = undefined;
|
|
13679
14773
|
}
|
|
13680
14774
|
return {
|
|
@@ -13687,8 +14781,12 @@ class DriftClient {
|
|
|
13687
14781
|
driftMarketIndexesSpot: glamState?.driftMarketIndexesSpot || []
|
|
13688
14782
|
};
|
|
13689
14783
|
}
|
|
13690
|
-
async composeRemainingAccounts(glamState, subAccountId,
|
|
13691
|
-
const
|
|
14784
|
+
async composeRemainingAccounts(glamState, subAccountId, marketType, marketIndex) {
|
|
14785
|
+
const driftUser = await this.fetchDriftUser(glamState, subAccountId);
|
|
14786
|
+
if (!driftUser) {
|
|
14787
|
+
throw new Error("Drift user not found");
|
|
14788
|
+
}
|
|
14789
|
+
const { spotPositions, perpPositions } = driftUser;
|
|
13692
14790
|
const spotMarketIndexes = spotPositions.map((p)=>p.marketIndex);
|
|
13693
14791
|
const perpMarketIndexes = perpPositions.map((p)=>p.marketIndex);
|
|
13694
14792
|
// Note that marketIndex is could be 0, need to explicitly check undefined
|
|
@@ -13703,10 +14801,13 @@ class DriftClient {
|
|
|
13703
14801
|
spotMarketIndexes.push(0);
|
|
13704
14802
|
}
|
|
13705
14803
|
}
|
|
13706
|
-
const
|
|
13707
|
-
const
|
|
13708
|
-
console.log("[composeRemainingAccounts]
|
|
13709
|
-
|
|
14804
|
+
const spotMarkets = await this.fetchAndParseSpotMarkets(spotMarketIndexes);
|
|
14805
|
+
const perpMarkets = await this.fetchAndParsePerpMarkets(perpMarketIndexes);
|
|
14806
|
+
console.log("[composeRemainingAccounts] perpMarkets:", perpMarkets);
|
|
14807
|
+
const oracles = spotMarkets.map((m)=>m.oracle).concat(perpMarkets.map((m)=>m.oracle));
|
|
14808
|
+
const markets = spotMarkets.map((m)=>m.marketPda).concat(perpMarkets.map((m)=>m.marketPda));
|
|
14809
|
+
console.log("[composeRemainingAccounts] markets:", markets.map((m)=>m.toBase58()));
|
|
14810
|
+
console.log("[composeRemainingAccounts] oracles:", oracles.map((o)=>o.toBase58()));
|
|
13710
14811
|
return oracles.map((o)=>({
|
|
13711
14812
|
pubkey: new PublicKey(o),
|
|
13712
14813
|
isWritable: false,
|
|
@@ -13718,35 +14819,44 @@ class DriftClient {
|
|
|
13718
14819
|
})));
|
|
13719
14820
|
}
|
|
13720
14821
|
async initializeUserStatsIx(glamState, glamSigner) {
|
|
13721
|
-
const
|
|
13722
|
-
const state = await getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
|
|
14822
|
+
const { userStats } = this.getDriftUserPdas(glamState);
|
|
13723
14823
|
// @ts-ignore
|
|
13724
14824
|
return await this.base.program.methods.driftInitializeUserStats().accounts({
|
|
13725
14825
|
glamState,
|
|
13726
14826
|
glamSigner,
|
|
13727
|
-
state,
|
|
14827
|
+
state: this.driftStatePda,
|
|
13728
14828
|
userStats
|
|
13729
14829
|
}).instruction();
|
|
13730
14830
|
}
|
|
13731
14831
|
async initializeUserIx(glamState, glamSigner, subAccountId) {
|
|
13732
14832
|
const name = `GLAM *.+ ${subAccountId}`.split("").map((char)=>char.charCodeAt(0)).concat(Array(24).fill(0));
|
|
13733
|
-
const
|
|
13734
|
-
const
|
|
14833
|
+
const { user, userStats } = this.getDriftUserPdas(glamState, subAccountId);
|
|
14834
|
+
const { user: referrer, userStats: referrerStats } = this.getGlamReferrerPdas();
|
|
14835
|
+
const remainingAccounts = [
|
|
14836
|
+
{
|
|
14837
|
+
pubkey: referrer,
|
|
14838
|
+
isWritable: true,
|
|
14839
|
+
isSigner: false
|
|
14840
|
+
},
|
|
14841
|
+
{
|
|
14842
|
+
pubkey: referrerStats,
|
|
14843
|
+
isWritable: true,
|
|
14844
|
+
isSigner: false
|
|
14845
|
+
}
|
|
14846
|
+
];
|
|
13735
14847
|
return await this.base.program.methods.driftInitializeUser(subAccountId, name).accounts({
|
|
13736
14848
|
glamState,
|
|
13737
14849
|
user,
|
|
13738
14850
|
userStats,
|
|
13739
|
-
state,
|
|
14851
|
+
state: this.driftStatePda,
|
|
13740
14852
|
glamSigner
|
|
13741
|
-
})
|
|
13742
|
-
// .remainingAccounts([]) TODO: set glam referral account
|
|
13743
|
-
.instruction();
|
|
14853
|
+
}).remainingAccounts(remainingAccounts).instruction();
|
|
13744
14854
|
}
|
|
13745
14855
|
async initializeTx(glamState, subAccountId = 0, txOptions = {}) {
|
|
13746
14856
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13747
14857
|
const tx = new Transaction();
|
|
13748
14858
|
// Create userStats account if it doesn't exist
|
|
13749
|
-
const
|
|
14859
|
+
const { userStats } = this.getDriftUserPdas(glamState);
|
|
13750
14860
|
const userStatsInfo = await this.base.provider.connection.getAccountInfo(userStats);
|
|
13751
14861
|
if (!userStatsInfo) {
|
|
13752
14862
|
tx.add(await this.initializeUserStatsIx(glamState, glamSigner));
|
|
@@ -13757,7 +14867,7 @@ class DriftClient {
|
|
|
13757
14867
|
}
|
|
13758
14868
|
async updateUserCustomMarginRatioIx(glamState, maxLeverage, subAccountId = 0, txOptions = {}) {
|
|
13759
14869
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13760
|
-
const
|
|
14870
|
+
const { user } = this.getDriftUserPdas(glamState, subAccountId);
|
|
13761
14871
|
// https://github.com/drift-labs/protocol-v2/blob/babed162b08b1fe34e49a81c5aa3e4ec0a88ecdf/programs/drift/src/math/constants.rs#L183-L184
|
|
13762
14872
|
const marginRatio = DRIFT_MARGIN_PRECISION / maxLeverage;
|
|
13763
14873
|
return await this.base.program.methods.driftUpdateUserCustomMarginRatio(subAccountId, marginRatio).accounts({
|
|
@@ -13772,7 +14882,7 @@ class DriftClient {
|
|
|
13772
14882
|
}
|
|
13773
14883
|
async updateUserMarginTradingEnabledIx(glamState, marginTradingEnabled, subAccountId = 0, txOptions = {}) {
|
|
13774
14884
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13775
|
-
const
|
|
14885
|
+
const { user } = this.getDriftUserPdas(glamState, subAccountId);
|
|
13776
14886
|
return await this.base.program.methods.driftUpdateUserMarginTradingEnabled(subAccountId, marginTradingEnabled).accounts({
|
|
13777
14887
|
glamState,
|
|
13778
14888
|
glamSigner,
|
|
@@ -13785,7 +14895,7 @@ class DriftClient {
|
|
|
13785
14895
|
}
|
|
13786
14896
|
async updateUserDelegateIx(glamState, delegate, subAccountId = 0, txOptions = {}) {
|
|
13787
14897
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13788
|
-
const
|
|
14898
|
+
const { user } = this.getDriftUserPdas(glamState, subAccountId);
|
|
13789
14899
|
return await this.base.program.methods.driftUpdateUserDelegate(subAccountId, new PublicKey(delegate)).accounts({
|
|
13790
14900
|
glamState,
|
|
13791
14901
|
glamSigner,
|
|
@@ -13798,32 +14908,28 @@ class DriftClient {
|
|
|
13798
14908
|
}
|
|
13799
14909
|
async deleteUserTx(glamState, subAccountId = 0, txOptions = {}) {
|
|
13800
14910
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13801
|
-
const
|
|
13802
|
-
const state = await getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
|
|
14911
|
+
const { user, userStats } = this.getDriftUserPdas(glamState, subAccountId);
|
|
13803
14912
|
const tx = await this.base.program.methods.driftDeleteUser().accounts({
|
|
13804
14913
|
glamState,
|
|
13805
|
-
state,
|
|
14914
|
+
state: this.driftStatePda,
|
|
13806
14915
|
user,
|
|
13807
14916
|
userStats,
|
|
13808
14917
|
glamSigner
|
|
13809
14918
|
}).transaction();
|
|
13810
14919
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13811
14920
|
}
|
|
13812
|
-
async depositTx(glamState, amount, marketIndex = 1, subAccountId = 0,
|
|
14921
|
+
async depositTx(glamState, amount, marketIndex = 1, subAccountId = 0, txOptions = {}) {
|
|
13813
14922
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13814
|
-
const
|
|
13815
|
-
const
|
|
13816
|
-
|
|
13817
|
-
console.log("mint, oracle, marketPDA, vaultPDA", mint, oracle, marketPDA, vaultPDA);
|
|
14923
|
+
const { user, userStats } = this.getDriftUserPdas(glamState, subAccountId);
|
|
14924
|
+
const { mint, oracle, tokenProgram, marketPda, vault: driftVault } = await this.fetchAndParseSpotMarket(marketIndex);
|
|
14925
|
+
console.log(`Spot market ${marketIndex} mint ${mint}, oracle: ${oracle}, marketPda: ${marketPda}, vault: ${driftVault}`);
|
|
13818
14926
|
const preInstructions = [];
|
|
13819
14927
|
const postInstructions = [];
|
|
13820
14928
|
// If drift user doesn't exist, prepend initializeUserStats and initializeUser instructions
|
|
13821
|
-
|
|
13822
|
-
await this.fetchGlamDriftUser(glamState, subAccountId);
|
|
13823
|
-
} catch (_) {
|
|
14929
|
+
if (!await this.fetchDriftUser(glamState, subAccountId)) {
|
|
13824
14930
|
preInstructions.push(await this.initializeUserStatsIx(glamState, glamSigner), await this.initializeUserIx(glamState, glamSigner, subAccountId));
|
|
13825
14931
|
}
|
|
13826
|
-
if (mint
|
|
14932
|
+
if (mint.equals(WSOL)) {
|
|
13827
14933
|
const wrapSolIxs = await this.base.maybeWrapSol(glamState, amount, glamSigner);
|
|
13828
14934
|
preInstructions.push(...wrapSolIxs);
|
|
13829
14935
|
// If we need to wrap SOL, it means the wSOL balance will be drained,
|
|
@@ -13837,75 +14943,97 @@ class DriftClient {
|
|
|
13837
14943
|
}).instruction();
|
|
13838
14944
|
postInstructions.push(closeTokenAccountIx);
|
|
13839
14945
|
}
|
|
13840
|
-
const
|
|
13841
|
-
glamState,
|
|
13842
|
-
state,
|
|
13843
|
-
user,
|
|
13844
|
-
userStats,
|
|
13845
|
-
spotMarketVault: new PublicKey(vaultPDA),
|
|
13846
|
-
userTokenAccount: this.base.getVaultAta(glamState, new PublicKey(mint)),
|
|
13847
|
-
glamSigner,
|
|
13848
|
-
tokenProgram: TOKEN_PROGRAM_ID
|
|
13849
|
-
}).remainingAccounts([
|
|
14946
|
+
const remainingAccounts = [
|
|
13850
14947
|
{
|
|
13851
14948
|
pubkey: new PublicKey(oracle),
|
|
13852
14949
|
isSigner: false,
|
|
13853
14950
|
isWritable: false
|
|
13854
14951
|
},
|
|
13855
14952
|
{
|
|
13856
|
-
pubkey: new PublicKey(
|
|
14953
|
+
pubkey: new PublicKey(marketPda),
|
|
13857
14954
|
isSigner: false,
|
|
13858
14955
|
isWritable: true
|
|
13859
14956
|
}
|
|
13860
|
-
]
|
|
14957
|
+
];
|
|
14958
|
+
if (tokenProgram.equals(TOKEN_2022_PROGRAM_ID)) {
|
|
14959
|
+
remainingAccounts.push({
|
|
14960
|
+
pubkey: mint,
|
|
14961
|
+
isSigner: false,
|
|
14962
|
+
isWritable: false
|
|
14963
|
+
});
|
|
14964
|
+
}
|
|
14965
|
+
const tx = await this.base.program.methods.driftDeposit(marketIndex, amount, false).accounts({
|
|
14966
|
+
glamState,
|
|
14967
|
+
state: this.driftStatePda,
|
|
14968
|
+
user,
|
|
14969
|
+
userStats,
|
|
14970
|
+
spotMarketVault: driftVault,
|
|
14971
|
+
userTokenAccount: this.base.getVaultAta(glamState, mint, tokenProgram),
|
|
14972
|
+
glamSigner,
|
|
14973
|
+
tokenProgram
|
|
14974
|
+
}).remainingAccounts(remainingAccounts).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
|
|
13861
14975
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13862
14976
|
}
|
|
13863
|
-
async withdrawTx(statePda, amount, marketIndex = 1, subAccountId = 0,
|
|
14977
|
+
async withdrawTx(statePda, amount, marketIndex = 1, subAccountId = 0, txOptions = {}) {
|
|
13864
14978
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13865
|
-
const
|
|
13866
|
-
const
|
|
13867
|
-
const
|
|
13868
|
-
const
|
|
13869
|
-
const
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
|
|
13873
|
-
|
|
14979
|
+
const { user, userStats } = this.getDriftUserPdas(statePda, subAccountId);
|
|
14980
|
+
const { mint, tokenProgram, vault: driftVault } = await this.fetchAndParseSpotMarket(marketIndex);
|
|
14981
|
+
const glamVault = this.base.getVaultPda(statePda);
|
|
14982
|
+
const glamVaultAta = this.base.getVaultAta(statePda, mint, tokenProgram);
|
|
14983
|
+
const remainingAccounts = await this.composeRemainingAccounts(statePda, subAccountId, MarketType.SPOT, marketIndex);
|
|
14984
|
+
if (tokenProgram.equals(TOKEN_2022_PROGRAM_ID)) {
|
|
14985
|
+
remainingAccounts.push({
|
|
14986
|
+
pubkey: mint,
|
|
14987
|
+
isSigner: false,
|
|
14988
|
+
isWritable: false
|
|
14989
|
+
});
|
|
14990
|
+
}
|
|
13874
14991
|
// Create vault ata in case it doesn't exist
|
|
13875
14992
|
const preInstructions = [
|
|
13876
|
-
createAssociatedTokenAccountIdempotentInstruction(glamSigner,
|
|
14993
|
+
createAssociatedTokenAccountIdempotentInstruction(glamSigner, glamVaultAta, glamVault, mint, tokenProgram)
|
|
13877
14994
|
];
|
|
13878
14995
|
const tx = await this.base.program.methods.driftWithdraw(marketIndex, amount, false).accounts({
|
|
13879
14996
|
glamState: statePda,
|
|
13880
|
-
state,
|
|
14997
|
+
state: this.driftStatePda,
|
|
13881
14998
|
user,
|
|
13882
14999
|
userStats,
|
|
13883
15000
|
glamSigner,
|
|
13884
|
-
spotMarketVault:
|
|
13885
|
-
userTokenAccount:
|
|
13886
|
-
driftSigner:
|
|
13887
|
-
tokenProgram
|
|
15001
|
+
spotMarketVault: driftVault,
|
|
15002
|
+
userTokenAccount: glamVaultAta,
|
|
15003
|
+
driftSigner: DRIFT_SIGNER,
|
|
15004
|
+
tokenProgram
|
|
13888
15005
|
}).remainingAccounts(remainingAccounts).preInstructions(preInstructions).transaction();
|
|
13889
15006
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13890
15007
|
}
|
|
13891
|
-
async placeOrderTx(glamState, orderParams, subAccountId = 0,
|
|
15008
|
+
async placeOrderTx(glamState, orderParams, subAccountId = 0, txOptions = {}) {
|
|
13892
15009
|
const { marketIndex, marketType } = orderParams;
|
|
13893
|
-
const
|
|
15010
|
+
const { user: referrer, userStats: referrerStats } = this.getGlamReferrerPdas();
|
|
15011
|
+
const remainingAccounts = (await this.composeRemainingAccounts(glamState, subAccountId, marketType, marketIndex)).concat([
|
|
15012
|
+
{
|
|
15013
|
+
pubkey: referrer,
|
|
15014
|
+
isWritable: true,
|
|
15015
|
+
isSigner: false
|
|
15016
|
+
},
|
|
15017
|
+
{
|
|
15018
|
+
pubkey: referrerStats,
|
|
15019
|
+
isWritable: true,
|
|
15020
|
+
isSigner: false
|
|
15021
|
+
}
|
|
15022
|
+
]);
|
|
13894
15023
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13895
|
-
const
|
|
13896
|
-
|
|
13897
|
-
const tx = await this.base.program.methods
|
|
13898
|
-
.driftPlaceOrders([
|
|
15024
|
+
const { user } = this.getDriftUserPdas(glamState, subAccountId);
|
|
15025
|
+
// @ts-ignore
|
|
15026
|
+
const tx = await this.base.program.methods.driftPlaceOrders([
|
|
13899
15027
|
orderParams
|
|
13900
15028
|
]).accounts({
|
|
13901
15029
|
glamState,
|
|
13902
15030
|
user,
|
|
13903
|
-
state,
|
|
15031
|
+
state: this.driftStatePda,
|
|
13904
15032
|
glamSigner
|
|
13905
15033
|
}).remainingAccounts(remainingAccounts).transaction();
|
|
13906
15034
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13907
15035
|
}
|
|
13908
|
-
async modifyOrderTx(statePda, modifyOrderParams, subAccountId = 0,
|
|
15036
|
+
async modifyOrderTx(statePda, modifyOrderParams, subAccountId = 0, txOptions = {}) {
|
|
13909
15037
|
// const { marketIndex, marketType } = orderParams;
|
|
13910
15038
|
// const remainingAccounts = await this.composeRemainingAccounts(
|
|
13911
15039
|
// statePda,
|
|
@@ -13915,65 +15043,62 @@ class DriftClient {
|
|
|
13915
15043
|
// marketIndex,
|
|
13916
15044
|
// );
|
|
13917
15045
|
const signer = txOptions.signer || this.base.getSigner();
|
|
13918
|
-
const
|
|
13919
|
-
const driftState = await getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
|
|
15046
|
+
const { user } = this.getDriftUserPdas(statePda, subAccountId);
|
|
13920
15047
|
const tx = await this.base.program.methods// @ts-ignore
|
|
13921
15048
|
.driftModifyOrder(1, modifyOrderParams).accounts({
|
|
13922
15049
|
glamState: statePda,
|
|
13923
15050
|
glamSigner: signer,
|
|
13924
15051
|
user,
|
|
13925
|
-
state:
|
|
15052
|
+
state: this.driftStatePda
|
|
13926
15053
|
})// .remainingAccounts(remainingAccounts)
|
|
13927
15054
|
.transaction();
|
|
13928
15055
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13929
15056
|
}
|
|
13930
|
-
async cancelOrdersTx(glamState, marketType, marketIndex, direction, subAccountId = 0,
|
|
15057
|
+
async cancelOrdersTx(glamState, marketType, marketIndex, direction, subAccountId = 0, txOptions = {}) {
|
|
13931
15058
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13932
|
-
const
|
|
13933
|
-
const
|
|
13934
|
-
const remainingAccounts = await this.composeRemainingAccounts(glamState, subAccountId, marketConfigs, marketType, marketIndex);
|
|
15059
|
+
const { user } = this.getDriftUserPdas(glamState, subAccountId);
|
|
15060
|
+
const remainingAccounts = await this.composeRemainingAccounts(glamState, subAccountId, marketType, marketIndex);
|
|
13935
15061
|
// @ts-ignore
|
|
13936
15062
|
const tx = await this.base.program.methods.driftCancelOrders(marketType, marketIndex, direction).accounts({
|
|
13937
15063
|
glamState,
|
|
13938
15064
|
glamSigner,
|
|
13939
15065
|
user,
|
|
13940
|
-
state:
|
|
15066
|
+
state: this.driftStatePda
|
|
13941
15067
|
}).remainingAccounts(remainingAccounts).transaction();
|
|
13942
15068
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13943
15069
|
}
|
|
13944
|
-
async cancelOrdersByIdsTx(glamState, orderIds, subAccountId = 0,
|
|
15070
|
+
async cancelOrdersByIdsTx(glamState, orderIds, subAccountId = 0, txOptions = {}) {
|
|
13945
15071
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13946
|
-
const
|
|
13947
|
-
const
|
|
13948
|
-
|
|
15072
|
+
const { user } = this.getDriftUserPdas(glamState, subAccountId);
|
|
15073
|
+
const remainingAccounts = await this.composeRemainingAccounts(glamState, subAccountId);
|
|
15074
|
+
// @ts-ignore
|
|
13949
15075
|
const tx = await this.base.program.methods.driftCancelOrdersByIds(orderIds).accounts({
|
|
13950
15076
|
glamState,
|
|
13951
15077
|
glamSigner,
|
|
13952
15078
|
user,
|
|
13953
|
-
state:
|
|
15079
|
+
state: this.driftStatePda
|
|
13954
15080
|
}).remainingAccounts(remainingAccounts).transaction();
|
|
13955
15081
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13956
15082
|
}
|
|
13957
|
-
async settlePnlTx(glamState, marketIndex, subAccountId = 0,
|
|
15083
|
+
async settlePnlTx(glamState, marketIndex, subAccountId = 0, txOptions = {}) {
|
|
13958
15084
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13959
|
-
const
|
|
13960
|
-
const
|
|
13961
|
-
|
|
15085
|
+
const { user } = this.getDriftUserPdas(glamState, subAccountId);
|
|
15086
|
+
const { vault: driftVault } = await this.fetchAndParseSpotMarket(marketIndex);
|
|
15087
|
+
// @ts-ignore
|
|
13962
15088
|
const tx = await this.base.program.methods.driftSettlePnl(marketIndex).accounts({
|
|
13963
15089
|
glamState,
|
|
13964
15090
|
glamSigner,
|
|
13965
15091
|
user,
|
|
13966
|
-
state:
|
|
13967
|
-
spotMarketVault:
|
|
15092
|
+
state: this.driftStatePda,
|
|
15093
|
+
spotMarketVault: driftVault
|
|
13968
15094
|
}).transaction();
|
|
13969
15095
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13970
15096
|
}
|
|
13971
|
-
async priceDriftTx(glamState,
|
|
15097
|
+
async priceDriftTx(glamState, priceDenom, txOptions = {}) {
|
|
13972
15098
|
const signer = txOptions.signer || this.base.getSigner();
|
|
13973
15099
|
const glamVault = this.base.getVaultPda(glamState);
|
|
13974
|
-
const
|
|
13975
|
-
const
|
|
13976
|
-
const remainingAccounts = await this.composeRemainingAccounts(glamState, 0, marketConfigs);
|
|
15100
|
+
const { user, userStats } = this.getDriftUserPdas(glamState);
|
|
15101
|
+
const remainingAccounts = await this.composeRemainingAccounts(glamState, 0);
|
|
13977
15102
|
const tx = await this.base.program.methods.priceDrift(priceDenom).accounts({
|
|
13978
15103
|
glamState,
|
|
13979
15104
|
signer,
|
|
@@ -13981,12 +15106,30 @@ class DriftClient {
|
|
|
13981
15106
|
user,
|
|
13982
15107
|
userStats,
|
|
13983
15108
|
solOracle: SOL_ORACLE,
|
|
13984
|
-
state:
|
|
15109
|
+
state: this.driftStatePda
|
|
13985
15110
|
}).remainingAccounts(remainingAccounts).transaction();
|
|
13986
15111
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
13987
15112
|
}
|
|
13988
15113
|
constructor(base){
|
|
13989
15114
|
this.base = base;
|
|
15115
|
+
this.spotMarkets = new Map();
|
|
15116
|
+
this.perpMarkets = new Map();
|
|
15117
|
+
this.marketConfigs = null;
|
|
15118
|
+
this./*
|
|
15119
|
+
* Utils
|
|
15120
|
+
*/ getMarketPda = (marketType, marketIndex)=>PublicKey.findProgramAddressSync([
|
|
15121
|
+
Buffer.from(`${marketType === MarketType.PERP ? "perp" : "spot"}_market`),
|
|
15122
|
+
new anchor.BN(marketIndex).toArrayLike(Buffer, "le", 2)
|
|
15123
|
+
], DRIFT_PROGRAM_ID)[0];
|
|
15124
|
+
this.getUserPda = (authority, subAccountId = 0)=>PublicKey.findProgramAddressSync([
|
|
15125
|
+
Buffer.from("user"),
|
|
15126
|
+
authority.toBuffer(),
|
|
15127
|
+
new anchor.BN(subAccountId).toArrayLike(Buffer, "le", 2)
|
|
15128
|
+
], DRIFT_PROGRAM_ID)[0];
|
|
15129
|
+
this.getUserStatsPda = (authority)=>PublicKey.findProgramAddressSync([
|
|
15130
|
+
Buffer.from("user_stats"),
|
|
15131
|
+
authority.toBuffer()
|
|
15132
|
+
], DRIFT_PROGRAM_ID)[0];
|
|
13990
15133
|
this.marketTypeEquals = (a, b)=>a && Object.keys(a)[0] === Object.keys(b)[0];
|
|
13991
15134
|
}
|
|
13992
15135
|
}
|
|
@@ -15653,7 +16796,7 @@ const DEFAULT_OBLIGATION_ARGS = {
|
|
|
15653
16796
|
id: 0
|
|
15654
16797
|
};
|
|
15655
16798
|
const SCOPE_PRICES = new PublicKey("3NJYftD5sjVfxSnUdZ1wVML8f3aC6mp1CXCL6L7TnU8C");
|
|
15656
|
-
function refreshObligation(accounts, programId) {
|
|
16799
|
+
function refreshObligation(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
15657
16800
|
const keys = [
|
|
15658
16801
|
{
|
|
15659
16802
|
pubkey: accounts.lendingMarket,
|
|
@@ -15691,7 +16834,7 @@ function refreshObligation(accounts, programId) {
|
|
|
15691
16834
|
});
|
|
15692
16835
|
return ix;
|
|
15693
16836
|
}
|
|
15694
|
-
function refreshReserve(accounts, programId) {
|
|
16837
|
+
function refreshReserve(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
15695
16838
|
const keys = [
|
|
15696
16839
|
{
|
|
15697
16840
|
pubkey: accounts.reserve,
|
|
@@ -15742,7 +16885,7 @@ function refreshReserve(accounts, programId) {
|
|
|
15742
16885
|
});
|
|
15743
16886
|
return ix;
|
|
15744
16887
|
}
|
|
15745
|
-
function refreshObligationFarmsForReserve(args, accounts, programId) {
|
|
16888
|
+
function refreshObligationFarmsForReserve(args, accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
15746
16889
|
const keys = [
|
|
15747
16890
|
{
|
|
15748
16891
|
pubkey: accounts.crank,
|
|
@@ -15833,7 +16976,7 @@ class KaminoLendingClient {
|
|
|
15833
16976
|
* @param txOptions
|
|
15834
16977
|
* @returns
|
|
15835
16978
|
*/ async initUserMetadata(statePda, referrer, txOptions = {}) {
|
|
15836
|
-
const tx = await this.initUserMetadataTx(new PublicKey(statePda), referrer ? new PublicKey(referrer) :
|
|
16979
|
+
const tx = await this.initUserMetadataTx(new PublicKey(statePda), referrer ? new PublicKey(referrer) : null, txOptions);
|
|
15837
16980
|
return await this.base.sendAndConfirm(tx);
|
|
15838
16981
|
}
|
|
15839
16982
|
/**
|
|
@@ -15919,18 +17062,17 @@ class KaminoLendingClient {
|
|
|
15919
17062
|
], KAMINO_FARM_PROGRAM);
|
|
15920
17063
|
return obligationFarm;
|
|
15921
17064
|
}
|
|
15922
|
-
async initUserMetadataTx(glamState, referrer, txOptions) {
|
|
17065
|
+
async initUserMetadataTx(glamState, referrer, txOptions = {}) {
|
|
15923
17066
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
15924
17067
|
const vault = this.base.getVaultPda(glamState);
|
|
15925
17068
|
const userMetadata = this.getUserMetadataPda(vault);
|
|
15926
17069
|
const lookupTable = new PublicKey(0); // FIXME: create lookup table
|
|
15927
|
-
const referrerUserMetadata = referrer.equals(PublicKey.default) ? KAMINO_LENDING_PROGRAM : referrer;
|
|
15928
17070
|
// @ts-ignore
|
|
15929
17071
|
const tx = await this.base.program.methods.kaminoLendingInitUserMetadata(lookupTable).accounts({
|
|
15930
17072
|
glamState,
|
|
15931
17073
|
glamSigner,
|
|
15932
17074
|
userMetadata,
|
|
15933
|
-
referrerUserMetadata
|
|
17075
|
+
referrerUserMetadata: referrer
|
|
15934
17076
|
}).transaction();
|
|
15935
17077
|
const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
|
|
15936
17078
|
return vTx;
|
|
@@ -15943,7 +17085,7 @@ class KaminoLendingClient {
|
|
|
15943
17085
|
switchboardPriceOracle: KAMINO_LENDING_PROGRAM,
|
|
15944
17086
|
switchboardTwapOracle: KAMINO_LENDING_PROGRAM,
|
|
15945
17087
|
scopePrices: SCOPE_PRICES
|
|
15946
|
-
}
|
|
17088
|
+
}));
|
|
15947
17089
|
}
|
|
15948
17090
|
refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves) {
|
|
15949
17091
|
return parsedReserves.map((parsedReserve)=>{
|
|
@@ -15968,18 +17110,21 @@ class KaminoLendingClient {
|
|
|
15968
17110
|
farmsProgram: KAMINO_FARM_PROGRAM,
|
|
15969
17111
|
rent: SYSVAR_RENT_PUBKEY,
|
|
15970
17112
|
systemProgram: SystemProgram.programId
|
|
15971
|
-
}
|
|
17113
|
+
});
|
|
15972
17114
|
});
|
|
15973
17115
|
}).flat();
|
|
15974
17116
|
}
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
const { deposits, borrows } = await this.fetchAndParseObligation(obligation);
|
|
17117
|
+
// If obligation has deposits or borrows, we need the following refresh ixs:
|
|
17118
|
+
// - refreshReserve x N_reserves
|
|
17119
|
+
// - refreshObligation
|
|
17120
|
+
// - refreshObligationFarmsForReserve x M_farms
|
|
17121
|
+
//
|
|
17122
|
+
// For pricing purpose, we don't need to refresh farm states
|
|
17123
|
+
async getRefreshIxs(obligation, refreshFarms = true) {
|
|
17124
|
+
const { lendingMarket, deposits, borrows } = await this.fetchAndParseObligation(obligation);
|
|
17125
|
+
if (!lendingMarket) {
|
|
17126
|
+
throw new Error("Lending market not found");
|
|
17127
|
+
}
|
|
15983
17128
|
const reserves = deposits.concat(borrows).map((d)=>d.reserve);
|
|
15984
17129
|
const parsedReserves = await this.fetchAndParseReserves(reserves);
|
|
15985
17130
|
return [
|
|
@@ -15988,8 +17133,8 @@ class KaminoLendingClient {
|
|
|
15988
17133
|
lendingMarket,
|
|
15989
17134
|
obligation,
|
|
15990
17135
|
reserves
|
|
15991
|
-
}
|
|
15992
|
-
...this.refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves)
|
|
17136
|
+
}),
|
|
17137
|
+
...refreshFarms ? this.refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves) : []
|
|
15993
17138
|
];
|
|
15994
17139
|
}
|
|
15995
17140
|
getMarketAuthority(market) {
|
|
@@ -16040,11 +17185,14 @@ class KaminoLendingClient {
|
|
|
16040
17185
|
const obligationAccount = await this.base.provider.connection.getAccountInfo(obligation);
|
|
16041
17186
|
if (!obligationAccount) {
|
|
16042
17187
|
return {
|
|
17188
|
+
address: obligation,
|
|
17189
|
+
lendingMarket: null,
|
|
16043
17190
|
deposits: [],
|
|
16044
17191
|
borrows: []
|
|
16045
17192
|
};
|
|
16046
17193
|
}
|
|
16047
17194
|
const data = obligationAccount.data;
|
|
17195
|
+
const lendingMarket = new PublicKey(data.subarray(32, 64));
|
|
16048
17196
|
// read deposits
|
|
16049
17197
|
let depositsOffset = 96;
|
|
16050
17198
|
let depositSize = 136;
|
|
@@ -16054,8 +17202,9 @@ class KaminoLendingClient {
|
|
|
16054
17202
|
length: numDeposits
|
|
16055
17203
|
}, (_, i)=>{
|
|
16056
17204
|
const depositData = depositsData.subarray(i * depositSize, (i + 1) * depositSize);
|
|
17205
|
+
const reserve = new PublicKey(depositData.subarray(0, 32));
|
|
16057
17206
|
return {
|
|
16058
|
-
reserve
|
|
17207
|
+
reserve
|
|
16059
17208
|
};
|
|
16060
17209
|
}).filter((d)=>!d.reserve.equals(PublicKey.default));
|
|
16061
17210
|
// read borrows
|
|
@@ -16067,24 +17216,33 @@ class KaminoLendingClient {
|
|
|
16067
17216
|
length: numBorrows
|
|
16068
17217
|
}, (_, i)=>{
|
|
16069
17218
|
const borrowData = borrowsData.subarray(i * borrowSize, (i + 1) * borrowSize);
|
|
17219
|
+
const reserve = new PublicKey(borrowData.subarray(0, 32));
|
|
16070
17220
|
return {
|
|
16071
|
-
reserve
|
|
17221
|
+
reserve
|
|
16072
17222
|
};
|
|
16073
17223
|
}).filter((d)=>!d.reserve.equals(PublicKey.default));
|
|
16074
17224
|
const parsedObligation = {
|
|
17225
|
+
address: obligation,
|
|
17226
|
+
lendingMarket,
|
|
16075
17227
|
deposits,
|
|
16076
17228
|
borrows
|
|
16077
17229
|
};
|
|
16078
17230
|
this.obligations.set(obligation, parsedObligation);
|
|
16079
17231
|
return parsedObligation;
|
|
16080
17232
|
}
|
|
16081
|
-
|
|
16082
|
-
|
|
16083
|
-
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16087
|
-
|
|
17233
|
+
_parseReserveAccount(data) {
|
|
17234
|
+
const market = new PublicKey(data.subarray(32, 64));
|
|
17235
|
+
const farmCollateral = new PublicKey(data.subarray(64, 96));
|
|
17236
|
+
const farmDebt = new PublicKey(data.subarray(96, 128));
|
|
17237
|
+
const liquidityMint = new PublicKey(data.subarray(128, 160));
|
|
17238
|
+
return {
|
|
17239
|
+
farmCollateral: farmCollateral.equals(PublicKey.default) ? null : farmCollateral,
|
|
17240
|
+
farmDebt: farmDebt.equals(PublicKey.default) ? null : farmDebt,
|
|
17241
|
+
liquidityMint,
|
|
17242
|
+
...this.reservePdas(market, liquidityMint)
|
|
17243
|
+
};
|
|
17244
|
+
}
|
|
17245
|
+
async fetchAndParseReserves(reserves) {
|
|
16088
17246
|
if (this.pubkeyArraysEqual(reserves, Array.from(this.reserves.keys()))) {
|
|
16089
17247
|
return Array.from(this.reserves.values());
|
|
16090
17248
|
}
|
|
@@ -16093,20 +17251,12 @@ class KaminoLendingClient {
|
|
|
16093
17251
|
throw new Error("Not all reserves can be found");
|
|
16094
17252
|
}
|
|
16095
17253
|
return reserveAccounts.filter((a)=>!!a).map((account, i)=>{
|
|
16096
|
-
const
|
|
16097
|
-
const market = new PublicKey(data.subarray(32, 64));
|
|
16098
|
-
const farmCollateral = new PublicKey(data.subarray(64, 96));
|
|
16099
|
-
const farmDebt = new PublicKey(data.subarray(96, 128));
|
|
16100
|
-
const liquidityMint = new PublicKey(data.subarray(128, 160));
|
|
16101
|
-
const parsed = {
|
|
17254
|
+
const parsedReserve = {
|
|
16102
17255
|
address: reserves[i],
|
|
16103
|
-
|
|
16104
|
-
farmDebt: farmDebt.equals(PublicKey.default) ? null : farmDebt,
|
|
16105
|
-
liquidityMint,
|
|
16106
|
-
...this.reservePdas(market, liquidityMint)
|
|
17256
|
+
...this._parseReserveAccount(account.data)
|
|
16107
17257
|
};
|
|
16108
|
-
this.reserves.set(reserves[i],
|
|
16109
|
-
return
|
|
17258
|
+
this.reserves.set(reserves[i], parsedReserve);
|
|
17259
|
+
return parsedReserve;
|
|
16110
17260
|
});
|
|
16111
17261
|
}
|
|
16112
17262
|
async findAndParseReserve(market, asset) {
|
|
@@ -16133,18 +17283,12 @@ class KaminoLendingClient {
|
|
|
16133
17283
|
throw new Error("Reserve not found");
|
|
16134
17284
|
}
|
|
16135
17285
|
const account = accounts[0];
|
|
16136
|
-
const
|
|
16137
|
-
const farmCollateral = new PublicKey(data.subarray(64, 96));
|
|
16138
|
-
const farmDebt = new PublicKey(data.subarray(96, 128));
|
|
16139
|
-
const parsed = {
|
|
17286
|
+
const parsedReserve = {
|
|
16140
17287
|
address: account.pubkey,
|
|
16141
|
-
|
|
16142
|
-
farmDebt: farmDebt.equals(PublicKey.default) ? null : farmDebt,
|
|
16143
|
-
liquidityMint: asset,
|
|
16144
|
-
...this.reservePdas(market, asset)
|
|
17288
|
+
...this._parseReserveAccount(account.account.data)
|
|
16145
17289
|
};
|
|
16146
|
-
this.reserves.set(account.pubkey,
|
|
16147
|
-
return
|
|
17290
|
+
this.reserves.set(account.pubkey, parsedReserve);
|
|
17291
|
+
return parsedReserve;
|
|
16148
17292
|
}
|
|
16149
17293
|
async depositTx(glamState, market, asset, amount, txOptions) {
|
|
16150
17294
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
@@ -16202,7 +17346,7 @@ class KaminoLendingClient {
|
|
|
16202
17346
|
lendingMarket: market,
|
|
16203
17347
|
obligation,
|
|
16204
17348
|
reserves: reservesInUse
|
|
16205
|
-
}
|
|
17349
|
+
}));
|
|
16206
17350
|
if (depositReserve.farmCollateral) {
|
|
16207
17351
|
const ixs = this.refreshObligationFarmsForReserveIxs(obligation, market, [
|
|
16208
17352
|
depositReserve
|
|
@@ -16298,7 +17442,7 @@ class KaminoLendingClient {
|
|
|
16298
17442
|
lendingMarket: market,
|
|
16299
17443
|
obligation,
|
|
16300
17444
|
reserves: reservesInUse
|
|
16301
|
-
}
|
|
17445
|
+
}));
|
|
16302
17446
|
if (withdrawReserve.farmCollateral) {
|
|
16303
17447
|
const ixs = this.refreshObligationFarmsForReserveIxs(obligation, market, [
|
|
16304
17448
|
withdrawReserve
|
|
@@ -16388,7 +17532,7 @@ class KaminoLendingClient {
|
|
|
16388
17532
|
lendingMarket: market,
|
|
16389
17533
|
obligation,
|
|
16390
17534
|
reserves: reservesInUse
|
|
16391
|
-
}
|
|
17535
|
+
}));
|
|
16392
17536
|
// Don't need to refresh debt farm for borrow
|
|
16393
17537
|
/*
|
|
16394
17538
|
if (borrowReserve.farmDebt) {
|
|
@@ -16476,7 +17620,7 @@ class KaminoLendingClient {
|
|
|
16476
17620
|
lendingMarket: market,
|
|
16477
17621
|
obligation,
|
|
16478
17622
|
reserves: reservesInUse
|
|
16479
|
-
}
|
|
17623
|
+
}));
|
|
16480
17624
|
const repayIx = await this.base.program.methods.kaminoLendingRepayObligationLiquidityV2(amount).accounts({
|
|
16481
17625
|
glamState,
|
|
16482
17626
|
glamSigner,
|
|
@@ -16520,6 +17664,135 @@ class KaminoLendingClient {
|
|
|
16520
17664
|
};
|
|
16521
17665
|
}
|
|
16522
17666
|
}
|
|
17667
|
+
class KaminoFarmClient {
|
|
17668
|
+
async findAndParseFarmStates(owner) {
|
|
17669
|
+
const accounts = await this.base.provider.connection.getProgramAccounts(KAMINO_FARM_PROGRAM, {
|
|
17670
|
+
filters: [
|
|
17671
|
+
{
|
|
17672
|
+
dataSize: 920
|
|
17673
|
+
},
|
|
17674
|
+
{
|
|
17675
|
+
memcmp: {
|
|
17676
|
+
offset: 48,
|
|
17677
|
+
bytes: owner.toBase58()
|
|
17678
|
+
}
|
|
17679
|
+
}
|
|
17680
|
+
]
|
|
17681
|
+
});
|
|
17682
|
+
return accounts.map((account)=>{
|
|
17683
|
+
const data = account.account.data;
|
|
17684
|
+
const farmState = new PublicKey(data.subarray(16, 48));
|
|
17685
|
+
return {
|
|
17686
|
+
userFarmState: account.pubkey,
|
|
17687
|
+
farmState
|
|
17688
|
+
};
|
|
17689
|
+
});
|
|
17690
|
+
}
|
|
17691
|
+
async parseFarm(data) {
|
|
17692
|
+
const globalConfig = new PublicKey(data.subarray(40, 72));
|
|
17693
|
+
const rewardsOffset = 192;
|
|
17694
|
+
const numRewards = 10;
|
|
17695
|
+
const rewardSize = 704;
|
|
17696
|
+
const rewardsData = data.subarray(rewardsOffset, rewardsOffset + numRewards * rewardSize);
|
|
17697
|
+
const rewards = Array.from({
|
|
17698
|
+
length: numRewards
|
|
17699
|
+
}, (_, i)=>{
|
|
17700
|
+
const rewardData = rewardsData.subarray(i * rewardSize, (i + 1) * rewardSize);
|
|
17701
|
+
const mint = new PublicKey(rewardData.subarray(0, 32));
|
|
17702
|
+
const tokenProgram = new PublicKey(rewardData.subarray(40, 72));
|
|
17703
|
+
const rewardsVault = new PublicKey(rewardData.subarray(120, 152));
|
|
17704
|
+
const minClaimDurationSeconds = new BN(rewardData.subarray(480, 488), "le");
|
|
17705
|
+
return {
|
|
17706
|
+
index: i,
|
|
17707
|
+
mint,
|
|
17708
|
+
minClaimDurationSeconds,
|
|
17709
|
+
tokenProgram,
|
|
17710
|
+
rewardsVault
|
|
17711
|
+
};
|
|
17712
|
+
}).filter((r)=>{
|
|
17713
|
+
if (r.mint.equals(PublicKey.default)) {
|
|
17714
|
+
return false;
|
|
17715
|
+
}
|
|
17716
|
+
// Filter out rewards with minClaimDurationSeconds > 1 year, they are considered disabled
|
|
17717
|
+
if (r.minClaimDurationSeconds.div(new BN(365 * 24 * 60 * 60)).gt(new BN(1))) {
|
|
17718
|
+
return false;
|
|
17719
|
+
}
|
|
17720
|
+
return true;
|
|
17721
|
+
});
|
|
17722
|
+
return {
|
|
17723
|
+
globalConfig,
|
|
17724
|
+
rewards
|
|
17725
|
+
};
|
|
17726
|
+
}
|
|
17727
|
+
async fetchAndParseFarms(farms) {
|
|
17728
|
+
const farmAccounts = await this.base.provider.connection.getMultipleAccountsInfo(farms);
|
|
17729
|
+
const map = new Map();
|
|
17730
|
+
for(let i = 0; i < farmAccounts.length; i++){
|
|
17731
|
+
const account = farmAccounts[i];
|
|
17732
|
+
if (!account) {
|
|
17733
|
+
continue;
|
|
17734
|
+
}
|
|
17735
|
+
const data = account.data;
|
|
17736
|
+
const parsedFarm = await this.parseFarm(data);
|
|
17737
|
+
map.set(farms[i].toBase58(), parsedFarm);
|
|
17738
|
+
}
|
|
17739
|
+
return map;
|
|
17740
|
+
}
|
|
17741
|
+
async harvest(statePda, txOptions = {}) {
|
|
17742
|
+
const tx = await this.harvestTx(new PublicKey(statePda), txOptions);
|
|
17743
|
+
return await this.base.sendAndConfirm(tx);
|
|
17744
|
+
}
|
|
17745
|
+
async harvestTx(glamState, txOptions = {}) {
|
|
17746
|
+
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
17747
|
+
const vault = this.base.getVaultPda(glamState);
|
|
17748
|
+
const farmStates = await this.findAndParseFarmStates(vault);
|
|
17749
|
+
const parsedFarms = await this.fetchAndParseFarms(farmStates.map((f)=>f.farmState));
|
|
17750
|
+
const tx = new Transaction();
|
|
17751
|
+
for (const { userFarmState, farmState } of farmStates){
|
|
17752
|
+
const { globalConfig, rewards } = parsedFarms.get(farmState.toBase58());
|
|
17753
|
+
for (const { index, mint, tokenProgram, rewardsVault } of rewards){
|
|
17754
|
+
console.log("Reward token:", mint.toBase58());
|
|
17755
|
+
const vaultAta = this.base.getVaultAta(glamState, mint, tokenProgram);
|
|
17756
|
+
const createAtaIx = createAssociatedTokenAccountIdempotentInstruction(glamSigner, vaultAta, vault, mint, tokenProgram);
|
|
17757
|
+
const harvestIx = await this.base.program.methods.kaminoFarmHarvestReward(new BN(index)).accounts({
|
|
17758
|
+
glamState,
|
|
17759
|
+
glamSigner,
|
|
17760
|
+
userState: userFarmState,
|
|
17761
|
+
farmState,
|
|
17762
|
+
globalConfig,
|
|
17763
|
+
rewardMint: mint,
|
|
17764
|
+
userRewardAta: vaultAta,
|
|
17765
|
+
rewardsVault,
|
|
17766
|
+
rewardsTreasuryVault: this.rewardsTreasuryVault(globalConfig, mint),
|
|
17767
|
+
farmVaultsAuthority: this.farmVaultsAuthority(farmState),
|
|
17768
|
+
scopePrices: null,
|
|
17769
|
+
tokenProgram
|
|
17770
|
+
}).instruction();
|
|
17771
|
+
tx.add(createAtaIx, harvestIx);
|
|
17772
|
+
}
|
|
17773
|
+
}
|
|
17774
|
+
const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
|
|
17775
|
+
LOOKUP_TABLE
|
|
17776
|
+
]);
|
|
17777
|
+
const vTx = await this.base.intoVersionedTransaction(tx, {
|
|
17778
|
+
...txOptions,
|
|
17779
|
+
lookupTables
|
|
17780
|
+
});
|
|
17781
|
+
return vTx;
|
|
17782
|
+
}
|
|
17783
|
+
constructor(base){
|
|
17784
|
+
this.base = base;
|
|
17785
|
+
this.farmVaultsAuthority = (farm)=>PublicKey.findProgramAddressSync([
|
|
17786
|
+
Buffer.from("authority"),
|
|
17787
|
+
farm.toBuffer()
|
|
17788
|
+
], KAMINO_FARM_PROGRAM)[0];
|
|
17789
|
+
this.rewardsTreasuryVault = (globalConfig, mint)=>PublicKey.findProgramAddressSync([
|
|
17790
|
+
Buffer.from("tvault"),
|
|
17791
|
+
globalConfig.toBuffer(),
|
|
17792
|
+
mint.toBuffer()
|
|
17793
|
+
], KAMINO_FARM_PROGRAM)[0];
|
|
17794
|
+
}
|
|
17795
|
+
}
|
|
16523
17796
|
|
|
16524
17797
|
// Pubkey::find_program_address(&[b"__event_authority"], &dlmm_interface::ID)
|
|
16525
17798
|
const EVENT_AUTHORITY = new PublicKey("D1ZN9Wj1fRSUQfCjhvnu1hqDMT7hzjzBBpi12nVniYD6");
|
|
@@ -16996,6 +18269,28 @@ class PriceClient {
|
|
|
16996
18269
|
});
|
|
16997
18270
|
return pricedAssets.reduce((sum, p)=>new BN(p.amount).add(sum), new BN(0));
|
|
16998
18271
|
}
|
|
18272
|
+
async priceKaminoIxs(glamState, priceDenom) {
|
|
18273
|
+
const glamVault = this.base.getVaultPda(glamState);
|
|
18274
|
+
const obligations = await fetchKaminoObligations(this.base.provider.connection, glamVault);
|
|
18275
|
+
const refreshIxs = [];
|
|
18276
|
+
for (const obligation of obligations){
|
|
18277
|
+
const ixs = await this.klend.getRefreshIxs(obligation, false); // skip farms
|
|
18278
|
+
refreshIxs.push(...ixs);
|
|
18279
|
+
}
|
|
18280
|
+
// @ts-ignore
|
|
18281
|
+
const priceIx = await this.base.program.methods.priceKaminoObligations(priceDenom).accounts({
|
|
18282
|
+
glamState,
|
|
18283
|
+
solOracle: SOL_ORACLE
|
|
18284
|
+
}).remainingAccounts(obligations.map((o)=>({
|
|
18285
|
+
pubkey: o,
|
|
18286
|
+
isSigner: false,
|
|
18287
|
+
isWritable: false
|
|
18288
|
+
}))).instruction();
|
|
18289
|
+
return [
|
|
18290
|
+
...refreshIxs,
|
|
18291
|
+
priceIx
|
|
18292
|
+
];
|
|
18293
|
+
}
|
|
16999
18294
|
async priceVaultIxs(glamState, priceDenom) {
|
|
17000
18295
|
const vault = this.base.getVaultPda(glamState);
|
|
17001
18296
|
const tickets = await fetchMarinadeTicketAccounts(this.base.provider.connection, vault);
|
|
@@ -17025,29 +18320,18 @@ class PriceClient {
|
|
|
17025
18320
|
glamState,
|
|
17026
18321
|
solOracle: SOL_ORACLE
|
|
17027
18322
|
}).remainingAccounts(await this.remainingAccountsForPricingMeteora(glamState)).instruction();
|
|
17028
|
-
const
|
|
17029
|
-
glamState,
|
|
17030
|
-
solOracle: SOL_ORACLE
|
|
17031
|
-
}).remainingAccounts(await this.remainingAccountsForPricingKamino(glamState)).instruction();
|
|
18323
|
+
const priceKaminoIxs = await this.priceKaminoIxs(glamState, priceDenom);
|
|
17032
18324
|
return [
|
|
17033
18325
|
priceTicketsIx,
|
|
17034
18326
|
priceStakesIx,
|
|
17035
18327
|
priceVaultIx,
|
|
17036
18328
|
priceMeteoraIx,
|
|
17037
|
-
|
|
18329
|
+
...priceKaminoIxs
|
|
17038
18330
|
];
|
|
17039
18331
|
}
|
|
17040
|
-
constructor(base){
|
|
18332
|
+
constructor(base, klend){
|
|
17041
18333
|
this.base = base;
|
|
17042
|
-
this.
|
|
17043
|
-
const glamVault = this.base.getVaultPda(glamState);
|
|
17044
|
-
const obligationAccounts = await fetchKaminoObligations(this.base.provider.connection, glamVault);
|
|
17045
|
-
return obligationAccounts.map((a)=>({
|
|
17046
|
-
pubkey: a,
|
|
17047
|
-
isSigner: false,
|
|
17048
|
-
isWritable: false
|
|
17049
|
-
}));
|
|
17050
|
-
};
|
|
18334
|
+
this.klend = klend;
|
|
17051
18335
|
this.remainingAccountsForPricingMeteora = async (glamState)=>{
|
|
17052
18336
|
const glamVault = this.base.getVaultPda(glamState);
|
|
17053
18337
|
const positions = await fetchMeteoraPositions(this.base.provider.connection, glamVault);
|
|
@@ -17133,7 +18417,7 @@ class PriceClient {
|
|
|
17133
18417
|
}
|
|
17134
18418
|
get price() {
|
|
17135
18419
|
if (!this._price) {
|
|
17136
|
-
this._price = new PriceClient(this);
|
|
18420
|
+
this._price = new PriceClient(this, this.kaminoLending);
|
|
17137
18421
|
}
|
|
17138
18422
|
return this._price;
|
|
17139
18423
|
}
|
|
@@ -17155,6 +18439,12 @@ class PriceClient {
|
|
|
17155
18439
|
}
|
|
17156
18440
|
return this._kaminoLending;
|
|
17157
18441
|
}
|
|
18442
|
+
get kaminoFarm() {
|
|
18443
|
+
if (!this._kaminoFarm) {
|
|
18444
|
+
this._kaminoFarm = new KaminoFarmClient(this);
|
|
18445
|
+
}
|
|
18446
|
+
return this._kaminoFarm;
|
|
18447
|
+
}
|
|
17158
18448
|
get meteoraDlmm() {
|
|
17159
18449
|
if (!this._meteoraDlmm) {
|
|
17160
18450
|
this._meteoraDlmm = new MeteoraDlmmClient(this);
|
|
@@ -17170,7 +18460,7 @@ const getPriorityFeeEstimate = async (heliusApiKey, tx, accountKeys, priorityLev
|
|
|
17170
18460
|
if (!tx && !accountKeys) {
|
|
17171
18461
|
throw new Error("Either tx or accountKeys must be provided");
|
|
17172
18462
|
}
|
|
17173
|
-
const options = priorityLevel ? {
|
|
18463
|
+
const options = priorityLevel && priorityLevel !== "Recommended" ? {
|
|
17174
18464
|
priorityLevel
|
|
17175
18465
|
} : {
|
|
17176
18466
|
recommended: true
|
|
@@ -17202,4 +18492,39 @@ const getPriorityFeeEstimate = async (heliusApiKey, tx, accountKeys, priorityLev
|
|
|
17202
18492
|
return data.result.priorityFeeEstimate;
|
|
17203
18493
|
};
|
|
17204
18494
|
|
|
17205
|
-
|
|
18495
|
+
function getLimitOrderParams(params) {
|
|
18496
|
+
return getOrderParams(Object.assign({}, params, {
|
|
18497
|
+
orderType: OrderType.LIMIT
|
|
18498
|
+
}));
|
|
18499
|
+
}
|
|
18500
|
+
function getTriggerMarketOrderParams(params) {
|
|
18501
|
+
return getOrderParams(Object.assign({}, params, {
|
|
18502
|
+
orderType: OrderType.TRIGGER_MARKET
|
|
18503
|
+
}));
|
|
18504
|
+
}
|
|
18505
|
+
function getTriggerLimitOrderParams(params) {
|
|
18506
|
+
return getOrderParams(Object.assign({}, params, {
|
|
18507
|
+
orderType: OrderType.TRIGGER_LIMIT
|
|
18508
|
+
}));
|
|
18509
|
+
}
|
|
18510
|
+
function getMarketOrderParams(params) {
|
|
18511
|
+
return getOrderParams(Object.assign({}, params, {
|
|
18512
|
+
orderType: OrderType.MARKET
|
|
18513
|
+
}));
|
|
18514
|
+
}
|
|
18515
|
+
/**
|
|
18516
|
+
* Creates an OrderParams object with the given OptionalOrderParams and any params to override.
|
|
18517
|
+
*
|
|
18518
|
+
* example:
|
|
18519
|
+
* ```
|
|
18520
|
+
* const orderParams = getOrderParams(optionalOrderParams, { marketType: MarketType.PERP });
|
|
18521
|
+
* ```
|
|
18522
|
+
*
|
|
18523
|
+
* @param optionalOrderParams
|
|
18524
|
+
* @param overridingParams
|
|
18525
|
+
* @returns
|
|
18526
|
+
*/ function getOrderParams(optionalOrderParams, overridingParams = {}) {
|
|
18527
|
+
return Object.assign({}, DefaultOrderParams, optionalOrderParams, overridingParams);
|
|
18528
|
+
}
|
|
18529
|
+
|
|
18530
|
+
export { ASSETS_MAINNET, ASSETS_TESTS, AssetTier, BaseClient, ClusterNetwork, CompanyModel, ContractTier, ContractType, CreatedModel, DRIFT_PROGRAM_ID, DefaultOrderParams, DelegateAcl, DepositDirection, DepositExplanation, DriftClient, ExchangeStatus, FuelOverflowStatus, FundOpenfundsModel, GLAM_REFERRER, GOVERNANCE_PROGRAM_ID, GlamClient, GlamError, GlamIdl, GlamIntegrations, GlamPermissions, GlamProtocolIdlJson, InsuranceFundOperation, JITOSOL, JITO_STAKE_POOL, JITO_TIP_DEFAULT, JUP, JUPITER_API_DEFAULT, JUPITER_PROGRAM_ID, JUPSOL_STAKE_POOL, JUP_VOTE_PROGRAM, JupiterSwapClient, JupiterVoteClient, KAMINO_FARM_PROGRAM, KAMINO_LENDING_PROGRAM, KAMINO_OBTRIGATION_SIZE, LPAction, LiquidationType, MARINADE_PROGRAM_ID, MARINADE_TICKET_SIZE, MEMO_PROGRAM, MERKLE_DISTRIBUTOR_PROGRAM, METEORA_DLMM_PROGRAM, METEORA_POSITION_SIZE, MSOL, ManagerModel, MarginMode, MarketStatus, MarketType, Metadata, MintIdlModel, MintModel, MintOpenfundsModel, ModifyOrderPolicy, OracleSource, OracleSourceNum, OrderAction, OrderActionExplanation, OrderStatus, OrderTriggerCondition, OrderType, PerpOperation, PlaceAndTakeOrderSuccessCondition, PositionDirection, PostOnlyParams, PriceDenom, ReferrerStatus, SANCTUM_STAKE_POOL_PROGRAM_ID, SEED_ESCROW, SEED_METADATA, SEED_MINT, SEED_STATE, SEED_VAULT, SOL_ORACLE, STAKE_ACCOUNT_SIZE, SettlePnlExplanation, SettlePnlMode, SpotBalanceType, SpotFulfillmentConfigStatus, SpotFulfillmentStatus, SpotFulfillmentType, SpotOperation, StakeAction, StateIdlModel, StateModel, SwapDirection, SwapReduceOnly, TRANSFER_HOOK_PROGRAM, TradeSide, USDC, UserStatus, WBTC, WETH, WSOL, ZERO, decodeUser, fetchKaminoObligations, fetchMarinadeTicketAccounts, fetchMeteoraPositions, fetchStakeAccounts, getGlamProgram, getGlamProgramId, getLimitOrderParams, getMarketOrderParams, getOrderParams, getPriorityFeeEstimate, getSimulationComputeUnits, getTriggerLimitOrderParams, getTriggerMarketOrderParams, getVariant, isBrowser, isOneOfVariant, isVariant, parseMeteoraPosition, setsAreEqual };
|