@wireio/stake 0.2.1 → 0.2.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.
- package/lib/stake.browser.js +295 -73
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +157 -66
- package/lib/stake.js +398 -127
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +295 -73
- 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/contract.ts +9 -12
- package/src/networks/ethereum/ethereum.ts +25 -1
- package/src/networks/ethereum/types.ts +1 -1
- package/src/networks/solana/clients/token.client.ts +251 -0
- package/src/networks/solana/constants.ts +9 -0
- package/src/networks/solana/solana.ts +205 -7
- package/src/networks/solana/types.ts +11 -1
- package/src/networks/solana/utils.ts +17 -3
- package/src/{staker/staker.ts → staker.ts} +2 -2
- package/src/types.ts +105 -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';
|
|
@@ -53,20 +53,17 @@ export const ADDRESSES: AddressBook = {
|
|
|
53
53
|
StakingModule: "0xBd13C85fdefBBc63904e7301aCdeFE87c9C93234",
|
|
54
54
|
WithdrawalQueue: "0xD9A1D38ae4A636DEf20B02F35387a6b126D73fAe", //aka "queue"
|
|
55
55
|
WithdrawalVault: "0x150334D09a1d3d30EE93d5e6009EB897B5dDF5b2", //aka withdrawVault
|
|
56
|
-
|
|
57
|
-
//not in last set of deployments 12/18/25
|
|
58
|
-
// LiqEthMint: "0xdBAa1539eB7b80C29d825FCda76c0d7F8F0E6cFB",
|
|
59
|
-
// LiqEthBurn: "0x02e0A02fE2311FAd661677B7117FDdc801c1216b",
|
|
56
|
+
|
|
60
57
|
|
|
61
58
|
//Outpost contracts
|
|
62
|
-
Depositor: "
|
|
63
|
-
ReceiptNFT: "
|
|
64
|
-
OutpostManager: "
|
|
65
|
-
BAR: "
|
|
66
|
-
OPP: "
|
|
67
|
-
OPPCommon: "
|
|
68
|
-
OPPInbound: "
|
|
69
|
-
Warrant: "
|
|
59
|
+
Depositor: "0x6aE1D7095B81970654Bd51bCAD42825C6E579088",
|
|
60
|
+
ReceiptNFT: "0x38eAEa05cB1FFD0c8426A3f9e77815a251DdC197",
|
|
61
|
+
OutpostManager: "0x6512bB8E7f8418A8e3bB73c49E33EcC30F53f221",
|
|
62
|
+
BAR: "0x00c128A37598d018Eb8ca4f516688695D83bD413",
|
|
63
|
+
OPP: "0x8C5710103Ec6a7608dAC539DC232d3822bA3d14C",
|
|
64
|
+
OPPCommon: "0x52C1d7F02B35176F79b03F6eF7E5b74b27d1dB8c",
|
|
65
|
+
OPPInbound: "0x39feC7536BaEd4E376b1B5cf2f2e8182ab203418",
|
|
66
|
+
Warrant: "0x9190bBcaB5cfeb4b7b6DE5Ae21105F3114753F10",
|
|
70
67
|
};
|
|
71
68
|
|
|
72
69
|
export type Contracts<T extends string = ContractName> = Record<T, ContractConfig>;
|
|
@@ -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,251 @@
|
|
|
1
|
+
import { AnchorProvider, BN, Program } from '@coral-xyz/anchor';
|
|
2
|
+
import type { TransactionInstruction } 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 } from '../utils';
|
|
10
|
+
import { SolanaProgramService } from '../program';
|
|
11
|
+
import { LiqsolCore } from '../../../assets/solana/types/liqsol_core';
|
|
12
|
+
import { GlobalState, PriceHistory, TrancheState, UserWarrantRecord, WalletLike, WireReceipt } from '../types';
|
|
13
|
+
import { derivePriceHistoryPda } from '../constants';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Client for interacting with the Pretoken (Outpost) program on Solana.
|
|
17
|
+
*
|
|
18
|
+
* Provides account fetching and instruction building for pretoken operations.
|
|
19
|
+
* Does NOT send or confirm transactions; keeps SDK composable.
|
|
20
|
+
*
|
|
21
|
+
* TODO: Update to $WIRE Token implementation Post-Launch
|
|
22
|
+
*/
|
|
23
|
+
export class TokenClient {
|
|
24
|
+
private readonly program: Program<LiqsolCore>;
|
|
25
|
+
|
|
26
|
+
get wallet(): WalletLike { return this.provider.wallet; }
|
|
27
|
+
|
|
28
|
+
constructor(private readonly provider: AnchorProvider) {
|
|
29
|
+
const svc = new SolanaProgramService(provider);
|
|
30
|
+
this.program = svc.getProgram('liqsolCore');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Single source of truth for outpost/pretoken accounts.
|
|
35
|
+
* Uses your existing PDA + ATA derivations in buildOutpostAccounts().
|
|
36
|
+
*/
|
|
37
|
+
async getAccounts(user: PublicKey): Promise<OutpostAccounts> {
|
|
38
|
+
return buildOutpostAccounts(this.provider.connection, user);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Lightweight, UI-friendly snapshot fetchers.
|
|
43
|
+
* (No decoding assumptions beyond what Anchor already provides.)
|
|
44
|
+
*/
|
|
45
|
+
async fetchGlobalState(): Promise<GlobalState> {
|
|
46
|
+
const { globalState } = await this.getAccounts(this.provider.wallet.publicKey);
|
|
47
|
+
return this.program.account.globalState.fetch(globalState);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async fetchTrancheState(): Promise<TrancheState> {
|
|
51
|
+
const { trancheState } = await this.getAccounts(this.provider.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
|
+
// Instruction builders (no send, no confirmation: SDK stays composable)
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* purchase_with_sol(amount u64)
|
|
71
|
+
*
|
|
72
|
+
* amountLamports is bigint to match your SDK convention.
|
|
73
|
+
*/
|
|
74
|
+
async buildPurchaseWithSolIx(amountLamports: bigint, user = this.wallet.publicKey): Promise<TransactionInstruction> {
|
|
75
|
+
const a = await this.getAccounts(user);
|
|
76
|
+
|
|
77
|
+
return this.program.methods
|
|
78
|
+
.purchaseWithSol(new BN(amountLamports.toString()))
|
|
79
|
+
.accounts({
|
|
80
|
+
// signer
|
|
81
|
+
user: a.user,
|
|
82
|
+
|
|
83
|
+
// core state
|
|
84
|
+
liqsolMint: a.liqsolMint,
|
|
85
|
+
globalState: a.globalState,
|
|
86
|
+
|
|
87
|
+
// liqSOL pool + distribution plumbing
|
|
88
|
+
poolAuthority: a.poolAuthority,
|
|
89
|
+
liqsolPoolAta: a.liqsolPoolAta,
|
|
90
|
+
liqsolPoolUserRecord: a.poolUserRecord,
|
|
91
|
+
distributionState: a.distributionState,
|
|
92
|
+
payRateHistory: a.payRateHistory,
|
|
93
|
+
bucketAuthority: a.bucketAuthority,
|
|
94
|
+
bucketTokenAccount: a.bucketTokenAccount,
|
|
95
|
+
solBucket: a.solBucket,
|
|
96
|
+
|
|
97
|
+
// IMPORTANT: IDL name (not wireReceipt)
|
|
98
|
+
warrantDepositRecord: a.wireReceipt,
|
|
99
|
+
|
|
100
|
+
// pretoken state
|
|
101
|
+
trancheState: a.trancheState,
|
|
102
|
+
userWarrantRecord: a.userWarrantRecord,
|
|
103
|
+
|
|
104
|
+
// Chainlink (IDL names are chainlinkFeed / chainlinkProgram in old utils)
|
|
105
|
+
chainlinkFeed: a.chainLinkFeed,
|
|
106
|
+
chainlinkProgram: a.chainLinkProgram,
|
|
107
|
+
|
|
108
|
+
// programs
|
|
109
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
110
|
+
systemProgram: SystemProgram.programId,
|
|
111
|
+
})
|
|
112
|
+
.instruction();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* purchase_with_liqsol(amount u64)
|
|
117
|
+
*
|
|
118
|
+
* amount is liqSOL *raw base units* (Token-2022 amount).
|
|
119
|
+
*/
|
|
120
|
+
async buildPurchaseWithLiqsolIx(amountLamports: bigint, user = this.wallet.publicKey): Promise<TransactionInstruction> {
|
|
121
|
+
const a = await this.getAccounts(user);
|
|
122
|
+
|
|
123
|
+
return this.program.methods
|
|
124
|
+
.purchaseWithLiqsol(new BN(amountLamports.toString()))
|
|
125
|
+
.accounts({
|
|
126
|
+
// signer
|
|
127
|
+
user: a.user,
|
|
128
|
+
|
|
129
|
+
// core state
|
|
130
|
+
liqsolMint: a.liqsolMint,
|
|
131
|
+
globalState: a.globalState,
|
|
132
|
+
|
|
133
|
+
// token movement
|
|
134
|
+
buyerAta: a.userAta, // Token-2022 ATA for user
|
|
135
|
+
poolAuthority: a.poolAuthority,
|
|
136
|
+
liqsolPoolAta: a.liqsolPoolAta,
|
|
137
|
+
|
|
138
|
+
// IMPORTANT: IDL name (not wireReceipt)
|
|
139
|
+
warrantDepositRecord: a.wireReceipt,
|
|
140
|
+
|
|
141
|
+
// distribution plumbing (per old utils)
|
|
142
|
+
liqsolPoolUserRecord: a.poolUserRecord, // pool user_record PDA
|
|
143
|
+
distributionState: a.distributionState,
|
|
144
|
+
payRateHistory: a.payRateHistory,
|
|
145
|
+
bucketAuthority: a.bucketAuthority,
|
|
146
|
+
bucketTokenAccount: a.bucketTokenAccount,
|
|
147
|
+
solBucket: a.solBucket,
|
|
148
|
+
|
|
149
|
+
// pretoken state
|
|
150
|
+
trancheState: a.trancheState,
|
|
151
|
+
userWarrantRecord: a.userWarrantRecord,
|
|
152
|
+
|
|
153
|
+
// Chainlink
|
|
154
|
+
chainlinkFeed: a.chainLinkFeed,
|
|
155
|
+
chainlinkProgram: a.chainLinkProgram,
|
|
156
|
+
|
|
157
|
+
// programs
|
|
158
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
159
|
+
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
160
|
+
systemProgram: SystemProgram.programId,
|
|
161
|
+
})
|
|
162
|
+
.instruction();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* purchase_warrants_from_yield()
|
|
167
|
+
*
|
|
168
|
+
* No amount arg; it consumes tracked yield according to on-chain rules.
|
|
169
|
+
*/
|
|
170
|
+
async buildPurchaseFromYieldIx(user = this.wallet.publicKey): Promise<TransactionInstruction> {
|
|
171
|
+
const a = await this.getAccounts(user);
|
|
172
|
+
|
|
173
|
+
return this.program.methods
|
|
174
|
+
.purchaseWarrantsFromYield()
|
|
175
|
+
.accounts({
|
|
176
|
+
// signer
|
|
177
|
+
user: a.user,
|
|
178
|
+
|
|
179
|
+
// core state
|
|
180
|
+
globalState: a.globalState,
|
|
181
|
+
liqsolMint: a.liqsolMint,
|
|
182
|
+
poolAuthority: a.poolAuthority,
|
|
183
|
+
liqsolPoolAta: a.liqsolPoolAta,
|
|
184
|
+
solBucket: a.solBucket,
|
|
185
|
+
|
|
186
|
+
liqsolPoolUserRecord: a.poolUserRecord,
|
|
187
|
+
|
|
188
|
+
distributionState: a.distributionState,
|
|
189
|
+
payRateHistory: a.payRateHistory,
|
|
190
|
+
bucketAuthority: a.bucketAuthority,
|
|
191
|
+
bucketTokenAccount: a.bucketTokenAccount,
|
|
192
|
+
|
|
193
|
+
// programs
|
|
194
|
+
tokenProgram: TOKEN_2022_PROGRAM_ID,
|
|
195
|
+
systemProgram: SystemProgram.programId,
|
|
196
|
+
|
|
197
|
+
// pretoken state + chainlink (per old utils)
|
|
198
|
+
trancheState: a.trancheState,
|
|
199
|
+
userWarrantRecord: a.userWarrantRecord,
|
|
200
|
+
chainlinkFeed: a.chainLinkFeed,
|
|
201
|
+
chainlinkProgram: a.chainLinkProgram,
|
|
202
|
+
})
|
|
203
|
+
.instruction();
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
// HELPERS
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Fetch the SOL price in 1e8 USD units from liqsol_core.priceHistory.
|
|
211
|
+
*
|
|
212
|
+
* This uses the same ring-buffer semantics as the on-chain program:
|
|
213
|
+
* the latest price is the entry just before `nextIndex`.
|
|
214
|
+
*/
|
|
215
|
+
async getSolPriceUsd(): Promise<BN> {
|
|
216
|
+
const priceHistoryPda = derivePriceHistoryPda();
|
|
217
|
+
|
|
218
|
+
const history : PriceHistory = await this.program.account.priceHistory.fetch(
|
|
219
|
+
priceHistoryPda
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
console.log('PRICE HISTORY', history);
|
|
223
|
+
|
|
224
|
+
const { windowSize, prices, nextIndex, count } = history;
|
|
225
|
+
|
|
226
|
+
if (!prices || prices.length === 0 || count === 0) {
|
|
227
|
+
throw new Error("Price history is empty – no SOL price available");
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Use the actual buffer length as capacity (should match windowSize)
|
|
231
|
+
const capacity = prices.length || windowSize;
|
|
232
|
+
if (capacity === 0) {
|
|
233
|
+
throw new Error("Price history capacity is zero – check account layout");
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Last written slot in the ring buffer
|
|
237
|
+
const lastIndex =
|
|
238
|
+
nextIndex === 0
|
|
239
|
+
? capacity - 1
|
|
240
|
+
: nextIndex - 1;
|
|
241
|
+
|
|
242
|
+
const priceUsd = prices[lastIndex];
|
|
243
|
+
|
|
244
|
+
if (!BN.isBN(priceUsd)) {
|
|
245
|
+
throw new Error("Latest price entry is not a BN – check IDL/decoder");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// priceUsd is already 1e8-scaled USD (same scale used in warrant pricing)
|
|
249
|
+
return priceUsd;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
@@ -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.
|