@wireio/stake 0.2.5 → 0.3.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 +2461 -2074
- package/lib/stake.browser.js.map +1 -1
- package/lib/stake.d.ts +29 -55
- package/lib/stake.js +2615 -2211
- package/lib/stake.js.map +1 -1
- package/lib/stake.m.js +2461 -2074
- 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 +3 -9
- package/src/networks/solana/clients/token.client.ts +0 -1
- package/src/networks/solana/solana.ts +44 -146
- package/src/networks/solana/types.ts +6 -2
- package/src/networks/solana/utils.ts +4 -6
- package/src/types.ts +6 -34
- 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();
|
|
@@ -313,7 +281,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
313
281
|
wireReceipt?.stakedLiqsol?.toString() ?? '0';
|
|
314
282
|
|
|
315
283
|
const wireSharesStr =
|
|
316
|
-
userWarrantRecord?.
|
|
284
|
+
userWarrantRecord?.totalPretokensPurchased?.toString() ?? '0';
|
|
317
285
|
|
|
318
286
|
return {
|
|
319
287
|
native: {
|
|
@@ -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;
|
|
@@ -402,95 +372,12 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
402
372
|
});
|
|
403
373
|
}
|
|
404
374
|
|
|
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
375
|
/**
|
|
490
376
|
* Convenience helper to fetch the distribution userRecord for the current user.
|
|
491
377
|
* Used by balance-correction flows and debugging.
|
|
492
378
|
*/
|
|
493
379
|
async getUserRecord() {
|
|
380
|
+
if (!this.pubKey) throw new Error('User pubKey is undefined');
|
|
494
381
|
return this.distributionClient.getUserRecord(this.solPubKey);
|
|
495
382
|
}
|
|
496
383
|
|
|
@@ -500,6 +387,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
500
387
|
* - signs and sends the transaction if it can succeed
|
|
501
388
|
*/
|
|
502
389
|
async correctBalance(amount?: bigint): Promise<string> {
|
|
390
|
+
this.ensureWriteAccess();
|
|
503
391
|
const build = await this.distributionClient.buildCorrectRegisterTx({ amount });
|
|
504
392
|
if (!build.canSucceed || !build.transaction) {
|
|
505
393
|
throw new Error(build.reason ?? 'Unable to build Correct&Register transaction');
|
|
@@ -528,7 +416,8 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
528
416
|
signed: SolanaTransaction,
|
|
529
417
|
ctx: { blockhash: string; lastValidBlockHeight: number },
|
|
530
418
|
): Promise<string> {
|
|
531
|
-
|
|
419
|
+
this.ensureWriteAccess();
|
|
420
|
+
const signature = await this.connection.sendRawTransaction(
|
|
532
421
|
signed.serialize(),
|
|
533
422
|
{
|
|
534
423
|
skipPreflight: false,
|
|
@@ -557,6 +446,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
557
446
|
* Sign a single Solana transaction using the connected wallet adapter.
|
|
558
447
|
*/
|
|
559
448
|
async signTransaction(tx: SolanaTransaction): Promise<SolanaTransaction> {
|
|
449
|
+
this.ensureWriteAccess();
|
|
560
450
|
return this.anchor.wallet.signTransaction(tx);
|
|
561
451
|
}
|
|
562
452
|
|
|
@@ -565,6 +455,7 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
565
455
|
* prepared and signed the transaction.
|
|
566
456
|
*/
|
|
567
457
|
async sendTransaction(signed: SolanaTransaction): Promise<TransactionSignature> {
|
|
458
|
+
this.ensureWriteAccess();
|
|
568
459
|
return this.anchor.sendAndConfirm(signed);
|
|
569
460
|
}
|
|
570
461
|
|
|
@@ -581,4 +472,11 @@ export class SolanaStakingClient implements IStakingClient {
|
|
|
581
472
|
tx.feePayer = this.solPubKey;
|
|
582
473
|
return { tx, blockhash, lastValidBlockHeight };
|
|
583
474
|
}
|
|
475
|
+
|
|
476
|
+
ensureWriteAccess() {
|
|
477
|
+
if (!this.pubKey || !this.anchor.wallet.publicKey)
|
|
478
|
+
throw new Error('User Authorization required: pubKey is undefined');
|
|
479
|
+
if (this.solPubKey.toBase58() !== this.anchor.wallet.publicKey.toBase58())
|
|
480
|
+
throw new Error('Write access requires connected wallet to match pubKey');
|
|
481
|
+
}
|
|
584
482
|
}
|
|
@@ -99,7 +99,7 @@ export type GlobalState = {
|
|
|
99
99
|
export type UserWarrantRecord = {
|
|
100
100
|
user: PublicKey;
|
|
101
101
|
totalSolDeposited: BN;
|
|
102
|
-
|
|
102
|
+
totalPretokensPurchased: BN;
|
|
103
103
|
lastTrancheNumber: BN;
|
|
104
104
|
lastTranchePriceUsd: BN;
|
|
105
105
|
bump: number;
|
|
@@ -110,7 +110,11 @@ export type TrancheState = {
|
|
|
110
110
|
currentTrancheNumber: BN;
|
|
111
111
|
currentTrancheSupply: BN;
|
|
112
112
|
currentTranchePriceUsd: BN;
|
|
113
|
-
|
|
113
|
+
//Currently working on renaming Warrants to Pretokens,
|
|
114
|
+
// current version of sol contracts appears to still
|
|
115
|
+
// be using warrants phrasing for this variable
|
|
116
|
+
totalPretokensSold?: BN;
|
|
117
|
+
totalWarrantsSold?: BN;
|
|
114
118
|
initialTrancheSupply: BN;
|
|
115
119
|
supplyGrowthBps: number;
|
|
116
120
|
priceGrowthBps: number;
|
|
@@ -116,7 +116,7 @@ export function buildSolanaTrancheLadder(options: {
|
|
|
116
116
|
currentTranche: number;
|
|
117
117
|
initialTrancheSupply: bigint;
|
|
118
118
|
currentTrancheSupply: bigint;
|
|
119
|
-
|
|
119
|
+
totalPretokensSold: bigint; // informational only
|
|
120
120
|
currentPriceUsd: bigint;
|
|
121
121
|
supplyGrowthBps: number;
|
|
122
122
|
priceGrowthBps: number;
|
|
@@ -213,7 +213,7 @@ export function buildSolanaTrancheSnapshot(options: {
|
|
|
213
213
|
const currentTranche = trancheState.currentTrancheNumber.toNumber();
|
|
214
214
|
const currentTrancheSupply = toBigint(trancheState.currentTrancheSupply);
|
|
215
215
|
const initialTrancheSupply = toBigint(trancheState.initialTrancheSupply);
|
|
216
|
-
const
|
|
216
|
+
const totalPretokensSold = toBigint(trancheState.totalPretokensSold);
|
|
217
217
|
const currentPriceUsd = toBigint(trancheState.currentTranchePriceUsd);
|
|
218
218
|
|
|
219
219
|
const supplyGrowthBps = trancheState.supplyGrowthBps;
|
|
@@ -230,7 +230,7 @@ export function buildSolanaTrancheSnapshot(options: {
|
|
|
230
230
|
currentTranche,
|
|
231
231
|
initialTrancheSupply,
|
|
232
232
|
currentTrancheSupply,
|
|
233
|
-
|
|
233
|
+
totalPretokensSold,
|
|
234
234
|
currentPriceUsd,
|
|
235
235
|
supplyGrowthBps,
|
|
236
236
|
priceGrowthBps,
|
|
@@ -244,13 +244,11 @@ export function buildSolanaTrancheSnapshot(options: {
|
|
|
244
244
|
totalShares,
|
|
245
245
|
currentTranche,
|
|
246
246
|
currentPriceUsd,
|
|
247
|
-
minPriceUsd,
|
|
248
|
-
maxPriceUsd,
|
|
249
247
|
supplyGrowthBps,
|
|
250
248
|
priceGrowthBps,
|
|
251
249
|
currentTrancheSupply,
|
|
252
250
|
initialTrancheSupply,
|
|
253
|
-
|
|
251
|
+
totalPretokensSold,
|
|
254
252
|
nativePriceUsd: solPriceUsd,
|
|
255
253
|
nativePriceTimestamp,
|
|
256
254
|
ladder,
|
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,18 +104,16 @@ 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
|
|
|
118
113
|
/** Current tranche supply state (1e8 scale) */
|
|
119
114
|
currentTrancheSupply: bigint; // remaining in current tranche
|
|
120
115
|
initialTrancheSupply: bigint; // capacity for current tranche
|
|
121
|
-
|
|
116
|
+
totalPretokensSold: bigint; // global cumulative sold (all tranches), 1e8
|
|
122
117
|
|
|
123
118
|
/** Native token → USD price if available (SOL/USD, ETH/USD, etc, 1e8 scale) */
|
|
124
119
|
nativePriceUsd?: bigint;
|
|
@@ -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
|
-
}
|