@wireio/stake 2.3.0 → 2.4.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.
- package/lib/stake.browser.js +1224 -71
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +1150 -163
- package/lib/stake.js +1234 -71
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +1224 -71
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/solana/devnet/idl/liqsol_core.json +472 -27
- package/src/assets/solana/devnet/idl/liqsol_token.json +34 -0
- package/src/assets/solana/devnet/idl/transfer_hook.json +34 -0
- package/src/assets/solana/devnet/types/liqsol_core.ts +472 -27
- package/src/assets/solana/devnet/types/liqsol_token.ts +34 -0
- package/src/assets/solana/devnet/types/transfer_hook.ts +34 -0
- package/src/assets/solana/mainnet/idl/liqsol_core.json +472 -27
- package/src/assets/solana/mainnet/idl/liqsol_token.json +34 -0
- package/src/assets/solana/mainnet/idl/transfer_hook.json +34 -0
- package/src/assets/solana/mainnet/types/liqsol_core.ts +472 -27
- package/src/assets/solana/mainnet/types/liqsol_token.ts +34 -0
- package/src/assets/solana/mainnet/types/transfer_hook.ts +34 -0
- package/src/networks/ethereum/ethereum.ts +9 -9
- package/src/networks/solana/clients/distribution.client.ts +114 -2
- package/src/networks/solana/clients/outpost.client.ts +2 -0
- package/src/networks/solana/clients/token.client.ts +2 -0
- package/src/networks/solana/constants.ts +3 -0
- package/src/networks/solana/program.ts +7 -0
- package/src/networks/solana/solana.ts +26 -1
- package/src/networks/solana/types.ts +3 -3
- package/src/networks/solana/utils.ts +7 -1
- package/src/types.ts +10 -1
|
@@ -118,6 +118,40 @@ export type LiqsolToken = {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "updateLiqsolMetadataPermissionless",
|
|
124
|
+
"discriminator": [
|
|
125
|
+
21,
|
|
126
|
+
255,
|
|
127
|
+
26,
|
|
128
|
+
184,
|
|
129
|
+
136,
|
|
130
|
+
110,
|
|
131
|
+
214,
|
|
132
|
+
33
|
|
133
|
+
],
|
|
134
|
+
"accounts": [
|
|
135
|
+
{
|
|
136
|
+
"name": "payer",
|
|
137
|
+
"writable": true,
|
|
138
|
+
"signer": true
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"name": "mintAuthority"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"name": "mint",
|
|
145
|
+
"writable": true
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"name": "tokenProgram"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"name": "systemProgram"
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
"args": []
|
|
121
155
|
}
|
|
122
156
|
],
|
|
123
157
|
"errors": [
|
|
@@ -100,6 +100,40 @@ export type TransferHook = {
|
|
|
100
100
|
"type": "u64"
|
|
101
101
|
}
|
|
102
102
|
]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "updateExtraAccountMetaList",
|
|
106
|
+
"discriminator": [
|
|
107
|
+
44,
|
|
108
|
+
125,
|
|
109
|
+
141,
|
|
110
|
+
226,
|
|
111
|
+
97,
|
|
112
|
+
179,
|
|
113
|
+
166,
|
|
114
|
+
96
|
|
115
|
+
],
|
|
116
|
+
"accounts": [
|
|
117
|
+
{
|
|
118
|
+
"name": "payer",
|
|
119
|
+
"writable": true,
|
|
120
|
+
"signer": true
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "extraAccountMetaList",
|
|
124
|
+
"writable": true
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "mint"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "systemProgram"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"name": "liqsolCore"
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"args": []
|
|
103
137
|
}
|
|
104
138
|
],
|
|
105
139
|
"accounts": [
|
|
@@ -32,9 +32,9 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
32
32
|
private receiptClient: ReceiptClient;
|
|
33
33
|
private validatorClient: ValidatorClient;
|
|
34
34
|
|
|
35
|
-
|
|
36
35
|
get contract() { return this.contractService.contract; }
|
|
37
36
|
get network() { return this.config.network; }
|
|
37
|
+
get address() { return this.signer?.getAddress(); }
|
|
38
38
|
|
|
39
39
|
constructor(private config: StakerConfig) {
|
|
40
40
|
try {
|
|
@@ -95,7 +95,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
95
95
|
async withdraw(amount: bigint): Promise<string> {
|
|
96
96
|
this.ensureUser();
|
|
97
97
|
|
|
98
|
-
const address = await this.
|
|
98
|
+
const address = await this.address!;
|
|
99
99
|
const amountWei = BigNumber.from(amount);
|
|
100
100
|
|
|
101
101
|
const result = await this.convertClient.performWithdraw(address, amountWei)
|
|
@@ -109,7 +109,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
109
109
|
*/
|
|
110
110
|
async getPendingWithdraws(): Promise<WithdrawReceipt[]> {
|
|
111
111
|
this.ensureUser();
|
|
112
|
-
const address = await this.
|
|
112
|
+
const address = await this.address!;
|
|
113
113
|
|
|
114
114
|
return await this.receiptClient.fetchWithdrawReceipts(address);
|
|
115
115
|
}
|
|
@@ -136,7 +136,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
136
136
|
async stake(amount: bigint): Promise<string> {
|
|
137
137
|
this.ensureUser();
|
|
138
138
|
|
|
139
|
-
const walletAddress = await this.
|
|
139
|
+
const walletAddress = await this.address!;
|
|
140
140
|
const amountWei = BigNumber.from(amount);
|
|
141
141
|
|
|
142
142
|
const result = await this.stakeClient.performStake(amountWei, walletAddress);
|
|
@@ -168,7 +168,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
168
168
|
async buy(amount: bigint): Promise<string> {
|
|
169
169
|
this.ensureUser();
|
|
170
170
|
|
|
171
|
-
const buyer = await this.
|
|
171
|
+
const buyer = await this.address!;
|
|
172
172
|
|
|
173
173
|
// ! Hoodi only - check if the mock aggregator price is stale, and if so, update it before submitting the buy request
|
|
174
174
|
// const network = await this.provider.getNetwork();
|
|
@@ -208,7 +208,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
208
208
|
try {
|
|
209
209
|
if (!this.signer) return Promise.resolve(null);
|
|
210
210
|
|
|
211
|
-
const walletAddress = await this.
|
|
211
|
+
const walletAddress = await this.address!;
|
|
212
212
|
|
|
213
213
|
// 1) Native ETH balance
|
|
214
214
|
const nativeBalance = await this.provider.getBalance(walletAddress);
|
|
@@ -314,7 +314,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
314
314
|
async fetchPrelaunchReceipts(address?: string): Promise<preLaunchReceipt[]> {
|
|
315
315
|
this.ensureUser();
|
|
316
316
|
|
|
317
|
-
if (address === undefined) address = await this.
|
|
317
|
+
if (address === undefined) address = await this.address!;
|
|
318
318
|
|
|
319
319
|
//default to stake receipts
|
|
320
320
|
return await this.receiptClient.stakeReceipts(address);
|
|
@@ -323,7 +323,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
323
323
|
async getOPPMessages(address?: string): Promise<OPPAssertion[]> {
|
|
324
324
|
this.ensureUser();
|
|
325
325
|
|
|
326
|
-
if (!address) address = await this.
|
|
326
|
+
if (!address) address = await this.address!;
|
|
327
327
|
|
|
328
328
|
return await this.oppClient.getMessages(address);
|
|
329
329
|
}
|
|
@@ -460,7 +460,7 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
460
460
|
}): Promise<bigint> {
|
|
461
461
|
this.ensureUser();
|
|
462
462
|
|
|
463
|
-
const walletAddress = await this.
|
|
463
|
+
const walletAddress = await this.address!;
|
|
464
464
|
|
|
465
465
|
// 1) Estimate a baseline gas usage using a simple self-transfer.
|
|
466
466
|
// This is cheap and doesn't depend on your contract ABI at all.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AnchorProvider, Program, BN } from '@coral-xyz/anchor';
|
|
2
|
-
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { PublicKey, TransactionInstruction } from '@solana/web3.js';
|
|
3
3
|
|
|
4
4
|
import { LiqsolCoreClientIdl, SolanaProgramService } from '../program';
|
|
5
5
|
import type { LiqsolCore } from '../../../assets/solana/devnet/types/liqsol_core';
|
|
@@ -7,6 +7,8 @@ import type { DistributionState, DistributionUserRecord, GlobalConfig, PayRateEn
|
|
|
7
7
|
import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';
|
|
8
8
|
import { ceilDiv } from '../utils';
|
|
9
9
|
|
|
10
|
+
const INDEX_SCALE_BN = new BN('1000000000000');
|
|
11
|
+
|
|
10
12
|
/**
|
|
11
13
|
* Distribution client – wraps the distribution portion of the liqsol_core
|
|
12
14
|
* program in the *new* shares-only model.
|
|
@@ -39,6 +41,15 @@ export class DistributionClient {
|
|
|
39
41
|
return this.provider.connection;
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
private async getTokenBalance(ata: PublicKey): Promise<BN> {
|
|
45
|
+
try {
|
|
46
|
+
const bal = await this.connection.getTokenAccountBalance(ata);
|
|
47
|
+
return new BN(bal.value.amount);
|
|
48
|
+
} catch {
|
|
49
|
+
return new BN(0);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
/**
|
|
43
54
|
* Fetch the global distribution state account.
|
|
44
55
|
*
|
|
@@ -162,6 +173,107 @@ export class DistributionClient {
|
|
|
162
173
|
return { shares: userShares, totalShares, ratio };
|
|
163
174
|
}
|
|
164
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Compute claimable liqSOL for a wallet:
|
|
178
|
+
* claimable = max(0, entitled - actual)
|
|
179
|
+
* entitled = floor(shares * syncedIndex / 1e12)
|
|
180
|
+
*
|
|
181
|
+
* `syncedIndex` mirrors on-chain `sync_index` behavior by incorporating any
|
|
182
|
+
* unsynced bucket delta (bucket_balance - last_bucket_balance).
|
|
183
|
+
*/
|
|
184
|
+
async getClaimableLiqsol(user: PublicKey): Promise<BN> {
|
|
185
|
+
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
186
|
+
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
187
|
+
|
|
188
|
+
const userAta = getAssociatedTokenAddressSync(
|
|
189
|
+
liqsolMint,
|
|
190
|
+
user,
|
|
191
|
+
true,
|
|
192
|
+
TOKEN_2022_PROGRAM_ID,
|
|
193
|
+
);
|
|
194
|
+
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
195
|
+
liqsolMint,
|
|
196
|
+
bucketAuthority,
|
|
197
|
+
true,
|
|
198
|
+
TOKEN_2022_PROGRAM_ID,
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const [distributionState, userRecord, actualBalance, bucketBalance] = await Promise.all([
|
|
202
|
+
this.getDistributionState(),
|
|
203
|
+
this.getUserRecord(user),
|
|
204
|
+
this.getTokenBalance(userAta),
|
|
205
|
+
this.getTokenBalance(bucketTokenAccount),
|
|
206
|
+
]);
|
|
207
|
+
|
|
208
|
+
if (!distributionState || !userRecord) {
|
|
209
|
+
return new BN(0);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
let syncedIndex = new BN(distributionState.currentIndex.toString());
|
|
213
|
+
const totalShares = new BN(distributionState.totalShares.toString());
|
|
214
|
+
const lastBucketBalance = new BN(distributionState.lastBucketBalance.toString());
|
|
215
|
+
|
|
216
|
+
if (totalShares.gt(new BN(0)) && bucketBalance.gt(lastBucketBalance)) {
|
|
217
|
+
const delta = bucketBalance.sub(lastBucketBalance);
|
|
218
|
+
const indexDelta = delta.mul(INDEX_SCALE_BN).div(totalShares);
|
|
219
|
+
if (indexDelta.gt(new BN(0))) {
|
|
220
|
+
syncedIndex = syncedIndex.add(indexDelta);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const shares = new BN(userRecord.shares.toString());
|
|
225
|
+
const entitled = shares.mul(syncedIndex).div(INDEX_SCALE_BN);
|
|
226
|
+
|
|
227
|
+
if (entitled.lte(actualBalance)) {
|
|
228
|
+
return new BN(0);
|
|
229
|
+
}
|
|
230
|
+
return entitled.sub(actualBalance);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Build claim_rewards instruction for a wallet.
|
|
235
|
+
*/
|
|
236
|
+
async buildClaimRewardsIx(user: PublicKey): Promise<TransactionInstruction> {
|
|
237
|
+
const liqsolMint = this.pgs.deriveLiqsolMintPda();
|
|
238
|
+
const distributionState = this.pgs.deriveDistributionStatePda();
|
|
239
|
+
const bucketAuthority = this.pgs.deriveBucketAuthorityPda();
|
|
240
|
+
|
|
241
|
+
const userAta = getAssociatedTokenAddressSync(
|
|
242
|
+
liqsolMint,
|
|
243
|
+
user,
|
|
244
|
+
true,
|
|
245
|
+
TOKEN_2022_PROGRAM_ID,
|
|
246
|
+
);
|
|
247
|
+
const bucketTokenAccount = getAssociatedTokenAddressSync(
|
|
248
|
+
liqsolMint,
|
|
249
|
+
bucketAuthority,
|
|
250
|
+
true,
|
|
251
|
+
TOKEN_2022_PROGRAM_ID,
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
const userRecord = this.pgs.deriveUserRecordPda(userAta);
|
|
255
|
+
const bucketUserRecord = this.pgs.deriveUserRecordPda(bucketTokenAccount);
|
|
256
|
+
const extraAccountMetaList = this.pgs.deriveExtraAccountMetaListPda(liqsolMint);
|
|
257
|
+
|
|
258
|
+
return this.program.methods
|
|
259
|
+
.claimRewards()
|
|
260
|
+
.accounts({
|
|
261
|
+
user,
|
|
262
|
+
userAta,
|
|
263
|
+
userRecord,
|
|
264
|
+
bucketUserRecord,
|
|
265
|
+
distributionState,
|
|
266
|
+
extraAccountMetaList,
|
|
267
|
+
liqsolCoreProgram: this.pgs.PROGRAM_IDS.LIQSOL_CORE,
|
|
268
|
+
transferHookProgram: this.pgs.PROGRAM_IDS.TRANSFER_HOOK,
|
|
269
|
+
liqsolMint,
|
|
270
|
+
bucketAuthority,
|
|
271
|
+
bucketTokenAccount,
|
|
272
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
273
|
+
})
|
|
274
|
+
.instruction();
|
|
275
|
+
}
|
|
276
|
+
|
|
165
277
|
/**
|
|
166
278
|
* Compute an average scaled pay rate over the most recent `windowSize`
|
|
167
279
|
* valid entries in the pay-rate history circular buffer.
|
|
@@ -243,4 +355,4 @@ export class DistributionClient {
|
|
|
243
355
|
// Same behavior as the dashboard: use a ceiling-like average
|
|
244
356
|
return ceilDiv(sum, new BN(valid));
|
|
245
357
|
}
|
|
246
|
-
}
|
|
358
|
+
}
|
|
@@ -169,6 +169,7 @@ export class OutpostClient {
|
|
|
169
169
|
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
170
170
|
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
171
171
|
systemProgram: SystemProgram.programId,
|
|
172
|
+
pretokenPurchaseHistory: a.pretokenPurchaseHistory,
|
|
172
173
|
})
|
|
173
174
|
.instruction();
|
|
174
175
|
}
|
|
@@ -210,6 +211,7 @@ export class OutpostClient {
|
|
|
210
211
|
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
211
212
|
systemProgram: SystemProgram.programId,
|
|
212
213
|
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
214
|
+
pretokenPurchaseHistory: a.pretokenPurchaseHistory,
|
|
213
215
|
})
|
|
214
216
|
.instruction();
|
|
215
217
|
}
|
|
@@ -147,6 +147,8 @@ export class TokenClient {
|
|
|
147
147
|
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
148
148
|
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
149
149
|
systemProgram: SystemProgram.programId,
|
|
150
|
+
|
|
151
|
+
pretokenPurchaseHistory: a.pretokenPurchaseHistory,
|
|
150
152
|
})
|
|
151
153
|
.instruction();
|
|
152
154
|
}
|
|
@@ -263,6 +263,13 @@ export class SolanaProgramService {
|
|
|
263
263
|
)[0];
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
derivePretokenPurchaseHistoryPda(): PublicKey {
|
|
267
|
+
return PublicKey.findProgramAddressSync(
|
|
268
|
+
[Buffer.from(PDA_SEEDS.PRETOKEN_PURCHASE_HISTORY)],
|
|
269
|
+
this.ids.LIQSOL_CORE,
|
|
270
|
+
)[0];
|
|
271
|
+
}
|
|
272
|
+
|
|
266
273
|
/**
|
|
267
274
|
* NFT mint for withdrawal receipt, derived from nextReceiptId.
|
|
268
275
|
*/
|
|
@@ -298,6 +298,24 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
+
/**
|
|
302
|
+
* Claim accrued liqSOL distribution rewards (liqsol_core::claim_rewards).
|
|
303
|
+
*/
|
|
304
|
+
async claimLiqsolRewards(): Promise<string> {
|
|
305
|
+
this.ensureUser();
|
|
306
|
+
const owner = this.squadsVaultPDA ?? this.anchor.wallet.publicKey;
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
const ix = await this.distributionClient.buildClaimRewardsIx(owner);
|
|
310
|
+
return !!this.squadsX
|
|
311
|
+
? await this.sendSquadsIxs(ix)
|
|
312
|
+
: await this.buildAndSendIx(ix);
|
|
313
|
+
} catch (err) {
|
|
314
|
+
console.log(`Failed to claim liqSOL rewards on Solana: ${err}`);
|
|
315
|
+
throw err;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
301
319
|
/**
|
|
302
320
|
* Stake liqSOL into Outpost (liqSOL → pool) via liqsol_core::synd.
|
|
303
321
|
*/
|
|
@@ -391,12 +409,13 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
391
409
|
// - nativeLamports: wallet SOL
|
|
392
410
|
// - actualBalResp: liqSOL balance in user ATA
|
|
393
411
|
// - snapshot: Outpost + pretokens + global index/shares
|
|
394
|
-
const [nativeLamports, actualBalResp, snapshot] = await Promise.all([
|
|
412
|
+
const [nativeLamports, actualBalResp, snapshot, claimableLamports] = await Promise.all([
|
|
395
413
|
this.connection.getBalance(user, 'confirmed'),
|
|
396
414
|
this.connection
|
|
397
415
|
.getTokenAccountBalance(userLiqsolAta, 'confirmed')
|
|
398
416
|
.catch(() => null),
|
|
399
417
|
this.outpostClient.fetchWireState(user).catch(() => null),
|
|
418
|
+
this.distributionClient.getClaimableLiqsol(user).catch(() => new BN(0)),
|
|
400
419
|
]);
|
|
401
420
|
|
|
402
421
|
const LIQSOL_DECIMALS = 9;
|
|
@@ -472,6 +491,12 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
472
491
|
decimals: LIQSOL_DECIMALS,
|
|
473
492
|
ata: userLiqsolAta,
|
|
474
493
|
},
|
|
494
|
+
claimable: {
|
|
495
|
+
amount: BigInt(claimableLamports.toString()),
|
|
496
|
+
symbol: 'LiqSOL',
|
|
497
|
+
decimals: LIQSOL_DECIMALS,
|
|
498
|
+
ata: userLiqsolAta,
|
|
499
|
+
},
|
|
475
500
|
staked: {
|
|
476
501
|
// liqSOL staked in Outpost via `synd`
|
|
477
502
|
amount: stakedLiqsol,
|
|
@@ -238,10 +238,10 @@ export type GlobalState = {
|
|
|
238
238
|
currentIndex: BN;
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
241
|
+
* Replaced legacy `lastPoolLiqsolBalance`
|
|
242
|
+
* with expected balance based on total shares and current index.
|
|
243
243
|
*/
|
|
244
|
-
|
|
244
|
+
expectedPoolBalance: BN;
|
|
245
245
|
|
|
246
246
|
/**
|
|
247
247
|
* Accumulated liqSOL yield available to the protocol
|
|
@@ -278,6 +278,9 @@ export interface OutpostAccounts {
|
|
|
278
278
|
|
|
279
279
|
// Transfer hook extra accounts
|
|
280
280
|
extraAccountMetaList: PublicKey;
|
|
281
|
+
|
|
282
|
+
// New
|
|
283
|
+
pretokenPurchaseHistory: PublicKey;
|
|
281
284
|
}
|
|
282
285
|
|
|
283
286
|
export async function buildOutpostAccounts(
|
|
@@ -325,6 +328,8 @@ export async function buildOutpostAccounts(
|
|
|
325
328
|
|
|
326
329
|
const extraAccountMetaList = pgs.deriveExtraAccountMetaListPda(liqsolMint);
|
|
327
330
|
|
|
331
|
+
const pretokenPurchaseHistory = pgs.derivePretokenPurchaseHistoryPda();
|
|
332
|
+
|
|
328
333
|
// Chainlink program feeds
|
|
329
334
|
let chainLinkFeed = CHAINLINK_FEED;
|
|
330
335
|
let chainLinkProgram = CHAINLINK_PROGRAM;
|
|
@@ -365,7 +370,8 @@ export async function buildOutpostAccounts(
|
|
|
365
370
|
trancheState,
|
|
366
371
|
chainLinkFeed,
|
|
367
372
|
chainLinkProgram,
|
|
368
|
-
extraAccountMetaList
|
|
373
|
+
extraAccountMetaList,
|
|
374
|
+
pretokenPurchaseHistory
|
|
369
375
|
};
|
|
370
376
|
}
|
|
371
377
|
// -----------------------------------------------------------------------------
|
package/src/types.ts
CHANGED
|
@@ -42,6 +42,9 @@ export interface IStakingClient {
|
|
|
42
42
|
|
|
43
43
|
/** Claim a withdrawal receipt (burn NFT + receive ETH/SOL) via claim_withdraw. */
|
|
44
44
|
claimWithdraw(tokenId: bigint): Promise<string>
|
|
45
|
+
|
|
46
|
+
/** Solana only: claim accrued liqSOL distribution rewards. */
|
|
47
|
+
claimLiqsolRewards?(): Promise<string>
|
|
45
48
|
|
|
46
49
|
/** Enumerate withdrawal receipt NFTs held by the user (queued/ready/claimed). */
|
|
47
50
|
getPendingWithdraws(): Promise<WithdrawReceipt[]>
|
|
@@ -105,6 +108,12 @@ export interface Portfolio {
|
|
|
105
108
|
/** Liquid staking token balance (LiqETH, LiqSOL, etc.). */
|
|
106
109
|
liq: BalanceView;
|
|
107
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Solana-only liqSOL rewards currently claimable from the distribution bucket.
|
|
113
|
+
* Not populated on Ethereum.
|
|
114
|
+
*/
|
|
115
|
+
claimable?: BalanceView;
|
|
116
|
+
|
|
108
117
|
/**
|
|
109
118
|
* Outpost-staked balance:
|
|
110
119
|
* - On Solana: liqSOL staked via `synd` (stakedLiqsol, in lamports).
|
|
@@ -341,4 +350,4 @@ export interface WithdrawReceipt {
|
|
|
341
350
|
/** Optional explicit contract address for ETH queue NFT. */
|
|
342
351
|
contractAddress?: string;
|
|
343
352
|
};
|
|
344
|
-
}
|
|
353
|
+
}
|