@wireio/stake 0.5.0 → 0.5.2
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/lib/stake.browser.js +702 -587
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +1165 -208
- package/lib/stake.js +794 -661
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +702 -587
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/ethereum/ABI/outpost/Aggregator.sol/Aggregator.json +82 -0
- package/src/assets/solana/idl/liqsol_core.json +132 -182
- package/src/assets/solana/types/liqsol_core.ts +132 -182
- package/src/networks/ethereum/clients/pretoken.client.ts +2 -5
- package/src/networks/ethereum/clients/stake.client.ts +2 -5
- package/src/networks/ethereum/contract.ts +13 -13
- package/src/networks/ethereum/ethereum.ts +89 -13
- package/src/networks/ethereum/utils.ts +8 -8
- package/src/networks/solana/clients/deposit.client.ts +25 -7
- package/src/networks/solana/clients/distribution.client.ts +84 -1
- package/src/networks/solana/clients/outpost.client.ts +34 -28
- package/src/networks/solana/constants.ts +0 -3
- package/src/networks/solana/solana.ts +191 -89
- package/src/networks/solana/types.ts +3 -9
- package/src/networks/solana/utils.ts +14 -7
- package/src/staker.ts +1 -1
- package/src/types.ts +14 -10
- package/src/staker/types.ts +0 -62
|
@@ -16,6 +16,8 @@ import { PretokenClient } from './clients/pretoken.client';
|
|
|
16
16
|
import { OPPClient } from './clients/opp.client';
|
|
17
17
|
import { ReceiptClient } from './clients/receipt.client';
|
|
18
18
|
|
|
19
|
+
export const INITIAL_TRANCHE_SUPPLY = 35000;
|
|
20
|
+
|
|
19
21
|
export class EthereumStakingClient implements IStakingClient {
|
|
20
22
|
private readonly provider: ethers.providers.Web3Provider | ethers.providers.JsonRpcProvider;
|
|
21
23
|
public readonly pubKey?: WirePubKey;
|
|
@@ -154,8 +156,8 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
154
156
|
* actual = liqETH token balance (ERC-20)
|
|
155
157
|
* tracked = liqETH tracked balance (protocol/accounting view)
|
|
156
158
|
*/
|
|
157
|
-
async getPortfolio(): Promise<Portfolio> {
|
|
158
|
-
this.
|
|
159
|
+
async getPortfolio(): Promise<Portfolio | null> {
|
|
160
|
+
if (!this.signer) return Promise.resolve(null);
|
|
159
161
|
|
|
160
162
|
const walletAddress = await this.signer!.getAddress();
|
|
161
163
|
|
|
@@ -199,7 +201,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
199
201
|
currentIndex = BigInt(indexBn.toString());
|
|
200
202
|
totalShares = BigInt(totalSharesBn.toString());
|
|
201
203
|
userShares = BigInt(userSharesBn.toString());
|
|
202
|
-
} catch {}
|
|
204
|
+
} catch { }
|
|
203
205
|
|
|
204
206
|
// sharesToTokens(userShares, currentIndex) = userShares * currentIndex / indexScale
|
|
205
207
|
let estimatedClaim = BigInt(0);
|
|
@@ -287,10 +289,18 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
287
289
|
// READ-ONLY Public Methods
|
|
288
290
|
// ---------------------------------------------------------------------
|
|
289
291
|
|
|
290
|
-
//
|
|
292
|
+
// Protocol-wide ETH staking APY in percent, e.g. 3.0 => "3.00%"
|
|
291
293
|
async getSystemAPY(): Promise<number> {
|
|
294
|
+
// NOTE: despite the name, this value is effectively *annual* BPS on-chain.
|
|
295
|
+
// e.g. 300 => 3% APY
|
|
292
296
|
const annualBpsBn = await this.contract.DepositManager.dailyRateBPS();
|
|
293
|
-
|
|
297
|
+
const annualBps = annualBpsBn.toNumber(); // e.g. 300 for 3%
|
|
298
|
+
|
|
299
|
+
// Convert basis points (1/100 of 1%) to percent:
|
|
300
|
+
// 10,000 bps = 100% ⇒ 100 bps = 1% ⇒ divide by 100.
|
|
301
|
+
const apyPercent = annualBps / 100;
|
|
302
|
+
|
|
303
|
+
return apyPercent; // 3 => "3.00%"
|
|
294
304
|
}
|
|
295
305
|
|
|
296
306
|
// Protocol fee charged for deposit from Native to LIQ
|
|
@@ -339,7 +349,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
339
349
|
|
|
340
350
|
|
|
341
351
|
// Fetch all required contract data
|
|
342
|
-
const [totalSharesBn, indexBn, trancheNumberBn, trancheSupplyBn, tranchePriceWadBn, totalSupplyBn, supplyGrowthBps,
|
|
352
|
+
const [totalSharesBn, indexBn, trancheNumberBn, trancheSupplyBn, tranchePriceWadBn, totalSupplyBn, supplyGrowthBps, priceGrowthCents, minPriceUsd, maxPriceUsd] = await Promise.all([
|
|
343
353
|
this.contract.Depositor.totalShares(blockTag),
|
|
344
354
|
this.contract.Depositor.index(blockTag),
|
|
345
355
|
this.contract.Pretoken.trancheNumber(blockTag),
|
|
@@ -362,11 +372,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
362
372
|
let ethPriceUsd: bigint = BigInt(answer.toString());
|
|
363
373
|
let nativePriceTimestamp: number = Number(updatedAt);
|
|
364
374
|
|
|
365
|
-
|
|
366
|
-
const initialTrancheSupply = BigInt(70000) * BigInt(1e8);
|
|
367
|
-
|
|
368
|
-
console.log('priceIncrementUsd',priceIncrementUsd);
|
|
369
|
-
|
|
375
|
+
const initialTrancheSupply = BigInt(INITIAL_TRANCHE_SUPPLY) * BigInt(1e8);
|
|
370
376
|
|
|
371
377
|
return buildEthereumTrancheSnapshot({
|
|
372
378
|
chainID,
|
|
@@ -378,7 +384,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
378
384
|
totalTrancheSupply,
|
|
379
385
|
initialTrancheSupply,
|
|
380
386
|
supplyGrowthBps,
|
|
381
|
-
|
|
387
|
+
priceGrowthCents,
|
|
382
388
|
minPriceUsd,
|
|
383
389
|
maxPriceUsd,
|
|
384
390
|
|
|
@@ -390,11 +396,81 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
390
396
|
}
|
|
391
397
|
catch (err: any) {
|
|
392
398
|
console.log(err);
|
|
393
|
-
|
|
399
|
+
|
|
394
400
|
throw new Error(`Error fetching Ethereum tranche snapshot: ${err?.message || err}`);
|
|
395
401
|
}
|
|
396
402
|
}
|
|
397
403
|
|
|
404
|
+
/**
|
|
405
|
+
* Estimate a conservative native ETH buffer (in wei) to leave in the wallet
|
|
406
|
+
* so the user can pay gas for the current deposit and at least one more tx.
|
|
407
|
+
*
|
|
408
|
+
* Typical usage in UI:
|
|
409
|
+
* const buffer = await client.estimateGasBuffer();
|
|
410
|
+
* const maxSpendable = balanceWei > buffer ? balanceWei - buffer : 0n;
|
|
411
|
+
*
|
|
412
|
+
* @param options.txCount How many transactions to cover (default 2: deposit + 1 more)
|
|
413
|
+
* @param options.safetyMultiplier Additional safety multiplier on top of txCount (default 1.5x)
|
|
414
|
+
* @param options.minBufferWei Optional override minimum buffer (defaults ~0.002 ETH)
|
|
415
|
+
*/
|
|
416
|
+
async estimateGasBuffer(options?: {
|
|
417
|
+
txCount?: number;
|
|
418
|
+
safetyMultiplier?: number;
|
|
419
|
+
minBufferWei?: bigint;
|
|
420
|
+
}): Promise<bigint> {
|
|
421
|
+
this.ensureUser();
|
|
422
|
+
|
|
423
|
+
const walletAddress = await this.signer!.getAddress();
|
|
424
|
+
|
|
425
|
+
// 1) Estimate a baseline gas usage using a simple self-transfer.
|
|
426
|
+
// This is cheap and doesn't depend on your contract ABI at all.
|
|
427
|
+
const baseGas = await this.provider.estimateGas({
|
|
428
|
+
from: walletAddress,
|
|
429
|
+
to: walletAddress,
|
|
430
|
+
value: ethers.constants.Zero,
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
// 2) Fetch current gas price / max fee per gas.
|
|
434
|
+
const feeData = await this.provider.getFeeData();
|
|
435
|
+
let gasPrice =
|
|
436
|
+
feeData.maxFeePerGas ??
|
|
437
|
+
feeData.gasPrice ??
|
|
438
|
+
ethers.utils.parseUnits('20', 'gwei'); // conservative fallback
|
|
439
|
+
|
|
440
|
+
// 3) How many txs do we want to cover?
|
|
441
|
+
// Default: 2 (deposit + one extra action such as stake or small follow-up).
|
|
442
|
+
const txCount = options?.txCount ?? 2;
|
|
443
|
+
|
|
444
|
+
// We also assume that contract interactions are more expensive than a simple transfer.
|
|
445
|
+
// Use a multiplier (e.g., 5x) on baseGas to approximate a more complex tx.
|
|
446
|
+
const COMPLEX_TX_MULTIPLIER = 5; // tuning knob
|
|
447
|
+
const totalGasUnits = baseGas
|
|
448
|
+
.mul(COMPLEX_TX_MULTIPLIER)
|
|
449
|
+
.mul(txCount);
|
|
450
|
+
|
|
451
|
+
const baseCost = totalGasUnits.mul(gasPrice);
|
|
452
|
+
|
|
453
|
+
// 4) Safety multiplier on top of that (e.g. 1.5x).
|
|
454
|
+
const safetyMultiplier = options?.safetyMultiplier ?? 1.5;
|
|
455
|
+
const safetyScaled = Math.round(safetyMultiplier * 100); // e.g. 150
|
|
456
|
+
|
|
457
|
+
const bufferedCost = baseCost
|
|
458
|
+
.mul(safetyScaled)
|
|
459
|
+
.div(100); // apply safety factor
|
|
460
|
+
|
|
461
|
+
let bufferWei = bufferedCost.toBigInt();
|
|
462
|
+
|
|
463
|
+
// 5) Enforce a minimum floor (e.g. ~0.002 ETH).
|
|
464
|
+
const defaultMinBufferWei = BigInt(2_000_000_000_000_000); // 0.002 ETH
|
|
465
|
+
const minBufferWei = options?.minBufferWei ?? defaultMinBufferWei;
|
|
466
|
+
|
|
467
|
+
if (bufferWei < minBufferWei) {
|
|
468
|
+
bufferWei = minBufferWei;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
return bufferWei;
|
|
472
|
+
}
|
|
473
|
+
|
|
398
474
|
// ---------------------------------------------------------------------
|
|
399
475
|
// Internal ETH Staking client helper functions
|
|
400
476
|
// ---------------------------------------------------------------------
|
|
@@ -157,7 +157,7 @@ export function buildEthereumTrancheLadder(options: {
|
|
|
157
157
|
currentTrancheSupply: bigint;
|
|
158
158
|
currentPriceUsd: bigint;
|
|
159
159
|
supplyGrowthBps: number;
|
|
160
|
-
|
|
160
|
+
priceGrowthCents: number;
|
|
161
161
|
windowBefore?: number;
|
|
162
162
|
windowAfter?: number;
|
|
163
163
|
}): TrancheLadderItem[] {
|
|
@@ -167,7 +167,7 @@ export function buildEthereumTrancheLadder(options: {
|
|
|
167
167
|
currentTrancheSupply,
|
|
168
168
|
currentPriceUsd,
|
|
169
169
|
supplyGrowthBps,
|
|
170
|
-
|
|
170
|
+
priceGrowthCents,
|
|
171
171
|
windowBefore = 5,
|
|
172
172
|
windowAfter = 5,
|
|
173
173
|
} = options;
|
|
@@ -190,7 +190,7 @@ export function buildEthereumTrancheLadder(options: {
|
|
|
190
190
|
const prevCap = capacity.get(id - 1)!;
|
|
191
191
|
const prevPrice = price.get(id - 1)!;
|
|
192
192
|
capacity.set(id, growOnce(prevCap, supplyGrowthBps));
|
|
193
|
-
price.set(id, growOnce(prevPrice,
|
|
193
|
+
price.set(id, growOnce(prevPrice, priceGrowthCents));
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
// Backward (past tranches)
|
|
@@ -198,7 +198,7 @@ export function buildEthereumTrancheLadder(options: {
|
|
|
198
198
|
const nextCap = capacity.get(id + 1)!;
|
|
199
199
|
const nextPrice = price.get(id + 1)!;
|
|
200
200
|
capacity.set(id, shrinkOnce(nextCap, supplyGrowthBps));
|
|
201
|
-
price.set(id, shrinkOnce(nextPrice,
|
|
201
|
+
price.set(id, shrinkOnce(nextPrice, priceGrowthCents));
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
const ladder: TrancheLadderItem[] = [];
|
|
@@ -240,7 +240,7 @@ export async function buildEthereumTrancheSnapshot(options: {
|
|
|
240
240
|
totalTrancheSupply;
|
|
241
241
|
initialTrancheSupply;
|
|
242
242
|
supplyGrowthBps;
|
|
243
|
-
|
|
243
|
+
priceGrowthCents;
|
|
244
244
|
minPriceUsd;
|
|
245
245
|
maxPriceUsd;
|
|
246
246
|
|
|
@@ -264,7 +264,7 @@ export async function buildEthereumTrancheSnapshot(options: {
|
|
|
264
264
|
totalTrancheSupply,
|
|
265
265
|
initialTrancheSupply,
|
|
266
266
|
supplyGrowthBps,
|
|
267
|
-
|
|
267
|
+
priceGrowthCents,
|
|
268
268
|
minPriceUsd,
|
|
269
269
|
maxPriceUsd,
|
|
270
270
|
} = options;
|
|
@@ -284,7 +284,7 @@ export async function buildEthereumTrancheSnapshot(options: {
|
|
|
284
284
|
currentTrancheSupply,
|
|
285
285
|
currentPriceUsd,
|
|
286
286
|
supplyGrowthBps,
|
|
287
|
-
|
|
287
|
+
priceGrowthCents,
|
|
288
288
|
windowBefore: ladderWindowBefore,
|
|
289
289
|
windowAfter: ladderWindowAfter,
|
|
290
290
|
});
|
|
@@ -297,7 +297,7 @@ export async function buildEthereumTrancheSnapshot(options: {
|
|
|
297
297
|
currentTranche,
|
|
298
298
|
currentPriceUsd,
|
|
299
299
|
supplyGrowthBps,
|
|
300
|
-
|
|
300
|
+
priceGrowthCents,
|
|
301
301
|
currentTrancheSupply,
|
|
302
302
|
initialTrancheSupply,
|
|
303
303
|
totalPretokensSold: totalTrancheSupply,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
deriveLiqReceiptDataPda,
|
|
43
43
|
deriveGlobalConfigPda,
|
|
44
44
|
} from '../constants';
|
|
45
|
-
import { WalletLike } from '../types';
|
|
45
|
+
import { GlobalAccount, WalletLike } from '../types';
|
|
46
46
|
|
|
47
47
|
export class DepositClient {
|
|
48
48
|
private program: Program<LiqsolCore>;
|
|
@@ -192,23 +192,41 @@ export class DepositClient {
|
|
|
192
192
|
);
|
|
193
193
|
|
|
194
194
|
// Distribution / balance-tracking
|
|
195
|
-
// user_record is keyed by the user’s liqSOL ATA (same convention
|
|
195
|
+
// user_record is keyed by the user’s liqSOL ATA (same convention
|
|
196
|
+
// as deposit/purchase).
|
|
196
197
|
const userRecord = deriveUserRecordPda(userAta);
|
|
197
198
|
const distributionState = deriveDistributionStatePda();
|
|
198
199
|
|
|
199
200
|
// Reserve + stake controller PDAs
|
|
200
|
-
const global = deriveWithdrawGlobalPda();
|
|
201
|
+
const global = deriveWithdrawGlobalPda(); // withdraw operator state
|
|
201
202
|
const reservePool = deriveReservePoolPda();
|
|
202
203
|
const stakeAllocationState = deriveStakeAllocationStatePda();
|
|
203
204
|
const stakeMetrics = deriveStakeMetricsPda();
|
|
204
205
|
const maintenanceLedger = deriveMaintenanceLedgerPda();
|
|
205
|
-
const globalConfig = deriveGlobalConfigPda();
|
|
206
|
+
const globalConfig = deriveGlobalConfigPda(); // liqSOL config / roles
|
|
206
207
|
|
|
207
208
|
// -------------------------------------------------------------
|
|
208
209
|
// Need nextReceiptId from withdraw global state
|
|
209
210
|
// -------------------------------------------------------------
|
|
210
|
-
const
|
|
211
|
-
|
|
211
|
+
const globalAcct : GlobalAccount = await this.program.account.global.fetch(global);
|
|
212
|
+
|
|
213
|
+
const rawId = globalAcct.nextReceiptId;
|
|
214
|
+
let receiptId: bigint;
|
|
215
|
+
|
|
216
|
+
if (typeof rawId === 'bigint') {
|
|
217
|
+
// New-style IDL / accounts returning bigint directly
|
|
218
|
+
receiptId = rawId;
|
|
219
|
+
} else if (rawId != null && typeof rawId === 'object' && 'toString' in rawId) {
|
|
220
|
+
// Anchor BN / bn.js or similar – normalize through string
|
|
221
|
+
receiptId = BigInt(rawId.toString());
|
|
222
|
+
} else if (typeof rawId === 'number') {
|
|
223
|
+
// Just in case someone typed it as a JS number in tests
|
|
224
|
+
receiptId = BigInt(rawId);
|
|
225
|
+
} else {
|
|
226
|
+
throw new Error(
|
|
227
|
+
`DepositClient.buildWithdrawTx: unexpected nextReceiptId type (${typeof rawId})`,
|
|
228
|
+
);
|
|
229
|
+
}
|
|
212
230
|
|
|
213
231
|
// -------------------------------------------------------------
|
|
214
232
|
// NFT receipt PDAs (mint, metadata, data, ATA)
|
|
@@ -265,7 +283,7 @@ export class DepositClient {
|
|
|
265
283
|
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
266
284
|
systemProgram: SystemProgram.programId,
|
|
267
285
|
rent: SYSVAR_RENT_PUBKEY,
|
|
268
|
-
globalConfig
|
|
286
|
+
globalConfig,
|
|
269
287
|
})
|
|
270
288
|
.instruction();
|
|
271
289
|
|
|
@@ -10,8 +10,9 @@ import {
|
|
|
10
10
|
derivePayRateHistoryPda,
|
|
11
11
|
deriveUserRecordPda,
|
|
12
12
|
} from '../constants';
|
|
13
|
-
import type { DistributionState, DistributionUserRecord, GlobalConfig, PayRateHistory } from '../types';
|
|
13
|
+
import type { DistributionState, DistributionUserRecord, GlobalConfig, PayRateEntry, PayRateHistory } from '../types';
|
|
14
14
|
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';
|
|
15
|
+
import { ceilDiv } from '../utils';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Distribution client – wraps the distribution portion of the liqsol_core
|
|
@@ -165,4 +166,86 @@ export class DistributionClient {
|
|
|
165
166
|
|
|
166
167
|
return { shares: userShares, totalShares, ratio };
|
|
167
168
|
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Compute an average scaled pay rate over the most recent `windowSize`
|
|
172
|
+
* valid entries in the pay-rate history circular buffer.
|
|
173
|
+
*
|
|
174
|
+
* Returns a BN scaled by 1e12 (same as on-chain).
|
|
175
|
+
*/
|
|
176
|
+
async getAverageScaledPayRate(windowSize = 5): Promise<BN> {
|
|
177
|
+
const history = await this.getPayRateHistory();
|
|
178
|
+
if (!history) {
|
|
179
|
+
return new BN(0);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const entries: PayRateEntry[] = history.entries ?? [];
|
|
183
|
+
if (!entries.length) {
|
|
184
|
+
return new BN(0);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const maxEntries: number =
|
|
188
|
+
typeof history.maxEntries === 'number'
|
|
189
|
+
? history.maxEntries
|
|
190
|
+
: entries.length;
|
|
191
|
+
|
|
192
|
+
const rawTotalAdded: any = history.totalEntriesAdded ?? 0;
|
|
193
|
+
const totalAddedBn = new BN(rawTotalAdded.toString());
|
|
194
|
+
|
|
195
|
+
// No valid entries written yet
|
|
196
|
+
if (totalAddedBn.isZero()) {
|
|
197
|
+
return new BN(0);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const totalAdded = Math.min(
|
|
201
|
+
totalAddedBn.toNumber(),
|
|
202
|
+
maxEntries,
|
|
203
|
+
entries.length,
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
if (!totalAdded) {
|
|
207
|
+
return new BN(0);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const COUNT = Math.max(1, Math.min(windowSize, totalAdded));
|
|
211
|
+
|
|
212
|
+
const currentIndexNum = Number(history.currentIndex ?? 0);
|
|
213
|
+
|
|
214
|
+
// Most recently written entry is at currentIndex - 1 (mod maxEntries)
|
|
215
|
+
let idx =
|
|
216
|
+
currentIndexNum === 0
|
|
217
|
+
? maxEntries - 1
|
|
218
|
+
: currentIndexNum - 1;
|
|
219
|
+
|
|
220
|
+
let sum = new BN(0);
|
|
221
|
+
let valid = 0;
|
|
222
|
+
const zero = new BN(0);
|
|
223
|
+
|
|
224
|
+
for (let i = 0; i < COUNT; i++) {
|
|
225
|
+
const entry: any = entries[idx];
|
|
226
|
+
if (entry) {
|
|
227
|
+
// Support both camelCase and snake_case (for safety)
|
|
228
|
+
const rawScaled =
|
|
229
|
+
entry.scaledRate ??
|
|
230
|
+
entry.scaled_rate ??
|
|
231
|
+
0;
|
|
232
|
+
|
|
233
|
+
const rate = new BN(rawScaled.toString());
|
|
234
|
+
if (rate.gt(zero)) {
|
|
235
|
+
sum = sum.add(rate);
|
|
236
|
+
valid += 1;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Walk backwards through the circular buffer
|
|
241
|
+
idx = idx === 0 ? maxEntries - 1 : idx - 1;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (!valid) {
|
|
245
|
+
return new BN(0);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Same behavior as the dashboard: use a ceiling-like average
|
|
249
|
+
return ceilDiv(sum, new BN(valid));
|
|
250
|
+
}
|
|
168
251
|
}
|
|
@@ -100,34 +100,40 @@ export class OutpostClient {
|
|
|
100
100
|
|
|
101
101
|
const pdas = await this.buildAccounts(userPk);
|
|
102
102
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
103
|
+
try {
|
|
104
|
+
const [
|
|
105
|
+
globalState,
|
|
106
|
+
outpostAccount,
|
|
107
|
+
distributionState,
|
|
108
|
+
userPretokenRecord,
|
|
109
|
+
trancheState,
|
|
110
|
+
] = await Promise.all([
|
|
111
|
+
this.program.account.globalState.fetch(pdas.globalState),
|
|
112
|
+
this.program.account.outpostAccount.fetchNullable(pdas.outpostAccount),
|
|
113
|
+
this.program.account.distributionState.fetchNullable(pdas.distributionState),
|
|
114
|
+
this.program.account.userPretokenRecord.fetchNullable(pdas.userPretokenRecord),
|
|
115
|
+
this.program.account.trancheState.fetchNullable(pdas.trancheState),
|
|
116
|
+
]);
|
|
117
|
+
|
|
118
|
+
const [liqsolPoolBalance, userLiqsolBalance] = await Promise.all([
|
|
119
|
+
this.getTokenBalance(pdas.liqsolPoolAta),
|
|
120
|
+
this.getTokenBalance(pdas.userAta),
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
globalState,
|
|
125
|
+
outpostAccount,
|
|
126
|
+
distributionState,
|
|
127
|
+
trancheState,
|
|
128
|
+
userPretokenRecord,
|
|
129
|
+
liqsolPoolBalance,
|
|
130
|
+
userLiqsolBalance,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
console.error('Error fetching Outpost wire state:', err);
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
131
137
|
}
|
|
132
138
|
|
|
133
139
|
// -------------------------------------------------------------------------
|