@glamsystems/glam-sdk 0.1.29 → 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 +544 -333
- package/index.esm.js +545 -336
- package/package.json +1 -1
- package/src/client/base.d.ts +1 -1
- package/src/client/kamino.d.ts +34 -0
- package/src/client/price.d.ts +21 -13
- 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 +27 -24
- package/target/types/glam_protocol.d.ts +26 -23
- package/target/types/glam_protocol.ts +27 -24
package/index.cjs.js
CHANGED
|
@@ -34,7 +34,7 @@ var borsh__namespace = /*#__PURE__*/_interopNamespaceDefault(borsh);
|
|
|
34
34
|
var address = "GLAMbTqav9N9witRjswJ8enwp9vv5G8bsSJ2kPJ4rcyc";
|
|
35
35
|
var metadata = {
|
|
36
36
|
name: "glam_protocol",
|
|
37
|
-
version: "0.4.
|
|
37
|
+
version: "0.4.35",
|
|
38
38
|
spec: "0.1.0",
|
|
39
39
|
description: "Glam Protocol"
|
|
40
40
|
};
|
|
@@ -6900,7 +6900,9 @@ var instructions = [
|
|
|
6900
6900
|
docs: [
|
|
6901
6901
|
"Extra accounts for pricing N vault depositors:",
|
|
6902
6902
|
"- (vault_depositor, drift_vault, drift_user) x N",
|
|
6903
|
-
"-
|
|
6903
|
+
"- spot_market used by drift users of vaults (no specific order)",
|
|
6904
|
+
"- perp markets used by drift users of vaults (no specific order)",
|
|
6905
|
+
"- oracles of spot markets and perp markets (no specific order)"
|
|
6904
6906
|
],
|
|
6905
6907
|
discriminator: [
|
|
6906
6908
|
234,
|
|
@@ -7021,6 +7023,14 @@ var instructions = [
|
|
|
7021
7023
|
{
|
|
7022
7024
|
name: "num_vault_depositors",
|
|
7023
7025
|
type: "u8"
|
|
7026
|
+
},
|
|
7027
|
+
{
|
|
7028
|
+
name: "num_spot_markets",
|
|
7029
|
+
type: "u8"
|
|
7030
|
+
},
|
|
7031
|
+
{
|
|
7032
|
+
name: "num_perp_markets",
|
|
7033
|
+
type: "u8"
|
|
7024
7034
|
}
|
|
7025
7035
|
]
|
|
7026
7036
|
},
|
|
@@ -7167,9 +7177,14 @@ var instructions = [
|
|
|
7167
7177
|
{
|
|
7168
7178
|
name: "price_kamino_vault_shares",
|
|
7169
7179
|
docs: [
|
|
7180
|
+
"Price Kamino vault shares.",
|
|
7181
|
+
"- `num_vaults` Number of kamino vaults to price.",
|
|
7182
|
+
"",
|
|
7170
7183
|
"Extra accounts for pricing N kamino vault shares:",
|
|
7171
7184
|
"- (kvault_share_ata, kvault_share_mint, kvault_state, kvault_deposit_token_oracle) x N",
|
|
7172
|
-
"-
|
|
7185
|
+
"- reserve x M",
|
|
7186
|
+
"- M = number of reserves used by all kvaults' allocations",
|
|
7187
|
+
"- reserve pubkeys must follow the same order of reserves used by each allocation"
|
|
7173
7188
|
],
|
|
7174
7189
|
discriminator: [
|
|
7175
7190
|
112,
|
|
@@ -7212,10 +7227,6 @@ var instructions = [
|
|
|
7212
7227
|
writable: true,
|
|
7213
7228
|
signer: true
|
|
7214
7229
|
},
|
|
7215
|
-
{
|
|
7216
|
-
name: "kamino_lending_program",
|
|
7217
|
-
address: "KLend2g3cP87fffoy8q1mQqGKjrxjC8boSyAYavgmjD"
|
|
7218
|
-
},
|
|
7219
7230
|
{
|
|
7220
7231
|
name: "sol_oracle"
|
|
7221
7232
|
},
|
|
@@ -7280,22 +7291,6 @@ var instructions = [
|
|
|
7280
7291
|
]
|
|
7281
7292
|
}
|
|
7282
7293
|
}
|
|
7283
|
-
},
|
|
7284
|
-
{
|
|
7285
|
-
name: "pyth_oracle",
|
|
7286
|
-
optional: true
|
|
7287
|
-
},
|
|
7288
|
-
{
|
|
7289
|
-
name: "switchboard_price_oracle",
|
|
7290
|
-
optional: true
|
|
7291
|
-
},
|
|
7292
|
-
{
|
|
7293
|
-
name: "switchboard_twap_oracle",
|
|
7294
|
-
optional: true
|
|
7295
|
-
},
|
|
7296
|
-
{
|
|
7297
|
-
name: "scope_prices",
|
|
7298
|
-
optional: true
|
|
7299
7294
|
}
|
|
7300
7295
|
],
|
|
7301
7296
|
args: [
|
|
@@ -9608,6 +9603,10 @@ var instructions = [
|
|
|
9608
9603
|
{
|
|
9609
9604
|
name: "stake_history",
|
|
9610
9605
|
address: "SysvarStakeHistory1111111111111111111111111"
|
|
9606
|
+
},
|
|
9607
|
+
{
|
|
9608
|
+
name: "system_program",
|
|
9609
|
+
address: "11111111111111111111111111111111"
|
|
9611
9610
|
}
|
|
9612
9611
|
],
|
|
9613
9612
|
args: [
|
|
@@ -10026,7 +10025,8 @@ var instructions = [
|
|
|
10026
10025
|
],
|
|
10027
10026
|
accounts: [
|
|
10028
10027
|
{
|
|
10029
|
-
name: "glam_state"
|
|
10028
|
+
name: "glam_state",
|
|
10029
|
+
writable: true
|
|
10030
10030
|
},
|
|
10031
10031
|
{
|
|
10032
10032
|
name: "glam_vault",
|
|
@@ -13573,6 +13573,9 @@ var types = [
|
|
|
13573
13573
|
},
|
|
13574
13574
|
{
|
|
13575
13575
|
name: "Fulfill"
|
|
13576
|
+
},
|
|
13577
|
+
{
|
|
13578
|
+
name: "ClaimFees"
|
|
13576
13579
|
}
|
|
13577
13580
|
]
|
|
13578
13581
|
}
|
|
@@ -14950,6 +14953,15 @@ class PriceDenom {
|
|
|
14950
14953
|
}
|
|
14951
14954
|
return PriceDenom.ASSET;
|
|
14952
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
|
+
}
|
|
14953
14965
|
}
|
|
14954
14966
|
PriceDenom.SOL = {
|
|
14955
14967
|
sol: {}
|
|
@@ -14985,6 +14997,67 @@ var ClusterNetwork = /*#__PURE__*/ function(ClusterNetwork) {
|
|
|
14985
14997
|
return ClusterNetwork;
|
|
14986
14998
|
}({});
|
|
14987
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
|
+
}
|
|
14988
15061
|
const findStakeAccounts = async (connection, withdrawAuthority)=>{
|
|
14989
15062
|
// stake authority offset: 12
|
|
14990
15063
|
// withdraw authority offset: 44
|
|
@@ -15203,7 +15276,7 @@ STAKE_POOLS.push({
|
|
|
15203
15276
|
symbol: "PSOL",
|
|
15204
15277
|
mint: "pSo1f9nQXWgXibFtKf7NWYxb5enAM4qfP6UJSiXRQfL",
|
|
15205
15278
|
decimals: 9,
|
|
15206
|
-
logoURI: "https://
|
|
15279
|
+
logoURI: "https://coin-images.coingecko.com/coins/images/55849/large/PSOL.png",
|
|
15207
15280
|
tokenProgram: splToken.TOKEN_PROGRAM_ID,
|
|
15208
15281
|
poolState: new web3_js.PublicKey("pSPcvR8GmG9aKDUbn9nbKYjkxt9hxMS7kF1qqKJaPqJ")
|
|
15209
15282
|
});
|
|
@@ -15284,6 +15357,15 @@ const ASSETS_MAINNET = new Map([
|
|
|
15284
15357
|
oracle: new web3_js.PublicKey("9PgHM68FNGDK6nHb29ERDBcFrV6gNMD8LyUqwxbyyeb2")
|
|
15285
15358
|
}
|
|
15286
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
|
+
],
|
|
15287
15369
|
[
|
|
15288
15370
|
// PYUSD
|
|
15289
15371
|
"2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo",
|
|
@@ -15507,12 +15589,6 @@ const LOOKUP_TABLES = [
|
|
|
15507
15589
|
new web3_js.PublicKey("D9cnvzswDikQDf53k4HpQ3KJ9y1Fv3HGGDFYMXnK5T6c"),
|
|
15508
15590
|
new web3_js.PublicKey("EiWSskK5HXnBTptiS5DH6gpAJRVNQ3cAhTKBGaiaysAb")
|
|
15509
15591
|
];
|
|
15510
|
-
const STATES_LOOKUP_TABLES_MAP = new Map([
|
|
15511
|
-
[
|
|
15512
|
-
"3tfbxaHBDjczQo3eyNJGGG64ChZ9nG4V3Gywa4k59d5a",
|
|
15513
|
-
new web3_js.PublicKey("8HUXT9abWS2z3z92QyDzg51nMcc18LyWFvaEQZJMPixu")
|
|
15514
|
-
]
|
|
15515
|
-
]);
|
|
15516
15592
|
const isBrowser = process.env.ANCHOR_BROWSER || typeof window !== "undefined" && !window.process?.hasOwnProperty("type");
|
|
15517
15593
|
class BaseClient {
|
|
15518
15594
|
get detectedCluster() {
|
|
@@ -15601,17 +15677,16 @@ class BaseClient {
|
|
|
15601
15677
|
if (glamApi) {
|
|
15602
15678
|
const response = await fetch(`${glamApi}/v0/lut/glam/?state=${this.statePda}`);
|
|
15603
15679
|
const data = await response.json();
|
|
15604
|
-
const
|
|
15605
|
-
const
|
|
15606
|
-
|
|
15607
|
-
|
|
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);
|
|
15608
15688
|
}
|
|
15609
|
-
|
|
15610
|
-
const tablePubkey = STATES_LOOKUP_TABLES_MAP.get(this.statePda.toBase58());
|
|
15611
|
-
if (tablePubkey) {
|
|
15612
|
-
return await this.fetchAdressLookupTableAccounts([
|
|
15613
|
-
tablePubkey
|
|
15614
|
-
]);
|
|
15689
|
+
return lookupTableAccounts;
|
|
15615
15690
|
}
|
|
15616
15691
|
// Fetch all accounts owned by the ALT program
|
|
15617
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"
|
|
@@ -15660,17 +15735,35 @@ class BaseClient {
|
|
|
15660
15735
|
}
|
|
15661
15736
|
const lookupTableAccounts = [];
|
|
15662
15737
|
if (lookupTables.every((t)=>t instanceof web3_js.AddressLookupTableAccount)) {
|
|
15663
|
-
const accounts = await this.
|
|
15738
|
+
const accounts = await this.fetchAddressLookupTableAccounts([
|
|
15664
15739
|
...LOOKUP_TABLES
|
|
15665
15740
|
]);
|
|
15666
15741
|
lookupTableAccounts.push(...lookupTables, ...accounts);
|
|
15667
15742
|
} else {
|
|
15668
|
-
const accounts = await this.
|
|
15743
|
+
const accounts = await this.fetchAddressLookupTableAccounts([
|
|
15669
15744
|
...lookupTables,
|
|
15670
15745
|
...LOOKUP_TABLES
|
|
15671
15746
|
]);
|
|
15672
15747
|
lookupTableAccounts.push(...accounts);
|
|
15673
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()));
|
|
15674
15767
|
const recentBlockhash = (await this.blockhashWithCache.get()).blockhash;
|
|
15675
15768
|
const { unitsConsumed, error, serializedTx } = await getSimulationResult(this.provider.connection, instructions, signer, lookupTableAccounts);
|
|
15676
15769
|
computeUnitLimit = unitsConsumed;
|
|
@@ -15749,7 +15842,7 @@ class BaseClient {
|
|
|
15749
15842
|
*
|
|
15750
15843
|
* @param pubkeys Array of lookup table public keys.
|
|
15751
15844
|
* @returns
|
|
15752
|
-
*/ async
|
|
15845
|
+
*/ async fetchAddressLookupTableAccounts(pubkeys) {
|
|
15753
15846
|
if (!pubkeys) {
|
|
15754
15847
|
throw new Error("addressLookupTableAddresses is undefined");
|
|
15755
15848
|
}
|
|
@@ -19762,176 +19855,6 @@ const DEFAULT_OBLIGATION_ARGS = {
|
|
|
19762
19855
|
id: 0
|
|
19763
19856
|
};
|
|
19764
19857
|
const EVENT_AUTHORITY$1 = new web3_js.PublicKey("24tHwQyJJ9akVXxnvkekGfAoeUJXXS7mE6kQNioNySsK");
|
|
19765
|
-
function refreshObligation(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19766
|
-
const keys = [
|
|
19767
|
-
{
|
|
19768
|
-
pubkey: accounts.lendingMarket,
|
|
19769
|
-
isSigner: false,
|
|
19770
|
-
isWritable: false
|
|
19771
|
-
},
|
|
19772
|
-
{
|
|
19773
|
-
pubkey: accounts.obligation,
|
|
19774
|
-
isSigner: false,
|
|
19775
|
-
isWritable: true
|
|
19776
|
-
}
|
|
19777
|
-
];
|
|
19778
|
-
accounts.reserves.forEach((reserve)=>{
|
|
19779
|
-
keys.push({
|
|
19780
|
-
pubkey: reserve,
|
|
19781
|
-
isSigner: false,
|
|
19782
|
-
isWritable: false
|
|
19783
|
-
});
|
|
19784
|
-
});
|
|
19785
|
-
const identifier = Buffer.from([
|
|
19786
|
-
33,
|
|
19787
|
-
132,
|
|
19788
|
-
147,
|
|
19789
|
-
228,
|
|
19790
|
-
151,
|
|
19791
|
-
192,
|
|
19792
|
-
72,
|
|
19793
|
-
89
|
|
19794
|
-
]);
|
|
19795
|
-
const data = identifier;
|
|
19796
|
-
const ix = new web3_js.TransactionInstruction({
|
|
19797
|
-
keys,
|
|
19798
|
-
programId,
|
|
19799
|
-
data
|
|
19800
|
-
});
|
|
19801
|
-
return ix;
|
|
19802
|
-
}
|
|
19803
|
-
function refreshReserve(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19804
|
-
const keys = [
|
|
19805
|
-
{
|
|
19806
|
-
pubkey: accounts.reserve,
|
|
19807
|
-
isSigner: false,
|
|
19808
|
-
isWritable: true
|
|
19809
|
-
},
|
|
19810
|
-
{
|
|
19811
|
-
pubkey: accounts.lendingMarket,
|
|
19812
|
-
isSigner: false,
|
|
19813
|
-
isWritable: false
|
|
19814
|
-
},
|
|
19815
|
-
{
|
|
19816
|
-
pubkey: accounts.pythOracle,
|
|
19817
|
-
isSigner: false,
|
|
19818
|
-
isWritable: false
|
|
19819
|
-
},
|
|
19820
|
-
{
|
|
19821
|
-
pubkey: accounts.switchboardPriceOracle,
|
|
19822
|
-
isSigner: false,
|
|
19823
|
-
isWritable: false
|
|
19824
|
-
},
|
|
19825
|
-
{
|
|
19826
|
-
pubkey: accounts.switchboardTwapOracle,
|
|
19827
|
-
isSigner: false,
|
|
19828
|
-
isWritable: false
|
|
19829
|
-
},
|
|
19830
|
-
{
|
|
19831
|
-
pubkey: accounts.scopePrices,
|
|
19832
|
-
isSigner: false,
|
|
19833
|
-
isWritable: false
|
|
19834
|
-
}
|
|
19835
|
-
];
|
|
19836
|
-
const identifier = Buffer.from([
|
|
19837
|
-
2,
|
|
19838
|
-
218,
|
|
19839
|
-
138,
|
|
19840
|
-
235,
|
|
19841
|
-
79,
|
|
19842
|
-
201,
|
|
19843
|
-
25,
|
|
19844
|
-
102
|
|
19845
|
-
]);
|
|
19846
|
-
const data = identifier;
|
|
19847
|
-
const ix = new web3_js.TransactionInstruction({
|
|
19848
|
-
keys,
|
|
19849
|
-
programId,
|
|
19850
|
-
data
|
|
19851
|
-
});
|
|
19852
|
-
return ix;
|
|
19853
|
-
}
|
|
19854
|
-
function refreshObligationFarmsForReserve(args, accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
19855
|
-
const keys = [
|
|
19856
|
-
{
|
|
19857
|
-
pubkey: accounts.crank,
|
|
19858
|
-
isSigner: true,
|
|
19859
|
-
isWritable: false
|
|
19860
|
-
},
|
|
19861
|
-
{
|
|
19862
|
-
pubkey: accounts.baseAccounts.obligation,
|
|
19863
|
-
isSigner: false,
|
|
19864
|
-
isWritable: false
|
|
19865
|
-
},
|
|
19866
|
-
{
|
|
19867
|
-
pubkey: accounts.baseAccounts.lendingMarketAuthority,
|
|
19868
|
-
isSigner: false,
|
|
19869
|
-
isWritable: true
|
|
19870
|
-
},
|
|
19871
|
-
{
|
|
19872
|
-
pubkey: accounts.baseAccounts.reserve,
|
|
19873
|
-
isSigner: false,
|
|
19874
|
-
isWritable: false
|
|
19875
|
-
},
|
|
19876
|
-
{
|
|
19877
|
-
pubkey: accounts.baseAccounts.reserveFarmState,
|
|
19878
|
-
isSigner: false,
|
|
19879
|
-
isWritable: true
|
|
19880
|
-
},
|
|
19881
|
-
{
|
|
19882
|
-
pubkey: accounts.baseAccounts.obligationFarmUserState,
|
|
19883
|
-
isSigner: false,
|
|
19884
|
-
isWritable: true
|
|
19885
|
-
},
|
|
19886
|
-
{
|
|
19887
|
-
pubkey: accounts.baseAccounts.lendingMarket,
|
|
19888
|
-
isSigner: false,
|
|
19889
|
-
isWritable: false
|
|
19890
|
-
},
|
|
19891
|
-
{
|
|
19892
|
-
pubkey: accounts.farmsProgram,
|
|
19893
|
-
isSigner: false,
|
|
19894
|
-
isWritable: false
|
|
19895
|
-
},
|
|
19896
|
-
{
|
|
19897
|
-
pubkey: accounts.rent,
|
|
19898
|
-
isSigner: false,
|
|
19899
|
-
isWritable: false
|
|
19900
|
-
},
|
|
19901
|
-
{
|
|
19902
|
-
pubkey: accounts.systemProgram,
|
|
19903
|
-
isSigner: false,
|
|
19904
|
-
isWritable: false
|
|
19905
|
-
}
|
|
19906
|
-
];
|
|
19907
|
-
const identifier = Buffer.from([
|
|
19908
|
-
140,
|
|
19909
|
-
144,
|
|
19910
|
-
253,
|
|
19911
|
-
21,
|
|
19912
|
-
10,
|
|
19913
|
-
74,
|
|
19914
|
-
248,
|
|
19915
|
-
3
|
|
19916
|
-
]);
|
|
19917
|
-
const buffer = Buffer.alloc(1000);
|
|
19918
|
-
const layout = borsh__namespace.struct([
|
|
19919
|
-
borsh__namespace.u8("mode")
|
|
19920
|
-
]);
|
|
19921
|
-
const len = layout.encode({
|
|
19922
|
-
mode: args.mode
|
|
19923
|
-
}, buffer);
|
|
19924
|
-
const data = Buffer.concat([
|
|
19925
|
-
identifier,
|
|
19926
|
-
buffer
|
|
19927
|
-
]).subarray(0, 8 + len);
|
|
19928
|
-
const ix = new web3_js.TransactionInstruction({
|
|
19929
|
-
keys,
|
|
19930
|
-
programId,
|
|
19931
|
-
data
|
|
19932
|
-
});
|
|
19933
|
-
return ix;
|
|
19934
|
-
}
|
|
19935
19858
|
class KaminoLendingClient {
|
|
19936
19859
|
/**
|
|
19937
19860
|
* Initializes Kamino user metadata
|
|
@@ -20023,8 +19946,228 @@ class KaminoLendingClient {
|
|
|
20023
19946
|
], KAMINO_FARM_PROGRAM);
|
|
20024
19947
|
return obligationFarm;
|
|
20025
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
|
+
}
|
|
20026
20169
|
refreshReserveIxs(lendingMarket, reserves) {
|
|
20027
|
-
return reserves.map((reserve)=>
|
|
20170
|
+
return reserves.map((reserve)=>this.refreshReserveIx({
|
|
20028
20171
|
reserve,
|
|
20029
20172
|
lendingMarket,
|
|
20030
20173
|
pythOracle: KAMINO_LENDING_PROGRAM,
|
|
@@ -20040,7 +20183,7 @@ class KaminoLendingClient {
|
|
|
20040
20183
|
farmCollateral
|
|
20041
20184
|
].filter((farm)=>!!farm).map((farm)=>{
|
|
20042
20185
|
const obligationFarmUserState = this.getObligationFarmState(obligation, farm);
|
|
20043
|
-
return
|
|
20186
|
+
return this.refreshObligationFarmsForReserveIx({
|
|
20044
20187
|
mode: 0
|
|
20045
20188
|
}, {
|
|
20046
20189
|
crank: this.base.getSigner(),
|
|
@@ -20066,7 +20209,7 @@ class KaminoLendingClient {
|
|
|
20066
20209
|
farmDebt
|
|
20067
20210
|
].filter((farm)=>!!farm).map((farm)=>{
|
|
20068
20211
|
const obligationFarmUserState = this.getObligationFarmState(obligation, farm);
|
|
20069
|
-
return
|
|
20212
|
+
return this.refreshObligationFarmsForReserveIx({
|
|
20070
20213
|
mode: 0
|
|
20071
20214
|
}, {
|
|
20072
20215
|
crank: this.base.getSigner(),
|
|
@@ -20352,7 +20495,7 @@ class KaminoLendingClient {
|
|
|
20352
20495
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20353
20496
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20354
20497
|
// Refresh obligation with reserves in use
|
|
20355
|
-
preInstructions.push(
|
|
20498
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20356
20499
|
lendingMarket: market,
|
|
20357
20500
|
obligation,
|
|
20358
20501
|
reserves: reservesInUse
|
|
@@ -20442,7 +20585,7 @@ class KaminoLendingClient {
|
|
|
20442
20585
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20443
20586
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20444
20587
|
// Refresh obligation with reserves in use
|
|
20445
|
-
preInstructions.push(
|
|
20588
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20446
20589
|
lendingMarket: market,
|
|
20447
20590
|
obligation,
|
|
20448
20591
|
reserves: reservesInUse
|
|
@@ -20526,7 +20669,7 @@ class KaminoLendingClient {
|
|
|
20526
20669
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20527
20670
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20528
20671
|
// Refresh obligation with reserves in use
|
|
20529
|
-
preInstructions.push(
|
|
20672
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20530
20673
|
lendingMarket: market,
|
|
20531
20674
|
obligation,
|
|
20532
20675
|
reserves: reservesInUse
|
|
@@ -20608,7 +20751,7 @@ class KaminoLendingClient {
|
|
|
20608
20751
|
// Refresh reserves, including deposit reserve and reserves in use
|
|
20609
20752
|
preInstructions.push(...this.refreshReserveIxs(market, reservesToRefresh));
|
|
20610
20753
|
// Refresh obligation with reserves in use
|
|
20611
|
-
preInstructions.push(
|
|
20754
|
+
preInstructions.push(this.refreshObligationIx({
|
|
20612
20755
|
lendingMarket: market,
|
|
20613
20756
|
obligation,
|
|
20614
20757
|
reserves: reservesInUse
|
|
@@ -20811,7 +20954,7 @@ class KaminoVaultsClient {
|
|
|
20811
20954
|
if (this.vaultStates.size === 0) {
|
|
20812
20955
|
await this.findAndParseKaminoVaults();
|
|
20813
20956
|
}
|
|
20814
|
-
return mints.map((mint)=>this.shareMintToVaultPdaMap.get(mint.toBase58()));
|
|
20957
|
+
return mints.map((mint)=>this.shareMintToVaultPdaMap.get(mint.toBase58())).filter((p)=>!!p);
|
|
20815
20958
|
}
|
|
20816
20959
|
async fetchAndParseVaultState(vault) {
|
|
20817
20960
|
const vaultAccount = await this.base.provider.connection.getAccountInfo(vault);
|
|
@@ -20824,9 +20967,7 @@ class KaminoVaultsClient {
|
|
|
20824
20967
|
return vaultState;
|
|
20825
20968
|
}
|
|
20826
20969
|
async composeRemainingAccounts(allocationStrategies, pricingMode = false) {
|
|
20827
|
-
|
|
20828
|
-
const reservesSet = new Set(allocationStrategies.map((strategy)=>strategy.reserve.toBase58()));
|
|
20829
|
-
const reserves = Array.from(reservesSet).map((p)=>new web3_js.PublicKey(p));
|
|
20970
|
+
const reserves = allocationStrategies.map((strategy)=>strategy.reserve);
|
|
20830
20971
|
const parsedReserves = await this.kaminoLending.fetchAndParseReserves(reserves);
|
|
20831
20972
|
const reserveMetas = reserves.map((pubkey)=>({
|
|
20832
20973
|
pubkey,
|
|
@@ -21368,6 +21509,21 @@ class InvestClient {
|
|
|
21368
21509
|
}
|
|
21369
21510
|
|
|
21370
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
|
+
}
|
|
21371
21527
|
/**
|
|
21372
21528
|
* !! This is a convenience method that calculates the AUM of the vault based on priced assets.
|
|
21373
21529
|
* !! It doesn't reflect the actual AUM of the vault.
|
|
@@ -21411,7 +21567,7 @@ class PriceClient {
|
|
|
21411
21567
|
async priceKaminoVaultSharesIx(priceDenom) {
|
|
21412
21568
|
const allKvaultStates = await this.kvaults.findAndParseKaminoVaults();
|
|
21413
21569
|
const allKvaultMints = allKvaultStates.map((kvault)=>kvault.sharesMint);
|
|
21414
|
-
// All share token accounts GLAM vault could possibly hold
|
|
21570
|
+
// All kvaut share token accounts GLAM vault could possibly hold
|
|
21415
21571
|
const possibleShareAtas = allKvaultMints.map((mint)=>this.base.getVaultAta(mint));
|
|
21416
21572
|
const possibleShareAtaAccountsInfo = await this.base.provider.connection.getMultipleAccountsInfo(possibleShareAtas);
|
|
21417
21573
|
const shareAtas = [];
|
|
@@ -21419,16 +21575,24 @@ class PriceClient {
|
|
|
21419
21575
|
const kvaultStates = [];
|
|
21420
21576
|
const oracles = []; // oracle of kvault deposit token
|
|
21421
21577
|
possibleShareAtaAccountsInfo.forEach((info, i)=>{
|
|
21422
|
-
|
|
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]))) {
|
|
21423
21581
|
shareAtas.push(possibleShareAtas[i]);
|
|
21424
21582
|
shareMints.push(allKvaultMints[i]);
|
|
21425
21583
|
kvaultStates.push(allKvaultStates[i]);
|
|
21426
|
-
|
|
21584
|
+
// get oracle and lookup table from kvault state
|
|
21585
|
+
const { tokenMint, vaultLookupTable } = allKvaultStates[i];
|
|
21427
21586
|
const assetMeta = ASSETS_MAINNET.get(tokenMint.toBase58());
|
|
21428
|
-
|
|
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
|
|
21429
21592
|
}
|
|
21430
21593
|
});
|
|
21431
21594
|
const kvaultPdas = await this.kvaults.getVaultPdasByShareMints(shareMints);
|
|
21595
|
+
kvaultPdas.forEach((p)=>this._kaminoVaults.add(p.toBase58())); // cache kvault keys
|
|
21432
21596
|
const remainingAccounts = [];
|
|
21433
21597
|
// first 3N remaining accounts are N tuples of (kvault_shares_ata, kvault_shares_mint, kvault_state)
|
|
21434
21598
|
for(let i = 0; i < shareAtas.length; i++){
|
|
@@ -21439,26 +21603,44 @@ class PriceClient {
|
|
|
21439
21603
|
oracles[i]
|
|
21440
21604
|
].map((pubkey)=>{
|
|
21441
21605
|
remainingAccounts.push({
|
|
21442
|
-
pubkey,
|
|
21606
|
+
pubkey: pubkey,
|
|
21443
21607
|
isSigner: false,
|
|
21444
21608
|
isWritable: false
|
|
21445
21609
|
});
|
|
21446
21610
|
});
|
|
21447
21611
|
}
|
|
21448
|
-
// markets and reserves
|
|
21449
21612
|
const marketsAndReserves = (await Promise.all(kvaultStates.map((kvault)=>{
|
|
21450
21613
|
return this.kvaults.composeRemainingAccounts(kvault.vaultAllocationStrategy.filter((alloc)=>!alloc.reserve.equals(web3_js.PublicKey.default)), true);
|
|
21451
21614
|
}))).flat();
|
|
21452
|
-
|
|
21615
|
+
const processed = new Set();
|
|
21616
|
+
const reserves = [];
|
|
21617
|
+
const markets = [];
|
|
21618
|
+
const chunkSize = 2;
|
|
21619
|
+
for(let i = 0; i < marketsAndReserves.length; i += chunkSize){
|
|
21620
|
+
const chunk = marketsAndReserves.slice(i, i + chunkSize);
|
|
21621
|
+
const market = chunk[0].pubkey;
|
|
21622
|
+
const reserve = chunk[1].pubkey;
|
|
21623
|
+
// reserve should always be added to remaining accounts
|
|
21624
|
+
remainingAccounts.push(chunk[1]);
|
|
21625
|
+
// record reserves and markets for refreshReservesBatchIx
|
|
21626
|
+
if (!processed.has(reserve.toBase58())) {
|
|
21627
|
+
reserves.push(reserve);
|
|
21628
|
+
markets.push(market);
|
|
21629
|
+
processed.add(reserve.toBase58());
|
|
21630
|
+
}
|
|
21631
|
+
}
|
|
21632
|
+
const refreshReservesIx = this.klend.refreshReservesBatchIx(reserves, markets, false);
|
|
21633
|
+
const preInstructions = [
|
|
21634
|
+
refreshReservesIx
|
|
21635
|
+
];
|
|
21453
21636
|
const priceIx = await this.base.program.methods.priceKaminoVaultShares(priceDenom, shareAtas.length).accounts({
|
|
21454
21637
|
glamState: this.base.statePda,
|
|
21455
|
-
solOracle: SOL_ORACLE
|
|
21456
|
-
pythOracle: null,
|
|
21457
|
-
switchboardPriceOracle: null,
|
|
21458
|
-
switchboardTwapOracle: null,
|
|
21459
|
-
scopePrices: KAMINO_SCOPE_PRICES
|
|
21638
|
+
solOracle: SOL_ORACLE
|
|
21460
21639
|
}).remainingAccounts(remainingAccounts).instruction();
|
|
21461
|
-
return
|
|
21640
|
+
return [
|
|
21641
|
+
...preInstructions,
|
|
21642
|
+
priceIx
|
|
21643
|
+
];
|
|
21462
21644
|
}
|
|
21463
21645
|
/**
|
|
21464
21646
|
* Returns an instruction that prices all Drift users (aka sub-accounts) controlled by the GLAM vault.
|
|
@@ -21526,43 +21708,8 @@ class PriceClient {
|
|
|
21526
21708
|
if (parsedVaultDepositors.length === 0) {
|
|
21527
21709
|
return null;
|
|
21528
21710
|
}
|
|
21529
|
-
|
|
21530
|
-
|
|
21531
|
-
// - drift vault
|
|
21532
|
-
// - drift user of the vault
|
|
21533
|
-
// - oracles
|
|
21534
|
-
// - spot & perp markets
|
|
21535
|
-
// There might be overlaps between markets and oracles so we use a set to avoid duplicates
|
|
21536
|
-
const remainingAccounts = [];
|
|
21537
|
-
const marketsAndOracles = new Set();
|
|
21538
|
-
for (const depositor of parsedVaultDepositors){
|
|
21539
|
-
const { user: driftUser } = await this.dvaults.parseDriftVault(depositor.driftVault);
|
|
21540
|
-
remainingAccounts.push({
|
|
21541
|
-
pubkey: depositor.address,
|
|
21542
|
-
isSigner: false,
|
|
21543
|
-
isWritable: false
|
|
21544
|
-
});
|
|
21545
|
-
remainingAccounts.push({
|
|
21546
|
-
pubkey: depositor.driftVault,
|
|
21547
|
-
isSigner: false,
|
|
21548
|
-
isWritable: false
|
|
21549
|
-
});
|
|
21550
|
-
remainingAccounts.push({
|
|
21551
|
-
pubkey: driftUser,
|
|
21552
|
-
isSigner: false,
|
|
21553
|
-
isWritable: false
|
|
21554
|
-
});
|
|
21555
|
-
const markets_and_oracles = (await this.dvaults.composeRemainingAccounts(driftUser)).map((a)=>a.pubkey.toBase58());
|
|
21556
|
-
for (const k of markets_and_oracles){
|
|
21557
|
-
marketsAndOracles.add(k);
|
|
21558
|
-
}
|
|
21559
|
-
}
|
|
21560
|
-
Array.from(marketsAndOracles).forEach((k)=>remainingAccounts.push({
|
|
21561
|
-
pubkey: new web3_js.PublicKey(k),
|
|
21562
|
-
isSigner: false,
|
|
21563
|
-
isWritable: false
|
|
21564
|
-
}));
|
|
21565
|
-
const priceIx = await this.base.program.methods.priceDriftVaultDepositors(priceDenom, parsedVaultDepositors.length).accounts({
|
|
21711
|
+
const { remainingAccounts, numSpotMarkets, numPerpMarkets } = await this.remainingAccountsForPricingDriftVaultDepositors(parsedVaultDepositors);
|
|
21712
|
+
const priceIx = await this.base.program.methods.priceDriftVaultDepositors(priceDenom, parsedVaultDepositors.length, numSpotMarkets, numPerpMarkets).accounts({
|
|
21566
21713
|
glamState: this.base.statePda,
|
|
21567
21714
|
solOracle: SOL_ORACLE
|
|
21568
21715
|
}).remainingAccounts(remainingAccounts).instruction();
|
|
@@ -21622,7 +21769,8 @@ class PriceClient {
|
|
|
21622
21769
|
}
|
|
21623
21770
|
// If there are no external assets, we don't need to price DeFi positions
|
|
21624
21771
|
const stateModel = await this.base.fetchStateModel();
|
|
21625
|
-
|
|
21772
|
+
this.stateModel = stateModel;
|
|
21773
|
+
if ((this.stateModel.externalVaultAccounts || []).length === 0) {
|
|
21626
21774
|
return [
|
|
21627
21775
|
priceVaultIx
|
|
21628
21776
|
];
|
|
@@ -21642,72 +21790,133 @@ class PriceClient {
|
|
|
21642
21790
|
];
|
|
21643
21791
|
for (const fn of pricingFns){
|
|
21644
21792
|
const ix = await fn(priceDenom);
|
|
21645
|
-
|
|
21793
|
+
if (Array.isArray(ix)) {
|
|
21794
|
+
pricingIxs.push(...ix);
|
|
21795
|
+
} else {
|
|
21796
|
+
pricingIxs.push(ix);
|
|
21797
|
+
}
|
|
21646
21798
|
}
|
|
21647
21799
|
return pricingIxs.filter(Boolean);
|
|
21648
21800
|
}
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21657
|
-
|
|
21658
|
-
|
|
21659
|
-
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21801
|
+
async remainingAccountsForPricingDriftVaultDepositors(parsedVaultDepositors) {
|
|
21802
|
+
// Extra accounts for pricing N vault depositors:
|
|
21803
|
+
// - (vault_depositor, drift_vault, drift_user) x N
|
|
21804
|
+
// - spot_market used by drift users of vaults (no specific order)
|
|
21805
|
+
// - perp markets used by drift users of vaults (no specific order)
|
|
21806
|
+
// - oracles of spot markets and perp markets (no specific order)
|
|
21807
|
+
const remainingAccounts = [];
|
|
21808
|
+
const spotMarketsSet = new Set();
|
|
21809
|
+
const perpMarketsSet = new Set();
|
|
21810
|
+
const oraclesSet = new Set();
|
|
21811
|
+
for (const { address: depositor, driftVault } of parsedVaultDepositors){
|
|
21812
|
+
const { user } = await this.dvaults.parseDriftVault(driftVault); // get drift user used by the vault
|
|
21813
|
+
[
|
|
21814
|
+
depositor,
|
|
21815
|
+
driftVault,
|
|
21816
|
+
user
|
|
21817
|
+
].forEach((k)=>remainingAccounts.push({
|
|
21818
|
+
pubkey: k,
|
|
21819
|
+
isSigner: false,
|
|
21820
|
+
isWritable: false
|
|
21821
|
+
}));
|
|
21822
|
+
const { spotPositions, perpPositions } = await this.dvaults.fetchUserPositions(user);
|
|
21823
|
+
const spotMarketIndexes = spotPositions.map((p)=>p.marketIndex);
|
|
21824
|
+
const perpMarketIndexes = perpPositions.map((p)=>p.marketIndex);
|
|
21825
|
+
// If there are perp positions, add spot market 0 as it's used as quote market for perp
|
|
21826
|
+
if (perpMarketIndexes.length > 0 && !spotMarketIndexes.includes(0)) {
|
|
21827
|
+
spotMarketIndexes.push(0);
|
|
21828
|
+
}
|
|
21829
|
+
const spotMarkets = await this.drift.fetchAndParseSpotMarkets(spotMarketIndexes);
|
|
21830
|
+
const perpMarkets = await this.drift.fetchAndParsePerpMarkets(perpMarketIndexes);
|
|
21831
|
+
spotMarkets.forEach((m)=>{
|
|
21832
|
+
oraclesSet.add(m.oracle.toBase58());
|
|
21833
|
+
spotMarketsSet.add(m.marketPda.toBase58());
|
|
21834
|
+
});
|
|
21835
|
+
perpMarkets.forEach((m)=>{
|
|
21836
|
+
oraclesSet.add(m.oracle.toBase58());
|
|
21837
|
+
perpMarketsSet.add(m.marketPda.toBase58());
|
|
21838
|
+
});
|
|
21839
|
+
}
|
|
21840
|
+
[
|
|
21841
|
+
...spotMarketsSet,
|
|
21842
|
+
...perpMarketsSet,
|
|
21843
|
+
...oraclesSet
|
|
21844
|
+
].forEach((k)=>remainingAccounts.push({
|
|
21845
|
+
pubkey: new web3_js.PublicKey(k),
|
|
21846
|
+
isSigner: false,
|
|
21847
|
+
isWritable: false
|
|
21671
21848
|
}));
|
|
21672
|
-
|
|
21849
|
+
return {
|
|
21850
|
+
remainingAccounts,
|
|
21851
|
+
numSpotMarkets: spotMarketsSet.size,
|
|
21852
|
+
numPerpMarkets: perpMarketsSet.size
|
|
21673
21853
|
};
|
|
21674
|
-
|
|
21675
|
-
|
|
21676
|
-
|
|
21677
|
-
|
|
21678
|
-
|
|
21679
|
-
|
|
21680
|
-
|
|
21681
|
-
|
|
21682
|
-
|
|
21683
|
-
|
|
21684
|
-
|
|
21685
|
-
|
|
21686
|
-
|
|
21687
|
-
|
|
21688
|
-
|
|
21689
|
-
|
|
21690
|
-
|
|
21691
|
-
|
|
21854
|
+
}
|
|
21855
|
+
async remainingAccountsForPricingMeteora() {
|
|
21856
|
+
const positions = await fetchMeteoraPositions(this.base.provider.connection, this.base.vaultPda);
|
|
21857
|
+
let chunks = await Promise.all(positions.map(async (pubkey)=>{
|
|
21858
|
+
const { lbPair, binArrayLower, binArrayUpper } = await parseMeteoraPosition(this.base.provider.connection, pubkey);
|
|
21859
|
+
return [
|
|
21860
|
+
pubkey,
|
|
21861
|
+
lbPair,
|
|
21862
|
+
binArrayLower,
|
|
21863
|
+
binArrayUpper,
|
|
21864
|
+
SOL_ORACLE,
|
|
21865
|
+
USDC_ORACLE
|
|
21866
|
+
].map((k)=>({
|
|
21867
|
+
pubkey: k,
|
|
21868
|
+
isSigner: false,
|
|
21869
|
+
isWritable: false
|
|
21870
|
+
}));
|
|
21871
|
+
}));
|
|
21872
|
+
return chunks.flat();
|
|
21873
|
+
}
|
|
21874
|
+
async remainingAccountsForPricingVaultAssets(baseAssetOnly = false) {
|
|
21875
|
+
const stateModel = await this.base.fetchStateModel();
|
|
21876
|
+
if (baseAssetOnly) {
|
|
21877
|
+
if (!stateModel.baseAsset) {
|
|
21878
|
+
throw new Error("Base asset not configured for the vault");
|
|
21692
21879
|
}
|
|
21693
|
-
|
|
21694
|
-
|
|
21695
|
-
|
|
21696
|
-
|
|
21697
|
-
|
|
21698
|
-
|
|
21699
|
-
|
|
21700
|
-
|
|
21701
|
-
|
|
21702
|
-
mint,
|
|
21703
|
-
assetMeta?.oracle
|
|
21704
|
-
];
|
|
21705
|
-
}).flat().map((a)=>({
|
|
21706
|
-
pubkey: a,
|
|
21880
|
+
// FIXME: support token 2022 base asset
|
|
21881
|
+
const ata = this.base.getVaultAta(stateModel.baseAsset);
|
|
21882
|
+
// Set oracle to default pubkey (aka system program) to indicate oracle isn't needed
|
|
21883
|
+
return [
|
|
21884
|
+
ata,
|
|
21885
|
+
stateModel.baseAsset,
|
|
21886
|
+
web3_js.PublicKey.default
|
|
21887
|
+
].map((k)=>({
|
|
21888
|
+
pubkey: k,
|
|
21707
21889
|
isSigner: false,
|
|
21708
21890
|
isWritable: false
|
|
21709
21891
|
}));
|
|
21710
|
-
}
|
|
21892
|
+
}
|
|
21893
|
+
const assetsForPricing = (stateModel.borrowableAssets || []).concat(stateModel.assets || []);
|
|
21894
|
+
return assetsForPricing.map((mint)=>{
|
|
21895
|
+
const assetMeta = ASSETS_MAINNET.get(mint.toBase58());
|
|
21896
|
+
if (!assetMeta) {
|
|
21897
|
+
throw new Error(`Asset meta not found for ${mint}`);
|
|
21898
|
+
}
|
|
21899
|
+
const ata = this.base.getVaultAta(mint, assetMeta?.programId);
|
|
21900
|
+
return [
|
|
21901
|
+
ata,
|
|
21902
|
+
mint,
|
|
21903
|
+
assetMeta?.oracle
|
|
21904
|
+
];
|
|
21905
|
+
}).flat().map((a)=>({
|
|
21906
|
+
pubkey: a,
|
|
21907
|
+
isSigner: false,
|
|
21908
|
+
isWritable: false
|
|
21909
|
+
}));
|
|
21910
|
+
}
|
|
21911
|
+
constructor(base, klend, kvaults, drift, dvaults){
|
|
21912
|
+
this.base = base;
|
|
21913
|
+
this.klend = klend;
|
|
21914
|
+
this.kvaults = kvaults;
|
|
21915
|
+
this.drift = drift;
|
|
21916
|
+
this.dvaults = dvaults;
|
|
21917
|
+
this._stateModel = null;
|
|
21918
|
+
this._lookupTables = new Set();
|
|
21919
|
+
this._kaminoVaults = new Set();
|
|
21711
21920
|
}
|
|
21712
21921
|
}
|
|
21713
21922
|
|
|
@@ -22129,8 +22338,10 @@ exports.getOpenfundsPda = getOpenfundsPda;
|
|
|
22129
22338
|
exports.getOrderParams = getOrderParams;
|
|
22130
22339
|
exports.getPriorityFeeEstimate = getPriorityFeeEstimate;
|
|
22131
22340
|
exports.getSimulationResult = getSimulationResult;
|
|
22341
|
+
exports.getSolAndTokenBalances = getSolAndTokenBalances;
|
|
22132
22342
|
exports.getStakeAccountsWithStates = getStakeAccountsWithStates;
|
|
22133
22343
|
exports.getStatePda = getStatePda;
|
|
22344
|
+
exports.getTokenAccountsByOwner = getTokenAccountsByOwner;
|
|
22134
22345
|
exports.getTriggerLimitOrderParams = getTriggerLimitOrderParams;
|
|
22135
22346
|
exports.getTriggerMarketOrderParams = getTriggerMarketOrderParams;
|
|
22136
22347
|
exports.getVariant = getVariant;
|