@glamsystems/glam-sdk 0.1.26 → 0.1.27
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/index.cjs.js +536 -95
- package/index.esm.js +536 -96
- package/package.json +1 -1
- package/src/client/base.d.ts +1 -1
- package/src/client/drift.d.ts +8 -8
- package/src/client/kamino.d.ts +18 -1
- package/src/client/price.d.ts +5 -3
- package/src/client/vault.d.ts +1 -1
- package/src/client.d.ts +3 -1
- package/src/constants.d.ts +1 -0
- package/src/{layouts/drift-vault.d.ts → deser/driftLayouts.d.ts} +17 -0
- package/src/deser/kaminoLayouts.d.ts +55 -0
- package/src/utils/driftTypes.d.ts +1 -0
- package/target/idl/glam_protocol.json +147 -3
- package/target/types/glam_protocol.d.ts +145 -1
- package/target/types/glam_protocol.ts +147 -3
package/index.esm.js
CHANGED
|
@@ -14,7 +14,7 @@ import { getStakePoolAccount } from '@solana/spl-stake-pool';
|
|
|
14
14
|
var address = "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc";
|
|
15
15
|
var metadata = {
|
|
16
16
|
name: "glam_protocol",
|
|
17
|
-
version: "0.4.
|
|
17
|
+
version: "0.4.29",
|
|
18
18
|
spec: "0.1.0",
|
|
19
19
|
description: "Glam Protocol"
|
|
20
20
|
};
|
|
@@ -4264,10 +4264,12 @@ var instructions = [
|
|
|
4264
4264
|
],
|
|
4265
4265
|
accounts: [
|
|
4266
4266
|
{
|
|
4267
|
-
name: "glam_state"
|
|
4267
|
+
name: "glam_state",
|
|
4268
|
+
writable: true
|
|
4268
4269
|
},
|
|
4269
4270
|
{
|
|
4270
4271
|
name: "glam_vault",
|
|
4272
|
+
writable: true,
|
|
4271
4273
|
pda: {
|
|
4272
4274
|
seeds: [
|
|
4273
4275
|
{
|
|
@@ -4359,10 +4361,12 @@ var instructions = [
|
|
|
4359
4361
|
],
|
|
4360
4362
|
accounts: [
|
|
4361
4363
|
{
|
|
4362
|
-
name: "glam_state"
|
|
4364
|
+
name: "glam_state",
|
|
4365
|
+
writable: true
|
|
4363
4366
|
},
|
|
4364
4367
|
{
|
|
4365
4368
|
name: "glam_vault",
|
|
4369
|
+
writable: true,
|
|
4366
4370
|
pda: {
|
|
4367
4371
|
seeds: [
|
|
4368
4372
|
{
|
|
@@ -6642,6 +6646,146 @@ var instructions = [
|
|
|
6642
6646
|
}
|
|
6643
6647
|
]
|
|
6644
6648
|
},
|
|
6649
|
+
{
|
|
6650
|
+
name: "price_kamino_vault_shares",
|
|
6651
|
+
discriminator: [
|
|
6652
|
+
112,
|
|
6653
|
+
92,
|
|
6654
|
+
238,
|
|
6655
|
+
224,
|
|
6656
|
+
145,
|
|
6657
|
+
105,
|
|
6658
|
+
38,
|
|
6659
|
+
249
|
|
6660
|
+
],
|
|
6661
|
+
accounts: [
|
|
6662
|
+
{
|
|
6663
|
+
name: "glam_state",
|
|
6664
|
+
writable: true
|
|
6665
|
+
},
|
|
6666
|
+
{
|
|
6667
|
+
name: "glam_vault",
|
|
6668
|
+
pda: {
|
|
6669
|
+
seeds: [
|
|
6670
|
+
{
|
|
6671
|
+
kind: "const",
|
|
6672
|
+
value: [
|
|
6673
|
+
118,
|
|
6674
|
+
97,
|
|
6675
|
+
117,
|
|
6676
|
+
108,
|
|
6677
|
+
116
|
|
6678
|
+
]
|
|
6679
|
+
},
|
|
6680
|
+
{
|
|
6681
|
+
kind: "account",
|
|
6682
|
+
path: "glam_state"
|
|
6683
|
+
}
|
|
6684
|
+
]
|
|
6685
|
+
}
|
|
6686
|
+
},
|
|
6687
|
+
{
|
|
6688
|
+
name: "signer",
|
|
6689
|
+
writable: true,
|
|
6690
|
+
signer: true
|
|
6691
|
+
},
|
|
6692
|
+
{
|
|
6693
|
+
name: "kamino_lending_program",
|
|
6694
|
+
address: "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"
|
|
6695
|
+
},
|
|
6696
|
+
{
|
|
6697
|
+
name: "sol_oracle"
|
|
6698
|
+
},
|
|
6699
|
+
{
|
|
6700
|
+
name: "glam_config",
|
|
6701
|
+
pda: {
|
|
6702
|
+
seeds: [
|
|
6703
|
+
{
|
|
6704
|
+
kind: "const",
|
|
6705
|
+
value: [
|
|
6706
|
+
103,
|
|
6707
|
+
108,
|
|
6708
|
+
111,
|
|
6709
|
+
98,
|
|
6710
|
+
97,
|
|
6711
|
+
108,
|
|
6712
|
+
95,
|
|
6713
|
+
99,
|
|
6714
|
+
111,
|
|
6715
|
+
110,
|
|
6716
|
+
102,
|
|
6717
|
+
105,
|
|
6718
|
+
103
|
|
6719
|
+
]
|
|
6720
|
+
}
|
|
6721
|
+
],
|
|
6722
|
+
program: {
|
|
6723
|
+
kind: "const",
|
|
6724
|
+
value: [
|
|
6725
|
+
10,
|
|
6726
|
+
11,
|
|
6727
|
+
0,
|
|
6728
|
+
83,
|
|
6729
|
+
72,
|
|
6730
|
+
16,
|
|
6731
|
+
46,
|
|
6732
|
+
144,
|
|
6733
|
+
46,
|
|
6734
|
+
42,
|
|
6735
|
+
79,
|
|
6736
|
+
22,
|
|
6737
|
+
157,
|
|
6738
|
+
123,
|
|
6739
|
+
21,
|
|
6740
|
+
242,
|
|
6741
|
+
192,
|
|
6742
|
+
146,
|
|
6743
|
+
1,
|
|
6744
|
+
78,
|
|
6745
|
+
88,
|
|
6746
|
+
59,
|
|
6747
|
+
102,
|
|
6748
|
+
9,
|
|
6749
|
+
190,
|
|
6750
|
+
226,
|
|
6751
|
+
92,
|
|
6752
|
+
189,
|
|
6753
|
+
187,
|
|
6754
|
+
232,
|
|
6755
|
+
83,
|
|
6756
|
+
220
|
|
6757
|
+
]
|
|
6758
|
+
}
|
|
6759
|
+
}
|
|
6760
|
+
},
|
|
6761
|
+
{
|
|
6762
|
+
name: "pyth_oracle",
|
|
6763
|
+
optional: true
|
|
6764
|
+
},
|
|
6765
|
+
{
|
|
6766
|
+
name: "switchboard_price_oracle",
|
|
6767
|
+
optional: true
|
|
6768
|
+
},
|
|
6769
|
+
{
|
|
6770
|
+
name: "switchboard_twap_oracle",
|
|
6771
|
+
optional: true
|
|
6772
|
+
},
|
|
6773
|
+
{
|
|
6774
|
+
name: "scope_prices",
|
|
6775
|
+
optional: true
|
|
6776
|
+
}
|
|
6777
|
+
],
|
|
6778
|
+
args: [
|
|
6779
|
+
{
|
|
6780
|
+
name: "denom",
|
|
6781
|
+
type: {
|
|
6782
|
+
defined: {
|
|
6783
|
+
name: "PriceDenom"
|
|
6784
|
+
}
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6787
|
+
]
|
|
6788
|
+
},
|
|
6645
6789
|
{
|
|
6646
6790
|
name: "price_meteora_positions",
|
|
6647
6791
|
discriminator: [
|
|
@@ -13718,6 +13862,7 @@ const MERKLE_DISTRIBUTOR_PROGRAM = new PublicKey("DiS3nNjFVMieMgmiQFm6wgJL7nevk4
|
|
|
13718
13862
|
const TRANSFER_HOOK_PROGRAM = new PublicKey("po1iCYakK3gHCLbuju4wGzFowTMpAJxkqK1iwUqMonY");
|
|
13719
13863
|
const METEORA_DLMM_PROGRAM = new PublicKey("LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo");
|
|
13720
13864
|
const KAMINO_LENDING_PROGRAM = new PublicKey("KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD");
|
|
13865
|
+
const KAMINO_VAULTS_PROGRAM = new PublicKey("KvauGMspG5k6rtzrqqn7WNn3oZdyKqLKwK2XWQ8FLjd");
|
|
13721
13866
|
const KAMINO_FARM_PROGRAM = new PublicKey("FarmsPZpWu9i7Kky8tPN37rs2TpmMrAZrC7S7vJa91Hr");
|
|
13722
13867
|
const MEMO_PROGRAM = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
|
|
13723
13868
|
/**
|
|
@@ -14661,7 +14806,7 @@ class BaseClient {
|
|
|
14661
14806
|
set statePda(statePda) {
|
|
14662
14807
|
this._statePda = statePda;
|
|
14663
14808
|
}
|
|
14664
|
-
isMainnet() {
|
|
14809
|
+
get isMainnet() {
|
|
14665
14810
|
return this.cluster === ClusterNetwork.Mainnet;
|
|
14666
14811
|
}
|
|
14667
14812
|
isPhantom() {
|
|
@@ -14676,7 +14821,7 @@ class BaseClient {
|
|
|
14676
14821
|
* @returns Metadata of the asset
|
|
14677
14822
|
*/ getAssetMeta(assetMint) {
|
|
14678
14823
|
let assetMeta = ASSETS_MAINNET.get(assetMint);
|
|
14679
|
-
if (!assetMeta && !this.isMainnet
|
|
14824
|
+
if (!assetMeta && !this.isMainnet) {
|
|
14680
14825
|
assetMeta = ASSETS_TESTS.get(assetMint);
|
|
14681
14826
|
}
|
|
14682
14827
|
if (!assetMeta) {
|
|
@@ -15066,9 +15211,9 @@ class BaseClient {
|
|
|
15066
15211
|
if (stateAccount.mints.length > 0) {
|
|
15067
15212
|
const mintPubkey = glamStatePda.equals(this.statePda) ? this.mintPda : getMintPda(glamStatePda, 0, this.program.programId);
|
|
15068
15213
|
const { mint } = await this.fetchMintAndTokenProgram(mintPubkey);
|
|
15069
|
-
return StateModel.fromOnchainAccounts(
|
|
15214
|
+
return StateModel.fromOnchainAccounts(glamStatePda, stateAccount, openfundsMetadataAccount, mint, this.program.programId);
|
|
15070
15215
|
}
|
|
15071
|
-
return StateModel.fromOnchainAccounts(
|
|
15216
|
+
return StateModel.fromOnchainAccounts(glamStatePda, stateAccount, openfundsMetadataAccount, undefined, this.program.programId);
|
|
15072
15217
|
}
|
|
15073
15218
|
/**
|
|
15074
15219
|
* Fetch all glam state models if no filter options provided
|
|
@@ -15288,6 +15433,12 @@ DepositDirection.WITHDRAW = {
|
|
|
15288
15433
|
withdraw: {}
|
|
15289
15434
|
};
|
|
15290
15435
|
class OracleSource {
|
|
15436
|
+
static fromString(name) {
|
|
15437
|
+
const k = name.slice(0, 1).toLowerCase() + name.slice(1);
|
|
15438
|
+
return {
|
|
15439
|
+
[k]: {}
|
|
15440
|
+
};
|
|
15441
|
+
}
|
|
15291
15442
|
static get(n) {
|
|
15292
15443
|
const name = Object.entries(OracleSourceNum).find(([, v])=>v === n)?.[0];
|
|
15293
15444
|
const source = Object.entries(OracleSource).find(([key, _])=>key.toLocaleLowerCase() === name?.toLocaleLowerCase())?.[1];
|
|
@@ -15743,6 +15894,24 @@ const DriftVaultLayout = struct([
|
|
|
15743
15894
|
// Final padding
|
|
15744
15895
|
array(u64(), 3, "padding")
|
|
15745
15896
|
]);
|
|
15897
|
+
struct([
|
|
15898
|
+
array(u8(), 8, "discriminator"),
|
|
15899
|
+
publicKey("marketPda"),
|
|
15900
|
+
publicKey("oracle"),
|
|
15901
|
+
publicKey("mint"),
|
|
15902
|
+
publicKey("vault"),
|
|
15903
|
+
array(u8(), 32, "name"),
|
|
15904
|
+
// Padding for bytes between name and cumulativeDepositInterest
|
|
15905
|
+
array(u8(), 464 - 168, "padding1"),
|
|
15906
|
+
u128("cumulativeDepositInterest"),
|
|
15907
|
+
u128("cumulativeBorrowInterest"),
|
|
15908
|
+
// Padding for bytes between cumulativeBorrowInterest and decimals
|
|
15909
|
+
array(u8(), 680 - 496, "padding2"),
|
|
15910
|
+
u32("decimals"),
|
|
15911
|
+
u16("marketIndex"),
|
|
15912
|
+
u8("padding3"),
|
|
15913
|
+
u8("oracleSource")
|
|
15914
|
+
]);
|
|
15746
15915
|
|
|
15747
15916
|
function readUnsignedBigInt64LE(buffer, offset) {
|
|
15748
15917
|
return new BN(buffer.subarray(offset, offset + 8), 10, "le");
|
|
@@ -16203,17 +16372,17 @@ class DriftClient {
|
|
|
16203
16372
|
Buffer.from("drift_state")
|
|
16204
16373
|
], DRIFT_PROGRAM_ID)[0];
|
|
16205
16374
|
}
|
|
16206
|
-
async fetchAndParseSpotMarket(marketIndex) {
|
|
16375
|
+
async fetchAndParseSpotMarket(marketIndex, skipCache = false) {
|
|
16207
16376
|
const markets = await this.fetchAndParseSpotMarkets([
|
|
16208
16377
|
marketIndex
|
|
16209
|
-
]);
|
|
16378
|
+
], skipCache);
|
|
16210
16379
|
if (!markets || markets.length === 0) {
|
|
16211
16380
|
throw new Error(`Spot market not found at index ${marketIndex}`);
|
|
16212
16381
|
}
|
|
16213
16382
|
return markets[0];
|
|
16214
16383
|
}
|
|
16215
|
-
async fetchAndParseSpotMarkets(marketIndexes) {
|
|
16216
|
-
const indexesToFetch = marketIndexes.filter((marketIndex)
|
|
16384
|
+
async fetchAndParseSpotMarkets(marketIndexes, skipCache = false) {
|
|
16385
|
+
const indexesToFetch = marketIndexes.filter((marketIndex)=>skipCache || !this.spotMarkets.has(marketIndex));
|
|
16217
16386
|
if (indexesToFetch.length > 0) {
|
|
16218
16387
|
if (process.env.NODE_ENV === "development") {
|
|
16219
16388
|
console.log("Fetching spot markets:", indexesToFetch);
|
|
@@ -16236,17 +16405,17 @@ class DriftClient {
|
|
|
16236
16405
|
}
|
|
16237
16406
|
return spotMarkets;
|
|
16238
16407
|
}
|
|
16239
|
-
async fetchAndParsePerpMarket(marketIndex) {
|
|
16408
|
+
async fetchAndParsePerpMarket(marketIndex, skipCache = false) {
|
|
16240
16409
|
const markets = await this.fetchAndParsePerpMarkets([
|
|
16241
16410
|
marketIndex
|
|
16242
|
-
]);
|
|
16411
|
+
], skipCache);
|
|
16243
16412
|
if (!markets || markets.length === 0) {
|
|
16244
16413
|
throw new Error(`Perp market not found at index ${marketIndex}`);
|
|
16245
16414
|
}
|
|
16246
16415
|
return markets[0];
|
|
16247
16416
|
}
|
|
16248
|
-
async fetchAndParsePerpMarkets(marketIndexes) {
|
|
16249
|
-
const indexesToFetch = marketIndexes.filter((marketIndex)
|
|
16417
|
+
async fetchAndParsePerpMarkets(marketIndexes, skipCache = false) {
|
|
16418
|
+
const indexesToFetch = marketIndexes.filter((marketIndex)=>skipCache || !this.perpMarkets.has(marketIndex));
|
|
16250
16419
|
if (indexesToFetch.length > 0) {
|
|
16251
16420
|
if (process.env.NODE_ENV === "development") {
|
|
16252
16421
|
console.log("Fetching perp markets:", indexesToFetch);
|
|
@@ -16271,33 +16440,56 @@ class DriftClient {
|
|
|
16271
16440
|
}
|
|
16272
16441
|
return perpMarkets;
|
|
16273
16442
|
}
|
|
16274
|
-
async fetchMarketConfigs() {
|
|
16275
|
-
//
|
|
16276
|
-
|
|
16277
|
-
|
|
16278
|
-
|
|
16279
|
-
|
|
16280
|
-
|
|
16281
|
-
|
|
16282
|
-
|
|
16283
|
-
|
|
16284
|
-
|
|
16285
|
-
|
|
16286
|
-
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
|
|
16294
|
-
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
|
|
16443
|
+
async fetchMarketConfigs(skipCache = false) {
|
|
16444
|
+
// Attempt to fetch market configs from glam API first
|
|
16445
|
+
const glamApi = process.env.NEXT_PUBLIC_GLAM_API || process.env.GLAM_API;
|
|
16446
|
+
if (glamApi) {
|
|
16447
|
+
const response = await fetch(`${glamApi}/v0/drift/market_configs/`);
|
|
16448
|
+
if (!response.ok) {
|
|
16449
|
+
throw new Error(`Failed to fetch market configs from ${glamApi}: ${response.status}`);
|
|
16450
|
+
}
|
|
16451
|
+
const data = await response.json();
|
|
16452
|
+
const { orderConstants, perp, spot } = data;
|
|
16453
|
+
// Transform perp market from API to `PerpMarket` type
|
|
16454
|
+
const perpMarkets = perp.map((m)=>({
|
|
16455
|
+
name: m.symbol,
|
|
16456
|
+
marketIndex: m.marketIndex,
|
|
16457
|
+
marketPda: new PublicKey(m.marketPDA),
|
|
16458
|
+
oracle: new PublicKey(m.oracle),
|
|
16459
|
+
oracleSource: OracleSource.fromString(m.oracleSource)
|
|
16460
|
+
}));
|
|
16461
|
+
perpMarkets.forEach((m)=>{
|
|
16462
|
+
this.perpMarkets.set(m.marketIndex, m);
|
|
16463
|
+
});
|
|
16464
|
+
// Transform spot market from API to `SpotMarket` type
|
|
16465
|
+
const spotMarkets = spot.map((m)=>({
|
|
16466
|
+
name: m.symbol,
|
|
16467
|
+
marketIndex: m.marketIndex,
|
|
16468
|
+
marketPda: new PublicKey(m.marketPDA),
|
|
16469
|
+
vault: new PublicKey(m.vaultPDA),
|
|
16470
|
+
oracle: new PublicKey(m.oracle),
|
|
16471
|
+
oracleSource: OracleSource.fromString(m.oracleSource),
|
|
16472
|
+
mint: new PublicKey(m.mint),
|
|
16473
|
+
decimals: m.decimals,
|
|
16474
|
+
tokenProgram: new PublicKey(m.tokenProgram),
|
|
16475
|
+
cumulativeDepositInterest: new BN(m.cumulativeDepositInterest),
|
|
16476
|
+
cumulativeBorrowInterest: new BN(m.cumulativeBorrowInterest)
|
|
16477
|
+
}));
|
|
16478
|
+
spotMarkets.forEach((m)=>{
|
|
16479
|
+
this.spotMarkets.set(m.marketIndex, m);
|
|
16480
|
+
});
|
|
16481
|
+
const marketConfigs = {
|
|
16482
|
+
orderConstants,
|
|
16483
|
+
perpMarkets,
|
|
16484
|
+
spotMarkets
|
|
16485
|
+
};
|
|
16486
|
+
this.marketConfigs = marketConfigs;
|
|
16487
|
+
return marketConfigs;
|
|
16488
|
+
}
|
|
16489
|
+
// If glam API is not available, fetch market configs from RPC
|
|
16298
16490
|
if (!this.marketConfigs) {
|
|
16299
|
-
const perpMarkets = await this.fetchAndParsePerpMarkets(Array.from(Array(100).keys()));
|
|
16300
|
-
const spotMarkets = await this.fetchAndParseSpotMarkets(Array.from(Array(100).keys()));
|
|
16491
|
+
const perpMarkets = await this.fetchAndParsePerpMarkets(Array.from(Array(100).keys()), skipCache);
|
|
16492
|
+
const spotMarkets = await this.fetchAndParseSpotMarkets(Array.from(Array(100).keys()), skipCache);
|
|
16301
16493
|
this.marketConfigs = {
|
|
16302
16494
|
orderConstants: {
|
|
16303
16495
|
perpBaseScale: 9,
|
|
@@ -16309,24 +16501,10 @@ class DriftClient {
|
|
|
16309
16501
|
}
|
|
16310
16502
|
return this.marketConfigs;
|
|
16311
16503
|
}
|
|
16312
|
-
// public async fetchGlamDriftUser(
|
|
16313
|
-
// glamState: PublicKey | string,
|
|
16314
|
-
// subAccountId: number = 0,
|
|
16315
|
-
// ): Promise<GlamDriftUser> {
|
|
16316
|
-
// const vault = this.base.getVaultPda(new PublicKey(glamState));
|
|
16317
|
-
// const response = await fetch(
|
|
16318
|
-
// `https://api.glam.systems/v0/drift/user?authority=${vault.toBase58()}&accountId=${subAccountId}`,
|
|
16319
|
-
// );
|
|
16320
|
-
// const data = await response.json();
|
|
16321
|
-
// if (!data) {
|
|
16322
|
-
// throw new Error("Failed to fetch drift user.");
|
|
16323
|
-
// }
|
|
16324
|
-
// return data as GlamDriftUser;
|
|
16325
|
-
// }
|
|
16326
16504
|
charsToName(chars) {
|
|
16327
16505
|
return String.fromCharCode(...chars).replace(/\0/g, "").trim();
|
|
16328
16506
|
}
|
|
16329
|
-
async fetchDriftUser(subAccountId = 0) {
|
|
16507
|
+
async fetchDriftUser(subAccountId = 0, skipCache = false) {
|
|
16330
16508
|
const { user } = this.getDriftUserPdas(subAccountId);
|
|
16331
16509
|
const accountInfo = await this.base.provider.connection.getAccountInfo(user);
|
|
16332
16510
|
if (!accountInfo) {
|
|
@@ -16334,7 +16512,7 @@ class DriftClient {
|
|
|
16334
16512
|
}
|
|
16335
16513
|
const { delegate, name, spotPositions, marginMode, perpPositions, isMarginTradingEnabled, maxMarginRatio, orders } = decodeUser(accountInfo.data);
|
|
16336
16514
|
// Prefetch market configs
|
|
16337
|
-
const marketConfigs = await this.fetchMarketConfigs();
|
|
16515
|
+
const marketConfigs = await this.fetchMarketConfigs(skipCache);
|
|
16338
16516
|
const spotPositionsExt = await Promise.all(spotPositions.map(async (p)=>{
|
|
16339
16517
|
const { amount, uiAmount } = await this.calcSpotBalance(p.marketIndex, p.scaledBalance, p.balanceType);
|
|
16340
16518
|
const spotMarket = marketConfigs.spotMarkets.find((m)=>m.marketIndex === p.marketIndex);
|
|
@@ -16359,22 +16537,10 @@ class DriftClient {
|
|
|
16359
16537
|
maxMarginRatio
|
|
16360
16538
|
};
|
|
16361
16539
|
}
|
|
16362
|
-
// async getPositions(statePda: PublicKey | string, subAccountId: number = 0) {
|
|
16363
|
-
// const driftUser = await this.fetchDriftUser(
|
|
16364
|
-
// new PublicKey(statePda),
|
|
16365
|
-
// subAccountId,
|
|
16366
|
-
// );
|
|
16367
|
-
// if (!driftUser) {
|
|
16368
|
-
// return { spotPositions: [], perpPositions: [] };
|
|
16369
|
-
// }
|
|
16370
|
-
// const marketConfigs = await this.fetchMarketConfigs();
|
|
16371
|
-
// const { spotPositions, perpPositions } = driftUser;
|
|
16372
|
-
// return { spotPositions, perpPositions };
|
|
16373
|
-
// }
|
|
16374
16540
|
/**
|
|
16375
16541
|
* @deprecated
|
|
16376
|
-
*/ async fetchPolicyConfig(
|
|
16377
|
-
const driftUserAccount =
|
|
16542
|
+
*/ async fetchPolicyConfig(stateModel) {
|
|
16543
|
+
const driftUserAccount = await this.fetchDriftUser();
|
|
16378
16544
|
let delegate = driftUserAccount?.delegate;
|
|
16379
16545
|
if (delegate && delegate.equals(PublicKey.default)) {
|
|
16380
16546
|
delegate = undefined;
|
|
@@ -16382,11 +16548,11 @@ class DriftClient {
|
|
|
16382
16548
|
return {
|
|
16383
16549
|
driftAccessControl: delegate ? 0 : 1,
|
|
16384
16550
|
driftDelegatedAccount: delegate || null,
|
|
16385
|
-
driftMarketIndexesPerp:
|
|
16386
|
-
driftOrderTypes:
|
|
16551
|
+
driftMarketIndexesPerp: stateModel?.driftMarketIndexesPerp || [],
|
|
16552
|
+
driftOrderTypes: stateModel?.driftOrderTypes || [],
|
|
16387
16553
|
driftMaxLeverage: driftUserAccount?.maxMarginRatio ? DRIFT_MARGIN_PRECISION / driftUserAccount?.maxMarginRatio : null,
|
|
16388
16554
|
driftEnableSpot: driftUserAccount?.isMarginTradingEnabled || false,
|
|
16389
|
-
driftMarketIndexesSpot:
|
|
16555
|
+
driftMarketIndexesSpot: stateModel?.driftMarketIndexesSpot || []
|
|
16390
16556
|
};
|
|
16391
16557
|
}
|
|
16392
16558
|
async composeRemainingAccounts(subAccountId, marketType, marketIndex) {
|
|
@@ -16481,7 +16647,8 @@ class DriftClient {
|
|
|
16481
16647
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
16482
16648
|
const { user } = this.getDriftUserPdas(subAccountId);
|
|
16483
16649
|
// https://github.com/drift-labs/protocol-v2/blob/babed162b08b1fe34e49a81c5aa3e4ec0a88ecdf/programs/drift/src/math/constants.rs#L183-L184
|
|
16484
|
-
|
|
16650
|
+
// 0 means No Limit
|
|
16651
|
+
const marginRatio = maxLeverage === 0 ? 0 : DRIFT_MARGIN_PRECISION / maxLeverage;
|
|
16485
16652
|
return await this.base.program.methods.driftUpdateUserCustomMarginRatio(subAccountId, marginRatio).accounts({
|
|
16486
16653
|
glamState: this.base.statePda,
|
|
16487
16654
|
glamSigner,
|
|
@@ -17505,7 +17672,8 @@ class MarinadeClient {
|
|
|
17505
17672
|
// Fetch stake accounts by withdraw authority
|
|
17506
17673
|
// Filter by state "active" does not work in localnet tests
|
|
17507
17674
|
const stakeAccounts = await getStakeAccountsWithStates(this.base.provider.connection, stakeWithdrawAuthority);
|
|
17508
|
-
const
|
|
17675
|
+
const idx = this.base.cluster === ClusterNetwork.Mainnet ? stakeAccounts.findIndex((s)=>s.state === "active") : 0;
|
|
17676
|
+
const { stakeIndex, validatorIndex } = await this.getIndexes(stakeAccounts[idx], stakeList, validatorList);
|
|
17509
17677
|
const burnMsolFrom = this.base.getVaultAta(MSOL);
|
|
17510
17678
|
const newStake = Keypair.generate();
|
|
17511
17679
|
const postInstructions = deactivate ? [
|
|
@@ -17521,7 +17689,7 @@ class MarinadeClient {
|
|
|
17521
17689
|
state: marinadeState.marinadeStateAddress,
|
|
17522
17690
|
validatorList: validatorList.account,
|
|
17523
17691
|
stakeList: stakeList.account,
|
|
17524
|
-
stakeAccount: stakeAccounts[
|
|
17692
|
+
stakeAccount: stakeAccounts[idx].address,
|
|
17525
17693
|
stakeWithdrawAuthority,
|
|
17526
17694
|
stakeDepositAuthority,
|
|
17527
17695
|
treasuryMsolAccount: marinadeState.treasuryMsolAccount,
|
|
@@ -17692,7 +17860,7 @@ class VaultClient {
|
|
|
17692
17860
|
const tx = new Transaction().add(createAssociatedTokenAccountIdempotentInstruction(signer, vaultAta, this.base.vaultPda, asset, tokenProgram), createTransferCheckedInstruction(signerAta, asset, vaultAta, signer, new BN(amount).toNumber(), mint.decimals, [], tokenProgram));
|
|
17693
17861
|
return await this.base.intoVersionedTransaction(tx, txOptions);
|
|
17694
17862
|
}
|
|
17695
|
-
async withdrawIxs(asset, amount, txOptions) {
|
|
17863
|
+
async withdrawIxs(asset, amount, txOptions = {}) {
|
|
17696
17864
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
17697
17865
|
const { tokenProgram } = await this.base.fetchMintAndTokenProgram(asset);
|
|
17698
17866
|
const signerAta = this.base.getAta(asset, glamSigner, tokenProgram);
|
|
@@ -18621,11 +18789,69 @@ class MintClient {
|
|
|
18621
18789
|
}
|
|
18622
18790
|
}
|
|
18623
18791
|
|
|
18792
|
+
const MAX_RESERVES = 25;
|
|
18793
|
+
const VaultAllocationLayout = struct([
|
|
18794
|
+
publicKey("reserve"),
|
|
18795
|
+
publicKey("ctokenVault"),
|
|
18796
|
+
u64("targetAllocationWeight"),
|
|
18797
|
+
u64("tokenAllocationCap"),
|
|
18798
|
+
u64("ctokenVaultBump"),
|
|
18799
|
+
array(u64(), 127, "configPadding"),
|
|
18800
|
+
u64("ctokenAllocation"),
|
|
18801
|
+
u64("lastInvestSlot"),
|
|
18802
|
+
u128("tokenTargetAllocationSf"),
|
|
18803
|
+
array(u64(), 128, "statePadding")
|
|
18804
|
+
]);
|
|
18805
|
+
const KVaultStateLayout = struct([
|
|
18806
|
+
array(u8(), 8, "discriminator"),
|
|
18807
|
+
// Admin
|
|
18808
|
+
publicKey("vaultAdminAuthority"),
|
|
18809
|
+
publicKey("baseVaultAuthority"),
|
|
18810
|
+
u64("baseVaultAuthorityBump"),
|
|
18811
|
+
publicKey("tokenMint"),
|
|
18812
|
+
u64("tokenMintDecimals"),
|
|
18813
|
+
publicKey("tokenVault"),
|
|
18814
|
+
publicKey("tokenProgram"),
|
|
18815
|
+
// shares
|
|
18816
|
+
publicKey("sharesMint"),
|
|
18817
|
+
u64("sharesMintDecimals"),
|
|
18818
|
+
// accounting
|
|
18819
|
+
u64("tokenAvailable"),
|
|
18820
|
+
u64("sharesIssued"),
|
|
18821
|
+
u64("availableCrankFunds"),
|
|
18822
|
+
u64("padding0"),
|
|
18823
|
+
u64("performanceFeeBps"),
|
|
18824
|
+
u64("managementFeeBps"),
|
|
18825
|
+
u64("lastFeeChargeTimestamp"),
|
|
18826
|
+
u128("prevAumSf"),
|
|
18827
|
+
u128("pendingFeesSf"),
|
|
18828
|
+
array(VaultAllocationLayout, MAX_RESERVES, "vaultAllocationStrategy"),
|
|
18829
|
+
array(u128(), 256, "padding1"),
|
|
18830
|
+
// General config
|
|
18831
|
+
u64("minDepositAmount"),
|
|
18832
|
+
u64("minWithdrawAmount"),
|
|
18833
|
+
u64("minInvestAmount"),
|
|
18834
|
+
u64("minInvestDelaySlots"),
|
|
18835
|
+
u64("crankFundFeePerReserve"),
|
|
18836
|
+
publicKey("pendingAdmin"),
|
|
18837
|
+
u128("cumulativeEarnedInterestSf"),
|
|
18838
|
+
u128("cumulativeMgmtFeesSf"),
|
|
18839
|
+
u128("cumulativePerfFeesSf"),
|
|
18840
|
+
array(u8(), 40, "name"),
|
|
18841
|
+
publicKey("vaultLookupTable"),
|
|
18842
|
+
publicKey("vaultFarm"),
|
|
18843
|
+
u64("creationTimestamp"),
|
|
18844
|
+
u64("padding2"),
|
|
18845
|
+
publicKey("allocationAdmin"),
|
|
18846
|
+
array(u128(), 242, "padding3")
|
|
18847
|
+
]);
|
|
18848
|
+
|
|
18624
18849
|
const LOOKUP_TABLE = new PublicKey("284iwGtA9X9aLy3KsyV8uT2pXLARhYbiSi5SiM2g47M2");
|
|
18625
18850
|
const DEFAULT_OBLIGATION_ARGS = {
|
|
18626
18851
|
tag: 0,
|
|
18627
18852
|
id: 0
|
|
18628
18853
|
};
|
|
18854
|
+
const EVENT_AUTHORITY$1 = new PublicKey("24tHwQyJJ9akVXxnvkekGfAoeUJXXS7mE6kQNioNySsK");
|
|
18629
18855
|
function refreshObligation(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
18630
18856
|
const keys = [
|
|
18631
18857
|
{
|
|
@@ -19024,7 +19250,7 @@ class KaminoLendingClient {
|
|
|
19024
19250
|
/**
|
|
19025
19251
|
* Fetches and parses an obligation account
|
|
19026
19252
|
*/ async fetchAndParseObligation(obligation) {
|
|
19027
|
-
const cached = this.obligations.get(obligation);
|
|
19253
|
+
const cached = this.obligations.get(obligation.toBase58());
|
|
19028
19254
|
if (cached) {
|
|
19029
19255
|
return cached;
|
|
19030
19256
|
}
|
|
@@ -19038,7 +19264,7 @@ class KaminoLendingClient {
|
|
|
19038
19264
|
};
|
|
19039
19265
|
}
|
|
19040
19266
|
const parsedObligation = this.parseObligation(obligation, obligationAccount.data);
|
|
19041
|
-
this.obligations.set(obligation, parsedObligation);
|
|
19267
|
+
this.obligations.set(obligation.toBase58(), parsedObligation);
|
|
19042
19268
|
return parsedObligation;
|
|
19043
19269
|
}
|
|
19044
19270
|
parseReserveAccount(reserve, data) {
|
|
@@ -19048,6 +19274,7 @@ class KaminoLendingClient {
|
|
|
19048
19274
|
const liquidityMint = new PublicKey(data.subarray(128, 160));
|
|
19049
19275
|
return {
|
|
19050
19276
|
address: reserve,
|
|
19277
|
+
market,
|
|
19051
19278
|
farmCollateral: farmCollateral.equals(PublicKey.default) ? null : farmCollateral,
|
|
19052
19279
|
farmDebt: farmDebt.equals(PublicKey.default) ? null : farmDebt,
|
|
19053
19280
|
liquidityMint,
|
|
@@ -19055,16 +19282,28 @@ class KaminoLendingClient {
|
|
|
19055
19282
|
};
|
|
19056
19283
|
}
|
|
19057
19284
|
async fetchAndParseReserves(reserves) {
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
|
|
19285
|
+
const requestReservesSet = new Set(reserves.map((r)=>r.toBase58()));
|
|
19286
|
+
const cachedReservesSet = new Set(this.reserves.keys());
|
|
19287
|
+
// If all requested reserves are cached, return data from cache
|
|
19288
|
+
if ([
|
|
19289
|
+
...requestReservesSet
|
|
19290
|
+
].every((r)=>cachedReservesSet.has(r))) {
|
|
19291
|
+
return Array.from(this.reserves.values()).filter((r)=>requestReservesSet.has(r.address.toBase58()));
|
|
19292
|
+
}
|
|
19293
|
+
// Only fetch reserves that are not cached
|
|
19294
|
+
const reservesToFetch = [
|
|
19295
|
+
...requestReservesSet
|
|
19296
|
+
].filter((r)=>!cachedReservesSet.has(r)).map((r)=>new PublicKey(r));
|
|
19297
|
+
if (process.env.NODE_ENV !== "production") {
|
|
19298
|
+
console.log("Fetching reserves:", reservesToFetch.map((r)=>r.toBase58()));
|
|
19299
|
+
}
|
|
19300
|
+
const reserveAccounts = await this.base.provider.connection.getMultipleAccountsInfo(reservesToFetch);
|
|
19301
|
+
if (reserveAccounts.some((a)=>!a)) {
|
|
19063
19302
|
throw new Error("Not all reserves can be found");
|
|
19064
19303
|
}
|
|
19065
|
-
return reserveAccounts.
|
|
19304
|
+
return reserveAccounts.map((account, i)=>{
|
|
19066
19305
|
const parsedReserve = this.parseReserveAccount(reserves[i], account.data);
|
|
19067
|
-
this.reserves.set(reserves[i], parsedReserve);
|
|
19306
|
+
this.reserves.set(reserves[i].toBase58(), parsedReserve);
|
|
19068
19307
|
return parsedReserve;
|
|
19069
19308
|
});
|
|
19070
19309
|
}
|
|
@@ -19092,7 +19331,7 @@ class KaminoLendingClient {
|
|
|
19092
19331
|
throw new Error("Reserve not found");
|
|
19093
19332
|
}
|
|
19094
19333
|
const parsedReserve = this.parseReserveAccount(accounts[0].pubkey, accounts[0].account.data);
|
|
19095
|
-
this.reserves.set(accounts[0].pubkey, parsedReserve);
|
|
19334
|
+
this.reserves.set(accounts[0].pubkey.toBase58(), parsedReserve);
|
|
19096
19335
|
return parsedReserve;
|
|
19097
19336
|
}
|
|
19098
19337
|
/**
|
|
@@ -19122,7 +19361,7 @@ class KaminoLendingClient {
|
|
|
19122
19361
|
// Parse obligations and cache them
|
|
19123
19362
|
return accounts.map((a)=>{
|
|
19124
19363
|
const parsedObligation = this.parseObligation(a.pubkey, a.account.data);
|
|
19125
|
-
this.obligations.set(a.pubkey, parsedObligation);
|
|
19364
|
+
this.obligations.set(a.pubkey.toBase58(), parsedObligation);
|
|
19126
19365
|
return parsedObligation;
|
|
19127
19366
|
});
|
|
19128
19367
|
}
|
|
@@ -19653,6 +19892,160 @@ class KaminoFarmClient {
|
|
|
19653
19892
|
], KAMINO_FARM_PROGRAM)[0];
|
|
19654
19893
|
}
|
|
19655
19894
|
}
|
|
19895
|
+
class KaminoVaultsClient {
|
|
19896
|
+
async deposit(vault, amount, txOptions = {}) {
|
|
19897
|
+
const tx = await this.depositTx(vault, amount, txOptions);
|
|
19898
|
+
return await this.base.sendAndConfirm(tx);
|
|
19899
|
+
}
|
|
19900
|
+
async withdraw(vault, amount, txOptions = {}) {
|
|
19901
|
+
const tx = await this.withdrawTx(vault, amount, txOptions);
|
|
19902
|
+
return await this.base.sendAndConfirm(tx);
|
|
19903
|
+
}
|
|
19904
|
+
async findAndParseKaminoVaults() {
|
|
19905
|
+
const accounts = await this.base.provider.connection.getProgramAccounts(KAMINO_VAULTS_PROGRAM, {
|
|
19906
|
+
filters: [
|
|
19907
|
+
{
|
|
19908
|
+
dataSize: 62552
|
|
19909
|
+
},
|
|
19910
|
+
{
|
|
19911
|
+
memcmp: {
|
|
19912
|
+
offset: 0,
|
|
19913
|
+
bytes: "5MRSpWLS65g=",
|
|
19914
|
+
encoding: "base64"
|
|
19915
|
+
}
|
|
19916
|
+
}
|
|
19917
|
+
]
|
|
19918
|
+
});
|
|
19919
|
+
if (accounts.length === 0) {
|
|
19920
|
+
throw new Error("Kamino vaults not found");
|
|
19921
|
+
}
|
|
19922
|
+
return accounts.map((a)=>{
|
|
19923
|
+
const vaultState = KVaultStateLayout.decode(a.account.data);
|
|
19924
|
+
this.vaultStates.set(a.pubkey.toBase58(), vaultState);
|
|
19925
|
+
this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), a.pubkey);
|
|
19926
|
+
return vaultState;
|
|
19927
|
+
});
|
|
19928
|
+
}
|
|
19929
|
+
async getVaultPdasByShareMints(mints) {
|
|
19930
|
+
if (this.vaultStates.size === 0) {
|
|
19931
|
+
await this.findAndParseKaminoVaults();
|
|
19932
|
+
}
|
|
19933
|
+
return mints.map((mint)=>this.shareMintToVaultPdaMap.get(mint.toBase58()));
|
|
19934
|
+
}
|
|
19935
|
+
async fetchAndParseVaultState(vault) {
|
|
19936
|
+
const vaultAccount = await this.base.provider.connection.getAccountInfo(vault);
|
|
19937
|
+
if (!vaultAccount) {
|
|
19938
|
+
throw new Error(`Kamino vault account not found:, ${vault}`);
|
|
19939
|
+
}
|
|
19940
|
+
const vaultState = KVaultStateLayout.decode(vaultAccount.data);
|
|
19941
|
+
this.vaultStates.set(vault.toBase58(), vaultState);
|
|
19942
|
+
this.shareMintToVaultPdaMap.set(vaultState.sharesMint.toBase58(), vault);
|
|
19943
|
+
return vaultState;
|
|
19944
|
+
}
|
|
19945
|
+
async composeRemainingAccounts(allocationStrategies) {
|
|
19946
|
+
// For each allocation get reserve and market pubkeys
|
|
19947
|
+
const reserves = allocationStrategies.map((strategy)=>strategy.reserve);
|
|
19948
|
+
const parsedReserves = await this.kaminoLending.fetchAndParseReserves(reserves);
|
|
19949
|
+
const reserveMetas = reserves.map((pubkey)=>({
|
|
19950
|
+
pubkey,
|
|
19951
|
+
isSigner: false,
|
|
19952
|
+
isWritable: true
|
|
19953
|
+
}));
|
|
19954
|
+
const marketMetas = parsedReserves.map(({ market })=>({
|
|
19955
|
+
pubkey: market,
|
|
19956
|
+
isSigner: false,
|
|
19957
|
+
isWritable: false
|
|
19958
|
+
}));
|
|
19959
|
+
return [
|
|
19960
|
+
...reserveMetas,
|
|
19961
|
+
...marketMetas
|
|
19962
|
+
];
|
|
19963
|
+
}
|
|
19964
|
+
async depositTx(vault, amount, txOptions = {}) {
|
|
19965
|
+
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
19966
|
+
const vaultState = await this.fetchAndParseVaultState(vault);
|
|
19967
|
+
const amountBN = new BN(amount * 10 ** vaultState.tokenMintDecimals.toNumber());
|
|
19968
|
+
const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
|
|
19969
|
+
const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
|
|
19970
|
+
const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
|
|
19971
|
+
// Create user shares ata
|
|
19972
|
+
const preInstructions = [
|
|
19973
|
+
createAssociatedTokenAccountIdempotentInstruction(glamSigner, userSharesAta, this.base.vaultPda, vaultState.sharesMint, sharesTokenProgram)
|
|
19974
|
+
];
|
|
19975
|
+
// Remaining accounts, skip empty allocation strategies
|
|
19976
|
+
const remainingAccounts = await this.composeRemainingAccounts(vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(PublicKey.default)));
|
|
19977
|
+
const tx = await this.base.program.methods.kaminoVaultsDeposit(amountBN).accounts({
|
|
19978
|
+
glamState: this.base.statePda,
|
|
19979
|
+
glamSigner,
|
|
19980
|
+
vaultState: vault,
|
|
19981
|
+
tokenVault: vaultState.tokenVault,
|
|
19982
|
+
tokenMint: vaultState.tokenMint,
|
|
19983
|
+
baseVaultAuthority: vaultState.baseVaultAuthority,
|
|
19984
|
+
sharesMint: vaultState.sharesMint,
|
|
19985
|
+
userTokenAta,
|
|
19986
|
+
userSharesAta,
|
|
19987
|
+
klendProgram: KAMINO_LENDING_PROGRAM,
|
|
19988
|
+
tokenProgram: vaultState.tokenProgram,
|
|
19989
|
+
sharesTokenProgram,
|
|
19990
|
+
eventAuthority: EVENT_AUTHORITY$1,
|
|
19991
|
+
program: KAMINO_VAULTS_PROGRAM
|
|
19992
|
+
}).remainingAccounts(remainingAccounts).preInstructions(preInstructions).transaction();
|
|
19993
|
+
const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
|
|
19994
|
+
return vTx;
|
|
19995
|
+
}
|
|
19996
|
+
async withdrawTx(vault, amount, txOptions = {}) {
|
|
19997
|
+
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
19998
|
+
const vaultState = await this.fetchAndParseVaultState(vault);
|
|
19999
|
+
const userTokenAta = this.base.getVaultAta(vaultState.tokenMint, vaultState.tokenProgram);
|
|
20000
|
+
const { tokenProgram: sharesTokenProgram } = await this.base.fetchMintAndTokenProgram(vaultState.sharesMint);
|
|
20001
|
+
const userSharesAta = this.base.getVaultAta(vaultState.sharesMint, sharesTokenProgram);
|
|
20002
|
+
const amountBN = new BN(amount * 10 ** vaultState.sharesMintDecimals.toNumber());
|
|
20003
|
+
const reserves = vaultState.vaultAllocationStrategy.filter(({ reserve })=>!reserve.equals(PublicKey.default));
|
|
20004
|
+
// Withdraw from the first reserve when kvault does not have enough liquidity
|
|
20005
|
+
const idx = 0;
|
|
20006
|
+
const withdrawReserve = (await this.kaminoLending.fetchAndParseReserves(reserves.map((r)=>r.reserve)))[idx];
|
|
20007
|
+
const vaultCollateralTokenVault = vaultState.vaultAllocationStrategy[idx].ctokenVault;
|
|
20008
|
+
const remainingAccounts = await this.composeRemainingAccounts(reserves);
|
|
20009
|
+
const preInstructions = [
|
|
20010
|
+
createAssociatedTokenAccountIdempotentInstruction(glamSigner, userTokenAta, this.base.vaultPda, vaultState.tokenMint, vaultState.tokenProgram)
|
|
20011
|
+
];
|
|
20012
|
+
const tx = await this.base.program.methods.kaminoVaultsWithdraw(amountBN).accounts({
|
|
20013
|
+
glamState: this.base.statePda,
|
|
20014
|
+
glamSigner,
|
|
20015
|
+
withdrawFromAvailableVaultState: vault,
|
|
20016
|
+
withdrawFromAvailableTokenVault: vaultState.tokenVault,
|
|
20017
|
+
withdrawFromAvailableBaseVaultAuthority: vaultState.baseVaultAuthority,
|
|
20018
|
+
withdrawFromAvailableUserTokenAta: userTokenAta,
|
|
20019
|
+
withdrawFromAvailableTokenMint: vaultState.tokenMint,
|
|
20020
|
+
withdrawFromAvailableUserSharesAta: userSharesAta,
|
|
20021
|
+
withdrawFromAvailableSharesMint: vaultState.sharesMint,
|
|
20022
|
+
withdrawFromAvailableTokenProgram: vaultState.tokenProgram,
|
|
20023
|
+
withdrawFromAvailableSharesTokenProgram: sharesTokenProgram,
|
|
20024
|
+
withdrawFromAvailableKlendProgram: KAMINO_LENDING_PROGRAM,
|
|
20025
|
+
withdrawFromAvailableEventAuthority: EVENT_AUTHORITY$1,
|
|
20026
|
+
withdrawFromAvailableProgram: KAMINO_VAULTS_PROGRAM,
|
|
20027
|
+
withdrawFromReserveVaultState: vault,
|
|
20028
|
+
withdrawFromReserveReserve: withdrawReserve.address,
|
|
20029
|
+
withdrawFromReserveCtokenVault: vaultCollateralTokenVault,
|
|
20030
|
+
withdrawFromReserveLendingMarket: withdrawReserve.market,
|
|
20031
|
+
withdrawFromReserveLendingMarketAuthority: this.kaminoLending.getMarketAuthority(withdrawReserve.market),
|
|
20032
|
+
withdrawFromReserveReserveLiquiditySupply: withdrawReserve.liquiditySupplyVault,
|
|
20033
|
+
withdrawFromReserveReserveCollateralMint: withdrawReserve.collateralMint,
|
|
20034
|
+
withdrawFromReserveReserveCollateralTokenProgram: TOKEN_PROGRAM_ID,
|
|
20035
|
+
withdrawFromReserveInstructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
20036
|
+
eventAuthority: EVENT_AUTHORITY$1,
|
|
20037
|
+
program: KAMINO_VAULTS_PROGRAM
|
|
20038
|
+
}).remainingAccounts(remainingAccounts).preInstructions(preInstructions).transaction();
|
|
20039
|
+
const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
|
|
20040
|
+
return vTx;
|
|
20041
|
+
}
|
|
20042
|
+
constructor(base, kaminoLending){
|
|
20043
|
+
this.base = base;
|
|
20044
|
+
this.kaminoLending = kaminoLending;
|
|
20045
|
+
this.vaultStates = new Map();
|
|
20046
|
+
this.shareMintToVaultPdaMap = new Map();
|
|
20047
|
+
}
|
|
20048
|
+
}
|
|
19656
20049
|
|
|
19657
20050
|
// Pubkey::find_program_address(&[b"__event_authority"], &dlmm_interface::ID)
|
|
19658
20051
|
const EVENT_AUTHORITY = new PublicKey("D1ZN9Wj1fRSUQfCjhvnu1hqDMT7hzjzBBpi12nVniYD6");
|
|
@@ -20151,6 +20544,46 @@ class PriceClient {
|
|
|
20151
20544
|
}).remainingAccounts(remainingAccounts).instruction();
|
|
20152
20545
|
return priceIx;
|
|
20153
20546
|
}
|
|
20547
|
+
async priceKaminoVaultSharesIx(priceDenom) {
|
|
20548
|
+
const allKvaultStates = await this.kvaults.findAndParseKaminoVaults();
|
|
20549
|
+
const allKvaultMints = allKvaultStates.map((kvault)=>kvault.sharesMint);
|
|
20550
|
+
// All share token accounts GLAM vault could possibly hold
|
|
20551
|
+
const possibleShareAtas = allKvaultMints.map((mint)=>this.base.getVaultAta(mint));
|
|
20552
|
+
const possibleShareAtaAccountsInfo = await this.base.provider.connection.getMultipleAccountsInfo(possibleShareAtas);
|
|
20553
|
+
const shareAtas = [];
|
|
20554
|
+
const shareMints = [];
|
|
20555
|
+
const kvaultStates = [];
|
|
20556
|
+
possibleShareAtaAccountsInfo.forEach((info, i)=>{
|
|
20557
|
+
if (info !== null) {
|
|
20558
|
+
shareAtas.push(possibleShareAtas[i]);
|
|
20559
|
+
shareMints.push(allKvaultMints[i]);
|
|
20560
|
+
kvaultStates.push(allKvaultStates[i]);
|
|
20561
|
+
}
|
|
20562
|
+
});
|
|
20563
|
+
const kvaultPdas = await this.kvaults.getVaultPdasByShareMints(shareMints);
|
|
20564
|
+
const remainingAccounts = (await Promise.all(kvaultStates.map((kvault)=>{
|
|
20565
|
+
return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(PublicKey.default)));
|
|
20566
|
+
}))).flat();
|
|
20567
|
+
[
|
|
20568
|
+
...kvaultPdas,
|
|
20569
|
+
...shareAtas
|
|
20570
|
+
].map((pubkey)=>{
|
|
20571
|
+
remainingAccounts.unshift({
|
|
20572
|
+
pubkey: pubkey,
|
|
20573
|
+
isSigner: false,
|
|
20574
|
+
isWritable: false
|
|
20575
|
+
});
|
|
20576
|
+
});
|
|
20577
|
+
const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom).accounts({
|
|
20578
|
+
glamState: this.base.statePda,
|
|
20579
|
+
solOracle: SOL_ORACLE,
|
|
20580
|
+
pythOracle: null,
|
|
20581
|
+
switchboardPriceOracle: null,
|
|
20582
|
+
switchboardTwapOracle: null,
|
|
20583
|
+
scopePrices: KAMINO_SCOPE_PRICES
|
|
20584
|
+
}).remainingAccounts(remainingAccounts).instruction();
|
|
20585
|
+
return priceIx;
|
|
20586
|
+
}
|
|
20154
20587
|
/**
|
|
20155
20588
|
* Returns an instruction that prices the all Drift users (aka sub-accounts) controlled by the GLAM vault.
|
|
20156
20589
|
* These Drift users must share the same user_stats that's also controlled by the GLAM vault.
|
|
@@ -20184,7 +20617,7 @@ class PriceClient {
|
|
|
20184
20617
|
* Returns an instruction that prices a drift vault depositor.
|
|
20185
20618
|
* If there are no vault depositor accounts, returns null.
|
|
20186
20619
|
*/ async priceDriftVaultDepositorsIx(priceDenom) {
|
|
20187
|
-
const parsedVaultDepositors = await this.
|
|
20620
|
+
const parsedVaultDepositors = await this.dvaults.findAndParseVaultDepositors();
|
|
20188
20621
|
if (parsedVaultDepositors.length === 0) {
|
|
20189
20622
|
return null;
|
|
20190
20623
|
}
|
|
@@ -20199,9 +20632,9 @@ class PriceClient {
|
|
|
20199
20632
|
for (const depositor of parsedVaultDepositors){
|
|
20200
20633
|
remainingAccountsKeys.add(depositor.address.toBase58());
|
|
20201
20634
|
remainingAccountsKeys.add(depositor.driftVault.toBase58());
|
|
20202
|
-
const { user: driftUser } = await this.
|
|
20635
|
+
const { user: driftUser } = await this.dvaults.parseDriftVault(depositor.driftVault);
|
|
20203
20636
|
remainingAccountsKeys.add(driftUser.toBase58());
|
|
20204
|
-
const markets_and_oracles = (await this.
|
|
20637
|
+
const markets_and_oracles = (await this.dvaults.composeRemainingAccounts(driftUser)).map((a)=>a.pubkey.toBase58());
|
|
20205
20638
|
for (const k of markets_and_oracles){
|
|
20206
20639
|
remainingAccountsKeys.add(k);
|
|
20207
20640
|
}
|
|
@@ -20290,11 +20723,12 @@ class PriceClient {
|
|
|
20290
20723
|
priceDriftVaultDepositorsIx
|
|
20291
20724
|
].filter((ix)=>ix !== null);
|
|
20292
20725
|
}
|
|
20293
|
-
constructor(base, klend, drift,
|
|
20726
|
+
constructor(base, klend, kvaults, drift, dvaults){
|
|
20294
20727
|
this.base = base;
|
|
20295
20728
|
this.klend = klend;
|
|
20729
|
+
this.kvaults = kvaults;
|
|
20296
20730
|
this.drift = drift;
|
|
20297
|
-
this.
|
|
20731
|
+
this.dvaults = dvaults;
|
|
20298
20732
|
this.remainingAccountsForPricingMeteora = async ()=>{
|
|
20299
20733
|
const positions = await fetchMeteoraPositions(this.base.provider.connection, this.base.vaultPda);
|
|
20300
20734
|
let chunks = await Promise.all(positions.map(async (pubkey)=>{
|
|
@@ -20409,7 +20843,7 @@ class PriceClient {
|
|
|
20409
20843
|
}
|
|
20410
20844
|
get price() {
|
|
20411
20845
|
if (!this._price) {
|
|
20412
|
-
this._price = new PriceClient(this, this.kaminoLending, this.drift, this.driftVaults);
|
|
20846
|
+
this._price = new PriceClient(this, this.kaminoLending, this.kaminoVaults, this.drift, this.driftVaults);
|
|
20413
20847
|
}
|
|
20414
20848
|
return this._price;
|
|
20415
20849
|
}
|
|
@@ -20437,6 +20871,12 @@ class PriceClient {
|
|
|
20437
20871
|
}
|
|
20438
20872
|
return this._kaminoFarm;
|
|
20439
20873
|
}
|
|
20874
|
+
get kaminoVaults() {
|
|
20875
|
+
if (!this._kaminoVaults) {
|
|
20876
|
+
this._kaminoVaults = new KaminoVaultsClient(this, this.kaminoLending);
|
|
20877
|
+
}
|
|
20878
|
+
return this._kaminoVaults;
|
|
20879
|
+
}
|
|
20440
20880
|
get meteoraDlmm() {
|
|
20441
20881
|
if (!this._meteoraDlmm) {
|
|
20442
20882
|
this._meteoraDlmm = new MeteoraDlmmClient(this);
|
|
@@ -20519,4 +20959,4 @@ function getMarketOrderParams(params) {
|
|
|
20519
20959
|
return Object.assign({}, DefaultOrderParams, optionalOrderParams, overridingParams);
|
|
20520
20960
|
}
|
|
20521
20961
|
|
|
20522
|
-
export { ASSETS_MAINNET, ASSETS_TESTS, AssetTier, BaseClient, ClusterNetwork, CompanyModel, ContractTier, ContractType, CreatedModel, DRIFT_PROGRAM_ID, DRIFT_VAULTS_PROGRAM_ID, DRIFT_VAULT_DEPOSITOR_SIZE, DefaultOrderParams, DelegateAcl, DepositDirection, DepositExplanation, DriftClient, DriftVaultsClient, ExchangeStatus, FuelOverflowStatus, FundOpenfundsModel, GLAM_REFERRER, GOVERNANCE_PROGRAM_ID, GlamClient, GlamError, GlamIdl, GlamIntegrations, GlamPermissions, GlamProtocolIdlJson, InsuranceFundOperation, 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, KAMINO_SCOPE_PRICES, LPAction, LiquidationType, MARINADE_NATIVE_STAKE_AUTHORITY, MARINADE_PROGRAM_ID, 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, STAKE_POOLS, STAKE_POOLS_MAP, SettlePnlExplanation, SettlePnlMode, SpotBalanceType, SpotFulfillmentConfigStatus, SpotFulfillmentStatus, SpotFulfillmentType, SpotOperation, StakeAction, StateIdlModel, StateModel, SwapDirection, SwapReduceOnly, TRANSFER_HOOK_PROGRAM, TimeUnit, TradeSide, USDC, USDC_ORACLE, UserStatus, WSOL, ZERO, decodeUser, fetchLookupTables, fetchMeteoraPositions, findStakeAccounts, getAccountPolicyPda, getEscrowPda, getExtraMetasPda, getGlamProgram, getGlamProgramId, getLimitOrderParams, getMarketOrderParams, getMintPda, getOpenfundsPda, getOrderParams, getPriorityFeeEstimate, getSimulationComputeUnits, getStakeAccountsWithStates, getStatePda, getTriggerLimitOrderParams, getTriggerMarketOrderParams, getVariant, getVaultPda, isBrowser, isOneOfVariant, isVariant, parseMeteoraPosition, parseProgramLogs, setsAreEqual };
|
|
20962
|
+
export { ASSETS_MAINNET, ASSETS_TESTS, AssetTier, BaseClient, ClusterNetwork, CompanyModel, ContractTier, ContractType, CreatedModel, DRIFT_PROGRAM_ID, DRIFT_VAULTS_PROGRAM_ID, DRIFT_VAULT_DEPOSITOR_SIZE, DefaultOrderParams, DelegateAcl, DepositDirection, DepositExplanation, DriftClient, DriftVaultsClient, ExchangeStatus, FuelOverflowStatus, FundOpenfundsModel, GLAM_REFERRER, GOVERNANCE_PROGRAM_ID, GlamClient, GlamError, GlamIdl, GlamIntegrations, GlamPermissions, GlamProtocolIdlJson, InsuranceFundOperation, 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, KAMINO_SCOPE_PRICES, KAMINO_VAULTS_PROGRAM, LPAction, LiquidationType, MARINADE_NATIVE_STAKE_AUTHORITY, MARINADE_PROGRAM_ID, 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, STAKE_POOLS, STAKE_POOLS_MAP, SettlePnlExplanation, SettlePnlMode, SpotBalanceType, SpotFulfillmentConfigStatus, SpotFulfillmentStatus, SpotFulfillmentType, SpotOperation, StakeAction, StateIdlModel, StateModel, SwapDirection, SwapReduceOnly, TRANSFER_HOOK_PROGRAM, TimeUnit, TradeSide, USDC, USDC_ORACLE, UserStatus, WSOL, ZERO, decodeUser, fetchLookupTables, fetchMeteoraPositions, findStakeAccounts, getAccountPolicyPda, getEscrowPda, getExtraMetasPda, getGlamProgram, getGlamProgramId, getLimitOrderParams, getMarketOrderParams, getMintPda, getOpenfundsPda, getOrderParams, getPriorityFeeEstimate, getSimulationComputeUnits, getStakeAccountsWithStates, getStatePda, getTriggerLimitOrderParams, getTriggerMarketOrderParams, getVariant, getVaultPda, isBrowser, isOneOfVariant, isVariant, parseMeteoraPosition, parseProgramLogs, setsAreEqual };
|