@wireio/stake 0.5.1 → 0.6.0

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.
@@ -8013,8 +8013,31 @@ class DepositClient {
8013
8013
  }
8014
8014
 
8015
8015
  const INDEX_SCALE = BigInt(1e12);
8016
- BigInt(1e8);
8017
- const BPS$1 = BigInt(1e4);
8016
+ const USD_SCALE = BigInt(1e8);
8017
+ const BPS = BigInt(1e4);
8018
+ function growSupplyOnce$1(value, growthBps) {
8019
+ const g = BigInt(growthBps);
8020
+ return (value * (BPS + g) + BPS / BigInt(2)) / BPS;
8021
+ }
8022
+ function shrinkSupplyOnce$1(value, growthBps) {
8023
+ const g = BigInt(growthBps);
8024
+ return (value * BPS + (BPS + g) / BigInt(2)) / (BPS + g);
8025
+ }
8026
+ function priceStepUsd1e8(priceGrowthCents) {
8027
+ if (!priceGrowthCents) return BigInt(0);
8028
+ const CENT_SCALE = USD_SCALE / BigInt(100);
8029
+ return BigInt(priceGrowthCents) * CENT_SCALE;
8030
+ }
8031
+ function growPriceOnceUsd1e8(value, priceGrowthCents) {
8032
+ const step = priceStepUsd1e8(priceGrowthCents);
8033
+ return value + step;
8034
+ }
8035
+ function shrinkPriceOnceUsd1e8(value, priceGrowthCents) {
8036
+ const step = priceStepUsd1e8(priceGrowthCents);
8037
+ if (step === BigInt(0)) return value;
8038
+ if (value <= step) return BigInt(0);
8039
+ return value - step;
8040
+ }
8018
8041
  function toBigint(x) {
8019
8042
  if (typeof x === "bigint") return x;
8020
8043
  if (typeof x === "number") return BigInt(x);
@@ -8027,14 +8050,6 @@ function tokensToShares(amount, currentIndex) {
8027
8050
  const r = num % currentIndex;
8028
8051
  return r === BigInt(0) ? q : q + BigInt(1);
8029
8052
  }
8030
- function growOnce$1(value, growthBps) {
8031
- const g = BigInt(growthBps);
8032
- return (value * (BPS$1 + g) + BPS$1 / BigInt(2)) / BPS$1;
8033
- }
8034
- function shrinkOnce$1(value, growthBps) {
8035
- const g = BigInt(growthBps);
8036
- return (value * BPS$1 + (BPS$1 + g) / BigInt(2)) / (BPS$1 + g);
8037
- }
8038
8053
  function buildSolanaTrancheLadder(options) {
8039
8054
  const {
8040
8055
  currentTranche,
@@ -8055,14 +8070,14 @@ function buildSolanaTrancheLadder(options) {
8055
8070
  for (let id = currentTranche + 1; id <= endId; id++) {
8056
8071
  const prevCap = capacity.get(id - 1);
8057
8072
  const prevPrice = price.get(id - 1);
8058
- capacity.set(id, growOnce$1(prevCap, supplyGrowthBps));
8059
- price.set(id, growOnce$1(prevPrice, priceGrowthCents));
8073
+ capacity.set(id, growSupplyOnce$1(prevCap, supplyGrowthBps));
8074
+ price.set(id, growPriceOnceUsd1e8(prevPrice, priceGrowthCents));
8060
8075
  }
8061
8076
  for (let id = currentTranche - 1; id >= startId; id--) {
8062
8077
  const nextCap = capacity.get(id + 1);
8063
8078
  const nextPrice = price.get(id + 1);
8064
- capacity.set(id, shrinkOnce$1(nextCap, supplyGrowthBps));
8065
- price.set(id, shrinkOnce$1(nextPrice, priceGrowthCents));
8079
+ capacity.set(id, shrinkSupplyOnce$1(nextCap, supplyGrowthBps));
8080
+ price.set(id, shrinkPriceOnceUsd1e8(nextPrice, priceGrowthCents));
8066
8081
  }
8067
8082
  const ladder = [];
8068
8083
  for (let id = startId; id <= endId; id++) {
@@ -8880,7 +8895,7 @@ class TokenClient {
8880
8895
 
8881
8896
  const commitment = "confirmed";
8882
8897
  const SCALE = new BN("1000000000000");
8883
- class SolanaStakingClient {
8898
+ const _SolanaStakingClient = class _SolanaStakingClient {
8884
8899
  constructor(config) {
8885
8900
  this.config = config;
8886
8901
  const adapter = config.provider;
@@ -8952,6 +8967,7 @@ class SolanaStakingClient {
8952
8967
  this.leaderboardClient = new LeaderboardClient(this.anchor);
8953
8968
  this.outpostClient = new OutpostClient(this.anchor);
8954
8969
  this.tokenClient = new TokenClient(this.anchor);
8970
+ this.program = new SolanaProgramService(this.anchor);
8955
8971
  }
8956
8972
  get solPubKey() {
8957
8973
  if (!this.pubKey) throw new Error("pubKey is undefined");
@@ -9116,17 +9132,51 @@ class SolanaStakingClient {
9116
9132
  return this.distributionClient.getUserRecord(this.solPubKey);
9117
9133
  }
9118
9134
  async getSystemAPY() {
9119
- const avgPayRate = await this.distributionClient.getAverageScaledPayRate(5);
9120
- if (avgPayRate.isZero()) {
9121
- return 0;
9122
- }
9123
- const SCALE2 = new BN("1000000000000");
9124
- const EPOCHS_PER_YEAR = 365;
9125
- const ratePerPeriod = avgPayRate.toNumber() / SCALE2.toNumber();
9126
- const apyDecimal = ratePerPeriod * EPOCHS_PER_YEAR;
9135
+ const ratePerEpoch = await this.getEpochRateDecimalFromProgram();
9136
+ const epochsPerYear = await this.getEpochsPerYearFromCluster();
9137
+ const apyDecimal = Math.pow(1 + ratePerEpoch, epochsPerYear) - 1;
9127
9138
  const apyPercent = apyDecimal * 100;
9128
9139
  return apyPercent;
9129
9140
  }
9141
+ async getEpochRateDecimalFromProgram() {
9142
+ const liqSolCoreProgram = this.program.getProgram("liqsolCore");
9143
+ const stakeMetricsPda = deriveStakeMetricsPda();
9144
+ const stakeMetrics = await liqSolCoreProgram.account.stakeMetrics.fetch(stakeMetricsPda);
9145
+ const raw = BigInt(stakeMetrics.solSystemPayRate.toString());
9146
+ const rateDecimal = Number(raw) / Number(PAY_RATE_SCALE_FACTOR);
9147
+ return rateDecimal;
9148
+ }
9149
+ async getEpochsPerYearFromCluster() {
9150
+ const now = Date.now();
9151
+ if (this.epochsPerYearCache && now - this.epochsPerYearCache.fetchedAt < _SolanaStakingClient.EPOCHS_PER_YEAR_TTL_MS) {
9152
+ return this.epochsPerYearCache.value;
9153
+ }
9154
+ const connection = this.anchor.connection;
9155
+ const samples = await connection.getRecentPerformanceSamples(
9156
+ 60
9157
+ );
9158
+ if (!samples.length) {
9159
+ throw new Error("No performance samples available from cluster");
9160
+ }
9161
+ const totalSlots = samples.reduce((acc, s) => acc + s.numSlots, 0);
9162
+ const totalSecs = samples.reduce((acc, s) => acc + s.samplePeriodSecs, 0);
9163
+ if (totalSecs === 0) {
9164
+ throw new Error(
9165
+ "Cluster returned zero samplePeriodSecs in performance samples"
9166
+ );
9167
+ }
9168
+ const slotsPerSecond = totalSlots / totalSecs;
9169
+ const epochInfo = await connection.getEpochInfo();
9170
+ const slotsPerEpoch = epochInfo.slotsInEpoch;
9171
+ const secondsPerEpoch = slotsPerEpoch / slotsPerSecond;
9172
+ const secondsPerYear = 365 * 24 * 60 * 60;
9173
+ const epochsPerYear = secondsPerYear / secondsPerEpoch;
9174
+ this.epochsPerYearCache = {
9175
+ value: epochsPerYear,
9176
+ fetchedAt: now
9177
+ };
9178
+ return epochsPerYear;
9179
+ }
9130
9180
  async getDepositFee(amountLamports, windowSize = 5) {
9131
9181
  if (amountLamports <= BigInt(0)) {
9132
9182
  return BigInt(0);
@@ -9248,7 +9298,9 @@ class SolanaStakingClient {
9248
9298
  );
9249
9299
  }
9250
9300
  }
9251
- }
9301
+ };
9302
+ _SolanaStakingClient.EPOCHS_PER_YEAR_TTL_MS = 10 * 60 * 1e3;
9303
+ let SolanaStakingClient = _SolanaStakingClient;
9252
9304
 
9253
9305
  var _format$q = "hh-sol-artifact-1";
9254
9306
  var contractName$q = "Accounting";
@@ -34781,22 +34833,22 @@ const ADDRESSES = {
34781
34833
  WithdrawalVault: "0xC82FAf3Fed135B70A7E797864F504819a98E96c4",
34782
34834
  StakingModule: "0xdd24EffAa4B42f3273E2b44995639119c08daBea",
34783
34835
  YieldOracle: "0x56A27E1d10d4aEc7402dC26693fb7c0Eb66eF802",
34784
- OutpostManagerAuthority: "0xAEcd2aa6EeFa4Aa7Cb9368728aA89Ca59Aa9ea59",
34785
- iodata: "0x2c2ab53F6Bc146bd31B459E832Ce0B9Da78712d8",
34786
- Base58: "0x9F188Ec124c9ad9bF6D195650d8360Fd052F585A",
34787
- sysio_merkle: "0x6eDA3C4c34421Cd667800C17fe33E48f5698e004",
34788
- ReceiptNFT: "0xd083051d9bb8353875abCecAB50C6e4FB5e527a8",
34789
- MockAggregator: "0xFCfc3ddd4CBd9Ad3b3af3A374B8bdA1b66eE6FFF",
34790
- Pool: "0xee5F11aC9b104c18d2423f266c5E737fC95ebA92",
34791
- OutpostManager: "0xB1B6ba7FA156652849069aC7ADB281283D235B9f",
34792
- sysio_write: "0xEfA608136d372349C09a7aA57665C09Fb4a620Ca",
34793
- EthUsdPriceConsumer: "0x6337A23b61f98b1526faF2848385Abe9cB4cFF21",
34794
- BAR: "0x9264eAA449da94caF70Fc18522021a94C8DF32Fb",
34795
- OPPCommon: "0x86A8cA16ce521De3EBdd1C541fAf188795b59FD0",
34796
- OPP: "0x79e8395Bb5131FB285aCEE5329BB43E66f50F88C",
34797
- Pretoken: "0x62f98AF2f9C3EF4eF2fA7bc0245BD5a9315E7541",
34798
- OPPInbound: "0xC85f57Ff069711e0b3472De3963bd2fC2FEfF3e2",
34799
- Depositor: "0xb0BACAb6f13dd96281300be13a6346461b2f35F3"
34836
+ OutpostManagerAuthority: "0x57A3723B9f3C6022CAe394C859655E59382Fad18",
34837
+ iodata: "0x88896d4fa70C3a7Fb833C80BB5763a4c53A6aCB5",
34838
+ Base58: "0x0E9E6e8A32477F3B086Aaa26db2b928a816Da711",
34839
+ sysio_merkle: "0xf5858B784B080A08063FAe06dB6d91c5BBAA48C7",
34840
+ ReceiptNFT: "0xF1F5e063bFF6E0c09b0ac8020376E16c0be8eA10",
34841
+ EthUsdPriceConsumer: "0xFdb3Ab290179CA85204aD1Ffb8c1c3c42AEB768F",
34842
+ Pool: "0x15DaeB9562c6Dd21558f14CcdDf5C855499B8693",
34843
+ OutpostManager: "0x1aCCc78FCA9e2Ea4dcE849bf072C2248f36435cC",
34844
+ sysio_write: "0x513e472904EE67A8E27ebaF2411f3ed3851F4514",
34845
+ Pretoken: "0xd7CDc79B90336720ecf02eD5A355cB0F7099F079",
34846
+ BAR: "0x4A01414dEA81b1961aE986Bc4E95B30f73770f99",
34847
+ OPPCommon: "0x3747Cc19A351BCBCE92055c419e7d710C4b399aA",
34848
+ OPP: "0xF577FDc80014ef19DF258243e0551c888Da809E4",
34849
+ Depositor: "0xD9Eb2A2d4e9eD7e2257153041B29DCeCDee8BCFe",
34850
+ OPPInbound: "0x232C01f2528A5013af3703bE4B4ce30A793Ee8BD",
34851
+ MockAggregator: "0xFCfc3ddd4CBd9Ad3b3af3A374B8bdA1b66eE6FFF"
34800
34852
  };
34801
34853
  const CONTRACTS = {
34802
34854
  LiqEthAuthority: {
@@ -34980,7 +35032,7 @@ class EthereumContractService {
34980
35032
  }
34981
35033
  }
34982
35034
 
34983
- const BPS = BigInt(1e4);
35035
+ BigInt(1e4);
34984
35036
  function formatContractErrors(err) {
34985
35037
  if (err.errorName && err.errorArgs) {
34986
35038
  const errorObj = {
@@ -35050,20 +35102,27 @@ async function sendOPPFinalize(opp, gasLimit) {
35050
35102
  throw err;
35051
35103
  }
35052
35104
  }
35053
- function growOnce(value, growthBps) {
35105
+ const BPS_DENOM = BigInt(1e4);
35106
+ const USD_ONCHAIN_SCALE = BigInt(1e18);
35107
+ const USD_CLIENT_SCALE = BigInt(1e8);
35108
+ const USD_SCALE_DOWN = USD_ONCHAIN_SCALE / USD_CLIENT_SCALE;
35109
+ function growSupplyOnce(value, growthBps) {
35054
35110
  const g = BigInt(growthBps);
35055
- return (value * (BPS + g) + BPS / BigInt(2)) / BPS;
35111
+ return value * (BPS_DENOM + g) / BPS_DENOM;
35056
35112
  }
35057
- function shrinkOnce(value, growthBps) {
35113
+ function shrinkSupplyOnce(value, growthBps) {
35058
35114
  const g = BigInt(growthBps);
35059
- return (value * BPS + (BPS + g) / BigInt(2)) / (BPS + g);
35115
+ return value * BPS_DENOM / (BPS_DENOM + g);
35060
35116
  }
35061
- function getTrancheSize(startSupply, supplyGrowthBps, trancheNumber) {
35062
- let supply = startSupply;
35063
- for (let i = 0; i < trancheNumber; i++) {
35064
- supply = (supply * (BPS + BigInt(supplyGrowthBps)) + BPS / BigInt(2)) / BPS;
35065
- }
35066
- return supply;
35117
+ function growPriceOnceUsd1e18(value, stepUsd1e18) {
35118
+ return value + stepUsd1e18;
35119
+ }
35120
+ function shrinkPriceOnceUsd1e18(value, stepUsd1e18) {
35121
+ if (value <= stepUsd1e18) return BigInt(0);
35122
+ return value - stepUsd1e18;
35123
+ }
35124
+ function usd1e18To1e8(raw) {
35125
+ return raw / USD_SCALE_DOWN;
35067
35126
  }
35068
35127
  function buildEthereumTrancheLadder(options) {
35069
35128
  const {
@@ -35071,29 +35130,32 @@ function buildEthereumTrancheLadder(options) {
35071
35130
  initialTrancheSupply,
35072
35131
  currentTrancheSupply,
35073
35132
  currentPriceUsd,
35074
- supplyGrowthBps,
35075
35133
  priceGrowthCents,
35134
+ supplyGrowthBps,
35076
35135
  windowBefore = 5,
35077
35136
  windowAfter = 5
35078
35137
  } = options;
35079
35138
  const startId = Math.max(0, currentTranche - windowBefore);
35080
35139
  const endId = currentTranche + windowAfter;
35081
- const currentTrancheSize = getTrancheSize(initialTrancheSupply, supplyGrowthBps, currentTranche);
35082
35140
  const capacity = new Map();
35083
- const price = new Map();
35084
- capacity.set(currentTranche, currentTrancheSize);
35085
- price.set(currentTranche, currentPriceUsd);
35141
+ const priceUsd = new Map();
35142
+ let currentCap = initialTrancheSupply;
35143
+ for (let i = 0; i < currentTranche; i++) {
35144
+ currentCap = growSupplyOnce(currentCap, supplyGrowthBps);
35145
+ }
35146
+ capacity.set(currentTranche, currentCap);
35147
+ priceUsd.set(currentTranche, currentPriceUsd);
35086
35148
  for (let id = currentTranche + 1; id <= endId; id++) {
35087
35149
  const prevCap = capacity.get(id - 1);
35088
- const prevPrice = price.get(id - 1);
35089
- capacity.set(id, growOnce(prevCap, supplyGrowthBps));
35090
- price.set(id, growOnce(prevPrice, priceGrowthCents));
35150
+ const prevPrice = priceUsd.get(id - 1);
35151
+ capacity.set(id, growSupplyOnce(prevCap, supplyGrowthBps));
35152
+ priceUsd.set(id, growPriceOnceUsd1e18(prevPrice, priceGrowthCents));
35091
35153
  }
35092
35154
  for (let id = currentTranche - 1; id >= startId; id--) {
35093
35155
  const nextCap = capacity.get(id + 1);
35094
- const nextPrice = price.get(id + 1);
35095
- capacity.set(id, shrinkOnce(nextCap, supplyGrowthBps));
35096
- price.set(id, shrinkOnce(nextPrice, priceGrowthCents));
35156
+ const nextPrice = priceUsd.get(id + 1);
35157
+ capacity.set(id, shrinkSupplyOnce(nextCap, supplyGrowthBps));
35158
+ priceUsd.set(id, shrinkPriceOnceUsd1e18(nextPrice, priceGrowthCents));
35097
35159
  }
35098
35160
  const ladder = [];
35099
35161
  for (let id = startId; id <= endId; id++) {
@@ -35106,12 +35168,14 @@ function buildEthereumTrancheLadder(options) {
35106
35168
  } else {
35107
35169
  sold = BigInt(0);
35108
35170
  }
35171
+ const remaining = cap - sold;
35172
+ const priceClientScale = usd1e18To1e8(priceUsd.get(id));
35109
35173
  ladder.push({
35110
35174
  id,
35111
35175
  capacity: cap,
35112
35176
  sold,
35113
- remaining: cap - sold,
35114
- priceUsd: price.get(id)
35177
+ remaining,
35178
+ priceUsd: priceClientScale
35115
35179
  });
35116
35180
  }
35117
35181
  return ladder;
@@ -35127,7 +35191,7 @@ async function buildEthereumTrancheSnapshot(options) {
35127
35191
  indexBn,
35128
35192
  trancheNumberBn,
35129
35193
  currentTrancheSupply,
35130
- tranchePriceWadBn,
35194
+ tranchePriceUsdBn,
35131
35195
  totalTrancheSupply,
35132
35196
  initialTrancheSupply,
35133
35197
  supplyGrowthBps,
@@ -35138,15 +35202,23 @@ async function buildEthereumTrancheSnapshot(options) {
35138
35202
  const totalShares = BigInt(totalSharesBn.toString()) / BigInt(1e10);
35139
35203
  const currentIndex = BigInt(indexBn.toString());
35140
35204
  const currentTranche = Number(trancheNumberBn.toString());
35141
- const currentPriceUsd = BigInt(tranchePriceWadBn.toString()) / BigInt(1e10);
35205
+ const currentPriceUsd1e18 = BigInt(tranchePriceUsdBn.toString());
35206
+ const priceGrowthStepUsd1e18 = BigInt(priceGrowthCents.toString());
35207
+ const priceGrowthCentsNumber = Number(
35208
+ priceGrowthStepUsd1e18 / BigInt(1e16)
35209
+ );
35210
+ const currentTrancheSupplyBig = BigInt(currentTrancheSupply.toString());
35211
+ const totalTrancheSupplyBig = BigInt(totalTrancheSupply.toString());
35212
+ const initialTrancheSupplyBig = BigInt(initialTrancheSupply.toString());
35213
+ const currentPriceUsd = currentPriceUsd1e18 / BigInt(1e10);
35142
35214
  const ladder = buildEthereumTrancheLadder({
35143
35215
  currentTranche,
35144
- totalTrancheSupply,
35145
- initialTrancheSupply,
35146
- currentTrancheSupply,
35147
- currentPriceUsd,
35216
+ totalTrancheSupply: totalTrancheSupplyBig,
35217
+ initialTrancheSupply: initialTrancheSupplyBig,
35218
+ currentTrancheSupply: currentTrancheSupplyBig,
35219
+ currentPriceUsd: currentPriceUsd1e18,
35220
+ priceGrowthCents: priceGrowthStepUsd1e18,
35148
35221
  supplyGrowthBps,
35149
- priceGrowthCents,
35150
35222
  windowBefore: ladderWindowBefore,
35151
35223
  windowAfter: ladderWindowAfter
35152
35224
  });
@@ -35157,10 +35229,10 @@ async function buildEthereumTrancheSnapshot(options) {
35157
35229
  currentTranche,
35158
35230
  currentPriceUsd,
35159
35231
  supplyGrowthBps,
35160
- priceGrowthCents,
35161
- currentTrancheSupply,
35162
- initialTrancheSupply,
35163
- totalPretokensSold: totalTrancheSupply,
35232
+ priceGrowthCents: priceGrowthCentsNumber,
35233
+ totalPretokensSold: totalTrancheSupplyBig,
35234
+ currentTrancheSupply: currentTrancheSupplyBig,
35235
+ initialTrancheSupply: initialTrancheSupplyBig,
35164
35236
  nativePriceUsd: ethPriceUsd,
35165
35237
  nativePriceTimestamp,
35166
35238
  ladder
@@ -35943,7 +36015,7 @@ class EthereumStakingClient {
35943
36015
  try {
35944
36016
  const blockNumber = await this.provider.getBlockNumber();
35945
36017
  const blockTag = { blockTag: blockNumber };
35946
- const [totalSharesBn, indexBn, trancheNumberBn, trancheSupplyBn, tranchePriceWadBn, totalSupplyBn, supplyGrowthBps, priceGrowthCents, minPriceUsd, maxPriceUsd] = await Promise.all([
36018
+ const [totalSharesBn, indexBn, trancheNumberBn, trancheSupplyBn, tranchePriceUsdBn, totalSupplyBn, supplyGrowthBps, priceGrowthCents, minPriceUsd, maxPriceUsd] = await Promise.all([
35947
36019
  this.contract.Depositor.totalShares(blockTag),
35948
36020
  this.contract.Depositor.index(blockTag),
35949
36021
  this.contract.Pretoken.trancheNumber(blockTag),
@@ -35967,7 +36039,7 @@ class EthereumStakingClient {
35967
36039
  indexBn,
35968
36040
  trancheNumberBn,
35969
36041
  currentTrancheSupply,
35970
- tranchePriceWadBn,
36042
+ tranchePriceUsdBn,
35971
36043
  totalTrancheSupply,
35972
36044
  initialTrancheSupply,
35973
36045
  supplyGrowthBps,
@@ -35980,7 +36052,6 @@ class EthereumStakingClient {
35980
36052
  ladderWindowAfter: windowAfter
35981
36053
  });
35982
36054
  } catch (err) {
35983
- console.log(err);
35984
36055
  throw new Error(`Error fetching Ethereum tranche snapshot: ${err?.message || err}`);
35985
36056
  }
35986
36057
  }
@@ -36046,6 +36117,7 @@ class Staker {
36046
36117
  if (!Array.isArray(config)) config = [config];
36047
36118
  config.forEach((cfg) => {
36048
36119
  switch (cfg.network.chainId) {
36120
+ case SolChainID.Devnet:
36049
36121
  case SolChainID.WireTestnet:
36050
36122
  this.clients.set(cfg.network.chainId, new SolanaStakingClient(cfg));
36051
36123
  break;