@wireio/stake 0.2.5 → 0.3.1
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 +2456 -2069
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +25 -52
- package/lib/stake.js +2610 -2206
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +2456 -2069
- package/lib/stake.m.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/BeaconState.sol/BeaconState.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/BeaconState.sol/BeaconState.json +807 -0
- package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/DepositManager.sol/DepositManager.json +184 -346
- package/src/assets/ethereum/ABI/liqEth/LiqEthAuthority.sol/LiqEthAuthority.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthAuthority.sol/LiqEthAuthority.json +1289 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IAccounting.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositContract.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IDepositManager.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthUpgradeable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/ILiqEthUpgradeable.json +29 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20.json +36 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20Pausable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IRewardsERC20Pausable.json +263 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IStakingModule.json +226 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IValidatorBalanceVerifier.json +59 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/IWithdrawalRecord.json +14 -12
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/LiqEthCommon.sol/LiqEthCommon.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/LiqEthManaged.sol/LiqEthManaged.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/LiqEthManaged.sol/LiqEthManaged.json +229 -0
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20Upgradeable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/{RewardsERC20Pausable.sol/RewardsERC20Pausable.json → RewardsERC20.sol/RewardsERC20Upgradeable.json} +140 -78
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20PausableUpgradeable.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/{RewardsERC20.sol/RewardsERC20.json → RewardsERC20Pausable.sol/RewardsERC20PausableUpgradeable.json} +218 -30
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/BeaconRoots.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZ.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZExtras.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZExtras.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZVec48.dbg.json +4 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/SSZVec48.json +10 -0
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/ValidatorBalanceVerifier.sol/ValidatorBalanceVerifier.json +121 -55
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/YieldOracle.json +836 -273
- package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/accounting.sol/Accounting.json +150 -168
- package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/liqEth.sol/LiqEthToken.json +301 -186
- package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/stakingModule.sol/StakingModule.json +814 -206
- package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/withdrawalQueue.sol/WithdrawalQueue.json +244 -198
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/Uint64BE.json +2 -2
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.dbg.json +1 -1
- package/src/assets/ethereum/ABI/liqEth/withdrawalVault.sol/WithdrawalVault.json +165 -152
- package/src/assets/ethereum/ABI/outpost/Depositor.sol/Depositor.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/Depositor.sol/Depositor.json +167 -282
- package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/AggregatorV3Interface.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/EthUsdPriceConsumer.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/EthUsdPriceConsumer.sol/EthUsdPriceConsumer.json +2 -54
- package/src/assets/ethereum/ABI/outpost/OPP.sol/OPP.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/OPP.sol/OPP.json +26 -8
- package/src/assets/ethereum/ABI/outpost/OPPInbound.sol/OPPInbound.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/OPPInbound.sol/OPPInbound.json +2 -2
- package/src/assets/ethereum/ABI/outpost/Pretoken.sol/Pretoken.dbg.json +4 -0
- package/src/assets/ethereum/ABI/outpost/Pretoken.sol/Pretoken.json +1650 -0
- package/src/assets/ethereum/ABI/outpost/ReceiptNFT.sol/ReceiptNFT.dbg.json +1 -1
- package/src/assets/ethereum/ABI/outpost/ReceiptNFT.sol/ReceiptNFT.json +2 -22
- package/src/assets/ethereum/ABI/outpost/interfaces/IPretoken.sol/IPretoken.dbg.json +4 -0
- package/src/assets/ethereum/ABI/outpost/interfaces/IPretoken.sol/IPretoken.json +29 -0
- package/src/assets/ethereum/ABI/outpost/interfaces/IWarrant.sol/IWarrant.dbg.json +1 -1
- package/src/networks/ethereum/clients/deposit.client.ts +11 -7
- package/src/networks/ethereum/clients/liq.client.ts +47 -0
- package/src/networks/ethereum/clients/pretoken.client.ts +47 -50
- package/src/networks/ethereum/contract.ts +24 -51
- package/src/networks/ethereum/ethereum.ts +29 -52
- package/src/networks/ethereum/types.ts +7 -6
- package/src/networks/ethereum/utils.ts +2 -8
- package/src/networks/solana/clients/token.client.ts +0 -1
- package/src/networks/solana/solana.ts +44 -145
- package/src/networks/solana/types.ts +4 -1
- package/src/networks/solana/utils.ts +1 -3
- package/src/types.ts +5 -33
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20.sol/RewardsERC20.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/RewardsERC20Pausable.sol/RewardsERC20Pausable.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/BeaconRoots.json +0 -10
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.dbg.json +0 -4
- package/src/assets/ethereum/ABI/liqEth/Yield.sol/SSZ.json +0 -10
- package/src/assets/ethereum/ABI/outpost/Warrant.sol/Warrant.dbg.json +0 -4
- package/src/assets/ethereum/ABI/outpost/Warrant.sol/Warrant.json +0 -1650
|
@@ -27,8 +27,6 @@ import {
|
|
|
27
27
|
import {
|
|
28
28
|
IStakingClient,
|
|
29
29
|
Portfolio,
|
|
30
|
-
PurchaseAsset,
|
|
31
|
-
PurchaseQuote,
|
|
32
30
|
StakerConfig,
|
|
33
31
|
TrancheSnapshot,
|
|
34
32
|
} from '../../types';
|
|
@@ -62,7 +60,7 @@ const commitment: Commitment = 'confirmed';
|
|
|
62
60
|
* This class composes lower-level clients; it does not know about UI.
|
|
63
61
|
*/
|
|
64
62
|
export class SolanaStakingClient implements IStakingClient {
|
|
65
|
-
public pubKey
|
|
63
|
+
public pubKey?: PublicKey;
|
|
66
64
|
public connection: Connection;
|
|
67
65
|
public anchor: AnchorProvider;
|
|
68
66
|
|
|
@@ -73,6 +71,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
73
71
|
private tokenClient: TokenClient;
|
|
74
72
|
|
|
75
73
|
get solPubKey(): SolPubKey {
|
|
74
|
+
if (!this.pubKey) throw new Error('pubKey is undefined');
|
|
76
75
|
return new SolPubKey(this.pubKey.data.array);
|
|
77
76
|
}
|
|
78
77
|
|
|
@@ -82,13 +81,17 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
82
81
|
|
|
83
82
|
constructor(private config: StakerConfig) {
|
|
84
83
|
const adapter = config.provider as BaseSignerWalletAdapter;
|
|
85
|
-
if (!adapter?.publicKey) throw new Error('Solana wallet adapter not connected');
|
|
84
|
+
// if (!adapter?.publicKey) throw new Error('Solana wallet adapter not connected');
|
|
86
85
|
if (!config.network.rpcUrls.length) throw new Error('No RPC URLs provided');
|
|
87
|
-
|
|
88
|
-
const publicKey = adapter.publicKey
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
|
|
87
|
+
const publicKey = adapter.publicKey || new SolPubKey(new Uint8Array(32))
|
|
88
|
+
if (config.pubKey){
|
|
89
|
+
// If pubKey provided, ensure it matches the adapter's pubkey
|
|
90
|
+
const wirePub = new PublicKey(KeyType.ED, publicKey.toBytes());
|
|
91
|
+
if (!wirePub.equals(config.pubKey))
|
|
92
|
+
throw new Error("Passed-in pubKey doesn't match adapter.publicKey");
|
|
93
|
+
// All good; assign it
|
|
94
|
+
this.pubKey = wirePub;
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
const opts: ConnectionConfig = { commitment };
|
|
@@ -111,7 +114,6 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
111
114
|
},
|
|
112
115
|
};
|
|
113
116
|
|
|
114
|
-
this.pubKey = wirePub;
|
|
115
117
|
this.connection = new Connection(config.network.rpcUrls[0], opts);
|
|
116
118
|
this.anchor = new AnchorProvider(this.connection, anchorWallet, { commitment });
|
|
117
119
|
|
|
@@ -120,7 +122,6 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
120
122
|
this.leaderboardClient = new LeaderboardClient(this.anchor);
|
|
121
123
|
this.outpostClient = new OutpostClient(this.anchor);
|
|
122
124
|
this.tokenClient = new TokenClient(this.anchor);
|
|
123
|
-
this.tokenClient = new TokenClient(this.anchor);
|
|
124
125
|
}
|
|
125
126
|
|
|
126
127
|
// ---------------------------------------------------------------------
|
|
@@ -132,6 +133,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
132
133
|
* Handles tx build, sign, send, and confirmation.
|
|
133
134
|
*/
|
|
134
135
|
async deposit(amountLamports: bigint): Promise<string> {
|
|
136
|
+
this.ensureWriteAccess();
|
|
135
137
|
if (amountLamports <= BigInt(0)) {
|
|
136
138
|
throw new Error('Deposit amount must be greater than zero.');
|
|
137
139
|
}
|
|
@@ -152,6 +154,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
152
154
|
* NOTE: placeholder until a withdraw flow is implemented in DepositClient.
|
|
153
155
|
*/
|
|
154
156
|
async withdraw(_amountLamports: bigint): Promise<string> {
|
|
157
|
+
this.ensureWriteAccess();
|
|
155
158
|
throw new Error('Withdraw method not yet implemented.');
|
|
156
159
|
}
|
|
157
160
|
|
|
@@ -160,6 +163,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
160
163
|
* Ensures user ATA exists, then stakes via outpostClient.
|
|
161
164
|
*/
|
|
162
165
|
async stake(amountLamports: bigint): Promise<string> {
|
|
166
|
+
this.ensureWriteAccess();
|
|
163
167
|
if (amountLamports <= BigInt(0)) {
|
|
164
168
|
throw new Error('Stake amount must be greater than zero.');
|
|
165
169
|
}
|
|
@@ -180,6 +184,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
180
184
|
* Mirrors stake() but calls withdrawStake.
|
|
181
185
|
*/
|
|
182
186
|
async unstake(amountLamports: bigint): Promise<string> {
|
|
187
|
+
this.ensureWriteAccess();
|
|
183
188
|
if (amountLamports <= BigInt(0)) {
|
|
184
189
|
throw new Error('Unstake amount must be greater than zero.');
|
|
185
190
|
}
|
|
@@ -204,56 +209,17 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
204
209
|
*
|
|
205
210
|
* ETH / LIQETH are not valid on Solana.
|
|
206
211
|
*/
|
|
207
|
-
async buy(amountLamports: bigint
|
|
212
|
+
async buy(amountLamports: bigint): Promise<string> {
|
|
213
|
+
this.ensureWriteAccess();
|
|
214
|
+
if (!amountLamports || amountLamports <= BigInt(0))
|
|
215
|
+
throw new Error('liqSOL pretoken purchase requires a positive amount.');
|
|
216
|
+
|
|
208
217
|
const user = this.solPubKey;
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if (!amountLamports || amountLamports <= BigInt(0)) {
|
|
215
|
-
throw new Error('SOL pretoken purchase requires a positive amount.');
|
|
216
|
-
}
|
|
217
|
-
ix = await this.tokenClient.buildPurchaseWithSolIx(
|
|
218
|
-
amountLamports,
|
|
219
|
-
user,
|
|
220
|
-
);
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
case PurchaseAsset.LIQSOL: {
|
|
225
|
-
if (!amountLamports || amountLamports <= BigInt(0)) {
|
|
226
|
-
throw new Error(
|
|
227
|
-
'liqSOL pretoken purchase requires a positive amount.',
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
preIxs = await this.outpostClient.maybeBuildCreateUserAtaIx(user);
|
|
231
|
-
ix = await this.tokenClient.buildPurchaseWithLiqsolIx(
|
|
232
|
-
amountLamports,
|
|
233
|
-
user,
|
|
234
|
-
);
|
|
235
|
-
break;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
case PurchaseAsset.YIELD: {
|
|
239
|
-
// Amount is ignored by the on-chain program; it consumes tracked yield.
|
|
240
|
-
ix = await this.tokenClient.buildPurchaseFromYieldIx(user);
|
|
241
|
-
break;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
case PurchaseAsset.ETH:
|
|
245
|
-
case PurchaseAsset.LIQETH: {
|
|
246
|
-
throw new Error(
|
|
247
|
-
'ETH / LIQETH pretoken purchases are not supported on Solana.',
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
default:
|
|
252
|
-
throw new Error(`Unsupported pretoken purchase asset: ${String(
|
|
253
|
-
purchaseAsset,
|
|
254
|
-
)}`);
|
|
255
|
-
}
|
|
256
|
-
|
|
218
|
+
const preIxs = await this.outpostClient.maybeBuildCreateUserAtaIx(user);
|
|
219
|
+
const ix = await this.tokenClient.buildPurchaseWithLiqsolIx(
|
|
220
|
+
amountLamports,
|
|
221
|
+
user,
|
|
222
|
+
);
|
|
257
223
|
const tx = new Transaction().add(...preIxs, ix);
|
|
258
224
|
const prepared = await this.prepareTx(tx);
|
|
259
225
|
const signed = await this.signTransaction(prepared.tx);
|
|
@@ -270,6 +236,8 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
270
236
|
* - extras: useful internal addresses and raw state for debugging/UX
|
|
271
237
|
*/
|
|
272
238
|
async getPortfolio(): Promise<Portfolio> {
|
|
239
|
+
if (!this.pubKey) throw new Error('User pubKey is undefined');
|
|
240
|
+
|
|
273
241
|
const user = this.solPubKey;
|
|
274
242
|
|
|
275
243
|
const reservePoolPDA = deriveReservePoolPda();
|
|
@@ -369,6 +337,8 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
369
337
|
* windowBefore/windowAfter control how many ladder rows we precompute
|
|
370
338
|
* around the current tranche for UI, but you can pass nothing if you
|
|
371
339
|
* only need current tranche info.
|
|
340
|
+
*
|
|
341
|
+
* READ-ONLY allowed
|
|
372
342
|
*/
|
|
373
343
|
async getTrancheSnapshot(options?: {
|
|
374
344
|
chainID?: ChainID;
|
|
@@ -387,6 +357,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
387
357
|
this.tokenClient.fetchTrancheState(),
|
|
388
358
|
]);
|
|
389
359
|
|
|
360
|
+
|
|
390
361
|
// Latest SOL/USD price (1e8) + timestamp from PriceHistory
|
|
391
362
|
const { price: solPriceUsd, timestamp } =
|
|
392
363
|
await this.tokenClient.getSolPriceUsdSafe();
|
|
@@ -402,95 +373,12 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
402
373
|
});
|
|
403
374
|
}
|
|
404
375
|
|
|
405
|
-
/**
|
|
406
|
-
* Approximate prelaunch WIRE quote for a given amount & asset.
|
|
407
|
-
*
|
|
408
|
-
* Uses TrancheSnapshot + SOL/USD price for:
|
|
409
|
-
* - SOL: amount is lamports
|
|
410
|
-
* - LIQSOL: amount is liqSOL base units (decimals = 9)
|
|
411
|
-
* - YIELD: amount is treated as SOL lamports-equivalent of yield
|
|
412
|
-
*
|
|
413
|
-
* NOTE: On-chain rounding may differ slightly (this is UI-only).
|
|
414
|
-
*/
|
|
415
|
-
async getBuyQuote(
|
|
416
|
-
amount: bigint,
|
|
417
|
-
asset: PurchaseAsset,
|
|
418
|
-
opts?: { chainID?: ChainID },
|
|
419
|
-
): Promise<PurchaseQuote> {
|
|
420
|
-
// For non-YIELD purchases we require a positive amount.
|
|
421
|
-
if (asset !== PurchaseAsset.YIELD && amount <= BigInt(0)) {
|
|
422
|
-
throw new Error('amount must be > 0 for non-YIELD purchases');
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
const snapshot = await this.getTrancheSnapshot({
|
|
426
|
-
chainID: opts?.chainID,
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
const wirePriceUsd = snapshot.currentPriceUsd; // 1e8
|
|
430
|
-
const solPriceUsd = snapshot.nativePriceUsd; // 1e8
|
|
431
|
-
|
|
432
|
-
if (!wirePriceUsd || wirePriceUsd <= BigInt(0)) {
|
|
433
|
-
throw new Error('Invalid WIRE price in tranche snapshot');
|
|
434
|
-
}
|
|
435
|
-
if (!solPriceUsd || solPriceUsd <= BigInt(0)) {
|
|
436
|
-
throw new Error('No SOL/USD price available');
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
const ONE_E9 = BigInt(LAMPORTS_PER_SOL); // 1e9
|
|
440
|
-
const ONE_E8 = BigInt(100_000_000); // 1e8
|
|
441
|
-
|
|
442
|
-
let notionalUsd: bigint;
|
|
443
|
-
|
|
444
|
-
switch (asset) {
|
|
445
|
-
case PurchaseAsset.SOL: {
|
|
446
|
-
// lamports * solPriceUsd / 1e9 → 1e8 USD
|
|
447
|
-
notionalUsd = (amount * solPriceUsd) / ONE_E9;
|
|
448
|
-
break;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
case PurchaseAsset.LIQSOL: {
|
|
452
|
-
// liqSOL also uses 9 decimals; use same conversion.
|
|
453
|
-
notionalUsd = (amount * solPriceUsd) / ONE_E9;
|
|
454
|
-
break;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
case PurchaseAsset.YIELD: {
|
|
458
|
-
// Treat amount as lamports-equivalent of SOL yield (UI convention).
|
|
459
|
-
notionalUsd = (amount * solPriceUsd) / ONE_E9;
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
case PurchaseAsset.ETH:
|
|
464
|
-
case PurchaseAsset.LIQETH:
|
|
465
|
-
throw new Error('getBuyQuote for ETH/LIQETH is not supported on Solana');
|
|
466
|
-
|
|
467
|
-
default:
|
|
468
|
-
throw new Error(`Unsupported purchase asset: ${String(asset)}`);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// WIRE shares (1e8) = (notionalUsd * 1e8) / wirePriceUsd
|
|
472
|
-
// Add a small bias to avoid truncating to 0 on tiny buys.
|
|
473
|
-
const numerator = notionalUsd * ONE_E8;
|
|
474
|
-
const wireShares =
|
|
475
|
-
numerator === BigInt(0)
|
|
476
|
-
? BigInt(0)
|
|
477
|
-
: (numerator + wirePriceUsd - BigInt(1)) / wirePriceUsd;
|
|
478
|
-
|
|
479
|
-
return {
|
|
480
|
-
purchaseAsset: asset,
|
|
481
|
-
amountIn: amount,
|
|
482
|
-
wireShares,
|
|
483
|
-
wireDecimals: 8,
|
|
484
|
-
wirePriceUsd,
|
|
485
|
-
notionalUsd,
|
|
486
|
-
};
|
|
487
|
-
}
|
|
488
|
-
|
|
489
376
|
/**
|
|
490
377
|
* Convenience helper to fetch the distribution userRecord for the current user.
|
|
491
378
|
* Used by balance-correction flows and debugging.
|
|
492
379
|
*/
|
|
493
380
|
async getUserRecord() {
|
|
381
|
+
if (!this.pubKey) throw new Error('User pubKey is undefined');
|
|
494
382
|
return this.distributionClient.getUserRecord(this.solPubKey);
|
|
495
383
|
}
|
|
496
384
|
|
|
@@ -500,6 +388,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
500
388
|
* - signs and sends the transaction if it can succeed
|
|
501
389
|
*/
|
|
502
390
|
async correctBalance(amount?: bigint): Promise<string> {
|
|
391
|
+
this.ensureWriteAccess();
|
|
503
392
|
const build = await this.distributionClient.buildCorrectRegisterTx({ amount });
|
|
504
393
|
if (!build.canSucceed || !build.transaction) {
|
|
505
394
|
throw new Error(build.reason ?? 'Unable to build Correct&Register transaction');
|
|
@@ -528,7 +417,8 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
528
417
|
signed: SolanaTransaction,
|
|
529
418
|
ctx: { blockhash: string; lastValidBlockHeight: number },
|
|
530
419
|
): Promise<string> {
|
|
531
|
-
|
|
420
|
+
this.ensureWriteAccess();
|
|
421
|
+
const signature = await this.connection.sendRawTransaction(
|
|
532
422
|
signed.serialize(),
|
|
533
423
|
{
|
|
534
424
|
skipPreflight: false,
|
|
@@ -557,6 +447,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
557
447
|
* Sign a single Solana transaction using the connected wallet adapter.
|
|
558
448
|
*/
|
|
559
449
|
async signTransaction(tx: SolanaTransaction): Promise<SolanaTransaction> {
|
|
450
|
+
this.ensureWriteAccess();
|
|
560
451
|
return this.anchor.wallet.signTransaction(tx);
|
|
561
452
|
}
|
|
562
453
|
|
|
@@ -565,6 +456,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
565
456
|
* prepared and signed the transaction.
|
|
566
457
|
*/
|
|
567
458
|
async sendTransaction(signed: SolanaTransaction): Promise<TransactionSignature> {
|
|
459
|
+
this.ensureWriteAccess();
|
|
568
460
|
return this.anchor.sendAndConfirm(signed);
|
|
569
461
|
}
|
|
570
462
|
|
|
@@ -581,4 +473,11 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
581
473
|
tx.feePayer = this.solPubKey;
|
|
582
474
|
return { tx, blockhash, lastValidBlockHeight };
|
|
583
475
|
}
|
|
476
|
+
|
|
477
|
+
ensureWriteAccess() {
|
|
478
|
+
if (!this.pubKey || !this.anchor.wallet.publicKey)
|
|
479
|
+
throw new Error('User Authorization required: pubKey is undefined');
|
|
480
|
+
if (this.solPubKey.toBase58() !== this.anchor.wallet.publicKey.toBase58())
|
|
481
|
+
throw new Error('Write access requires connected wallet to match pubKey');
|
|
482
|
+
}
|
|
584
483
|
}
|
|
@@ -110,7 +110,10 @@ export type TrancheState = {
|
|
|
110
110
|
currentTrancheNumber: BN;
|
|
111
111
|
currentTrancheSupply: BN;
|
|
112
112
|
currentTranchePriceUsd: BN;
|
|
113
|
-
|
|
113
|
+
//Currently working on renaming Warrants to Warrants,
|
|
114
|
+
// current version of sol contracts appears to still
|
|
115
|
+
// be using warrants phrasing for this variable
|
|
116
|
+
totalWarrantsSold?: BN;
|
|
114
117
|
initialTrancheSupply: BN;
|
|
115
118
|
supplyGrowthBps: number;
|
|
116
119
|
priceGrowthBps: number;
|
|
@@ -237,15 +237,13 @@ export function buildSolanaTrancheSnapshot(options: {
|
|
|
237
237
|
windowBefore: ladderWindowBefore,
|
|
238
238
|
windowAfter: ladderWindowAfter,
|
|
239
239
|
});
|
|
240
|
-
|
|
240
|
+
|
|
241
241
|
return {
|
|
242
242
|
chainID,
|
|
243
243
|
currentIndex,
|
|
244
244
|
totalShares,
|
|
245
245
|
currentTranche,
|
|
246
246
|
currentPriceUsd,
|
|
247
|
-
minPriceUsd,
|
|
248
|
-
maxPriceUsd,
|
|
249
247
|
supplyGrowthBps,
|
|
250
248
|
priceGrowthBps,
|
|
251
249
|
currentTrancheSupply,
|
package/src/types.ts
CHANGED
|
@@ -6,11 +6,11 @@ import { ethers } from 'ethers';
|
|
|
6
6
|
export type StakerConfig = {
|
|
7
7
|
network: ExternalNetwork;
|
|
8
8
|
provider: BaseSignerWalletAdapter | ethers.providers.Web3Provider;
|
|
9
|
-
pubKey
|
|
9
|
+
pubKey?: PublicKey;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export interface IStakingClient {
|
|
13
|
-
pubKey
|
|
13
|
+
pubKey?: PublicKey;
|
|
14
14
|
network: ExternalNetwork;
|
|
15
15
|
|
|
16
16
|
/** Amount is in the chain's smallest unit (lamports/wei, etc.) */
|
|
@@ -18,7 +18,7 @@ export interface IStakingClient {
|
|
|
18
18
|
withdraw(amount: bigint): Promise<string>;
|
|
19
19
|
stake(amount: bigint): Promise<string>;
|
|
20
20
|
unstake(amount: bigint): Promise<string>;
|
|
21
|
-
buy(amount: bigint
|
|
21
|
+
buy(amount: bigint): Promise<string>;
|
|
22
22
|
|
|
23
23
|
/** Fetch the complete user portfolio */
|
|
24
24
|
getPortfolio(): Promise<Portfolio>;
|
|
@@ -35,9 +35,6 @@ export interface IStakingClient {
|
|
|
35
35
|
windowBefore?: number;
|
|
36
36
|
windowAfter?: number;
|
|
37
37
|
}): Promise<TrancheSnapshot | null>;
|
|
38
|
-
|
|
39
|
-
/** */
|
|
40
|
-
getBuyQuote(amount: bigint, asset: PurchaseAsset): Promise<PurchaseQuote>;
|
|
41
38
|
}
|
|
42
39
|
|
|
43
40
|
export interface Portfolio {
|
|
@@ -47,7 +44,7 @@ export interface Portfolio {
|
|
|
47
44
|
liq: BalanceView;
|
|
48
45
|
/** Outpost Staked balance */
|
|
49
46
|
staked: BalanceView
|
|
50
|
-
/** Prelaunch WIRE “shares” (
|
|
47
|
+
/** Prelaunch WIRE “shares” (pretokens) */
|
|
51
48
|
wire: BalanceView;
|
|
52
49
|
/** SOL ONLY!
|
|
53
50
|
* Tracked liqSOL balance from distribution program */
|
|
@@ -107,11 +104,9 @@ export interface TrancheSnapshot {
|
|
|
107
104
|
|
|
108
105
|
/** Current tranche price in USD (1e8 scale) */
|
|
109
106
|
currentPriceUsd: bigint;
|
|
110
|
-
/** Optional min/max bounds for price validation (1e8 scale) */
|
|
111
|
-
minPriceUsd?: bigint;
|
|
112
|
-
maxPriceUsd?: bigint;
|
|
113
107
|
|
|
114
108
|
/** Tranche curve config (per-chain) */
|
|
109
|
+
// TODO make a constant?
|
|
115
110
|
supplyGrowthBps: number; // e.g. 100 = +1% per tranche
|
|
116
111
|
priceGrowthBps: number; // e.g. 200 = +2% per tranche
|
|
117
112
|
|
|
@@ -130,27 +125,4 @@ export interface TrancheSnapshot {
|
|
|
130
125
|
* Used directly by the frontend for ladder graphs.
|
|
131
126
|
*/
|
|
132
127
|
ladder: TrancheLadderItem[];
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// Enum describing which asset is being used to buy pretoken
|
|
137
|
-
export enum PurchaseAsset {
|
|
138
|
-
SOL = 'SOL',
|
|
139
|
-
LIQSOL = 'LIQSOL',
|
|
140
|
-
ETH = 'ETH',
|
|
141
|
-
LIQETH = 'LIQETH',
|
|
142
|
-
YIELD = 'YIELD',
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface PurchaseQuote {
|
|
146
|
-
purchaseAsset: PurchaseAsset;
|
|
147
|
-
amountIn: bigint; // lamports / wei / token units
|
|
148
|
-
|
|
149
|
-
/** Expected pretoken “shares” (pretokens) and decimals */
|
|
150
|
-
wireShares: bigint; // 1e8 scale
|
|
151
|
-
wireDecimals: number; // always 8 for now
|
|
152
|
-
|
|
153
|
-
/** Current price + notional in USD (1e8 scale) */
|
|
154
|
-
wirePriceUsd: bigint;
|
|
155
|
-
notionalUsd: bigint;
|
|
156
128
|
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_format": "hh-sol-artifact-1",
|
|
3
|
-
"contractName": "BeaconRoots",
|
|
4
|
-
"sourceName": "contracts/liqEth/Yield.sol",
|
|
5
|
-
"abi": [],
|
|
6
|
-
"bytecode": "0x60808060405234601757603a9081601d823930815050f35b600080fdfe600080fdfea264697066735822122031a0f5398756e42b92bee3bd69db499a6ba974a3821f736e80fb78b4b59bd4ad64736f6c63430008190033",
|
|
7
|
-
"deployedBytecode": "0x600080fdfea264697066735822122031a0f5398756e42b92bee3bd69db499a6ba974a3821f736e80fb78b4b59bd4ad64736f6c63430008190033",
|
|
8
|
-
"linkReferences": {},
|
|
9
|
-
"deployedLinkReferences": {}
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_format": "hh-sol-artifact-1",
|
|
3
|
-
"contractName": "SSZ",
|
|
4
|
-
"sourceName": "contracts/liqEth/Yield.sol",
|
|
5
|
-
"abi": [],
|
|
6
|
-
"bytecode": "0x60808060405234601757603a9081601d823930815050f35b600080fdfe600080fdfea2646970667358221220cb02051f443c7190a2fcd835a3bfa144af2732be9952e46973e867f22c854c8664736f6c63430008190033",
|
|
7
|
-
"deployedBytecode": "0x600080fdfea2646970667358221220cb02051f443c7190a2fcd835a3bfa144af2732be9952e46973e867f22c854c8664736f6c63430008190033",
|
|
8
|
-
"linkReferences": {},
|
|
9
|
-
"deployedLinkReferences": {}
|
|
10
|
-
}
|