@glamsystems/glam-sdk 0.1.30 → 0.1.31
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 +389 -212
- package/index.esm.js +390 -215
- package/package.json +1 -1
- package/src/client/kamino.d.ts +34 -0
- package/src/client/price.d.ts +8 -1
- package/src/models.d.ts +5 -0
- package/src/react/glam.d.ts +0 -8
- package/src/utils/helpers.d.ts +10 -0
- package/target/idl/glam_protocol.json +5 -1
- package/target/types/glam_protocol.d.ts +4 -0
- package/target/types/glam_protocol.ts +5 -1
package/index.cjs.js
CHANGED
|
@@ -10025,7 +10025,8 @@ var instructions = [
|
|
|
10025
10025
|
],
|
|
10026
10026
|
accounts: [
|
|
10027
10027
|
{
|
|
10028
|
-
name: "glam_state"
|
|
10028
|
+
name: "glam_state",
|
|
10029
|
+
writable: true
|
|
10029
10030
|
},
|
|
10030
10031
|
{
|
|
10031
10032
|
name: "glam_vault",
|
|
@@ -13572,6 +13573,9 @@ var types = [
|
|
|
13572
13573
|
},
|
|
13573
13574
|
{
|
|
13574
13575
|
name: "Fulfill"
|
|
13576
|
+
},
|
|
13577
|
+
{
|
|
13578
|
+
name: "ClaimFees"
|
|
13575
13579
|
}
|
|
13576
13580
|
]
|
|
13577
13581
|
}
|
|
@@ -14949,6 +14953,15 @@ class PriceDenom {
|
|
|
14949
14953
|
}
|
|
14950
14954
|
return PriceDenom.ASSET;
|
|
14951
14955
|
}
|
|
14956
|
+
static fromString(str) {
|
|
14957
|
+
if (str === "SOL") {
|
|
14958
|
+
return PriceDenom.SOL;
|
|
14959
|
+
}
|
|
14960
|
+
if (str === "USD") {
|
|
14961
|
+
return PriceDenom.USD;
|
|
14962
|
+
}
|
|
14963
|
+
throw new Error("Invalid price denomination");
|
|
14964
|
+
}
|
|
14952
14965
|
}
|
|
14953
14966
|
PriceDenom.SOL = {
|
|
14954
14967
|
sol: {}
|
|
@@ -14984,6 +14997,67 @@ var ClusterNetwork = /*#__PURE__*/ function(ClusterNetwork) {
|
|
|
14984
14997
|
return ClusterNetwork;
|
|
14985
14998
|
}({});
|
|
14986
14999
|
|
|
15000
|
+
/**
|
|
15001
|
+
* Fetches all the token accounts owned by the specified pubkey.
|
|
15002
|
+
*/ async function getTokenAccountsByOwner(connection, owner) {
|
|
15003
|
+
const tokenAccounts = await connection.getTokenAccountsByOwner(owner, {
|
|
15004
|
+
programId: splToken.TOKEN_PROGRAM_ID
|
|
15005
|
+
});
|
|
15006
|
+
const token2022Accounts = await connection.getTokenAccountsByOwner(owner, {
|
|
15007
|
+
programId: splToken.TOKEN_2022_PROGRAM_ID
|
|
15008
|
+
});
|
|
15009
|
+
const mintPubkeys = [];
|
|
15010
|
+
const parseTokenAccountInfo = (pubkey, account)=>{
|
|
15011
|
+
const { mint, amount, state } = splToken.AccountLayout.decode(account.data);
|
|
15012
|
+
mintPubkeys.push(mint);
|
|
15013
|
+
return {
|
|
15014
|
+
owner,
|
|
15015
|
+
pubkey,
|
|
15016
|
+
mint,
|
|
15017
|
+
amount: amount.toString(),
|
|
15018
|
+
frozen: state !== 1
|
|
15019
|
+
};
|
|
15020
|
+
};
|
|
15021
|
+
// Parse token accounts
|
|
15022
|
+
const partialTokenAccounts = tokenAccounts.value.map(({ pubkey, account })=>({
|
|
15023
|
+
...parseTokenAccountInfo(pubkey, account),
|
|
15024
|
+
programId: splToken.TOKEN_PROGRAM_ID
|
|
15025
|
+
})).concat(token2022Accounts.value.map(({ pubkey, account })=>({
|
|
15026
|
+
...parseTokenAccountInfo(pubkey, account),
|
|
15027
|
+
programId: splToken.TOKEN_2022_PROGRAM_ID
|
|
15028
|
+
})));
|
|
15029
|
+
// Get mint decimals
|
|
15030
|
+
const mintDecimalMap = new Map();
|
|
15031
|
+
const mintAccountsInfo = await connection.getMultipleAccountsInfo(mintPubkeys);
|
|
15032
|
+
mintAccountsInfo.forEach((accountInfo, i)=>{
|
|
15033
|
+
if (accountInfo) {
|
|
15034
|
+
const mint = splToken.unpackMint(mintPubkeys[i], accountInfo, accountInfo.owner);
|
|
15035
|
+
mintDecimalMap.set(mintPubkeys[i].toBase58(), mint.decimals);
|
|
15036
|
+
}
|
|
15037
|
+
});
|
|
15038
|
+
// Enrich token accounts with decimals and uiAmount
|
|
15039
|
+
return partialTokenAccounts.map((ta)=>{
|
|
15040
|
+
const decimals = mintDecimalMap.get(ta.mint.toBase58());
|
|
15041
|
+
if (!decimals) {
|
|
15042
|
+
return null;
|
|
15043
|
+
}
|
|
15044
|
+
return {
|
|
15045
|
+
...ta,
|
|
15046
|
+
decimals,
|
|
15047
|
+
uiAmount: Number(ta.amount) / 10 ** decimals
|
|
15048
|
+
};
|
|
15049
|
+
}).filter((ta)=>ta !== null);
|
|
15050
|
+
}
|
|
15051
|
+
async function getSolAndTokenBalances(connection, owner) {
|
|
15052
|
+
const balanceLamports = await connection.getBalance(owner);
|
|
15053
|
+
const tokenAccounts = await getTokenAccountsByOwner(connection, owner);
|
|
15054
|
+
const uiAmount = balanceLamports / web3_js.LAMPORTS_PER_SOL;
|
|
15055
|
+
return {
|
|
15056
|
+
balanceLamports,
|
|
15057
|
+
uiAmount,
|
|
15058
|
+
tokenAccounts
|
|
15059
|
+
};
|
|
15060
|
+
}
|
|
14987
15061
|
const findStakeAccounts = async (connection, withdrawAuthority)=>{
|
|
14988
15062
|
// stake authority offset: 12
|
|
14989
15063
|
// withdraw authority offset: 44
|
|
@@ -15202,7 +15276,7 @@ STAKE_POOLS.push({
|
|
|
15202
15276
|
symbol: "PSOL",
|
|
15203
15277
|
mint: "pSo1f9nQXWgXibFtKf7NWYxb5enAM4qfP6UJSiXRQfL",
|
|
15204
15278
|
decimals: 9,
|
|
15205
|
-
logoURI: "https://
|
|
15279
|
+
logoURI: "https://coin-images.coingecko.com/coins/images/55849/large/PSOL.png",
|
|
15206
15280
|
tokenProgram: splToken.TOKEN_PROGRAM_ID,
|
|
15207
15281
|
poolState: new web3_js.PublicKey("pSPcvR8GmG9aKDUbn9nbKYjkxt9hxMS7kF1qqKJaPqJ")
|
|
15208
15282
|
});
|
|
@@ -15283,6 +15357,15 @@ const ASSETS_MAINNET = new Map([
|
|
|
15283
15357
|
oracle: new web3_js.PublicKey("9PgHM68FNGDK6nHb29ERDBcFrV6gNMD8LyUqwxbyyeb2")
|
|
15284
15358
|
}
|
|
15285
15359
|
],
|
|
15360
|
+
[
|
|
15361
|
+
// USDG
|
|
15362
|
+
"2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH",
|
|
15363
|
+
{
|
|
15364
|
+
decimals: 6,
|
|
15365
|
+
oracle: new web3_js.PublicKey("6JkZmXGgWnzsyTQaqRARzP64iFYnpMNT4siiuUDUaB8s"),
|
|
15366
|
+
programId: splToken.TOKEN_2022_PROGRAM_ID
|
|
15367
|
+
}
|
|
15368
|
+
],
|
|
15286
15369
|
[
|
|
15287
15370
|
// PYUSD
|
|
15288
15371
|
"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
|
|
@@ -15506,12 +15589,6 @@ const LOOKUP_TABLES = [
|
|
|
15506
15589
|
new web3_js.PublicKey("D9cnvzswDikQDf53k4HpQ3KJ9y1Fv3HGGDFYMXnK5T6c"),
|
|
15507
15590
|
new web3_js.PublicKey("EiWSskK5HXnBTptiS5DH6gpAJRVNQ3cAhTKBGaiaysAb")
|
|
15508
15591
|
];
|
|
15509
|
-
const STATES_LOOKUP_TABLES_MAP = new Map([
|
|
15510
|
-
[
|
|
15511
|
-
"3tfbxaHBDjczQo3eyNJGGG64ChZ9nG4V3Gywa4k59d5a",
|
|
15512
|
-
new web3_js.PublicKey("8HUXT9abWS2z3z92QyDzg51nMcc18LyWFvaEQZJMPixu")
|
|
15513
|
-
]
|
|
15514
|
-
]);
|
|
15515
15592
|
const isBrowser = process.env.ANCHOR_BROWSER || typeof window !== "undefined" && !window.process?.hasOwnProperty("type");
|
|
15516
15593
|
class BaseClient {
|
|
15517
15594
|
get detectedCluster() {
|
|
@@ -15600,17 +15677,16 @@ class BaseClient {
|
|
|
15600
15677
|
if (glamApi) {
|
|
15601
15678
|
const response = await fetch(`${glamApi}/v0/lut/glam/?state=${this.statePda}`);
|
|
15602
15679
|
const data = await response.json();
|
|
15603
|
-
const
|
|
15604
|
-
const
|
|
15605
|
-
|
|
15606
|
-
|
|
15680
|
+
const lookupTables = data.t || {};
|
|
15681
|
+
const lookupTableAccounts = [];
|
|
15682
|
+
for (const [key, lookupTableData] of Object.entries(lookupTables)){
|
|
15683
|
+
const account = new web3_js.AddressLookupTableAccount({
|
|
15684
|
+
key: new web3_js.PublicKey(key),
|
|
15685
|
+
state: web3_js.AddressLookupTableAccount.deserialize(new Uint8Array(Buffer.from(lookupTableData, "base64")))
|
|
15686
|
+
});
|
|
15687
|
+
lookupTableAccounts.push(account);
|
|
15607
15688
|
}
|
|
15608
|
-
|
|
15609
|
-
const tablePubkey = STATES_LOOKUP_TABLES_MAP.get(this.statePda.toBase58());
|
|
15610
|
-
if (tablePubkey) {
|
|
15611
|
-
return await this.fetchAddressLookupTableAccounts([
|
|
15612
|
-
tablePubkey
|
|
15613
|
-
]);
|
|
15689
|
+
return lookupTableAccounts;
|
|
15614
15690
|
}
|
|
15615
15691
|
// Fetch all accounts owned by the ALT program
|
|
15616
15692
|
// This is very likely to hit the RPC error "Request deprioritized due to number of accounts requested. Slow down requests or add filters to narrow down results"
|
|
@@ -15670,6 +15746,24 @@ class BaseClient {
|
|
|
15670
15746
|
]);
|
|
15671
15747
|
lookupTableAccounts.push(...accounts);
|
|
15672
15748
|
}
|
|
15749
|
+
const glamApi = process.env.NEXT_PUBLIC_GLAM_API || process.env.GLAM_API;
|
|
15750
|
+
if (glamApi) {
|
|
15751
|
+
try {
|
|
15752
|
+
const response = await fetch(`${glamApi}/v0/lut/glam/?state=${this.statePda}`);
|
|
15753
|
+
const data = await response.json();
|
|
15754
|
+
const lookupTables = data.t || {};
|
|
15755
|
+
for (const [key, lookupTableData] of Object.entries(lookupTables)){
|
|
15756
|
+
const account = new web3_js.AddressLookupTableAccount({
|
|
15757
|
+
key: new web3_js.PublicKey(key),
|
|
15758
|
+
state: web3_js.AddressLookupTableAccount.deserialize(new Uint8Array(Buffer.from(lookupTableData, "base64")))
|
|
15759
|
+
});
|
|
15760
|
+
lookupTableAccounts.push(account);
|
|
15761
|
+
}
|
|
15762
|
+
} catch (e) {
|
|
15763
|
+
console.error("Failed to fetch lookup tables:", e); // Fail open
|
|
15764
|
+
}
|
|
15765
|
+
}
|
|
15766
|
+
console.log("lookupTableAccounts:", lookupTableAccounts.map((t)=>t.key.toBase58()));
|
|
15673
15767
|
const recentBlockhash = (await this.blockhashWithCache.get()).blockhash;
|
|
15674
15768
|
const { unitsConsumed, error, serializedTx } = await getSimulationResult(this.provider.connection, instructions, signer, lookupTableAccounts);
|
|
15675
15769
|
computeUnitLimit = unitsConsumed;
|
|
@@ -19761,176 +19855,6 @@ const DEFAULT_OBLIGATION_ARGS = {
|
|
|
19761
19855
|
id: 0
|
|
19762
19856
|
};
|
|
19763
19857
|
const EVENT_AUTHORITY$1 = new web3_js.PublicKey("24tHwQyJJ9akVXxnvkekGfAoeUJXXS7mE6kQNioNySsK");
|
|
19764
|
-
function refreshObligation(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19765
|
-
const keys = [
|
|
19766
|
-
{
|
|
19767
|
-
pubkey: accounts.lendingMarket,
|
|
19768
|
-
isSigner: false,
|
|
19769
|
-
isWritable: false
|
|
19770
|
-
},
|
|
19771
|
-
{
|
|
19772
|
-
pubkey: accounts.obligation,
|
|
19773
|
-
isSigner: false,
|
|
19774
|
-
isWritable: true
|
|
19775
|
-
}
|
|
19776
|
-
];
|
|
19777
|
-
accounts.reserves.forEach((reserve)=>{
|
|
19778
|
-
keys.push({
|
|
19779
|
-
pubkey: reserve,
|
|
19780
|
-
isSigner: false,
|
|
19781
|
-
isWritable: false
|
|
19782
|
-
});
|
|
19783
|
-
});
|
|
19784
|
-
const identifier = Buffer.from([
|
|
19785
|
-
33,
|
|
19786
|
-
132,
|
|
19787
|
-
147,
|
|
19788
|
-
228,
|
|
19789
|
-
151,
|
|
19790
|
-
192,
|
|
19791
|
-
72,
|
|
19792
|
-
89
|
|
19793
|
-
]);
|
|
19794
|
-
const data = identifier;
|
|
19795
|
-
const ix = new web3_js.TransactionInstruction({
|
|
19796
|
-
keys,
|
|
19797
|
-
programId,
|
|
19798
|
-
data
|
|
19799
|
-
});
|
|
19800
|
-
return ix;
|
|
19801
|
-
}
|
|
19802
|
-
function refreshReserve(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19803
|
-
const keys = [
|
|
19804
|
-
{
|
|
19805
|
-
pubkey: accounts.reserve,
|
|
19806
|
-
isSigner: false,
|
|
19807
|
-
isWritable: true
|
|
19808
|
-
},
|
|
19809
|
-
{
|
|
19810
|
-
pubkey: accounts.lendingMarket,
|
|
19811
|
-
isSigner: false,
|
|
19812
|
-
isWritable: false
|
|
19813
|
-
},
|
|
19814
|
-
{
|
|
19815
|
-
pubkey: accounts.pythOracle,
|
|
19816
|
-
isSigner: false,
|
|
19817
|
-
isWritable: false
|
|
19818
|
-
},
|
|
19819
|
-
{
|
|
19820
|
-
pubkey: accounts.switchboardPriceOracle,
|
|
19821
|
-
isSigner: false,
|
|
19822
|
-
isWritable: false
|
|
19823
|
-
},
|
|
19824
|
-
{
|
|
19825
|
-
pubkey: accounts.switchboardTwapOracle,
|
|
19826
|
-
isSigner: false,
|
|
19827
|
-
isWritable: false
|
|
19828
|
-
},
|
|
19829
|
-
{
|
|
19830
|
-
pubkey: accounts.scopePrices,
|
|
19831
|
-
isSigner: false,
|
|
19832
|
-
isWritable: false
|
|
19833
|
-
}
|
|
19834
|
-
];
|
|
19835
|
-
const identifier = Buffer.from([
|
|
19836
|
-
2,
|
|
19837
|
-
218,
|
|
19838
|
-
138,
|
|
19839
|
-
235,
|
|
19840
|
-
79,
|
|
19841
|
-
201,
|
|
19842
|
-
25,
|
|
19843
|
-
102
|
|
19844
|
-
]);
|
|
19845
|
-
const data = identifier;
|
|
19846
|
-
const ix = new web3_js.TransactionInstruction({
|
|
19847
|
-
keys,
|
|
19848
|
-
programId,
|
|
19849
|
-
data
|
|
19850
|
-
});
|
|
19851
|
-
return ix;
|
|
19852
|
-
}
|
|
19853
|
-
function refreshObligationFarmsForReserve(args, accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19854
|
-
const keys = [
|
|
19855
|
-
{
|
|
19856
|
-
pubkey: accounts.crank,
|
|
19857
|
-
isSigner: true,
|
|
19858
|
-
isWritable: false
|
|
19859
|
-
},
|
|
19860
|
-
{
|
|
19861
|
-
pubkey: accounts.baseAccounts.obligation,
|
|
19862
|
-
isSigner: false,
|
|
19863
|
-
isWritable: false
|
|
19864
|
-
},
|
|
19865
|
-
{
|
|
19866
|
-
pubkey: accounts.baseAccounts.lendingMarketAuthority,
|
|
19867
|
-
isSigner: false,
|
|
19868
|
-
isWritable: true
|
|
19869
|
-
},
|
|
19870
|
-
{
|
|
19871
|
-
pubkey: accounts.baseAccounts.reserve,
|
|
19872
|
-
isSigner: false,
|
|
19873
|
-
isWritable: false
|
|
19874
|
-
},
|
|
19875
|
-
{
|
|
19876
|
-
pubkey: accounts.baseAccounts.reserveFarmState,
|
|
19877
|
-
isSigner: false,
|
|
19878
|
-
isWritable: true
|
|
19879
|
-
},
|
|
19880
|
-
{
|
|
19881
|
-
pubkey: accounts.baseAccounts.obligationFarmUserState,
|
|
19882
|
-
isSigner: false,
|
|
19883
|
-
isWritable: true
|
|
19884
|
-
},
|
|
19885
|
-
{
|
|
19886
|
-
pubkey: accounts.baseAccounts.lendingMarket,
|
|
19887
|
-
isSigner: false,
|
|
19888
|
-
isWritable: false
|
|
19889
|
-
},
|
|
19890
|
-
{
|
|
19891
|
-
pubkey: accounts.farmsProgram,
|
|
19892
|
-
isSigner: false,
|
|
19893
|
-
isWritable: false
|
|
19894
|
-
},
|
|
19895
|
-
{
|
|
19896
|
-
pubkey: accounts.rent,
|
|
19897
|
-
isSigner: false,
|
|
19898
|
-
isWritable: false
|
|
19899
|
-
},
|
|
19900
|
-
{
|
|
19901
|
-
pubkey: accounts.systemProgram,
|
|
19902
|
-
isSigner: false,
|
|
19903
|
-
isWritable: false
|
|
19904
|
-
}
|
|
19905
|
-
];
|
|
19906
|
-
const identifier = Buffer.from([
|
|
19907
|
-
140,
|
|
19908
|
-
144,
|
|
19909
|
-
253,
|
|
19910
|
-
21,
|
|
19911
|
-
10,
|
|
19912
|
-
74,
|
|
19913
|
-
248,
|
|
19914
|
-
3
|
|
19915
|
-
]);
|
|
19916
|
-
const buffer = Buffer.alloc(1000);
|
|
19917
|
-
const layout = borsh__namespace.struct([
|
|
19918
|
-
borsh__namespace.u8("mode")
|
|
19919
|
-
]);
|
|
19920
|
-
const len = layout.encode({
|
|
19921
|
-
mode: args.mode
|
|
19922
|
-
}, buffer);
|
|
19923
|
-
const data = Buffer.concat([
|
|
19924
|
-
identifier,
|
|
19925
|
-
buffer
|
|
19926
|
-
]).subarray(0, 8 + len);
|
|
19927
|
-
const ix = new web3_js.TransactionInstruction({
|
|
19928
|
-
keys,
|
|
19929
|
-
programId,
|
|
19930
|
-
data
|
|
19931
|
-
});
|
|
19932
|
-
return ix;
|
|
19933
|
-
}
|
|
19934
19858
|
class KaminoLendingClient {
|
|
19935
19859
|
/**
|
|
19936
19860
|
* Initializes Kamino user metadata
|
|
@@ -20022,8 +19946,228 @@ class KaminoLendingClient {
|
|
|
20022
19946
|
], KAMINO_FARM_PROGRAM);
|
|
20023
19947
|
return obligationFarm;
|
|
20024
19948
|
}
|
|
19949
|
+
refreshObligationIx(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19950
|
+
const keys = [
|
|
19951
|
+
{
|
|
19952
|
+
pubkey: accounts.lendingMarket,
|
|
19953
|
+
isSigner: false,
|
|
19954
|
+
isWritable: false
|
|
19955
|
+
},
|
|
19956
|
+
{
|
|
19957
|
+
pubkey: accounts.obligation,
|
|
19958
|
+
isSigner: false,
|
|
19959
|
+
isWritable: true
|
|
19960
|
+
}
|
|
19961
|
+
];
|
|
19962
|
+
accounts.reserves.forEach((reserve)=>{
|
|
19963
|
+
keys.push({
|
|
19964
|
+
pubkey: reserve,
|
|
19965
|
+
isSigner: false,
|
|
19966
|
+
isWritable: false
|
|
19967
|
+
});
|
|
19968
|
+
});
|
|
19969
|
+
const identifier = Buffer.from([
|
|
19970
|
+
33,
|
|
19971
|
+
132,
|
|
19972
|
+
147,
|
|
19973
|
+
228,
|
|
19974
|
+
151,
|
|
19975
|
+
192,
|
|
19976
|
+
72,
|
|
19977
|
+
89
|
|
19978
|
+
]);
|
|
19979
|
+
const data = identifier;
|
|
19980
|
+
return new web3_js.TransactionInstruction({
|
|
19981
|
+
keys,
|
|
19982
|
+
programId,
|
|
19983
|
+
data
|
|
19984
|
+
});
|
|
19985
|
+
}
|
|
19986
|
+
refreshReserveIx(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19987
|
+
const keys = [
|
|
19988
|
+
{
|
|
19989
|
+
pubkey: accounts.reserve,
|
|
19990
|
+
isSigner: false,
|
|
19991
|
+
isWritable: true
|
|
19992
|
+
},
|
|
19993
|
+
{
|
|
19994
|
+
pubkey: accounts.lendingMarket,
|
|
19995
|
+
isSigner: false,
|
|
19996
|
+
isWritable: false
|
|
19997
|
+
},
|
|
19998
|
+
{
|
|
19999
|
+
pubkey: accounts.pythOracle,
|
|
20000
|
+
isSigner: false,
|
|
20001
|
+
isWritable: false
|
|
20002
|
+
},
|
|
20003
|
+
{
|
|
20004
|
+
pubkey: accounts.switchboardPriceOracle,
|
|
20005
|
+
isSigner: false,
|
|
20006
|
+
isWritable: false
|
|
20007
|
+
},
|
|
20008
|
+
{
|
|
20009
|
+
pubkey: accounts.switchboardTwapOracle,
|
|
20010
|
+
isSigner: false,
|
|
20011
|
+
isWritable: false
|
|
20012
|
+
},
|
|
20013
|
+
{
|
|
20014
|
+
pubkey: accounts.scopePrices,
|
|
20015
|
+
isSigner: false,
|
|
20016
|
+
isWritable: false
|
|
20017
|
+
}
|
|
20018
|
+
];
|
|
20019
|
+
const identifier = Buffer.from([
|
|
20020
|
+
2,
|
|
20021
|
+
218,
|
|
20022
|
+
138,
|
|
20023
|
+
235,
|
|
20024
|
+
79,
|
|
20025
|
+
201,
|
|
20026
|
+
25,
|
|
20027
|
+
102
|
|
20028
|
+
]);
|
|
20029
|
+
const data = identifier;
|
|
20030
|
+
return new web3_js.TransactionInstruction({
|
|
20031
|
+
keys,
|
|
20032
|
+
programId,
|
|
20033
|
+
data
|
|
20034
|
+
});
|
|
20035
|
+
}
|
|
20036
|
+
refreshObligationFarmsForReserveIx(args, accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
20037
|
+
const keys = [
|
|
20038
|
+
{
|
|
20039
|
+
pubkey: accounts.crank,
|
|
20040
|
+
isSigner: true,
|
|
20041
|
+
isWritable: false
|
|
20042
|
+
},
|
|
20043
|
+
{
|
|
20044
|
+
pubkey: accounts.baseAccounts.obligation,
|
|
20045
|
+
isSigner: false,
|
|
20046
|
+
isWritable: false
|
|
20047
|
+
},
|
|
20048
|
+
{
|
|
20049
|
+
pubkey: accounts.baseAccounts.lendingMarketAuthority,
|
|
20050
|
+
isSigner: false,
|
|
20051
|
+
isWritable: true
|
|
20052
|
+
},
|
|
20053
|
+
{
|
|
20054
|
+
pubkey: accounts.baseAccounts.reserve,
|
|
20055
|
+
isSigner: false,
|
|
20056
|
+
isWritable: false
|
|
20057
|
+
},
|
|
20058
|
+
{
|
|
20059
|
+
pubkey: accounts.baseAccounts.reserveFarmState,
|
|
20060
|
+
isSigner: false,
|
|
20061
|
+
isWritable: true
|
|
20062
|
+
},
|
|
20063
|
+
{
|
|
20064
|
+
pubkey: accounts.baseAccounts.obligationFarmUserState,
|
|
20065
|
+
isSigner: false,
|
|
20066
|
+
isWritable: true
|
|
20067
|
+
},
|
|
20068
|
+
{
|
|
20069
|
+
pubkey: accounts.baseAccounts.lendingMarket,
|
|
20070
|
+
isSigner: false,
|
|
20071
|
+
isWritable: false
|
|
20072
|
+
},
|
|
20073
|
+
{
|
|
20074
|
+
pubkey: accounts.farmsProgram,
|
|
20075
|
+
isSigner: false,
|
|
20076
|
+
isWritable: false
|
|
20077
|
+
},
|
|
20078
|
+
{
|
|
20079
|
+
pubkey: accounts.rent,
|
|
20080
|
+
isSigner: false,
|
|
20081
|
+
isWritable: false
|
|
20082
|
+
},
|
|
20083
|
+
{
|
|
20084
|
+
pubkey: accounts.systemProgram,
|
|
20085
|
+
isSigner: false,
|
|
20086
|
+
isWritable: false
|
|
20087
|
+
}
|
|
20088
|
+
];
|
|
20089
|
+
const identifier = Buffer.from([
|
|
20090
|
+
140,
|
|
20091
|
+
144,
|
|
20092
|
+
253,
|
|
20093
|
+
21,
|
|
20094
|
+
10,
|
|
20095
|
+
74,
|
|
20096
|
+
248,
|
|
20097
|
+
3
|
|
20098
|
+
]);
|
|
20099
|
+
const buffer = Buffer.alloc(1000);
|
|
20100
|
+
const layout = borsh__namespace.struct([
|
|
20101
|
+
borsh__namespace.u8("mode")
|
|
20102
|
+
]);
|
|
20103
|
+
const len = layout.encode({
|
|
20104
|
+
mode: args.mode
|
|
20105
|
+
}, buffer);
|
|
20106
|
+
const data = Buffer.concat([
|
|
20107
|
+
identifier,
|
|
20108
|
+
buffer
|
|
20109
|
+
]).subarray(0, 8 + len);
|
|
20110
|
+
return new web3_js.TransactionInstruction({
|
|
20111
|
+
keys,
|
|
20112
|
+
programId,
|
|
20113
|
+
data
|
|
20114
|
+
});
|
|
20115
|
+
}
|
|
20116
|
+
refreshReservesBatchIx(reserves, lendingMarkets, skipPriceUpdates, programId = KAMINO_LENDING_PROGRAM) {
|
|
20117
|
+
const keys = [];
|
|
20118
|
+
for(let i = 0; i < reserves.length; i++){
|
|
20119
|
+
keys.push({
|
|
20120
|
+
pubkey: reserves[i],
|
|
20121
|
+
isSigner: false,
|
|
20122
|
+
isWritable: false
|
|
20123
|
+
});
|
|
20124
|
+
keys.push({
|
|
20125
|
+
pubkey: lendingMarkets[i],
|
|
20126
|
+
isSigner: false,
|
|
20127
|
+
isWritable: true
|
|
20128
|
+
});
|
|
20129
|
+
if (!skipPriceUpdates) {
|
|
20130
|
+
[
|
|
20131
|
+
KAMINO_LENDING_PROGRAM,
|
|
20132
|
+
KAMINO_LENDING_PROGRAM,
|
|
20133
|
+
KAMINO_LENDING_PROGRAM,
|
|
20134
|
+
KAMINO_SCOPE_PRICES
|
|
20135
|
+
].forEach((p)=>keys.push({
|
|
20136
|
+
pubkey: p,
|
|
20137
|
+
isSigner: false,
|
|
20138
|
+
isWritable: false
|
|
20139
|
+
}));
|
|
20140
|
+
}
|
|
20141
|
+
}
|
|
20142
|
+
const identifier = Buffer.from([
|
|
20143
|
+
144,
|
|
20144
|
+
110,
|
|
20145
|
+
26,
|
|
20146
|
+
103,
|
|
20147
|
+
162,
|
|
20148
|
+
204,
|
|
20149
|
+
252,
|
|
20150
|
+
147
|
|
20151
|
+
]);
|
|
20152
|
+
const buffer = Buffer.alloc(1000);
|
|
20153
|
+
const layout = borsh__namespace.struct([
|
|
20154
|
+
borsh__namespace.bool("skipPriceUpdates")
|
|
20155
|
+
]);
|
|
20156
|
+
const len = layout.encode({
|
|
20157
|
+
skipPriceUpdates
|
|
20158
|
+
}, buffer);
|
|
20159
|
+
const data = Buffer.concat([
|
|
20160
|
+
identifier,
|
|
20161
|
+
buffer
|
|
20162
|
+
]).subarray(0, 8 + len);
|
|
20163
|
+
return new web3_js.TransactionInstruction({
|
|
20164
|
+
keys,
|
|
20165
|
+
programId,
|
|
20166
|
+
data
|
|
20167
|
+
});
|
|
20168
|
+
}
|
|
20025
20169
|
refreshReserveIxs(lendingMarket, reserves) {
|
|
20026
|
-
return reserves.map((reserve)=>
|
|
20170
|
+
return reserves.map((reserve)=>this.refreshReserveIx({
|
|
20027
20171
|
reserve,
|
|
20028
20172
|
lendingMarket,
|
|
20029
20173
|
pythOracle: KAMINO_LENDING_PROGRAM,
|
|
@@ -20039,7 +20183,7 @@ class KaminoLendingClient {
|
|
|
20039
20183
|
farmCollateral
|
|
20040
20184
|
].filter((farm)=>!!farm).map((farm)=>{
|
|
20041
20185
|
const obligationFarmUserState = this.getObligationFarmState(obligation, farm);
|
|
20042
|
-
return
|
|
20186
|
+
return this.refreshObligationFarmsForReserveIx({
|
|
20043
20187
|
mode: 0
|
|
20044
20188
|
}, {
|
|
20045
20189
|
crank: this.base.getSigner(),
|
|
@@ -20065,7 +20209,7 @@ class KaminoLendingClient {
|
|
|
20065
20209
|
farmDebt
|
|
20066
20210
|
].filter((farm)=>!!farm).map((farm)=>{
|
|
20067
20211
|
const obligationFarmUserState = this.getObligationFarmState(obligation, farm);
|
|
20068
|
-
return
|
|
20212
|
+
return this.refreshObligationFarmsForReserveIx({
|
|
20069
20213
|
mode: 0
|
|
20070
20214
|
}, {
|
|
20071
20215
|
crank: this.base.getSigner(),
|
|
@@ -20351,7 +20495,7 @@ class KaminoLendingClient {
|
|
|
20351
20495
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20352
20496
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20353
20497
|
// Refresh obligation with reserves in use
|
|
20354
|
-
preInstructions.push(
|
|
20498
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20355
20499
|
lendingMarket: market,
|
|
20356
20500
|
obligation,
|
|
20357
20501
|
reserves: reservesInUse
|
|
@@ -20441,7 +20585,7 @@ class KaminoLendingClient {
|
|
|
20441
20585
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20442
20586
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20443
20587
|
// Refresh obligation with reserves in use
|
|
20444
|
-
preInstructions.push(
|
|
20588
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20445
20589
|
lendingMarket: market,
|
|
20446
20590
|
obligation,
|
|
20447
20591
|
reserves: reservesInUse
|
|
@@ -20525,7 +20669,7 @@ class KaminoLendingClient {
|
|
|
20525
20669
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20526
20670
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20527
20671
|
// Refresh obligation with reserves in use
|
|
20528
|
-
preInstructions.push(
|
|
20672
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20529
20673
|
lendingMarket: market,
|
|
20530
20674
|
obligation,
|
|
20531
20675
|
reserves: reservesInUse
|
|
@@ -20607,7 +20751,7 @@ class KaminoLendingClient {
|
|
|
20607
20751
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20608
20752
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20609
20753
|
// Refresh obligation with reserves in use
|
|
20610
|
-
preInstructions.push(
|
|
20754
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20611
20755
|
lendingMarket: market,
|
|
20612
20756
|
obligation,
|
|
20613
20757
|
reserves: reservesInUse
|
|
@@ -20810,7 +20954,7 @@ class KaminoVaultsClient {
|
|
|
20810
20954
|
if (this.vaultStates.size === 0) {
|
|
20811
20955
|
await this.findAndParseKaminoVaults();
|
|
20812
20956
|
}
|
|
20813
|
-
return mints.map((mint)=>this.shareMintToVaultPdaMap.get(mint.toBase58()));
|
|
20957
|
+
return mints.map((mint)=>this.shareMintToVaultPdaMap.get(mint.toBase58())).filter((p)=>!!p);
|
|
20814
20958
|
}
|
|
20815
20959
|
async fetchAndParseVaultState(vault) {
|
|
20816
20960
|
const vaultAccount = await this.base.provider.connection.getAccountInfo(vault);
|
|
@@ -21365,6 +21509,21 @@ class InvestClient {
|
|
|
21365
21509
|
}
|
|
21366
21510
|
|
|
21367
21511
|
class PriceClient {
|
|
21512
|
+
get stateModel() {
|
|
21513
|
+
if (!this._stateModel) {
|
|
21514
|
+
throw new Error("State model not cached");
|
|
21515
|
+
}
|
|
21516
|
+
return this._stateModel;
|
|
21517
|
+
}
|
|
21518
|
+
set stateModel(stateModel) {
|
|
21519
|
+
this._stateModel = stateModel;
|
|
21520
|
+
}
|
|
21521
|
+
get lookupTables() {
|
|
21522
|
+
return Array.from(this._lookupTables).map((k)=>new web3_js.PublicKey(k));
|
|
21523
|
+
}
|
|
21524
|
+
get kaminoVaults() {
|
|
21525
|
+
return Array.from(this._kaminoVaults).map((k)=>new web3_js.PublicKey(k));
|
|
21526
|
+
}
|
|
21368
21527
|
/**
|
|
21369
21528
|
* !! This is a convenience method that calculates the AUM of the vault based on priced assets.
|
|
21370
21529
|
* !! It doesn't reflect the actual AUM of the vault.
|
|
@@ -21408,7 +21567,7 @@ class PriceClient {
|
|
|
21408
21567
|
async priceKaminoVaultSharesIx(priceDenom) {
|
|
21409
21568
|
const allKvaultStates = await this.kvaults.findAndParseKaminoVaults();
|
|
21410
21569
|
const allKvaultMints = allKvaultStates.map((kvault)=>kvault.sharesMint);
|
|
21411
|
-
// All share token accounts GLAM vault could possibly hold
|
|
21570
|
+
// All kvaut share token accounts GLAM vault could possibly hold
|
|
21412
21571
|
const possibleShareAtas = allKvaultMints.map((mint)=>this.base.getVaultAta(mint));
|
|
21413
21572
|
const possibleShareAtaAccountsInfo = await this.base.provider.connection.getMultipleAccountsInfo(possibleShareAtas);
|
|
21414
21573
|
const shareAtas = [];
|
|
@@ -21416,16 +21575,24 @@ class PriceClient {
|
|
|
21416
21575
|
const kvaultStates = [];
|
|
21417
21576
|
const oracles = []; // oracle of kvault deposit token
|
|
21418
21577
|
possibleShareAtaAccountsInfo.forEach((info, i)=>{
|
|
21419
|
-
|
|
21578
|
+
// share ata must exist and it must be tracked by glam state
|
|
21579
|
+
// otherwise skip it for pricing
|
|
21580
|
+
if (info !== null && this.stateModel.externalVaultAccounts?.find((a)=>a.equals(possibleShareAtas[i]))) {
|
|
21420
21581
|
shareAtas.push(possibleShareAtas[i]);
|
|
21421
21582
|
shareMints.push(allKvaultMints[i]);
|
|
21422
21583
|
kvaultStates.push(allKvaultStates[i]);
|
|
21423
|
-
|
|
21584
|
+
// get oracle and lookup table from kvault state
|
|
21585
|
+
const { tokenMint, vaultLookupTable } = allKvaultStates[i];
|
|
21424
21586
|
const assetMeta = ASSETS_MAINNET.get(tokenMint.toBase58());
|
|
21425
|
-
|
|
21587
|
+
if (!assetMeta || !assetMeta.oracle) {
|
|
21588
|
+
throw new Error(`Oracle unavailable for asset ${tokenMint}`);
|
|
21589
|
+
}
|
|
21590
|
+
oracles.push(assetMeta.oracle);
|
|
21591
|
+
this._lookupTables.add(vaultLookupTable.toBase58()); // cache lookup table
|
|
21426
21592
|
}
|
|
21427
21593
|
});
|
|
21428
21594
|
const kvaultPdas = await this.kvaults.getVaultPdasByShareMints(shareMints);
|
|
21595
|
+
kvaultPdas.forEach((p)=>this._kaminoVaults.add(p.toBase58())); // cache kvault keys
|
|
21429
21596
|
const remainingAccounts = [];
|
|
21430
21597
|
// first 3N remaining accounts are N tuples of (kvault_shares_ata, kvault_shares_mint, kvault_state)
|
|
21431
21598
|
for(let i = 0; i < shareAtas.length; i++){
|
|
@@ -21446,7 +21613,8 @@ class PriceClient {
|
|
|
21446
21613
|
return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(web3_js.PublicKey.default)), true);
|
|
21447
21614
|
}))).flat();
|
|
21448
21615
|
const processed = new Set();
|
|
21449
|
-
const
|
|
21616
|
+
const reserves = [];
|
|
21617
|
+
const markets = [];
|
|
21450
21618
|
const chunkSize = 2;
|
|
21451
21619
|
for(let i = 0; i < marketsAndReserves.length; i += chunkSize){
|
|
21452
21620
|
const chunk = marketsAndReserves.slice(i, i + chunkSize);
|
|
@@ -21454,15 +21622,17 @@ class PriceClient {
|
|
|
21454
21622
|
const reserve = chunk[1].pubkey;
|
|
21455
21623
|
// reserve should always be added to remaining accounts
|
|
21456
21624
|
remainingAccounts.push(chunk[1]);
|
|
21457
|
-
//
|
|
21625
|
+
// record reserves and markets for refreshReservesBatchIx
|
|
21458
21626
|
if (!processed.has(reserve.toBase58())) {
|
|
21459
|
-
|
|
21460
|
-
|
|
21461
|
-
]);
|
|
21462
|
-
preInstructions.push(...ix);
|
|
21627
|
+
reserves.push(reserve);
|
|
21628
|
+
markets.push(market);
|
|
21463
21629
|
processed.add(reserve.toBase58());
|
|
21464
21630
|
}
|
|
21465
21631
|
}
|
|
21632
|
+
const refreshReservesIx = this.klend.refreshReservesBatchIx(reserves, markets, false);
|
|
21633
|
+
const preInstructions = [
|
|
21634
|
+
refreshReservesIx
|
|
21635
|
+
];
|
|
21466
21636
|
const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom, shareAtas.length).accounts({
|
|
21467
21637
|
glamState: this.base.statePda,
|
|
21468
21638
|
solOracle: SOL_ORACLE
|
|
@@ -21599,18 +21769,20 @@ class PriceClient {
|
|
|
21599
21769
|
}
|
|
21600
21770
|
// If there are no external assets, we don't need to price DeFi positions
|
|
21601
21771
|
const stateModel = await this.base.fetchStateModel();
|
|
21602
|
-
|
|
21772
|
+
this.stateModel = stateModel;
|
|
21773
|
+
if ((this.stateModel.externalVaultAccounts || []).length === 0) {
|
|
21603
21774
|
return [
|
|
21604
21775
|
priceVaultIx
|
|
21605
21776
|
];
|
|
21606
21777
|
}
|
|
21607
21778
|
const integrations = (stateModel.integrations || []).map((i)=>Object.keys(i)[0]);
|
|
21608
21779
|
const integrationsToPricingFns = {
|
|
21609
|
-
|
|
21610
|
-
|
|
21611
|
-
|
|
21612
|
-
|
|
21613
|
-
driftVaults: this.priceDriftVaultDepositorsIx.bind(this)
|
|
21780
|
+
drift: this.priceDriftUsersIx.bind(this),
|
|
21781
|
+
kaminoLending: this.priceKaminoObligationsIx.bind(this),
|
|
21782
|
+
nativeStaking: this.priceStakesIx.bind(this),
|
|
21783
|
+
meteoraDlmm: this.priceMeteoraPositionsIx.bind(this),
|
|
21784
|
+
driftVaults: this.priceDriftVaultDepositorsIx.bind(this),
|
|
21785
|
+
kaminoVaults: this.priceKaminoVaultSharesIx.bind(this)
|
|
21614
21786
|
};
|
|
21615
21787
|
const pricingFns = integrations.map((integration)=>integrationsToPricingFns[integration]).filter(Boolean);
|
|
21616
21788
|
const pricingIxs = [
|
|
@@ -21742,6 +21914,9 @@ class PriceClient {
|
|
|
21742
21914
|
this.kvaults = kvaults;
|
|
21743
21915
|
this.drift = drift;
|
|
21744
21916
|
this.dvaults = dvaults;
|
|
21917
|
+
this._stateModel = null;
|
|
21918
|
+
this._lookupTables = new Set();
|
|
21919
|
+
this._kaminoVaults = new Set();
|
|
21745
21920
|
}
|
|
21746
21921
|
}
|
|
21747
21922
|
|
|
@@ -22163,8 +22338,10 @@ exports.getOpenfundsPda = getOpenfundsPda;
|
|
|
22163
22338
|
exports.getOrderParams = getOrderParams;
|
|
22164
22339
|
exports.getPriorityFeeEstimate = getPriorityFeeEstimate;
|
|
22165
22340
|
exports.getSimulationResult = getSimulationResult;
|
|
22341
|
+
exports.getSolAndTokenBalances = getSolAndTokenBalances;
|
|
22166
22342
|
exports.getStakeAccountsWithStates = getStakeAccountsWithStates;
|
|
22167
22343
|
exports.getStatePda = getStatePda;
|
|
22344
|
+
exports.getTokenAccountsByOwner = getTokenAccountsByOwner;
|
|
22168
22345
|
exports.getTriggerLimitOrderParams = getTriggerLimitOrderParams;
|
|
22169
22346
|
exports.getTriggerMarketOrderParams = getTriggerMarketOrderParams;
|
|
22170
22347
|
exports.getVariant = getVariant;
|