@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wireio/stake",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "LIQ Staking Module for Wire Network",
5
5
  "homepage": "https://gitea.gitgo.app/Wire/sdk-stake",
6
6
  "license": "FSL-1.1-Apache-2.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "address": "HR3t8mA25TdJpwLph2h2L7KhK7ynWoAByYYzgUAfd5rk",
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": "NoRewardsToClaim",
3155
- "msg": "No rewards to claim"
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": [
@@ -1,5 +1,5 @@
1
1
  {
2
- "address": "HEAKvfg2X7K4zbGDiAbfuu5abxQyk1HbKVgskZZFXrUx",
2
+ "address": "6cDoerqdV6UQDsGvUEq5Qj5HRxxyDxSuUaB2J6iK8cio",
3
3
  "metadata": {
4
4
  "name": "liqsol_token",
5
5
  "version": "0.1.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "address": "BcMW7wN54FexYaB7Xujvag5uUQ1WoDoGbzVg1VEXPBhV",
2
+ "address": "C4ddPrB1ALYpW4G1Qz4ffvETBA8YGUL7TVZaLiE6bb1q",
3
3
  "metadata": {
4
4
  "name": "validator_leaderboard",
5
5
  "version": "0.1.0",
@@ -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": "HR3t8mA25TdJpwLph2h2L7KhK7ynWoAByYYzgUAfd5rk",
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": "noRewardsToClaim",
3161
- "msg": "No rewards to claim"
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": "HEAKvfg2X7K4zbGDiAbfuu5abxQyk1HbKVgskZZFXrUx",
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": "BcMW7wN54FexYaB7Xujvag5uUQ1WoDoGbzVg1VEXPBhV",
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/staker';
3
- export * from './staker/types';
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: "0x0876f5f411651dFc67386Bc3D36315a3B2249F2e",
63
- ReceiptNFT: "0x726c91fB3218A745Bfec0302B4cBaeBeaA023a6d",
64
- OutpostManager: "0xB6Eb20f7916295853a318581eCB51Be4eeb107Fe",
65
- BAR: "0x1936EB941361da83EE0E68FB7Bd0DF210f090B5C",
66
- OPP: "0x2e4cc69D6F8CEC3eEec81F3051AD90fEa71e5D57",
67
- OPPCommon: "0xA79fB9e563cF70190346D66eA20A1F2E09e0f732",
68
- OPPInbound: "0xd63644d0e8c3610eEf9f0Fd5Ea884b962762c469",
69
- Warrant: "0x8613F6Bb9ad883e81338EF97A06c53459250c625",
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 '../../staker/types';
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
@@ -1,5 +1,5 @@
1
1
  import { BigNumber, ethers } from 'ethers';
2
- import { BalanceView } from '../../staker/types';
2
+ import { BalanceView } from '../../types';
3
3
 
4
4
  export const CONTRACT_NAMES = [
5
5
  'Accounting',
@@ -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.