@glamsystems/glam-sdk 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -37
- package/index.cjs.js +241 -80
- package/index.esm.js +241 -81
- package/package.json +2 -2
- package/src/client/drift.d.ts +1 -0
- package/src/client/kamino.d.ts +38 -14
- package/src/client/price.d.ts +4 -6
- package/src/client.d.ts +3 -1
- package/src/constants.d.ts +4 -0
- package/src/utils/priorityfee.d.ts +1 -1
- package/target/idl/glam_protocol.json +1 -0
- package/target/types/glam_protocol.d.ts +1 -0
- package/target/types/glam_protocol.ts +1 -0
package/index.esm.js
CHANGED
|
@@ -3230,6 +3230,7 @@ var instructions = [
|
|
|
3230
3230
|
},
|
|
3231
3231
|
{
|
|
3232
3232
|
name: "glam_vault",
|
|
3233
|
+
writable: true,
|
|
3233
3234
|
pda: {
|
|
3234
3235
|
seeds: [
|
|
3235
3236
|
{
|
|
@@ -12427,9 +12428,12 @@ const MEMO_PROGRAM = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"
|
|
|
12427
12428
|
* Stake pools
|
|
12428
12429
|
*/ const JITO_STAKE_POOL = new PublicKey("Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb");
|
|
12429
12430
|
const JUPSOL_STAKE_POOL = new PublicKey("8VpRhuxa7sUUepdY3kQiTmX9rS5vx4WgaXiAnXq4KCtr");
|
|
12431
|
+
/**
|
|
12432
|
+
* Referrers
|
|
12433
|
+
*/ const GLAM_REFERRER = new PublicKey("GLAMrG37ZqioqvzBNQGCfCUueDz3tsr7MwMFyRk9PS89");
|
|
12430
12434
|
|
|
12431
12435
|
const GlamIntegrations = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Integration")?.type?.variants?.map((v)=>v.name) ?? [];
|
|
12432
|
-
const GlamPermissions = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Permission")?.type?.variants?.map((v)=>v.name) ?? [];
|
|
12436
|
+
const GlamPermissions = GlamProtocolIdlJson?.types?.find((t)=>t.name === "Permission")?.type?.variants?.map((v)=>v.name).filter((v)=>!v.startsWith("__")) ?? [];
|
|
12433
12437
|
const GLAM_PROGRAM_ID_DEFAULT = new PublicKey(GlamProtocolIdlJson.address);
|
|
12434
12438
|
class StateIdlModel {
|
|
12435
12439
|
constructor(data){
|
|
@@ -13639,6 +13643,12 @@ class DriftClient {
|
|
|
13639
13643
|
getUserStatsAccountPublicKey(DRIFT_PROGRAM_ID, vault)
|
|
13640
13644
|
];
|
|
13641
13645
|
}
|
|
13646
|
+
getGlamReferrer() {
|
|
13647
|
+
return [
|
|
13648
|
+
getUserAccountPublicKeySync(DRIFT_PROGRAM_ID, GLAM_REFERRER, 0),
|
|
13649
|
+
getUserStatsAccountPublicKey(DRIFT_PROGRAM_ID, GLAM_REFERRER)
|
|
13650
|
+
];
|
|
13651
|
+
}
|
|
13642
13652
|
async fetchMarketConfigs() {
|
|
13643
13653
|
const response = await fetch("https://api.glam.systems/v0/drift/market_configs/");
|
|
13644
13654
|
if (!response.ok) {
|
|
@@ -13732,15 +13742,18 @@ class DriftClient {
|
|
|
13732
13742
|
const name = `GLAM *.+ ${subAccountId}`.split("").map((char)=>char.charCodeAt(0)).concat(Array(24).fill(0));
|
|
13733
13743
|
const [user, userStats] = this.getUser(glamState, subAccountId);
|
|
13734
13744
|
const state = await getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
|
|
13745
|
+
const remainingAccounts = this.getGlamReferrer().map((p)=>({
|
|
13746
|
+
pubkey: p,
|
|
13747
|
+
isWritable: true,
|
|
13748
|
+
isSigner: false
|
|
13749
|
+
}));
|
|
13735
13750
|
return await this.base.program.methods.driftInitializeUser(subAccountId, name).accounts({
|
|
13736
13751
|
glamState,
|
|
13737
13752
|
user,
|
|
13738
13753
|
userStats,
|
|
13739
13754
|
state,
|
|
13740
13755
|
glamSigner
|
|
13741
|
-
})
|
|
13742
|
-
// .remainingAccounts([]) TODO: set glam referral account
|
|
13743
|
-
.instruction();
|
|
13756
|
+
}).remainingAccounts(remainingAccounts).instruction();
|
|
13744
13757
|
}
|
|
13745
13758
|
async initializeTx(glamState, subAccountId = 0, txOptions = {}) {
|
|
13746
13759
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
@@ -13890,7 +13903,11 @@ class DriftClient {
|
|
|
13890
13903
|
}
|
|
13891
13904
|
async placeOrderTx(glamState, orderParams, subAccountId = 0, marketConfigs, txOptions = {}) {
|
|
13892
13905
|
const { marketIndex, marketType } = orderParams;
|
|
13893
|
-
const remainingAccounts = await this.composeRemainingAccounts(glamState, subAccountId, marketConfigs, marketType, marketIndex)
|
|
13906
|
+
const remainingAccounts = (await this.composeRemainingAccounts(glamState, subAccountId, marketConfigs, marketType, marketIndex)).concat(this.getGlamReferrer().map((p)=>({
|
|
13907
|
+
pubkey: p,
|
|
13908
|
+
isWritable: true,
|
|
13909
|
+
isSigner: false
|
|
13910
|
+
})));
|
|
13894
13911
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
13895
13912
|
const [user] = this.getUser(glamState, subAccountId);
|
|
13896
13913
|
const state = await getDriftStateAccountPublicKey(DRIFT_PROGRAM_ID);
|
|
@@ -15653,7 +15670,7 @@ const DEFAULT_OBLIGATION_ARGS = {
|
|
|
15653
15670
|
id: 0
|
|
15654
15671
|
};
|
|
15655
15672
|
const SCOPE_PRICES = new PublicKey("3NJYftD5sjVfxSnUdZ1wVML8f3aC6mp1CXCL6L7TnU8C");
|
|
15656
|
-
function refreshObligation(accounts, programId) {
|
|
15673
|
+
function refreshObligation(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
15657
15674
|
const keys = [
|
|
15658
15675
|
{
|
|
15659
15676
|
pubkey: accounts.lendingMarket,
|
|
@@ -15691,7 +15708,7 @@ function refreshObligation(accounts, programId) {
|
|
|
15691
15708
|
});
|
|
15692
15709
|
return ix;
|
|
15693
15710
|
}
|
|
15694
|
-
function refreshReserve(accounts, programId) {
|
|
15711
|
+
function refreshReserve(accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
15695
15712
|
const keys = [
|
|
15696
15713
|
{
|
|
15697
15714
|
pubkey: accounts.reserve,
|
|
@@ -15742,7 +15759,7 @@ function refreshReserve(accounts, programId) {
|
|
|
15742
15759
|
});
|
|
15743
15760
|
return ix;
|
|
15744
15761
|
}
|
|
15745
|
-
function refreshObligationFarmsForReserve(args, accounts, programId) {
|
|
15762
|
+
function refreshObligationFarmsForReserve(args, accounts, programId = KAMINO_LENDING_PROGRAM) {
|
|
15746
15763
|
const keys = [
|
|
15747
15764
|
{
|
|
15748
15765
|
pubkey: accounts.crank,
|
|
@@ -15833,7 +15850,7 @@ class KaminoLendingClient {
|
|
|
15833
15850
|
* @param txOptions
|
|
15834
15851
|
* @returns
|
|
15835
15852
|
*/ async initUserMetadata(statePda, referrer, txOptions = {}) {
|
|
15836
|
-
const tx = await this.initUserMetadataTx(new PublicKey(statePda), referrer ? new PublicKey(referrer) :
|
|
15853
|
+
const tx = await this.initUserMetadataTx(new PublicKey(statePda), referrer ? new PublicKey(referrer) : null, txOptions);
|
|
15837
15854
|
return await this.base.sendAndConfirm(tx);
|
|
15838
15855
|
}
|
|
15839
15856
|
/**
|
|
@@ -15919,18 +15936,17 @@ class KaminoLendingClient {
|
|
|
15919
15936
|
], KAMINO_FARM_PROGRAM);
|
|
15920
15937
|
return obligationFarm;
|
|
15921
15938
|
}
|
|
15922
|
-
async initUserMetadataTx(glamState, referrer, txOptions) {
|
|
15939
|
+
async initUserMetadataTx(glamState, referrer, txOptions = {}) {
|
|
15923
15940
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
15924
15941
|
const vault = this.base.getVaultPda(glamState);
|
|
15925
15942
|
const userMetadata = this.getUserMetadataPda(vault);
|
|
15926
15943
|
const lookupTable = new PublicKey(0); // FIXME: create lookup table
|
|
15927
|
-
const referrerUserMetadata = referrer.equals(PublicKey.default) ? KAMINO_LENDING_PROGRAM : referrer;
|
|
15928
15944
|
// @ts-ignore
|
|
15929
15945
|
const tx = await this.base.program.methods.kaminoLendingInitUserMetadata(lookupTable).accounts({
|
|
15930
15946
|
glamState,
|
|
15931
15947
|
glamSigner,
|
|
15932
15948
|
userMetadata,
|
|
15933
|
-
referrerUserMetadata
|
|
15949
|
+
referrerUserMetadata: referrer
|
|
15934
15950
|
}).transaction();
|
|
15935
15951
|
const vTx = await this.base.intoVersionedTransaction(tx, txOptions);
|
|
15936
15952
|
return vTx;
|
|
@@ -15943,7 +15959,7 @@ class KaminoLendingClient {
|
|
|
15943
15959
|
switchboardPriceOracle: KAMINO_LENDING_PROGRAM,
|
|
15944
15960
|
switchboardTwapOracle: KAMINO_LENDING_PROGRAM,
|
|
15945
15961
|
scopePrices: SCOPE_PRICES
|
|
15946
|
-
}
|
|
15962
|
+
}));
|
|
15947
15963
|
}
|
|
15948
15964
|
refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves) {
|
|
15949
15965
|
return parsedReserves.map((parsedReserve)=>{
|
|
@@ -15968,18 +15984,21 @@ class KaminoLendingClient {
|
|
|
15968
15984
|
farmsProgram: KAMINO_FARM_PROGRAM,
|
|
15969
15985
|
rent: SYSVAR_RENT_PUBKEY,
|
|
15970
15986
|
systemProgram: SystemProgram.programId
|
|
15971
|
-
}
|
|
15987
|
+
});
|
|
15972
15988
|
});
|
|
15973
15989
|
}).flat();
|
|
15974
15990
|
}
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
const { deposits, borrows } = await this.fetchAndParseObligation(obligation);
|
|
15991
|
+
// If obligation has deposits or borrows, we need the following refresh ixs:
|
|
15992
|
+
// - refreshReserve x N_reserves
|
|
15993
|
+
// - refreshObligation
|
|
15994
|
+
// - refreshObligationFarmsForReserve x M_farms
|
|
15995
|
+
//
|
|
15996
|
+
// For pricing purpose, we don't need to refresh farm states
|
|
15997
|
+
async getRefreshIxs(obligation, refreshFarms = true) {
|
|
15998
|
+
const { lendingMarket, deposits, borrows } = await this.fetchAndParseObligation(obligation);
|
|
15999
|
+
if (!lendingMarket) {
|
|
16000
|
+
throw new Error("Lending market not found");
|
|
16001
|
+
}
|
|
15983
16002
|
const reserves = deposits.concat(borrows).map((d)=>d.reserve);
|
|
15984
16003
|
const parsedReserves = await this.fetchAndParseReserves(reserves);
|
|
15985
16004
|
return [
|
|
@@ -15988,8 +16007,8 @@ class KaminoLendingClient {
|
|
|
15988
16007
|
lendingMarket,
|
|
15989
16008
|
obligation,
|
|
15990
16009
|
reserves
|
|
15991
|
-
}
|
|
15992
|
-
...this.refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves)
|
|
16010
|
+
}),
|
|
16011
|
+
...refreshFarms ? this.refreshObligationFarmsForReserveIxs(obligation, lendingMarket, parsedReserves) : []
|
|
15993
16012
|
];
|
|
15994
16013
|
}
|
|
15995
16014
|
getMarketAuthority(market) {
|
|
@@ -16040,11 +16059,14 @@ class KaminoLendingClient {
|
|
|
16040
16059
|
const obligationAccount = await this.base.provider.connection.getAccountInfo(obligation);
|
|
16041
16060
|
if (!obligationAccount) {
|
|
16042
16061
|
return {
|
|
16062
|
+
address: obligation,
|
|
16063
|
+
lendingMarket: null,
|
|
16043
16064
|
deposits: [],
|
|
16044
16065
|
borrows: []
|
|
16045
16066
|
};
|
|
16046
16067
|
}
|
|
16047
16068
|
const data = obligationAccount.data;
|
|
16069
|
+
const lendingMarket = new PublicKey(data.subarray(32, 64));
|
|
16048
16070
|
// read deposits
|
|
16049
16071
|
let depositsOffset = 96;
|
|
16050
16072
|
let depositSize = 136;
|
|
@@ -16054,8 +16076,9 @@ class KaminoLendingClient {
|
|
|
16054
16076
|
length: numDeposits
|
|
16055
16077
|
}, (_, i)=>{
|
|
16056
16078
|
const depositData = depositsData.subarray(i * depositSize, (i + 1) * depositSize);
|
|
16079
|
+
const reserve = new PublicKey(depositData.subarray(0, 32));
|
|
16057
16080
|
return {
|
|
16058
|
-
reserve
|
|
16081
|
+
reserve
|
|
16059
16082
|
};
|
|
16060
16083
|
}).filter((d)=>!d.reserve.equals(PublicKey.default));
|
|
16061
16084
|
// read borrows
|
|
@@ -16067,24 +16090,33 @@ class KaminoLendingClient {
|
|
|
16067
16090
|
length: numBorrows
|
|
16068
16091
|
}, (_, i)=>{
|
|
16069
16092
|
const borrowData = borrowsData.subarray(i * borrowSize, (i + 1) * borrowSize);
|
|
16093
|
+
const reserve = new PublicKey(borrowData.subarray(0, 32));
|
|
16070
16094
|
return {
|
|
16071
|
-
reserve
|
|
16095
|
+
reserve
|
|
16072
16096
|
};
|
|
16073
16097
|
}).filter((d)=>!d.reserve.equals(PublicKey.default));
|
|
16074
16098
|
const parsedObligation = {
|
|
16099
|
+
address: obligation,
|
|
16100
|
+
lendingMarket,
|
|
16075
16101
|
deposits,
|
|
16076
16102
|
borrows
|
|
16077
16103
|
};
|
|
16078
16104
|
this.obligations.set(obligation, parsedObligation);
|
|
16079
16105
|
return parsedObligation;
|
|
16080
16106
|
}
|
|
16081
|
-
|
|
16082
|
-
|
|
16083
|
-
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16087
|
-
|
|
16107
|
+
_parseReserveAccount(data) {
|
|
16108
|
+
const market = new PublicKey(data.subarray(32, 64));
|
|
16109
|
+
const farmCollateral = new PublicKey(data.subarray(64, 96));
|
|
16110
|
+
const farmDebt = new PublicKey(data.subarray(96, 128));
|
|
16111
|
+
const liquidityMint = new PublicKey(data.subarray(128, 160));
|
|
16112
|
+
return {
|
|
16113
|
+
farmCollateral: farmCollateral.equals(PublicKey.default) ? null : farmCollateral,
|
|
16114
|
+
farmDebt: farmDebt.equals(PublicKey.default) ? null : farmDebt,
|
|
16115
|
+
liquidityMint,
|
|
16116
|
+
...this.reservePdas(market, liquidityMint)
|
|
16117
|
+
};
|
|
16118
|
+
}
|
|
16119
|
+
async fetchAndParseReserves(reserves) {
|
|
16088
16120
|
if (this.pubkeyArraysEqual(reserves, Array.from(this.reserves.keys()))) {
|
|
16089
16121
|
return Array.from(this.reserves.values());
|
|
16090
16122
|
}
|
|
@@ -16093,20 +16125,12 @@ class KaminoLendingClient {
|
|
|
16093
16125
|
throw new Error("Not all reserves can be found");
|
|
16094
16126
|
}
|
|
16095
16127
|
return reserveAccounts.filter((a)=>!!a).map((account, i)=>{
|
|
16096
|
-
const
|
|
16097
|
-
const market = new PublicKey(data.subarray(32, 64));
|
|
16098
|
-
const farmCollateral = new PublicKey(data.subarray(64, 96));
|
|
16099
|
-
const farmDebt = new PublicKey(data.subarray(96, 128));
|
|
16100
|
-
const liquidityMint = new PublicKey(data.subarray(128, 160));
|
|
16101
|
-
const parsed = {
|
|
16128
|
+
const parsedReserve = {
|
|
16102
16129
|
address: reserves[i],
|
|
16103
|
-
|
|
16104
|
-
farmDebt: farmDebt.equals(PublicKey.default) ? undefined : farmDebt,
|
|
16105
|
-
liquidityMint,
|
|
16106
|
-
...this.reservePdas(market, liquidityMint)
|
|
16130
|
+
...this._parseReserveAccount(account.data)
|
|
16107
16131
|
};
|
|
16108
|
-
this.reserves.set(reserves[i],
|
|
16109
|
-
return
|
|
16132
|
+
this.reserves.set(reserves[i], parsedReserve);
|
|
16133
|
+
return parsedReserve;
|
|
16110
16134
|
});
|
|
16111
16135
|
}
|
|
16112
16136
|
async findAndParseReserve(market, asset) {
|
|
@@ -16133,18 +16157,12 @@ class KaminoLendingClient {
|
|
|
16133
16157
|
throw new Error("Reserve not found");
|
|
16134
16158
|
}
|
|
16135
16159
|
const account = accounts[0];
|
|
16136
|
-
const
|
|
16137
|
-
const farmCollateral = new PublicKey(data.subarray(64, 96));
|
|
16138
|
-
const farmDebt = new PublicKey(data.subarray(96, 128));
|
|
16139
|
-
const parsed = {
|
|
16160
|
+
const parsedReserve = {
|
|
16140
16161
|
address: account.pubkey,
|
|
16141
|
-
|
|
16142
|
-
farmDebt: farmDebt.equals(PublicKey.default) ? undefined : farmDebt,
|
|
16143
|
-
liquidityMint: asset,
|
|
16144
|
-
...this.reservePdas(market, asset)
|
|
16162
|
+
...this._parseReserveAccount(account.account.data)
|
|
16145
16163
|
};
|
|
16146
|
-
this.reserves.set(account.pubkey,
|
|
16147
|
-
return
|
|
16164
|
+
this.reserves.set(account.pubkey, parsedReserve);
|
|
16165
|
+
return parsedReserve;
|
|
16148
16166
|
}
|
|
16149
16167
|
async depositTx(glamState, market, asset, amount, txOptions) {
|
|
16150
16168
|
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
@@ -16202,7 +16220,7 @@ class KaminoLendingClient {
|
|
|
16202
16220
|
lendingMarket: market,
|
|
16203
16221
|
obligation,
|
|
16204
16222
|
reserves: reservesInUse
|
|
16205
|
-
}
|
|
16223
|
+
}));
|
|
16206
16224
|
if (depositReserve.farmCollateral) {
|
|
16207
16225
|
const ixs = this.refreshObligationFarmsForReserveIxs(obligation, market, [
|
|
16208
16226
|
depositReserve
|
|
@@ -16244,7 +16262,6 @@ class KaminoLendingClient {
|
|
|
16244
16262
|
liquidityTokenProgram: TOKEN_PROGRAM_ID,
|
|
16245
16263
|
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
16246
16264
|
obligationFarmUserState: obligationFarm,
|
|
16247
|
-
// @ts-ignore
|
|
16248
16265
|
reserveFarmState: depositReserve.farmCollateral,
|
|
16249
16266
|
farmsProgram: KAMINO_FARM_PROGRAM
|
|
16250
16267
|
}).preInstructions(preInstructions).postInstructions(postInstructions).transaction();
|
|
@@ -16299,7 +16316,7 @@ class KaminoLendingClient {
|
|
|
16299
16316
|
lendingMarket: market,
|
|
16300
16317
|
obligation,
|
|
16301
16318
|
reserves: reservesInUse
|
|
16302
|
-
}
|
|
16319
|
+
}));
|
|
16303
16320
|
if (withdrawReserve.farmCollateral) {
|
|
16304
16321
|
const ixs = this.refreshObligationFarmsForReserveIxs(obligation, market, [
|
|
16305
16322
|
withdrawReserve
|
|
@@ -16328,7 +16345,6 @@ class KaminoLendingClient {
|
|
|
16328
16345
|
liquidityTokenProgram: TOKEN_PROGRAM_ID,
|
|
16329
16346
|
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
16330
16347
|
obligationFarmUserState: obligationFarm,
|
|
16331
|
-
// @ts-ignore
|
|
16332
16348
|
reserveFarmState: withdrawReserve.farmCollateral,
|
|
16333
16349
|
farmsProgram: KAMINO_FARM_PROGRAM
|
|
16334
16350
|
}).instruction();
|
|
@@ -16390,7 +16406,7 @@ class KaminoLendingClient {
|
|
|
16390
16406
|
lendingMarket: market,
|
|
16391
16407
|
obligation,
|
|
16392
16408
|
reserves: reservesInUse
|
|
16393
|
-
}
|
|
16409
|
+
}));
|
|
16394
16410
|
// Don't need to refresh debt farm for borrow
|
|
16395
16411
|
/*
|
|
16396
16412
|
if (borrowReserve.farmDebt) {
|
|
@@ -16419,7 +16435,6 @@ class KaminoLendingClient {
|
|
|
16419
16435
|
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
16420
16436
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
16421
16437
|
obligationFarmUserState: obligationFarm,
|
|
16422
|
-
// @ts-ignore
|
|
16423
16438
|
reserveFarmState: borrowReserve.farmDebt,
|
|
16424
16439
|
farmsProgram: KAMINO_FARM_PROGRAM
|
|
16425
16440
|
}).instruction();
|
|
@@ -16479,7 +16494,7 @@ class KaminoLendingClient {
|
|
|
16479
16494
|
lendingMarket: market,
|
|
16480
16495
|
obligation,
|
|
16481
16496
|
reserves: reservesInUse
|
|
16482
|
-
}
|
|
16497
|
+
}));
|
|
16483
16498
|
const repayIx = await this.base.program.methods.kaminoLendingRepayObligationLiquidityV2(amount).accounts({
|
|
16484
16499
|
glamState,
|
|
16485
16500
|
glamSigner,
|
|
@@ -16493,7 +16508,6 @@ class KaminoLendingClient {
|
|
|
16493
16508
|
instructionSysvarAccount: SYSVAR_INSTRUCTIONS_PUBKEY,
|
|
16494
16509
|
tokenProgram: TOKEN_PROGRAM_ID,
|
|
16495
16510
|
obligationFarmUserState: obligationFarm,
|
|
16496
|
-
// @ts-ignore
|
|
16497
16511
|
reserveFarmState: repayReserve.farmDebt,
|
|
16498
16512
|
farmsProgram: KAMINO_FARM_PROGRAM
|
|
16499
16513
|
}).instruction();
|
|
@@ -16524,6 +16538,135 @@ class KaminoLendingClient {
|
|
|
16524
16538
|
};
|
|
16525
16539
|
}
|
|
16526
16540
|
}
|
|
16541
|
+
class KaminoFarmClient {
|
|
16542
|
+
async findAndParseFarmStates(owner) {
|
|
16543
|
+
const accounts = await this.base.provider.connection.getProgramAccounts(KAMINO_FARM_PROGRAM, {
|
|
16544
|
+
filters: [
|
|
16545
|
+
{
|
|
16546
|
+
dataSize: 920
|
|
16547
|
+
},
|
|
16548
|
+
{
|
|
16549
|
+
memcmp: {
|
|
16550
|
+
offset: 48,
|
|
16551
|
+
bytes: owner.toBase58()
|
|
16552
|
+
}
|
|
16553
|
+
}
|
|
16554
|
+
]
|
|
16555
|
+
});
|
|
16556
|
+
return accounts.map((account)=>{
|
|
16557
|
+
const data = account.account.data;
|
|
16558
|
+
const farmState = new PublicKey(data.subarray(16, 48));
|
|
16559
|
+
return {
|
|
16560
|
+
userFarmState: account.pubkey,
|
|
16561
|
+
farmState
|
|
16562
|
+
};
|
|
16563
|
+
});
|
|
16564
|
+
}
|
|
16565
|
+
async parseFarm(data) {
|
|
16566
|
+
const globalConfig = new PublicKey(data.subarray(40, 72));
|
|
16567
|
+
const rewardsOffset = 192;
|
|
16568
|
+
const numRewards = 10;
|
|
16569
|
+
const rewardSize = 704;
|
|
16570
|
+
const rewardsData = data.subarray(rewardsOffset, rewardsOffset + numRewards * rewardSize);
|
|
16571
|
+
const rewards = Array.from({
|
|
16572
|
+
length: numRewards
|
|
16573
|
+
}, (_, i)=>{
|
|
16574
|
+
const rewardData = rewardsData.subarray(i * rewardSize, (i + 1) * rewardSize);
|
|
16575
|
+
const mint = new PublicKey(rewardData.subarray(0, 32));
|
|
16576
|
+
const tokenProgram = new PublicKey(rewardData.subarray(40, 72));
|
|
16577
|
+
const rewardsVault = new PublicKey(rewardData.subarray(120, 152));
|
|
16578
|
+
const minClaimDurationSeconds = new BN(rewardData.subarray(480, 488), "le");
|
|
16579
|
+
return {
|
|
16580
|
+
index: i,
|
|
16581
|
+
mint,
|
|
16582
|
+
minClaimDurationSeconds,
|
|
16583
|
+
tokenProgram,
|
|
16584
|
+
rewardsVault
|
|
16585
|
+
};
|
|
16586
|
+
}).filter((r)=>{
|
|
16587
|
+
if (r.mint.equals(PublicKey.default)) {
|
|
16588
|
+
return false;
|
|
16589
|
+
}
|
|
16590
|
+
// Filter out rewards with minClaimDurationSeconds > 1 year, they are considered disabled
|
|
16591
|
+
if (r.minClaimDurationSeconds.div(new BN(365 * 24 * 60 * 60)).gt(new BN(1))) {
|
|
16592
|
+
return false;
|
|
16593
|
+
}
|
|
16594
|
+
return true;
|
|
16595
|
+
});
|
|
16596
|
+
return {
|
|
16597
|
+
globalConfig,
|
|
16598
|
+
rewards
|
|
16599
|
+
};
|
|
16600
|
+
}
|
|
16601
|
+
async fetchAndParseFarms(farms) {
|
|
16602
|
+
const farmAccounts = await this.base.provider.connection.getMultipleAccountsInfo(farms);
|
|
16603
|
+
const map = new Map();
|
|
16604
|
+
for(let i = 0; i < farmAccounts.length; i++){
|
|
16605
|
+
const account = farmAccounts[i];
|
|
16606
|
+
if (!account) {
|
|
16607
|
+
continue;
|
|
16608
|
+
}
|
|
16609
|
+
const data = account.data;
|
|
16610
|
+
const parsedFarm = await this.parseFarm(data);
|
|
16611
|
+
map.set(farms[i].toBase58(), parsedFarm);
|
|
16612
|
+
}
|
|
16613
|
+
return map;
|
|
16614
|
+
}
|
|
16615
|
+
async harvest(statePda, txOptions = {}) {
|
|
16616
|
+
const tx = await this.harvestTx(new PublicKey(statePda), txOptions);
|
|
16617
|
+
return await this.base.sendAndConfirm(tx);
|
|
16618
|
+
}
|
|
16619
|
+
async harvestTx(glamState, txOptions = {}) {
|
|
16620
|
+
const glamSigner = txOptions.signer || this.base.getSigner();
|
|
16621
|
+
const vault = this.base.getVaultPda(glamState);
|
|
16622
|
+
const farmStates = await this.findAndParseFarmStates(vault);
|
|
16623
|
+
const parsedFarms = await this.fetchAndParseFarms(farmStates.map((f)=>f.farmState));
|
|
16624
|
+
const tx = new Transaction();
|
|
16625
|
+
for (const { userFarmState, farmState } of farmStates){
|
|
16626
|
+
const { globalConfig, rewards } = parsedFarms.get(farmState.toBase58());
|
|
16627
|
+
for (const { index, mint, tokenProgram, rewardsVault } of rewards){
|
|
16628
|
+
console.log("Reward token:", mint.toBase58());
|
|
16629
|
+
const vaultAta = this.base.getVaultAta(glamState, mint, tokenProgram);
|
|
16630
|
+
const createAtaIx = createAssociatedTokenAccountIdempotentInstruction(glamSigner, vaultAta, vault, mint, tokenProgram);
|
|
16631
|
+
const harvestIx = await this.base.program.methods.kaminoFarmHarvestReward(new BN(index)).accounts({
|
|
16632
|
+
glamState,
|
|
16633
|
+
glamSigner,
|
|
16634
|
+
userState: userFarmState,
|
|
16635
|
+
farmState,
|
|
16636
|
+
globalConfig,
|
|
16637
|
+
rewardMint: mint,
|
|
16638
|
+
userRewardAta: vaultAta,
|
|
16639
|
+
rewardsVault,
|
|
16640
|
+
rewardsTreasuryVault: this.rewardsTreasuryVault(globalConfig, mint),
|
|
16641
|
+
farmVaultsAuthority: this.farmVaultsAuthority(farmState),
|
|
16642
|
+
scopePrices: null,
|
|
16643
|
+
tokenProgram
|
|
16644
|
+
}).instruction();
|
|
16645
|
+
tx.add(createAtaIx, harvestIx);
|
|
16646
|
+
}
|
|
16647
|
+
}
|
|
16648
|
+
const lookupTables = txOptions.lookupTables || await this.base.getAdressLookupTableAccounts([
|
|
16649
|
+
LOOKUP_TABLE
|
|
16650
|
+
]);
|
|
16651
|
+
const vTx = await this.base.intoVersionedTransaction(tx, {
|
|
16652
|
+
...txOptions,
|
|
16653
|
+
lookupTables
|
|
16654
|
+
});
|
|
16655
|
+
return vTx;
|
|
16656
|
+
}
|
|
16657
|
+
constructor(base){
|
|
16658
|
+
this.base = base;
|
|
16659
|
+
this.farmVaultsAuthority = (farm)=>PublicKey.findProgramAddressSync([
|
|
16660
|
+
Buffer.from("authority"),
|
|
16661
|
+
farm.toBuffer()
|
|
16662
|
+
], KAMINO_FARM_PROGRAM)[0];
|
|
16663
|
+
this.rewardsTreasuryVault = (globalConfig, mint)=>PublicKey.findProgramAddressSync([
|
|
16664
|
+
Buffer.from("tvault"),
|
|
16665
|
+
globalConfig.toBuffer(),
|
|
16666
|
+
mint.toBuffer()
|
|
16667
|
+
], KAMINO_FARM_PROGRAM)[0];
|
|
16668
|
+
}
|
|
16669
|
+
}
|
|
16527
16670
|
|
|
16528
16671
|
// Pubkey::find_program_address(&[b"__event_authority"], &dlmm_interface::ID)
|
|
16529
16672
|
const EVENT_AUTHORITY = new PublicKey("D1ZN9Wj1fRSUQfCjhvnu1hqDMT7hzjzBBpi12nVniYD6");
|
|
@@ -17000,6 +17143,28 @@ class PriceClient {
|
|
|
17000
17143
|
});
|
|
17001
17144
|
return pricedAssets.reduce((sum, p)=>new BN(p.amount).add(sum), new BN(0));
|
|
17002
17145
|
}
|
|
17146
|
+
async priceKaminoIxs(glamState, priceDenom) {
|
|
17147
|
+
const glamVault = this.base.getVaultPda(glamState);
|
|
17148
|
+
const obligations = await fetchKaminoObligations(this.base.provider.connection, glamVault);
|
|
17149
|
+
const refreshIxs = [];
|
|
17150
|
+
for (const obligation of obligations){
|
|
17151
|
+
const ixs = await this.klend.getRefreshIxs(obligation, false); // skip farms
|
|
17152
|
+
refreshIxs.push(...ixs);
|
|
17153
|
+
}
|
|
17154
|
+
// @ts-ignore
|
|
17155
|
+
const priceIx = await this.base.program.methods.priceKaminoObligations(priceDenom).accounts({
|
|
17156
|
+
glamState,
|
|
17157
|
+
solOracle: SOL_ORACLE
|
|
17158
|
+
}).remainingAccounts(obligations.map((o)=>({
|
|
17159
|
+
pubkey: o,
|
|
17160
|
+
isSigner: false,
|
|
17161
|
+
isWritable: false
|
|
17162
|
+
}))).instruction();
|
|
17163
|
+
return [
|
|
17164
|
+
...refreshIxs,
|
|
17165
|
+
priceIx
|
|
17166
|
+
];
|
|
17167
|
+
}
|
|
17003
17168
|
async priceVaultIxs(glamState, priceDenom) {
|
|
17004
17169
|
const vault = this.base.getVaultPda(glamState);
|
|
17005
17170
|
const tickets = await fetchMarinadeTicketAccounts(this.base.provider.connection, vault);
|
|
@@ -17029,29 +17194,18 @@ class PriceClient {
|
|
|
17029
17194
|
glamState,
|
|
17030
17195
|
solOracle: SOL_ORACLE
|
|
17031
17196
|
}).remainingAccounts(await this.remainingAccountsForPricingMeteora(glamState)).instruction();
|
|
17032
|
-
const
|
|
17033
|
-
glamState,
|
|
17034
|
-
solOracle: SOL_ORACLE
|
|
17035
|
-
}).remainingAccounts(await this.remainingAccountsForPricingKamino(glamState)).instruction();
|
|
17197
|
+
const priceKaminoIxs = await this.priceKaminoIxs(glamState, priceDenom);
|
|
17036
17198
|
return [
|
|
17037
17199
|
priceTicketsIx,
|
|
17038
17200
|
priceStakesIx,
|
|
17039
17201
|
priceVaultIx,
|
|
17040
17202
|
priceMeteoraIx,
|
|
17041
|
-
|
|
17203
|
+
...priceKaminoIxs
|
|
17042
17204
|
];
|
|
17043
17205
|
}
|
|
17044
|
-
constructor(base){
|
|
17206
|
+
constructor(base, klend){
|
|
17045
17207
|
this.base = base;
|
|
17046
|
-
this.
|
|
17047
|
-
const glamVault = this.base.getVaultPda(glamState);
|
|
17048
|
-
const obligationAccounts = await fetchKaminoObligations(this.base.provider.connection, glamVault);
|
|
17049
|
-
return obligationAccounts.map((a)=>({
|
|
17050
|
-
pubkey: a,
|
|
17051
|
-
isSigner: false,
|
|
17052
|
-
isWritable: false
|
|
17053
|
-
}));
|
|
17054
|
-
};
|
|
17208
|
+
this.klend = klend;
|
|
17055
17209
|
this.remainingAccountsForPricingMeteora = async (glamState)=>{
|
|
17056
17210
|
const glamVault = this.base.getVaultPda(glamState);
|
|
17057
17211
|
const positions = await fetchMeteoraPositions(this.base.provider.connection, glamVault);
|
|
@@ -17137,7 +17291,7 @@ class PriceClient {
|
|
|
17137
17291
|
}
|
|
17138
17292
|
get price() {
|
|
17139
17293
|
if (!this._price) {
|
|
17140
|
-
this._price = new PriceClient(this);
|
|
17294
|
+
this._price = new PriceClient(this, this.kaminoLending);
|
|
17141
17295
|
}
|
|
17142
17296
|
return this._price;
|
|
17143
17297
|
}
|
|
@@ -17159,6 +17313,12 @@ class PriceClient {
|
|
|
17159
17313
|
}
|
|
17160
17314
|
return this._kaminoLending;
|
|
17161
17315
|
}
|
|
17316
|
+
get kaminoFarm() {
|
|
17317
|
+
if (!this._kaminoFarm) {
|
|
17318
|
+
this._kaminoFarm = new KaminoFarmClient(this);
|
|
17319
|
+
}
|
|
17320
|
+
return this._kaminoFarm;
|
|
17321
|
+
}
|
|
17162
17322
|
get meteoraDlmm() {
|
|
17163
17323
|
if (!this._meteoraDlmm) {
|
|
17164
17324
|
this._meteoraDlmm = new MeteoraDlmmClient(this);
|
|
@@ -17174,7 +17334,7 @@ const getPriorityFeeEstimate = async (heliusApiKey, tx, accountKeys, priorityLev
|
|
|
17174
17334
|
if (!tx && !accountKeys) {
|
|
17175
17335
|
throw new Error("Either tx or accountKeys must be provided");
|
|
17176
17336
|
}
|
|
17177
|
-
const options = priorityLevel ? {
|
|
17337
|
+
const options = priorityLevel && priorityLevel !== "Recommended" ? {
|
|
17178
17338
|
priorityLevel
|
|
17179
17339
|
} : {
|
|
17180
17340
|
recommended: true
|
|
@@ -17206,4 +17366,4 @@ const getPriorityFeeEstimate = async (heliusApiKey, tx, accountKeys, priorityLev
|
|
|
17206
17366
|
return data.result.priorityFeeEstimate;
|
|
17207
17367
|
};
|
|
17208
17368
|
|
|
17209
|
-
export { ASSETS_MAINNET, ASSETS_TESTS, BaseClient, ClusterNetwork, CompanyModel, CreatedModel, DRIFT_PROGRAM_ID, DelegateAcl, DriftClient, FundOpenfundsModel, GOVERNANCE_PROGRAM_ID, GlamClient, GlamError, GlamIdl, GlamIntegrations, GlamPermissions, GlamProtocolIdlJson, JITOSOL, JITO_STAKE_POOL, JITO_TIP_DEFAULT, JUP, JUPITER_API_DEFAULT, JUPITER_PROGRAM_ID, JUPSOL_STAKE_POOL, JUP_VOTE_PROGRAM, JupiterSwapClient, JupiterVoteClient, KAMINO_FARM_PROGRAM, KAMINO_LENDING_PROGRAM, KAMINO_OBTRIGATION_SIZE, MARINADE_PROGRAM_ID, MARINADE_TICKET_SIZE, MEMO_PROGRAM, MERKLE_DISTRIBUTOR_PROGRAM, METEORA_DLMM_PROGRAM, METEORA_POSITION_SIZE, MSOL, ManagerModel, Metadata, MintIdlModel, MintModel, MintOpenfundsModel, PriceDenom, SANCTUM_STAKE_POOL_PROGRAM_ID, SEED_ESCROW, SEED_METADATA, SEED_MINT, SEED_STATE, SEED_VAULT, SOL_ORACLE, STAKE_ACCOUNT_SIZE, StateIdlModel, StateModel, TRANSFER_HOOK_PROGRAM, USDC, WBTC, WETH, WSOL, fetchKaminoObligations, fetchMarinadeTicketAccounts, fetchMeteoraPositions, fetchStakeAccounts, getGlamProgram, getGlamProgramId, getPriorityFeeEstimate, getSimulationComputeUnits, isBrowser, parseMeteoraPosition };
|
|
17369
|
+
export { ASSETS_MAINNET, ASSETS_TESTS, BaseClient, ClusterNetwork, CompanyModel, CreatedModel, DRIFT_PROGRAM_ID, DelegateAcl, DriftClient, FundOpenfundsModel, GLAM_REFERRER, GOVERNANCE_PROGRAM_ID, GlamClient, GlamError, GlamIdl, GlamIntegrations, GlamPermissions, GlamProtocolIdlJson, JITOSOL, JITO_STAKE_POOL, JITO_TIP_DEFAULT, JUP, JUPITER_API_DEFAULT, JUPITER_PROGRAM_ID, JUPSOL_STAKE_POOL, JUP_VOTE_PROGRAM, JupiterSwapClient, JupiterVoteClient, KAMINO_FARM_PROGRAM, KAMINO_LENDING_PROGRAM, KAMINO_OBTRIGATION_SIZE, MARINADE_PROGRAM_ID, MARINADE_TICKET_SIZE, MEMO_PROGRAM, MERKLE_DISTRIBUTOR_PROGRAM, METEORA_DLMM_PROGRAM, METEORA_POSITION_SIZE, MSOL, ManagerModel, Metadata, MintIdlModel, MintModel, MintOpenfundsModel, PriceDenom, SANCTUM_STAKE_POOL_PROGRAM_ID, SEED_ESCROW, SEED_METADATA, SEED_MINT, SEED_STATE, SEED_VAULT, SOL_ORACLE, STAKE_ACCOUNT_SIZE, StateIdlModel, StateModel, TRANSFER_HOOK_PROGRAM, USDC, WBTC, WETH, WSOL, fetchKaminoObligations, fetchMarinadeTicketAccounts, fetchMeteoraPositions, fetchStakeAccounts, getGlamProgram, getGlamProgramId, getPriorityFeeEstimate, getSimulationComputeUnits, isBrowser, parseMeteoraPosition };
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glamsystems/glam-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "TypeScript SDK for the GLAM Protocol",
|
|
5
5
|
"main": "./index.cjs.js",
|
|
6
6
|
"module": "./index.esm.js",
|
|
7
7
|
"homepage": "https://www.glam.systems",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git@github.com:glamsystems/glam.git"
|
|
10
|
+
"url": "git@github.com:glamsystems/glam-sdk.git"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"glam",
|
package/src/client/drift.d.ts
CHANGED
|
@@ -72,6 +72,7 @@ export declare class DriftClient {
|
|
|
72
72
|
settlePnl(statePda: PublicKey | string, marketIndex: number, subAccountId: number, marketConfigs: DriftMarketConfigs, txOptions?: TxOptions): Promise<TransactionSignature>;
|
|
73
73
|
priceDrift(statePda: PublicKey | string, marketConfigs: DriftMarketConfigs, priceDenom: PriceDenom, txOptions?: TxOptions): Promise<TransactionSignature>;
|
|
74
74
|
getUser(statePda: PublicKey | string, subAccountId?: number): PublicKey[];
|
|
75
|
+
getGlamReferrer(): PublicKey[];
|
|
75
76
|
fetchMarketConfigs(): Promise<DriftMarketConfigs>;
|
|
76
77
|
fetchGlamDriftUser(glamState: PublicKey | string, subAccountId?: number): Promise<GlamDriftUser>;
|
|
77
78
|
getPositions(statePda: PublicKey | string, subAccountId?: number): Promise<{
|