@pyron-finance/pyron-client 1.0.2 → 1.0.3

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.
@@ -5,13 +5,11 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (all) => {
9
- let target = {};
8
+ var __export = (target, all) => {
10
9
  for (var name in all) __defProp(target, name, {
11
10
  get: all[name],
12
11
  enumerable: true
13
12
  });
14
- return target;
15
13
  };
16
14
  var __copyProps = (to, from, except, desc) => {
17
15
  if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
@@ -29,32 +27,19 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
27
  }) : target, mod));
30
28
 
31
29
  //#endregion
32
- let __coral_xyz_anchor = require("@coral-xyz/anchor");
33
- __coral_xyz_anchor = __toESM(__coral_xyz_anchor);
34
- let bs58 = require("bs58");
35
- bs58 = __toESM(bs58);
36
- let __solana_web3_js = require("@solana/web3.js");
37
- __solana_web3_js = __toESM(__solana_web3_js);
38
- let bignumber_js = require("bignumber.js");
39
- bignumber_js = __toESM(bignumber_js);
40
- let zod = require("zod");
41
- zod = __toESM(zod);
42
- let bn_js = require("bn.js");
43
- bn_js = __toESM(bn_js);
44
- let __solana_spl_token = require("@solana/spl-token");
45
- __solana_spl_token = __toESM(__solana_spl_token);
46
- let decimal_js = require("decimal.js");
47
- decimal_js = __toESM(decimal_js);
48
- let numeral = require("numeral");
49
- numeral = __toESM(numeral);
50
- let borsh = require("borsh");
51
- borsh = __toESM(borsh);
52
- let __coral_xyz_borsh = require("@coral-xyz/borsh");
53
- __coral_xyz_borsh = __toESM(__coral_xyz_borsh);
54
- let big_js = require("big.js");
55
- big_js = __toESM(big_js);
56
- let zod_v4_mini = require("zod/v4-mini");
57
- zod_v4_mini = __toESM(zod_v4_mini);
30
+ const __coral_xyz_anchor = __toESM(require("@coral-xyz/anchor"));
31
+ const bs58 = __toESM(require("bs58"));
32
+ const __solana_web3_js = __toESM(require("@solana/web3.js"));
33
+ const bignumber_js = __toESM(require("bignumber.js"));
34
+ const zod = __toESM(require("zod"));
35
+ const bn_js = __toESM(require("bn.js"));
36
+ const __solana_spl_token = __toESM(require("@solana/spl-token"));
37
+ const decimal_js = __toESM(require("decimal.js"));
38
+ const numeral = __toESM(require("numeral"));
39
+ const borsh = __toESM(require("borsh"));
40
+ const __coral_xyz_borsh = __toESM(require("@coral-xyz/borsh"));
41
+ const big_js = __toESM(require("big.js"));
42
+ const zod_v4_mini = __toESM(require("zod/v4-mini"));
58
43
 
59
44
  //#region src/instructions.ts
60
45
  async function makeInitLendrAccountIx(ldProgram, accounts$2) {
@@ -2697,6 +2682,8 @@ const replenishPoolIx = (voteAccount) => {
2697
2682
  //#endregion
2698
2683
  //#region src/vendor/switchboard_legacy/account.ts
2699
2684
  var Account = class {
2685
+ program;
2686
+ publicKey;
2700
2687
  /**
2701
2688
  * Account constructor
2702
2689
  * @param program SwitchboardProgram
@@ -2733,16 +2720,10 @@ var AggregatorAccount = class extends Account {
2733
2720
  //#endregion
2734
2721
  //#region src/vendor/switchboard_legacy/AggregatorResolutionMode.ts
2735
2722
  var ModeRoundResolution = class {
2736
- constructor() {
2737
- this.discriminator = 0;
2738
- this.kind = "ModeRoundResolution";
2739
- }
2740
- static {
2741
- this.discriminator = 0;
2742
- }
2743
- static {
2744
- this.kind = "ModeRoundResolution";
2745
- }
2723
+ static discriminator = 0;
2724
+ static kind = "ModeRoundResolution";
2725
+ discriminator = 0;
2726
+ kind = "ModeRoundResolution";
2746
2727
  toJSON() {
2747
2728
  return { kind: "ModeRoundResolution" };
2748
2729
  }
@@ -2751,16 +2732,10 @@ var ModeRoundResolution = class {
2751
2732
  }
2752
2733
  };
2753
2734
  var ModeSlidingResolution = class {
2754
- constructor() {
2755
- this.discriminator = 1;
2756
- this.kind = "ModeSlidingResolution";
2757
- }
2758
- static {
2759
- this.discriminator = 1;
2760
- }
2761
- static {
2762
- this.kind = "ModeSlidingResolution";
2763
- }
2735
+ static discriminator = 1;
2736
+ static kind = "ModeSlidingResolution";
2737
+ discriminator = 1;
2738
+ kind = "ModeSlidingResolution";
2764
2739
  toJSON() {
2765
2740
  return { kind: "ModeSlidingResolution" };
2766
2741
  }
@@ -2801,6 +2776,13 @@ function layout(property) {
2801
2776
  //#endregion
2802
2777
  //#region src/vendor/switchboard_legacy/switchboardDecimal.ts
2803
2778
  var SwitchboardDecimal = class SwitchboardDecimal {
2779
+ /**
2780
+ * The part of a floating-point number that represents the significant digits of that number,
2781
+ * and that is multiplied by the base, 10, raised to the power of scale to give the actual value of the number.
2782
+ */
2783
+ mantissa;
2784
+ /** The number of decimal places to move to the left to yield the actual value. */
2785
+ scale;
2804
2786
  constructor(fields) {
2805
2787
  this.mantissa = fields.mantissa;
2806
2788
  this.scale = fields.scale;
@@ -2910,6 +2892,37 @@ var SwitchboardDecimal = class SwitchboardDecimal {
2910
2892
  //#endregion
2911
2893
  //#region src/vendor/switchboard_legacy/aggregatorRound.ts
2912
2894
  var AggregatorRound = class AggregatorRound {
2895
+ /**
2896
+ * Maintains the number of successful responses received from nodes.
2897
+ * Nodes can submit one successful response per round.
2898
+ */
2899
+ numSuccess;
2900
+ /** Number of error responses. */
2901
+ numError;
2902
+ /** Whether an update request round has ended. */
2903
+ isClosed;
2904
+ /** Maintains the `solana_program::clock::Slot` that the round was opened at. */
2905
+ roundOpenSlot;
2906
+ /** Maintains the `solana_program::clock::UnixTimestamp;` the round was opened at. */
2907
+ roundOpenTimestamp;
2908
+ /** Maintains the current median of all successful round responses. */
2909
+ result;
2910
+ /** Standard deviation of the accepted results in the round. */
2911
+ stdDeviation;
2912
+ /** Maintains the minimum node response this round. */
2913
+ minResponse;
2914
+ /** Maintains the maximum node response this round. */
2915
+ maxResponse;
2916
+ /** Pubkeys of the oracles fulfilling this round. */
2917
+ oraclePubkeysData;
2918
+ /** Represents all successful node responses this round. `NaN` if empty. */
2919
+ mediansData;
2920
+ /** Current rewards/slashes oracles have received this round. */
2921
+ currentPayout;
2922
+ /** Keep track of which responses are fulfilled here. */
2923
+ mediansFulfilled;
2924
+ /** Keeps track of which errors are fulfilled here. */
2925
+ errorsFulfilled;
2913
2926
  constructor(fields) {
2914
2927
  this.numSuccess = fields.numSuccess;
2915
2928
  this.numError = fields.numError;
@@ -3024,6 +3037,8 @@ var AggregatorRound = class AggregatorRound {
3024
3037
  //#endregion
3025
3038
  //#region src/vendor/switchboard_legacy/Hash.ts
3026
3039
  var Hash = class Hash {
3040
+ /** The bytes used to derive the hash. */
3041
+ data;
3027
3042
  constructor(fields) {
3028
3043
  this.data = fields.data;
3029
3044
  }
@@ -3050,57 +3065,125 @@ var Hash = class Hash {
3050
3065
  //#endregion
3051
3066
  //#region src/vendor/switchboard_legacy/aggregatorAccountData.ts
3052
3067
  var AggregatorAccountData = class AggregatorAccountData {
3053
- static {
3054
- this.discriminator = Buffer.from([
3055
- 217,
3056
- 230,
3057
- 65,
3058
- 101,
3059
- 201,
3060
- 162,
3061
- 27,
3062
- 125
3063
- ]);
3064
- }
3065
- static {
3066
- this.layout = __coral_xyz_borsh.struct([
3067
- __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 32, "name"),
3068
- __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 128, "metadata"),
3069
- __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 32, "reserved1"),
3070
- __coral_xyz_borsh.publicKey("queuePubkey"),
3071
- __coral_xyz_borsh.u32("oracleRequestBatchSize"),
3072
- __coral_xyz_borsh.u32("minOracleResults"),
3073
- __coral_xyz_borsh.u32("minJobResults"),
3074
- __coral_xyz_borsh.u32("minUpdateDelaySeconds"),
3075
- __coral_xyz_borsh.i64("startAfter"),
3076
- SwitchboardDecimal.layout("varianceThreshold"),
3077
- __coral_xyz_borsh.i64("forceReportPeriod"),
3078
- __coral_xyz_borsh.i64("expiration"),
3079
- __coral_xyz_borsh.u64("consecutiveFailureCount"),
3080
- __coral_xyz_borsh.i64("nextAllowedUpdateTime"),
3081
- __coral_xyz_borsh.bool("isLocked"),
3082
- __coral_xyz_borsh.publicKey("crankPubkey"),
3083
- AggregatorRound.layout("latestConfirmedRound"),
3084
- AggregatorRound.layout("currentRound"),
3085
- __coral_xyz_borsh.array(__coral_xyz_borsh.publicKey(), 16, "jobPubkeysData"),
3086
- __coral_xyz_borsh.array(Hash.layout({}), 16, "jobHashes"),
3087
- __coral_xyz_borsh.u32("jobPubkeysSize"),
3088
- __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 32, "jobsChecksum"),
3089
- __coral_xyz_borsh.publicKey("authority"),
3090
- __coral_xyz_borsh.publicKey("historyBuffer"),
3091
- SwitchboardDecimal.layout("previousConfirmedRoundResult"),
3092
- __coral_xyz_borsh.u64("previousConfirmedRoundSlot"),
3093
- __coral_xyz_borsh.bool("disableCrank"),
3094
- __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 16, "jobWeights"),
3095
- __coral_xyz_borsh.i64("creationTimestamp"),
3096
- layout("resolutionMode"),
3097
- __coral_xyz_borsh.u32("basePriorityFee"),
3098
- __coral_xyz_borsh.u32("priorityFeeBump"),
3099
- __coral_xyz_borsh.u32("priorityFeeBumpPeriod"),
3100
- __coral_xyz_borsh.u32("maxPriorityFeeMultiplier"),
3101
- __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 122, "ebuf")
3102
- ]);
3103
- }
3068
+ /** Name of the aggregator to store on-chain. */
3069
+ name;
3070
+ /** Metadata of the aggregator to store on-chain. */
3071
+ metadata;
3072
+ /** Reserved. */
3073
+ reserved1;
3074
+ /** Pubkey of the queue the aggregator belongs to. */
3075
+ queuePubkey;
3076
+ /**
3077
+ * CONFIGS
3078
+ * Number of oracles assigned to an update request.
3079
+ */
3080
+ oracleRequestBatchSize;
3081
+ /** Minimum number of oracle responses required before a round is validated. */
3082
+ minOracleResults;
3083
+ /** Minimum number of job results before an oracle accepts a result. */
3084
+ minJobResults;
3085
+ /** Minimum number of seconds required between aggregator rounds. */
3086
+ minUpdateDelaySeconds;
3087
+ /** Unix timestamp for which no feed update will occur before. */
3088
+ startAfter;
3089
+ /** Change percentage required between a previous round and the current round. If variance percentage is not met, reject new oracle responses. */
3090
+ varianceThreshold;
3091
+ /** Number of seconds for which, even if the variance threshold is not passed, accept new responses from oracles. */
3092
+ forceReportPeriod;
3093
+ /** Timestamp when the feed is no longer needed. */
3094
+ expiration;
3095
+ /** Counter for the number of consecutive failures before a feed is removed from a queue. If set to 0, failed feeds will remain on the queue. */
3096
+ consecutiveFailureCount;
3097
+ /** Timestamp when the next update request will be available. */
3098
+ nextAllowedUpdateTime;
3099
+ /** Flag for whether an aggregators configuration is locked for editing. */
3100
+ isLocked;
3101
+ /** Optional, public key of the crank the aggregator is currently using. Event based feeds do not need a crank. */
3102
+ crankPubkey;
3103
+ /** Latest confirmed update request result that has been accepted as valid. */
3104
+ latestConfirmedRound;
3105
+ /** Oracle results from the current round of update request that has not been accepted as valid yet. */
3106
+ currentRound;
3107
+ /** List of public keys containing the job definitions for how data is sourced off-chain by oracles. */
3108
+ jobPubkeysData;
3109
+ /** Used to protect against malicious RPC nodes providing incorrect task definitions to oracles before fulfillment. */
3110
+ jobHashes;
3111
+ /** Number of jobs assigned to an oracle. */
3112
+ jobPubkeysSize;
3113
+ /** Used to protect against malicious RPC nodes providing incorrect task definitions to oracles before fulfillment. */
3114
+ jobsChecksum;
3115
+ /** The account delegated as the authority for making account changes. */
3116
+ authority;
3117
+ /** Optional, public key of a history buffer account storing the last N accepted results and their timestamps. */
3118
+ historyBuffer;
3119
+ /** The previous confirmed round result. */
3120
+ previousConfirmedRoundResult;
3121
+ /** The slot when the previous confirmed round was opened. */
3122
+ previousConfirmedRoundSlot;
3123
+ /** Whether an aggregator is permitted to join a crank. */
3124
+ disableCrank;
3125
+ /** Job weights used for the weighted median of the aggregator's assigned job accounts. */
3126
+ jobWeights;
3127
+ /** Unix timestamp when the feed was created. */
3128
+ creationTimestamp;
3129
+ /**
3130
+ * Use sliding window or round based resolution
3131
+ * NOTE: This changes result propogation in latest_round_result
3132
+ */
3133
+ resolutionMode;
3134
+ basePriorityFee;
3135
+ priorityFeeBump;
3136
+ priorityFeeBumpPeriod;
3137
+ maxPriorityFeeMultiplier;
3138
+ /** Reserved for future info. */
3139
+ ebuf;
3140
+ static discriminator = Buffer.from([
3141
+ 217,
3142
+ 230,
3143
+ 65,
3144
+ 101,
3145
+ 201,
3146
+ 162,
3147
+ 27,
3148
+ 125
3149
+ ]);
3150
+ static layout = __coral_xyz_borsh.struct([
3151
+ __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 32, "name"),
3152
+ __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 128, "metadata"),
3153
+ __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 32, "reserved1"),
3154
+ __coral_xyz_borsh.publicKey("queuePubkey"),
3155
+ __coral_xyz_borsh.u32("oracleRequestBatchSize"),
3156
+ __coral_xyz_borsh.u32("minOracleResults"),
3157
+ __coral_xyz_borsh.u32("minJobResults"),
3158
+ __coral_xyz_borsh.u32("minUpdateDelaySeconds"),
3159
+ __coral_xyz_borsh.i64("startAfter"),
3160
+ SwitchboardDecimal.layout("varianceThreshold"),
3161
+ __coral_xyz_borsh.i64("forceReportPeriod"),
3162
+ __coral_xyz_borsh.i64("expiration"),
3163
+ __coral_xyz_borsh.u64("consecutiveFailureCount"),
3164
+ __coral_xyz_borsh.i64("nextAllowedUpdateTime"),
3165
+ __coral_xyz_borsh.bool("isLocked"),
3166
+ __coral_xyz_borsh.publicKey("crankPubkey"),
3167
+ AggregatorRound.layout("latestConfirmedRound"),
3168
+ AggregatorRound.layout("currentRound"),
3169
+ __coral_xyz_borsh.array(__coral_xyz_borsh.publicKey(), 16, "jobPubkeysData"),
3170
+ __coral_xyz_borsh.array(Hash.layout({}), 16, "jobHashes"),
3171
+ __coral_xyz_borsh.u32("jobPubkeysSize"),
3172
+ __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 32, "jobsChecksum"),
3173
+ __coral_xyz_borsh.publicKey("authority"),
3174
+ __coral_xyz_borsh.publicKey("historyBuffer"),
3175
+ SwitchboardDecimal.layout("previousConfirmedRoundResult"),
3176
+ __coral_xyz_borsh.u64("previousConfirmedRoundSlot"),
3177
+ __coral_xyz_borsh.bool("disableCrank"),
3178
+ __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 16, "jobWeights"),
3179
+ __coral_xyz_borsh.i64("creationTimestamp"),
3180
+ layout("resolutionMode"),
3181
+ __coral_xyz_borsh.u32("basePriorityFee"),
3182
+ __coral_xyz_borsh.u32("priorityFeeBump"),
3183
+ __coral_xyz_borsh.u32("priorityFeeBumpPeriod"),
3184
+ __coral_xyz_borsh.u32("maxPriorityFeeMultiplier"),
3185
+ __coral_xyz_borsh.array(__coral_xyz_borsh.u8(), 122, "ebuf")
3186
+ ]);
3104
3187
  constructor(fields) {
3105
3188
  this.name = fields.name;
3106
3189
  this.metadata = fields.metadata;
@@ -6860,7 +6943,8 @@ function decodeSwitchboardPullFeedData(data) {
6860
6943
 
6861
6944
  //#endregion
6862
6945
  //#region src/vendor/index.ts
6863
- var vendor_exports = /* @__PURE__ */ __export({
6946
+ var vendor_exports = {};
6947
+ __export(vendor_exports, {
6864
6948
  AccountType: () => AccountType$1,
6865
6949
  AggregatorAccount: () => AggregatorAccount,
6866
6950
  AggregatorAccountData: () => AggregatorAccountData,
@@ -11668,6 +11752,8 @@ function isWeightedPrice(reqType) {
11668
11752
  //#endregion
11669
11753
  //#region src/models/account/wrapper.ts
11670
11754
  var LendrAccountWrapper = class LendrAccountWrapper {
11755
+ address;
11756
+ _lendrAccount;
11671
11757
  /**
11672
11758
  * @internal
11673
11759
  */
@@ -13350,6 +13436,7 @@ var HealthCache = class HealthCache {
13350
13436
  //#endregion
13351
13437
  //#region src/services/transaction/helpers/bundle-sending.ts
13352
13438
  var SendBundleError = class extends Error {
13439
+ bundleId;
13353
13440
  constructor(message, bundleId) {
13354
13441
  super(message);
13355
13442
  Object.setPrototypeOf(this, new.target.prototype);
@@ -19510,6 +19597,11 @@ let ProcessTransactionErrorType = /* @__PURE__ */ function(ProcessTransactionErr
19510
19597
  return ProcessTransactionErrorType$1;
19511
19598
  }({});
19512
19599
  var ProcessTransactionError = class ProcessTransactionError extends Error {
19600
+ logs;
19601
+ type;
19602
+ programId;
19603
+ failedTxs;
19604
+ _error;
19513
19605
  constructor({ message, type, logs, programId, code, failedTxs, _error }) {
19514
19606
  super(message);
19515
19607
  this.programId = programId;
@@ -20909,6 +21001,8 @@ function healthCacheToDto(healthCache) {
20909
21001
  * Custom error class for health cache simulation failures
20910
21002
  */
20911
21003
  var HealthCacheSimulationError = class HealthCacheSimulationError extends Error {
21004
+ lndrErr;
21005
+ internalErr;
20912
21006
  constructor(message, lndrErr, internalErr) {
20913
21007
  super(message);
20914
21008
  this.name = "HealthCacheSimulationError";
@@ -21338,9 +21432,12 @@ const metadataSchema = zod_v4_mini.z.object({
21338
21432
  });
21339
21433
  const endpointSchema = zod_v4_mini.z.record(zod_v4_mini.z.string(), metadataSchema);
21340
21434
  var MetadataService = class {
21435
+ /** NOTE: record key is base58 of mint public key */
21436
+ _cache = new Map();
21437
+ /** NOTE: record key is base58 of mint public key */
21438
+ overrides;
21341
21439
  constructor(connection, overrides = {}) {
21342
21440
  this.connection = connection;
21343
- this._cache = new Map();
21344
21441
  this.overrides = overrides;
21345
21442
  }
21346
21443
  async forMints(mints) {
@@ -21707,6 +21804,8 @@ function fetchLatestIdl() {
21707
21804
  //#endregion
21708
21805
  //#region src/models/group.ts
21709
21806
  var LendrGroup = class LendrGroup {
21807
+ address;
21808
+ admin;
21710
21809
  constructor(admin, address$2) {
21711
21810
  this.admin = admin;
21712
21811
  this.address = address$2;
@@ -21756,6 +21855,24 @@ var LendrGroup = class LendrGroup {
21756
21855
  * Entrypoint to interact with the lendr contract.
21757
21856
  */
21758
21857
  var LendrClient = class LendrClient {
21858
+ program;
21859
+ wallet;
21860
+ config;
21861
+ isReadOnly;
21862
+ logger;
21863
+ group;
21864
+ banks;
21865
+ oraclePrices;
21866
+ mintDatas;
21867
+ addressLookupTables;
21868
+ lookupTablesAddresses;
21869
+ feedIdMap;
21870
+ processTransactionStrategy;
21871
+ bundleSimRpcEndpoint;
21872
+ bankMetadataMap;
21873
+ overrideBankAddresses;
21874
+ overrideBanksMetadata;
21875
+ metadataService;
21759
21876
  constructor({ program, wallet, config, isReadOnly, group, banks, priceInfos, mintDatas, addressLookupTables, feedIdMap, logger, bankMetadataMap, overrideBanksMetadata, overrideBankAddresses, bundleSimRpcEndpoint, processTransactionStrategy, lookupTablesAddresses, metadataService }) {
21760
21877
  this.program = program;
21761
21878
  this.wallet = wallet;
@@ -21854,165 +21971,174 @@ var LendrClient = class LendrClient {
21854
21971
  const accounts$2 = await Promise.all(addressLookupTableAddresses.map((address$2) => connection.getAddressLookupTable(address$2)));
21855
21972
  return accounts$2.map((response) => response?.value).filter((table) => table !== null);
21856
21973
  }
21857
- static {
21858
- this.fetchGroupData = async ({ connection, program, groupAddress, commitment, overrideBanksMetadata, overrideBankAddresses, logger = new NoopLogger(), metadataService }) => {
21859
- const banksRawData = await LendrClient.fetchRawBanks({
21860
- program,
21861
- groupAddress,
21862
- logger,
21863
- bankAddresses: overrideBankAddresses,
21864
- commitment
21865
- });
21866
- const feedIdMap = await buildFeedIdMap(banksRawData.map((b) => b.data.config), program.provider.connection);
21867
- const mintKeys = [];
21868
- const emissionMintKeys = [];
21869
- const oracleKeys = [];
21870
- for (const bank of banksRawData) {
21871
- mintKeys.push(bank.data.mint);
21872
- if (!bank.data.emissionsMint.equals(__solana_web3_js.PublicKey.default)) {
21873
- emissionMintKeys.push(bank.data.emissionsMint);
21874
- }
21875
- oracleKeys.push(findOracleKey(BankConfig.fromAccountParsed(bank.data.config), feedIdMap).oracleKey);
21974
+ /**
21975
+ * Fetches all data for a group, including banks and oracle prices
21976
+ * NOTE: If bankAddresses not provided, this will make 2 RPC calls
21977
+ * @param connection
21978
+ * @param program The Lendr program
21979
+ * @param groupAddress The address of the group
21980
+ * @param logger Optional logger
21981
+ * @param commitment Transaction commitment level
21982
+ * @param overrideBankAddresses Optional list of bank addresses to fetch
21983
+ * @param overrideBanksMetadata Optional bank metadata for overriding on-chain metadata
21984
+ * @param metadataService Metadata service for fetching mint metadata
21985
+ * @returns Lending group data, banks, and oracle prices
21986
+ */
21987
+ static fetchGroupData = async ({ connection, program, groupAddress, commitment, overrideBanksMetadata, overrideBankAddresses, logger = new NoopLogger(), metadataService }) => {
21988
+ const banksRawData = await LendrClient.fetchRawBanks({
21989
+ program,
21990
+ groupAddress,
21991
+ logger,
21992
+ bankAddresses: overrideBankAddresses,
21993
+ commitment
21994
+ });
21995
+ const feedIdMap = await buildFeedIdMap(banksRawData.map((b) => b.data.config), program.provider.connection);
21996
+ const mintKeys = [];
21997
+ const emissionMintKeys = [];
21998
+ const oracleKeys = [];
21999
+ for (const bank of banksRawData) {
22000
+ mintKeys.push(bank.data.mint);
22001
+ if (!bank.data.emissionsMint.equals(__solana_web3_js.PublicKey.default)) {
22002
+ emissionMintKeys.push(bank.data.emissionsMint);
21876
22003
  }
21877
- const allAccountInfos = await chunkedGetRawMultipleAccountInfoOrdered(program.provider.connection, [
21878
- groupAddress.toBase58(),
21879
- ...oracleKeys.map((pk) => pk.toBase58()),
21880
- ...mintKeys.map((pk) => pk.toBase58()),
21881
- ...emissionMintKeys.map((pk) => pk.toBase58())
21882
- ]);
21883
- const groupAccountInfo = allAccountInfos.shift();
21884
- if (!groupAccountInfo) {
21885
- throw new Error("Failed to fetch the on-chain group data");
22004
+ oracleKeys.push(findOracleKey(BankConfig.fromAccountParsed(bank.data.config), feedIdMap).oracleKey);
22005
+ }
22006
+ const allAccountInfos = await chunkedGetRawMultipleAccountInfoOrdered(program.provider.connection, [
22007
+ groupAddress.toBase58(),
22008
+ ...oracleKeys.map((pk) => pk.toBase58()),
22009
+ ...mintKeys.map((pk) => pk.toBase58()),
22010
+ ...emissionMintKeys.map((pk) => pk.toBase58())
22011
+ ]);
22012
+ const groupAccountInfo = allAccountInfos.shift();
22013
+ if (!groupAccountInfo) {
22014
+ throw new Error("Failed to fetch the on-chain group data");
22015
+ }
22016
+ const oracleAccountInfos = allAccountInfos.splice(0, oracleKeys.length);
22017
+ const mintAccountInfos = allAccountInfos.splice(0, mintKeys.length);
22018
+ const emissionMintAccountInfos = allAccountInfos.splice(0);
22019
+ const lendrGroup = LendrGroup.fromBuffer(groupAddress, groupAccountInfo.data, program.idl);
22020
+ const banksExtendedMetadata = await fetchBanksExtendedMetadata({
22021
+ mintsWithOwner: mintKeys.map((mint, idx) => ({
22022
+ mint,
22023
+ owner: mintAccountInfos[idx].owner
22024
+ })),
22025
+ metadataService,
22026
+ logger,
22027
+ overrideBanksMetadata
22028
+ });
22029
+ const banks = new Map();
22030
+ const priceInfos = new Map();
22031
+ const pythStakedCollateralBanks = [];
22032
+ const tokensData = new Map();
22033
+ const stakedCollatMap = {};
22034
+ const solPools = [];
22035
+ const mints = [];
22036
+ banksRawData.forEach(({ address: address$2, data }, index) => {
22037
+ const bankAddressStr = address$2.toBase58();
22038
+ const metadata$2 = banksExtendedMetadata.get(data.mint.toBase58());
22039
+ const mintDataRaw = mintAccountInfos[index];
22040
+ if (!mintDataRaw) {
22041
+ throw new Error(`Failed to fetch mint account for bank ${bankAddressStr}`);
21886
22042
  }
21887
- const oracleAccountInfos = allAccountInfos.splice(0, oracleKeys.length);
21888
- const mintAccountInfos = allAccountInfos.splice(0, mintKeys.length);
21889
- const emissionMintAccountInfos = allAccountInfos.splice(0);
21890
- const lendrGroup = LendrGroup.fromBuffer(groupAddress, groupAccountInfo.data, program.idl);
21891
- const banksExtendedMetadata = await fetchBanksExtendedMetadata({
21892
- mintsWithOwner: mintKeys.map((mint, idx) => ({
21893
- mint,
21894
- owner: mintAccountInfos[idx].owner
21895
- })),
21896
- metadataService,
21897
- logger,
21898
- overrideBanksMetadata
21899
- });
21900
- const banks = new Map();
21901
- const priceInfos = new Map();
21902
- const pythStakedCollateralBanks = [];
21903
- const tokensData = new Map();
21904
- const stakedCollatMap = {};
21905
- const solPools = [];
21906
- const mints = [];
21907
- banksRawData.forEach(({ address: address$2, data }, index) => {
21908
- const bankAddressStr = address$2.toBase58();
21909
- const metadata$2 = banksExtendedMetadata.get(data.mint.toBase58());
21910
- const mintDataRaw = mintAccountInfos[index];
21911
- if (!mintDataRaw) {
21912
- throw new Error(`Failed to fetch mint account for bank ${bankAddressStr}`);
21913
- }
21914
- const priceDataRaw = oracleAccountInfos[index];
21915
- if (!priceDataRaw) {
21916
- throw new Error(`Failed to fetch price oracle account for bank ${bankAddressStr}`);
21917
- }
21918
- const bank = Bank.fromAccountParsed(address$2, data, feedIdMap, metadata$2, mintDataRaw.owner);
21919
- banks.set(bankAddressStr, bank);
21920
- let emissionTokenProgram = null;
21921
- if (!data.emissionsMint.equals(__solana_web3_js.PublicKey.default)) {
21922
- const emissionMintDataRawIndex = emissionMintKeys.findIndex((pk) => pk.equals(data.emissionsMint));
21923
- emissionTokenProgram = emissionMintDataRawIndex >= 0 ? emissionMintAccountInfos[emissionMintDataRawIndex].owner : null;
21924
- }
21925
- tokensData.set(bankAddressStr, {
21926
- mint: mintKeys[index],
21927
- tokenProgram: mintDataRaw.owner,
21928
- feeBps: 0,
21929
- emissionTokenProgram
21930
- });
21931
- const oracleSetup = parseOracleSetup(data.config.oracleSetup);
21932
- priceInfos.set(bankAddressStr, parseOraclePriceData(oracleSetup, priceDataRaw.data, logger));
21933
- if (oracleSetup === OracleSetup.StakedWithPythPush && metadata$2?.validatorVoteAccount) {
21934
- const [poolAddress] = __solana_web3_js.PublicKey.findProgramAddressSync([Buffer.from("pool"), new __solana_web3_js.PublicKey(metadata$2.validatorVoteAccount).toBuffer()], SINGLE_POOL_PROGRAM_ID);
21935
- const [stakePoolAddress] = __solana_web3_js.PublicKey.findProgramAddressSync([Buffer.from("stake"), poolAddress.toBuffer()], SINGLE_POOL_PROGRAM_ID);
21936
- stakedCollatMap[address$2.toBase58()] = {
21937
- bankAddress: address$2,
21938
- mint: new __solana_web3_js.PublicKey(metadata$2.mint),
21939
- stakePoolAddress,
21940
- poolAddress
21941
- };
21942
- solPools.push(stakePoolAddress.toBase58());
21943
- mints.push(metadata$2.mint);
21944
- }
21945
- });
21946
- const dataAis = await chunkedGetRawMultipleAccountInfoOrdered(program.provider.connection, [...mints, ...solPools]);
21947
- const stakePoolsAis = dataAis.slice(mints.length).map((ai) => getStakeAccount(ai.data));
21948
- const lstMintsAis = dataAis.slice(0, mints.length).map((mintAi) => __solana_spl_token.MintLayout.decode(mintAi.data));
21949
- const lstMintRecord = Object.fromEntries(mints.map((mint, i) => [mint, lstMintsAis[i]]));
21950
- const solPoolsRecord = Object.fromEntries(solPools.map((poolKey, i) => [poolKey, stakePoolsAis[i]]));
21951
- for (const index in stakedCollatMap) {
21952
- const { bankAddress, mint, stakePoolAddress, poolAddress } = stakedCollatMap[index];
21953
- const stakeAccount = solPoolsRecord[stakePoolAddress.toBase58()];
21954
- const tokenSupply = lstMintRecord[mint.toBase58()].supply;
21955
- const stakeActual = Number(stakeAccount.stake.delegation.stake);
21956
- const oracle = priceInfos.get(bankAddress.toBase58());
21957
- if (oracle) {
21958
- const adjustPrice = (price, stakeActual$1, tokenSupply$1) => {
21959
- return Number(tokenSupply$1) === 0 ? price : new bignumber_js.default(price.toNumber() * (stakeActual$1 - __solana_web3_js.LAMPORTS_PER_SOL) / Number(tokenSupply$1));
21960
- };
21961
- const adjustPriceComponent$1 = (priceComponent, stakeActual$1, tokenSupply$1) => ({
21962
- price: adjustPrice(priceComponent.price, stakeActual$1, tokenSupply$1),
21963
- confidence: priceComponent.confidence,
21964
- lowestPrice: adjustPrice(priceComponent.lowestPrice, stakeActual$1, tokenSupply$1),
21965
- highestPrice: adjustPrice(priceComponent.highestPrice, stakeActual$1, tokenSupply$1)
21966
- });
21967
- const oraclePrice = {
21968
- timestamp: oracle.timestamp,
21969
- priceRealtime: adjustPriceComponent$1(oracle.priceRealtime, stakeActual, tokenSupply),
21970
- priceWeighted: adjustPriceComponent$1(oracle.priceWeighted, stakeActual, tokenSupply)
21971
- };
21972
- priceInfos.set(bankAddress.toBase58(), oraclePrice);
21973
- }
22043
+ const priceDataRaw = oracleAccountInfos[index];
22044
+ if (!priceDataRaw) {
22045
+ throw new Error(`Failed to fetch price oracle account for bank ${bankAddressStr}`);
21974
22046
  }
21975
- logger.debug({
21976
- banksSize: banks.size,
21977
- priceFeedsSize: priceInfos.size
21978
- }, "[lendr:client] Fetched banks and price feeds");
21979
- return {
21980
- lendrGroup,
21981
- banks,
21982
- priceInfos,
21983
- tokensData,
21984
- feedIdMap,
21985
- banksExtendedMetadata
21986
- };
21987
- };
21988
- }
21989
- static {
21990
- this.fetchRawBanks = async ({ groupAddress, bankAddresses, program, logger = new NoopLogger(), commitment }) => {
21991
- if (!bankAddresses || bankAddresses.length === 0) {
21992
- const bankAccountsData$1 = await program.account.bank.all([{ memcmp: {
21993
- offset: 8 + 32 + 1,
21994
- bytes: groupAddress.toBase58()
21995
- } }]);
21996
- return bankAccountsData$1.map((account) => ({
21997
- address: account.publicKey,
21998
- data: account.account
21999
- }));
22047
+ const bank = Bank.fromAccountParsed(address$2, data, feedIdMap, metadata$2, mintDataRaw.owner);
22048
+ banks.set(bankAddressStr, bank);
22049
+ let emissionTokenProgram = null;
22050
+ if (!data.emissionsMint.equals(__solana_web3_js.PublicKey.default)) {
22051
+ const emissionMintDataRawIndex = emissionMintKeys.findIndex((pk) => pk.equals(data.emissionsMint));
22052
+ emissionTokenProgram = emissionMintDataRawIndex >= 0 ? emissionMintAccountInfos[emissionMintDataRawIndex].owner : null;
22000
22053
  }
22001
- logger.debug({ banksLength: bankAddresses.length }, "[lending:client] Using preloaded bank addresses, skipping gpa call");
22002
- const bankAccountsData = await program.account.bank.fetchMultiple(bankAddresses, commitment);
22003
- const banksRawData = [];
22004
- for (let i = 0; i < bankAccountsData.length; i++) {
22005
- if (bankAccountsData[i] === null) {
22006
- continue;
22007
- }
22008
- banksRawData.push({
22009
- address: bankAddresses[i],
22010
- data: bankAccountsData[i]
22054
+ tokensData.set(bankAddressStr, {
22055
+ mint: mintKeys[index],
22056
+ tokenProgram: mintDataRaw.owner,
22057
+ feeBps: 0,
22058
+ emissionTokenProgram
22059
+ });
22060
+ const oracleSetup = parseOracleSetup(data.config.oracleSetup);
22061
+ priceInfos.set(bankAddressStr, parseOraclePriceData(oracleSetup, priceDataRaw.data, logger));
22062
+ if (oracleSetup === OracleSetup.StakedWithPythPush && metadata$2?.validatorVoteAccount) {
22063
+ const [poolAddress] = __solana_web3_js.PublicKey.findProgramAddressSync([Buffer.from("pool"), new __solana_web3_js.PublicKey(metadata$2.validatorVoteAccount).toBuffer()], SINGLE_POOL_PROGRAM_ID);
22064
+ const [stakePoolAddress] = __solana_web3_js.PublicKey.findProgramAddressSync([Buffer.from("stake"), poolAddress.toBuffer()], SINGLE_POOL_PROGRAM_ID);
22065
+ stakedCollatMap[address$2.toBase58()] = {
22066
+ bankAddress: address$2,
22067
+ mint: new __solana_web3_js.PublicKey(metadata$2.mint),
22068
+ stakePoolAddress,
22069
+ poolAddress
22070
+ };
22071
+ solPools.push(stakePoolAddress.toBase58());
22072
+ mints.push(metadata$2.mint);
22073
+ }
22074
+ });
22075
+ const dataAis = await chunkedGetRawMultipleAccountInfoOrdered(program.provider.connection, [...mints, ...solPools]);
22076
+ const stakePoolsAis = dataAis.slice(mints.length).map((ai) => getStakeAccount(ai.data));
22077
+ const lstMintsAis = dataAis.slice(0, mints.length).map((mintAi) => __solana_spl_token.MintLayout.decode(mintAi.data));
22078
+ const lstMintRecord = Object.fromEntries(mints.map((mint, i) => [mint, lstMintsAis[i]]));
22079
+ const solPoolsRecord = Object.fromEntries(solPools.map((poolKey, i) => [poolKey, stakePoolsAis[i]]));
22080
+ for (const index in stakedCollatMap) {
22081
+ const { bankAddress, mint, stakePoolAddress, poolAddress } = stakedCollatMap[index];
22082
+ const stakeAccount = solPoolsRecord[stakePoolAddress.toBase58()];
22083
+ const tokenSupply = lstMintRecord[mint.toBase58()].supply;
22084
+ const stakeActual = Number(stakeAccount.stake.delegation.stake);
22085
+ const oracle = priceInfos.get(bankAddress.toBase58());
22086
+ if (oracle) {
22087
+ const adjustPrice = (price, stakeActual$1, tokenSupply$1) => {
22088
+ return Number(tokenSupply$1) === 0 ? price : new bignumber_js.default(price.toNumber() * (stakeActual$1 - __solana_web3_js.LAMPORTS_PER_SOL) / Number(tokenSupply$1));
22089
+ };
22090
+ const adjustPriceComponent$1 = (priceComponent, stakeActual$1, tokenSupply$1) => ({
22091
+ price: adjustPrice(priceComponent.price, stakeActual$1, tokenSupply$1),
22092
+ confidence: priceComponent.confidence,
22093
+ lowestPrice: adjustPrice(priceComponent.lowestPrice, stakeActual$1, tokenSupply$1),
22094
+ highestPrice: adjustPrice(priceComponent.highestPrice, stakeActual$1, tokenSupply$1)
22011
22095
  });
22096
+ const oraclePrice = {
22097
+ timestamp: oracle.timestamp,
22098
+ priceRealtime: adjustPriceComponent$1(oracle.priceRealtime, stakeActual, tokenSupply),
22099
+ priceWeighted: adjustPriceComponent$1(oracle.priceWeighted, stakeActual, tokenSupply)
22100
+ };
22101
+ priceInfos.set(bankAddress.toBase58(), oraclePrice);
22012
22102
  }
22013
- return banksRawData;
22103
+ }
22104
+ logger.debug({
22105
+ banksSize: banks.size,
22106
+ priceFeedsSize: priceInfos.size
22107
+ }, "[lendr:client] Fetched banks and price feeds");
22108
+ return {
22109
+ lendrGroup,
22110
+ banks,
22111
+ priceInfos,
22112
+ tokensData,
22113
+ feedIdMap,
22114
+ banksExtendedMetadata
22014
22115
  };
22015
- }
22116
+ };
22117
+ static fetchRawBanks = async ({ groupAddress, bankAddresses, program, logger = new NoopLogger(), commitment }) => {
22118
+ if (!bankAddresses || bankAddresses.length === 0) {
22119
+ const bankAccountsData$1 = await program.account.bank.all([{ memcmp: {
22120
+ offset: 8 + 32 + 1,
22121
+ bytes: groupAddress.toBase58()
22122
+ } }]);
22123
+ return bankAccountsData$1.map((account) => ({
22124
+ address: account.publicKey,
22125
+ data: account.account
22126
+ }));
22127
+ }
22128
+ logger.debug({ banksLength: bankAddresses.length }, "[lending:client] Using preloaded bank addresses, skipping gpa call");
22129
+ const bankAccountsData = await program.account.bank.fetchMultiple(bankAddresses, commitment);
22130
+ const banksRawData = [];
22131
+ for (let i = 0; i < bankAccountsData.length; i++) {
22132
+ if (bankAccountsData[i] === null) {
22133
+ continue;
22134
+ }
22135
+ banksRawData.push({
22136
+ address: bankAddresses[i],
22137
+ data: bankAccountsData[i]
22138
+ });
22139
+ }
22140
+ return banksRawData;
22141
+ };
22016
22142
  async reload() {
22017
22143
  const { lendrGroup, banks, priceInfos, tokensData, feedIdMap, banksExtendedMetadata } = await LendrClient.fetchGroupData({
22018
22144
  connection: this.program.provider.connection,