@wireio/stake 0.2.2 → 0.2.4
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 +488 -92
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +267 -84
- package/lib/stake.js +596 -145
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +488 -92
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/solana/idl/liqsol_core.json +3 -53
- package/src/assets/solana/idl/liqsol_token.json +1 -1
- package/src/assets/solana/idl/validator_leaderboard.json +1 -1
- package/src/assets/solana/types/liqsol_core.ts +3 -53
- package/src/assets/solana/types/liqsol_token.ts +1 -1
- package/src/assets/solana/types/validator_leaderboard.ts +1 -1
- package/src/index.ts +4 -3
- package/src/networks/ethereum/ethereum.ts +25 -1
- package/src/networks/ethereum/types.ts +1 -1
- package/src/networks/solana/clients/token.client.ts +225 -0
- package/src/networks/solana/constants.ts +9 -0
- package/src/networks/solana/solana.ts +372 -74
- package/src/networks/solana/types.ts +11 -1
- package/src/networks/solana/utils.ts +223 -5
- package/src/{staker/staker.ts → staker.ts} +2 -2
- package/src/types.ts +143 -0
- package/src/staker/types.ts +0 -51
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"address": "
|
|
2
|
+
"address": "BBkVcNWNQz1vZ6esv5US4QnNFWPRqxWbdpJHur9GVXSu",
|
|
3
3
|
"metadata": {
|
|
4
4
|
"name": "liqsol_core",
|
|
5
5
|
"version": "0.1.0",
|
|
@@ -3151,58 +3151,8 @@
|
|
|
3151
3151
|
"errors": [
|
|
3152
3152
|
{
|
|
3153
3153
|
"code": 6000,
|
|
3154
|
-
"name": "
|
|
3155
|
-
"msg": "
|
|
3156
|
-
},
|
|
3157
|
-
{
|
|
3158
|
-
"code": 6001,
|
|
3159
|
-
"name": "InsufficientBalance",
|
|
3160
|
-
"msg": "Insufficient balance"
|
|
3161
|
-
},
|
|
3162
|
-
{
|
|
3163
|
-
"code": 6002,
|
|
3164
|
-
"name": "InsufficientFunds",
|
|
3165
|
-
"msg": "Insufficient funds"
|
|
3166
|
-
},
|
|
3167
|
-
{
|
|
3168
|
-
"code": 6003,
|
|
3169
|
-
"name": "Unauthorized",
|
|
3170
|
-
"msg": "Unauthorized - caller is not the distribution authority"
|
|
3171
|
-
},
|
|
3172
|
-
{
|
|
3173
|
-
"code": 6004,
|
|
3174
|
-
"name": "InvalidMint",
|
|
3175
|
-
"msg": "Invalid mint"
|
|
3176
|
-
},
|
|
3177
|
-
{
|
|
3178
|
-
"code": 6005,
|
|
3179
|
-
"name": "InvalidOwner",
|
|
3180
|
-
"msg": "Invalid owner"
|
|
3181
|
-
},
|
|
3182
|
-
{
|
|
3183
|
-
"code": 6006,
|
|
3184
|
-
"name": "InvalidUserRecord",
|
|
3185
|
-
"msg": "Invalid user record"
|
|
3186
|
-
},
|
|
3187
|
-
{
|
|
3188
|
-
"code": 6007,
|
|
3189
|
-
"name": "InvalidWithdrawal",
|
|
3190
|
-
"msg": "Invalid withdrawal - balance increased instead of decreased"
|
|
3191
|
-
},
|
|
3192
|
-
{
|
|
3193
|
-
"code": 6008,
|
|
3194
|
-
"name": "InvalidProgramId",
|
|
3195
|
-
"msg": "Invalid program ID"
|
|
3196
|
-
},
|
|
3197
|
-
{
|
|
3198
|
-
"code": 6009,
|
|
3199
|
-
"name": "InstructionIntrospectionFailed",
|
|
3200
|
-
"msg": "Instruction introspection failed"
|
|
3201
|
-
},
|
|
3202
|
-
{
|
|
3203
|
-
"code": 6010,
|
|
3204
|
-
"name": "ReceiptFulfilled",
|
|
3205
|
-
"msg": "Receipt already fulfilled"
|
|
3154
|
+
"name": "AccountBorrowFailed",
|
|
3155
|
+
"msg": "Util Acc borrow Failed"
|
|
3206
3156
|
}
|
|
3207
3157
|
],
|
|
3208
3158
|
"types": [
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* IDL can be found at `target/idl/liqsol_core.json`.
|
|
6
6
|
*/
|
|
7
7
|
export type LiqsolCore = {
|
|
8
|
-
"address": "
|
|
8
|
+
"address": "BBkVcNWNQz1vZ6esv5US4QnNFWPRqxWbdpJHur9GVXSu",
|
|
9
9
|
"metadata": {
|
|
10
10
|
"name": "liqsolCore",
|
|
11
11
|
"version": "0.1.0",
|
|
@@ -3157,58 +3157,8 @@ export type LiqsolCore = {
|
|
|
3157
3157
|
"errors": [
|
|
3158
3158
|
{
|
|
3159
3159
|
"code": 6000,
|
|
3160
|
-
"name": "
|
|
3161
|
-
"msg": "
|
|
3162
|
-
},
|
|
3163
|
-
{
|
|
3164
|
-
"code": 6001,
|
|
3165
|
-
"name": "insufficientBalance",
|
|
3166
|
-
"msg": "Insufficient balance"
|
|
3167
|
-
},
|
|
3168
|
-
{
|
|
3169
|
-
"code": 6002,
|
|
3170
|
-
"name": "insufficientFunds",
|
|
3171
|
-
"msg": "Insufficient funds"
|
|
3172
|
-
},
|
|
3173
|
-
{
|
|
3174
|
-
"code": 6003,
|
|
3175
|
-
"name": "unauthorized",
|
|
3176
|
-
"msg": "Unauthorized - caller is not the distribution authority"
|
|
3177
|
-
},
|
|
3178
|
-
{
|
|
3179
|
-
"code": 6004,
|
|
3180
|
-
"name": "invalidMint",
|
|
3181
|
-
"msg": "Invalid mint"
|
|
3182
|
-
},
|
|
3183
|
-
{
|
|
3184
|
-
"code": 6005,
|
|
3185
|
-
"name": "invalidOwner",
|
|
3186
|
-
"msg": "Invalid owner"
|
|
3187
|
-
},
|
|
3188
|
-
{
|
|
3189
|
-
"code": 6006,
|
|
3190
|
-
"name": "invalidUserRecord",
|
|
3191
|
-
"msg": "Invalid user record"
|
|
3192
|
-
},
|
|
3193
|
-
{
|
|
3194
|
-
"code": 6007,
|
|
3195
|
-
"name": "invalidWithdrawal",
|
|
3196
|
-
"msg": "Invalid withdrawal - balance increased instead of decreased"
|
|
3197
|
-
},
|
|
3198
|
-
{
|
|
3199
|
-
"code": 6008,
|
|
3200
|
-
"name": "invalidProgramId",
|
|
3201
|
-
"msg": "Invalid program ID"
|
|
3202
|
-
},
|
|
3203
|
-
{
|
|
3204
|
-
"code": 6009,
|
|
3205
|
-
"name": "instructionIntrospectionFailed",
|
|
3206
|
-
"msg": "Instruction introspection failed"
|
|
3207
|
-
},
|
|
3208
|
-
{
|
|
3209
|
-
"code": 6010,
|
|
3210
|
-
"name": "receiptFulfilled",
|
|
3211
|
-
"msg": "Receipt already fulfilled"
|
|
3160
|
+
"name": "accountBorrowFailed",
|
|
3161
|
+
"msg": "Util Acc borrow Failed"
|
|
3212
3162
|
}
|
|
3213
3163
|
],
|
|
3214
3164
|
"types": [
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* IDL can be found at `target/idl/liqsol_token.json`.
|
|
6
6
|
*/
|
|
7
7
|
export type LiqsolToken = {
|
|
8
|
-
"address": "
|
|
8
|
+
"address": "6cDoerqdV6UQDsGvUEq5Qj5HRxxyDxSuUaB2J6iK8cio",
|
|
9
9
|
"metadata": {
|
|
10
10
|
"name": "liqsolToken",
|
|
11
11
|
"version": "0.1.0",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* IDL can be found at `target/idl/validator_leaderboard.json`.
|
|
6
6
|
*/
|
|
7
7
|
export type ValidatorLeaderboard = {
|
|
8
|
-
"address": "
|
|
8
|
+
"address": "C4ddPrB1ALYpW4G1Qz4ffvETBA8YGUL7TVZaLiE6bb1q",
|
|
9
9
|
"metadata": {
|
|
10
10
|
"name": "validatorLeaderboard",
|
|
11
11
|
"version": "0.1.0",
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Staker utilities
|
|
2
|
-
export * from './staker
|
|
3
|
-
export * from './
|
|
2
|
+
export * from './staker';
|
|
3
|
+
export * from './types';
|
|
4
4
|
|
|
5
5
|
// NETWORKS
|
|
6
6
|
export * from './networks/ethereum/ethereum';
|
|
@@ -16,4 +16,5 @@ export * from './networks/solana/utils';
|
|
|
16
16
|
export * from './networks/solana/clients/deposit.client';
|
|
17
17
|
export * from './networks/solana/clients/distribution.client';
|
|
18
18
|
export * from './networks/solana/clients/leaderboard.client';
|
|
19
|
-
export * from './networks/solana/clients/outpost.client';
|
|
19
|
+
export * from './networks/solana/clients/outpost.client';
|
|
20
|
+
export * from './networks/solana/clients/token.client';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BigNumber, ethers } from 'ethers';
|
|
2
|
-
import { IStakingClient, Portfolio, StakerConfig } from '../../
|
|
2
|
+
import { IStakingClient, Portfolio, PurchaseAsset, PurchaseQuote, StakerConfig, TrancheSnapshot } from '../../types';
|
|
3
3
|
import { PublicKey as WirePubKey } from '@wireio/core';
|
|
4
4
|
import { EthereumContractService } from './contract';
|
|
5
5
|
import { preLaunchReceipt, WithdrawRequestedEvent, WithdrawResult } from './types';
|
|
@@ -114,6 +114,16 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
// TODO
|
|
118
|
+
buy(amount: bigint, purchaseAsset: PurchaseAsset): Promise<string> {
|
|
119
|
+
throw new Error("Method not yet implemented.");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// TODO
|
|
123
|
+
getBuyQuote(amount: bigint, purchaseAsset: PurchaseAsset): Promise<PurchaseQuote> {
|
|
124
|
+
throw new Error("Method not yet implemented.");
|
|
125
|
+
}
|
|
126
|
+
|
|
117
127
|
|
|
118
128
|
/**
|
|
119
129
|
* Resolve the user's ETH + liqETH balances.
|
|
@@ -161,12 +171,26 @@ export class EthereumStakingClient implements IStakingClient {
|
|
|
161
171
|
decimals: nativeDecimals,
|
|
162
172
|
symbol: liqSymbol,
|
|
163
173
|
},
|
|
174
|
+
wire: {
|
|
175
|
+
amount: BigInt(0), // TODO
|
|
176
|
+
decimals: 0,
|
|
177
|
+
symbol: '$WIRE',
|
|
178
|
+
},
|
|
164
179
|
chainID: this.network.chainId
|
|
165
180
|
}
|
|
166
181
|
// console.log('ETH PORTFOLIO', portfolio);
|
|
167
182
|
return portfolio;
|
|
168
183
|
}
|
|
169
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Program-level prelaunch WIRE / tranche snapshot for Solana.
|
|
187
|
+
* Uses the same OutpostWireStateSnapshot primitive as getPortfolio().
|
|
188
|
+
* TODO! for eth
|
|
189
|
+
*/
|
|
190
|
+
async getTrancheSnapshot(): Promise<TrancheSnapshot | null> {
|
|
191
|
+
return null
|
|
192
|
+
}
|
|
193
|
+
|
|
170
194
|
|
|
171
195
|
// ---------------------------------------------------------------------
|
|
172
196
|
// Internal ETH Staking client helper functions
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { AnchorProvider, BN, Program } from '@coral-xyz/anchor';
|
|
2
|
+
import type { TransactionInstruction, Connection } from '@solana/web3.js';
|
|
3
|
+
import { PublicKey, SystemProgram } from '@solana/web3.js';
|
|
4
|
+
import {
|
|
5
|
+
TOKEN_2022_PROGRAM_ID,
|
|
6
|
+
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
7
|
+
} from '@solana/spl-token';
|
|
8
|
+
|
|
9
|
+
import { buildOutpostAccounts, type OutpostAccounts, buildSolanaTrancheSnapshot } from '../utils';
|
|
10
|
+
import { SolanaProgramService } from '../program';
|
|
11
|
+
import { LiqsolCore } from '../../../assets/solana/types/liqsol_core';
|
|
12
|
+
import {
|
|
13
|
+
GlobalState,
|
|
14
|
+
PriceHistory,
|
|
15
|
+
TrancheState,
|
|
16
|
+
UserWarrantRecord,
|
|
17
|
+
WalletLike,
|
|
18
|
+
WireReceipt,
|
|
19
|
+
} from '../types';
|
|
20
|
+
import { derivePriceHistoryPda } from '../constants';
|
|
21
|
+
import type { } from '../types';
|
|
22
|
+
import { ChainID, SolChainID } from '@wireio/core';
|
|
23
|
+
import { PurchaseAsset, PurchaseQuote, TrancheSnapshot } from '../../../types';
|
|
24
|
+
|
|
25
|
+
export class TokenClient {
|
|
26
|
+
private readonly program: Program<LiqsolCore>;
|
|
27
|
+
|
|
28
|
+
get wallet(): WalletLike {
|
|
29
|
+
return this.provider.wallet;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
constructor(private readonly provider: AnchorProvider) {
|
|
33
|
+
const svc = new SolanaProgramService(provider);
|
|
34
|
+
this.program = svc.getProgram('liqsolCore');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Account helpers
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
async getAccounts(user: PublicKey): Promise<OutpostAccounts> {
|
|
42
|
+
return buildOutpostAccounts(this.provider.connection, user);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async fetchGlobalState(): Promise<GlobalState> {
|
|
46
|
+
const { globalState } = await this.getAccounts(this.wallet.publicKey);
|
|
47
|
+
return this.program.account.globalState.fetch(globalState);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async fetchTrancheState(): Promise<TrancheState> {
|
|
51
|
+
const { trancheState } = await this.getAccounts(this.wallet.publicKey);
|
|
52
|
+
return this.program.account.trancheState.fetch(trancheState);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async fetchWireReceipt(user: PublicKey): Promise<WireReceipt> {
|
|
56
|
+
const { wireReceipt } = await this.getAccounts(user);
|
|
57
|
+
return this.program.account.wireReceipt.fetch(wireReceipt);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async fetchUserWarrantRecord(user: PublicKey): Promise<UserWarrantRecord> {
|
|
61
|
+
const { userWarrantRecord } = await this.getAccounts(user);
|
|
62
|
+
return this.program.account.userWarrantRecord.fetch(userWarrantRecord);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Tranche snapshot / quoting
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// Instruction builders (no send / confirm)
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
async buildPurchaseWithSolIx(
|
|
74
|
+
amountLamports: bigint,
|
|
75
|
+
user = this.wallet.publicKey,
|
|
76
|
+
): Promise<TransactionInstruction> {
|
|
77
|
+
const a = await this.getAccounts(user);
|
|
78
|
+
|
|
79
|
+
return this.program.methods
|
|
80
|
+
.purchaseWithSol(new BN(amountLamports.toString()))
|
|
81
|
+
.accounts({
|
|
82
|
+
user: a.user,
|
|
83
|
+
liqsolMint: a.liqsolMint,
|
|
84
|
+
globalState: a.globalState,
|
|
85
|
+
|
|
86
|
+
poolAuthority: a.poolAuthority,
|
|
87
|
+
liqsolPoolAta: a.liqsolPoolAta,
|
|
88
|
+
liqsolPoolUserRecord: a.poolUserRecord,
|
|
89
|
+
distributionState: a.distributionState,
|
|
90
|
+
payRateHistory: a.payRateHistory,
|
|
91
|
+
bucketAuthority: a.bucketAuthority,
|
|
92
|
+
bucketTokenAccount: a.bucketTokenAccount,
|
|
93
|
+
solBucket: a.solBucket,
|
|
94
|
+
|
|
95
|
+
// IDL name is warrantDepositRecord (wireReceipt PDA)
|
|
96
|
+
warrantDepositRecord: a.wireReceipt,
|
|
97
|
+
|
|
98
|
+
trancheState: a.trancheState,
|
|
99
|
+
userWarrantRecord: a.userWarrantRecord,
|
|
100
|
+
|
|
101
|
+
chainlinkFeed: a.chainLinkFeed,
|
|
102
|
+
chainlinkProgram: a.chainLinkProgram,
|
|
103
|
+
|
|
104
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
105
|
+
systemProgram: SystemProgram.programId,
|
|
106
|
+
})
|
|
107
|
+
.instruction();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async buildPurchaseWithLiqsolIx(
|
|
111
|
+
amountLamports: bigint,
|
|
112
|
+
user = this.wallet.publicKey,
|
|
113
|
+
): Promise<TransactionInstruction> {
|
|
114
|
+
const a = await this.getAccounts(user);
|
|
115
|
+
|
|
116
|
+
return this.program.methods
|
|
117
|
+
.purchaseWithLiqsol(new BN(amountLamports.toString()))
|
|
118
|
+
.accounts({
|
|
119
|
+
user: a.user,
|
|
120
|
+
liqsolMint: a.liqsolMint,
|
|
121
|
+
globalState: a.globalState,
|
|
122
|
+
|
|
123
|
+
buyerAta: a.userAta,
|
|
124
|
+
poolAuthority: a.poolAuthority,
|
|
125
|
+
liqsolPoolAta: a.liqsolPoolAta,
|
|
126
|
+
|
|
127
|
+
warrantDepositRecord: a.wireReceipt,
|
|
128
|
+
|
|
129
|
+
liqsolPoolUserRecord: a.poolUserRecord,
|
|
130
|
+
distributionState: a.distributionState,
|
|
131
|
+
payRateHistory: a.payRateHistory,
|
|
132
|
+
bucketAuthority: a.bucketAuthority,
|
|
133
|
+
bucketTokenAccount: a.bucketTokenAccount,
|
|
134
|
+
solBucket: a.solBucket,
|
|
135
|
+
|
|
136
|
+
trancheState: a.trancheState,
|
|
137
|
+
userWarrantRecord: a.userWarrantRecord,
|
|
138
|
+
|
|
139
|
+
chainlinkFeed: a.chainLinkFeed,
|
|
140
|
+
chainlinkProgram: a.chainLinkProgram,
|
|
141
|
+
|
|
142
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
143
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
144
|
+
systemProgram: SystemProgram.programId,
|
|
145
|
+
})
|
|
146
|
+
.instruction();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async buildPurchaseFromYieldIx(
|
|
150
|
+
user = this.wallet.publicKey,
|
|
151
|
+
): Promise<TransactionInstruction> {
|
|
152
|
+
const a = await this.getAccounts(user);
|
|
153
|
+
|
|
154
|
+
return this.program.methods
|
|
155
|
+
.purchaseWarrantsFromYield()
|
|
156
|
+
.accounts({
|
|
157
|
+
user: a.user,
|
|
158
|
+
globalState: a.globalState,
|
|
159
|
+
liqsolMint: a.liqsolMint,
|
|
160
|
+
poolAuthority: a.poolAuthority,
|
|
161
|
+
liqsolPoolAta: a.liqsolPoolAta,
|
|
162
|
+
solBucket: a.solBucket,
|
|
163
|
+
|
|
164
|
+
liqsolPoolUserRecord: a.poolUserRecord,
|
|
165
|
+
distributionState: a.distributionState,
|
|
166
|
+
payRateHistory: a.payRateHistory,
|
|
167
|
+
bucketAuthority: a.bucketAuthority,
|
|
168
|
+
bucketTokenAccount: a.bucketTokenAccount,
|
|
169
|
+
|
|
170
|
+
trancheState: a.trancheState,
|
|
171
|
+
userWarrantRecord: a.userWarrantRecord,
|
|
172
|
+
chainlinkFeed: a.chainLinkFeed,
|
|
173
|
+
chainlinkProgram: a.chainLinkProgram,
|
|
174
|
+
|
|
175
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
176
|
+
systemProgram: SystemProgram.programId,
|
|
177
|
+
})
|
|
178
|
+
.instruction();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Price helpers (SOL/USD via priceHistory account)
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
|
|
185
|
+
async getSolPriceUsdSafe(): Promise<{ price?: bigint; timestamp?: number }> {
|
|
186
|
+
try {
|
|
187
|
+
const price = await this.getSolPriceUsd();
|
|
188
|
+
// current priceHistory account has no timestamp; keep optional
|
|
189
|
+
return { price, timestamp: undefined };
|
|
190
|
+
} catch {
|
|
191
|
+
return { price: undefined, timestamp: undefined };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Fetch latest SOL/USD price (1e8 scale) from liqsol_core.priceHistory.
|
|
197
|
+
* Uses the ring-buffer semantics from earlier SDK code.
|
|
198
|
+
*/
|
|
199
|
+
async getSolPriceUsd(): Promise<bigint> {
|
|
200
|
+
const priceHistoryPda = derivePriceHistoryPda();
|
|
201
|
+
const history = (await this.program.account.priceHistory.fetch(
|
|
202
|
+
priceHistoryPda,
|
|
203
|
+
)) as PriceHistory;
|
|
204
|
+
|
|
205
|
+
const { prices, nextIndex, count, windowSize } = history;
|
|
206
|
+
|
|
207
|
+
if (!prices || prices.length === 0 || !count) {
|
|
208
|
+
throw new Error('Price history is empty – no SOL price available');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const capacity = prices.length || windowSize;
|
|
212
|
+
if (!capacity) {
|
|
213
|
+
throw new Error('Price history capacity is zero – check account layout');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const lastIndex = nextIndex === 0 ? capacity - 1 : nextIndex - 1;
|
|
217
|
+
const latest = prices[lastIndex];
|
|
218
|
+
|
|
219
|
+
if (!BN.isBN(latest)) {
|
|
220
|
+
throw new Error('Latest price entry is not a BN – check IDL/decoder');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return BigInt(latest.toString());
|
|
224
|
+
}
|
|
225
|
+
}
|
|
@@ -74,6 +74,9 @@ export const PDA_SEEDS = {
|
|
|
74
74
|
BAR_STATE_SEED: 'bar_state',
|
|
75
75
|
BONDED_ACTOR_SEED: 'bonded_actor',
|
|
76
76
|
BOND_LEVEL_SEED: 'bond_level',
|
|
77
|
+
|
|
78
|
+
// Other?
|
|
79
|
+
PRICE_HISTORY: 'price_history',
|
|
77
80
|
} as const;
|
|
78
81
|
|
|
79
82
|
/**
|
|
@@ -232,6 +235,12 @@ export const deriveBondedActorPda = (actor: PublicKey) =>
|
|
|
232
235
|
LIQSOL_CORE,
|
|
233
236
|
)[0];
|
|
234
237
|
|
|
238
|
+
export const derivePriceHistoryPda = () =>
|
|
239
|
+
PublicKey.findProgramAddressSync(
|
|
240
|
+
[Buffer.from(PDA_SEEDS.PRICE_HISTORY)],
|
|
241
|
+
LIQSOL_CORE,
|
|
242
|
+
)[0];
|
|
243
|
+
|
|
235
244
|
/**
|
|
236
245
|
* Ephemeral stake account address used per-deposit.
|
|
237
246
|
* On-chain convention: seed = `ephemeral_<u32>` under StakeProgram.programId.
|