@wireio/stake 0.0.6 → 0.1.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.
Files changed (48) hide show
  1. package/README.md +260 -13
  2. package/lib/stake.browser.js +4861 -4218
  3. package/lib/stake.browser.js.map +1 -1
  4. package/lib/stake.d.ts +434 -6484
  5. package/lib/stake.js +5059 -4371
  6. package/lib/stake.js.map +1 -1
  7. package/lib/stake.m.js +4861 -4218
  8. package/lib/stake.m.js.map +1 -1
  9. package/package.json +2 -2
  10. package/src/assets/solana/idl/liqsol_core.json +4239 -0
  11. package/src/assets/solana/idl/liqsol_token.json +183 -0
  12. package/src/assets/solana/idl/validator_leaderboard.json +296 -250
  13. package/src/assets/solana/types/liqsol_core.ts +4245 -0
  14. package/src/assets/solana/types/liqsol_token.ts +189 -0
  15. package/src/assets/solana/types/validator_leaderboard.ts +296 -250
  16. package/src/index.ts +2 -5
  17. package/src/networks/ethereum/contract.ts +138 -36
  18. package/src/networks/ethereum/ethereum.ts +167 -38
  19. package/src/networks/ethereum/types.ts +32 -1
  20. package/src/networks/solana/clients/deposit.client.ts +92 -139
  21. package/src/networks/solana/clients/distribution.client.ts +302 -178
  22. package/src/networks/solana/clients/leaderboard.client.ts +40 -160
  23. package/src/networks/solana/constants.ts +238 -69
  24. package/src/networks/solana/program.ts +27 -93
  25. package/src/networks/solana/solana.ts +181 -36
  26. package/src/networks/solana/types.ts +47 -0
  27. package/src/networks/solana/utils.ts +522 -93
  28. package/src/scripts/fetch-artifacts.sh +24 -0
  29. package/src/scripts/tsconfig.json +17 -0
  30. package/src/staker/staker.ts +35 -30
  31. package/src/staker/types.ts +25 -22
  32. package/src/assets/solana/idl/deposit.json +0 -260
  33. package/src/assets/solana/idl/distribution.json +0 -736
  34. package/src/assets/solana/idl/liq_sol_token.json +0 -275
  35. package/src/assets/solana/idl/stake_controller.json +0 -1788
  36. package/src/assets/solana/idl/stake_registry.json +0 -435
  37. package/src/assets/solana/idl/treasury.json +0 -336
  38. package/src/assets/solana/idl/validator_registry.json +0 -418
  39. package/src/assets/solana/idl/yield_oracle.json +0 -32
  40. package/src/assets/solana/types/deposit.ts +0 -266
  41. package/src/assets/solana/types/distribution.ts +0 -742
  42. package/src/assets/solana/types/liq_sol_token.ts +0 -281
  43. package/src/assets/solana/types/stake_controller.ts +0 -1794
  44. package/src/assets/solana/types/stake_registry.ts +0 -441
  45. package/src/assets/solana/types/treasury.ts +0 -342
  46. package/src/assets/solana/types/validator_registry.ts +0 -424
  47. package/src/assets/solana/types/yield_oracle.ts +0 -38
  48. package/src/utils.ts +0 -9
@@ -1,179 +1,59 @@
1
- // src/solana/clients/ValidatorLeaderboardClient.ts
2
- import { AnchorProvider, Program, BN } from '@coral-xyz/anchor';
3
- import { PublicKey, Transaction, TransactionInstruction, SystemProgram, VersionedTransaction } from '@solana/web3.js';
4
- import {
5
- deriveLeaderboardHeadPDA,
6
- deriveValidatorRecordPDA,
7
- deriveTop10CachePDA,
8
- } from '../utils';
9
- import { VALIDATOR_LEADERBOARD_PROGRAM_ID, ValidatorLeaderboard, ValidatorLeaderboardIDL } from '../constants';
10
-
11
- export class ValidatorLeaderboardClient {
12
- constructor(private provider: AnchorProvider) { }
13
-
14
- /**
15
- * Wrapped Anchor Program for ValidatorLeaderboard
16
- */
17
- private get program(): Program<ValidatorLeaderboard> {
18
- const idlWithAddress = {
19
- ...JSON.parse(JSON.stringify(ValidatorLeaderboardIDL)),
20
- address: VALIDATOR_LEADERBOARD_PROGRAM_ID.toString(),
21
- };
22
- return new Program(idlWithAddress as any, this.provider) as Program<ValidatorLeaderboard>;
23
- }
24
-
25
- /** Derive the PDA for the leaderboard head */
26
- deriveHeadPDA(): PublicKey {
27
- return deriveLeaderboardHeadPDA()[0];
28
- }
29
-
30
- /** Derive the PDA for a given validator record */
31
- deriveRecordPDA(voteAccount: PublicKey): PublicKey {
32
- return deriveValidatorRecordPDA(voteAccount)[0];
33
- }
34
-
35
- /**
36
- * Build the initialize instruction as a Transaction
37
- */
38
- async buildInitializeTransaction(authority: PublicKey): Promise<Transaction> {
39
- const [headPda] = deriveLeaderboardHeadPDA();
40
- const ix = await this.program.methods
41
- .initialize()
42
- .accounts({
43
- authority,
44
- leaderboardHead: headPda,
45
- systemProgram: SystemProgram.programId,
46
- } as any)
47
- .instruction();
48
-
49
- return new Transaction().add(ix);
50
- }
51
-
52
- /**
53
- * Build an updateValidator transaction
54
- */
55
- async buildUpdateValidatorTransaction(params: {
56
- authority: PublicKey;
57
- registrant: PublicKey;
58
- voteAccount: PublicKey;
59
- vpp: number;
60
- insertAfter?: PublicKey;
61
- insertBefore?: PublicKey;
62
- currentPrev?: PublicKey;
63
- currentNext?: PublicKey;
64
- }): Promise<Transaction> {
65
- const { authority, registrant, voteAccount, vpp, insertAfter, insertBefore, currentPrev, currentNext } = params;
66
- const [headPda] = deriveLeaderboardHeadPDA();
67
- const [recPda] = deriveValidatorRecordPDA(voteAccount);
68
-
69
- const accounts: any = {
70
- registrant,
71
- voteAccount,
72
- validatorRecord: recPda,
73
- leaderboardHead: headPda,
74
- systemProgram: SystemProgram.programId,
75
- ...(insertAfter && { insertAfter }),
76
- ...(insertBefore && { insertBefore }),
77
- ...(currentPrev && { currentPrev }),
78
- ...(currentNext && { currentNext }),
79
- };
80
-
81
- const ix = await this.program.methods
82
- .updateValidator(new BN(vpp))
83
- .accounts(accounts)
84
- .instruction();
1
+ import { AnchorProvider, Program } from '@coral-xyz/anchor';
2
+ import { PublicKey } from '@solana/web3.js';
85
3
 
86
- return new Transaction().add(ix);
87
- }
88
-
89
- /**
90
- * Build an updateTop10Cache transaction
91
- */
92
- async buildUpdateTop10CacheTransaction(params: {
93
- authority: PublicKey;
94
- top10Validators: PublicKey[];
95
- }): Promise<Transaction> {
96
- const { authority, top10Validators } = params;
97
- if (top10Validators.length !== 10) {
98
- throw new Error('Must supply exactly 10 validators');
99
- }
100
- const [cachePda] = deriveTop10CachePDA();
101
- const ix = await this.program.methods
102
- .updateTop10Cache(top10Validators)
103
- .accounts({ authority, cache: cachePda, systemProgram: SystemProgram.programId } as any)
104
- .instruction();
4
+ import { SolanaProgramService } from '../program';
5
+ import type { ValidatorLeaderboard } from '../../../assets/solana/types/validator_leaderboard';
6
+ import {
7
+ deriveLeaderboardStatePda,
8
+ deriveValidatorRecordPda,
9
+ } from '../constants';
105
10
 
106
- return new Transaction().add(ix);
107
- }
11
+ /**
12
+ * Simple read client for the validator_leaderboard program.
13
+ *
14
+ * Adjust account names/fields to match your IDL (state, validatorRecord, etc).
15
+ */
16
+ export class LeaderboardClient {
17
+ private program: Program<ValidatorLeaderboard>;
108
18
 
109
- /**
110
- * Fetch the cached top 10 validators via a view call
111
- */
112
- async getCachedTop10(): Promise<PublicKey[]> {
113
- const [cachePda] = deriveTop10CachePDA();
114
- return this.program.methods
115
- .getCachedTop10()
116
- .accounts({ cache: cachePda } as any)
117
- .view();
19
+ constructor(private provider: AnchorProvider) {
20
+ const svc = new SolanaProgramService(provider);
21
+ this.program = svc.getProgram('validatorLeaderboard');
118
22
  }
119
23
 
120
- /**
121
- * Traverse the on-chain linked list and return the sequence of PublicKeys
122
- */
123
- async getLeaderboard(): Promise<PublicKey[]> {
124
- const [headPda] = deriveLeaderboardHeadPDA();
125
- let headAccount;
24
+ async getState(): Promise<any | null> {
25
+ const pda = deriveLeaderboardStatePda();
126
26
  try {
127
- headAccount = await this.program.account.leaderboardHead.fetch(headPda);
27
+ // Assumes account name "leaderboardState"
28
+ return await this.program.account.leaderboardState.fetch(pda);
128
29
  } catch {
129
- return [];
130
- }
131
- const result: PublicKey[] = [];
132
- let cursor: PublicKey = headAccount.nextValidator;
133
- while (cursor && !cursor.equals(PublicKey.default)) {
134
- result.push(cursor);
135
- const rec = await this.program.account.validatorRecord.fetch(cursor);
136
- cursor = rec.nextValidator;
30
+ return null;
137
31
  }
138
- return result;
139
32
  }
140
33
 
141
- /**
142
- * Fetch a single validator record or null
143
- */
144
- async getRecord(voteAccount: PublicKey): Promise<any | null> {
145
- const [recPda] = deriveValidatorRecordPDA(voteAccount);
34
+ async getValidatorRecord(voteAccount: PublicKey): Promise<any | null> {
35
+ const pda = deriveValidatorRecordPda(voteAccount);
146
36
  try {
147
- return await this.program.account.validatorRecord.fetch(recPda);
37
+ // Assumes account name "validatorRecord"
38
+ return await this.program.account.validatorRecord.fetchNullable(pda);
148
39
  } catch {
149
40
  return null;
150
41
  }
151
42
  }
152
43
 
153
44
  /**
154
- * Send & confirm a single-IX Transaction; returns the signature
155
- */
156
- async sendTransaction(
157
- tx: Transaction,
158
- signers: import('@solana/web3.js').Signer[] = []
159
- ): Promise<string> {
160
- tx.feePayer = this.provider.wallet.publicKey;
161
- const { blockhash } = await this.provider.connection.getLatestBlockhash();
162
- tx.recentBlockhash = blockhash;
163
- return this.provider.sendAndConfirm(tx, signers);
164
- }
165
-
166
- /**
167
- * Simulate a single-IX Transaction; returns any err + compute units consumed
45
+ * Convenience helper to fetch and sort top validators by score.
46
+ * Assumes `validatorRecord` has a numeric `score` field in the IDL.
168
47
  */
169
- async simulateTransaction(
170
- tx: Transaction
171
- ): Promise<{ err: any; unitsConsumed: number }> {
172
- tx.feePayer = this.provider.wallet.publicKey;
173
- const { blockhash } = await this.provider.connection.getLatestBlockhash();
174
- tx.recentBlockhash = blockhash;
175
- const versioned = new VersionedTransaction(tx.compileMessage());
176
- const sim = await this.provider.connection.simulateTransaction(versioned, { sigVerify: false });
177
- return { err: sim.value.err, unitsConsumed: sim.value.unitsConsumed! };
48
+ async getTopValidators(limit = 20): Promise<any[]> {
49
+ const records = await (this.program.account as any).validatorRecord.all();
50
+ const sorted = (records as Array<{ publicKey: PublicKey; account: any }>).sort(
51
+ (a, b) => {
52
+ const sa = BigInt(a.account.score?.toString?.() ?? '0');
53
+ const sb = BigInt(b.account.score?.toString?.() ?? '0');
54
+ return sb > sa ? 1 : sb < sa ? -1 : 0;
55
+ },
56
+ );
57
+ return sorted.slice(0, limit);
178
58
  }
179
- }
59
+ }
@@ -1,73 +1,242 @@
1
1
  // src/networks/solana/constants.ts
2
+ import { PublicKey, StakeProgram } from '@solana/web3.js';
2
3
 
3
- import { PublicKey } from '@solana/web3.js';
4
- import { TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID } from '@solana/spl-token';
5
-
6
- // — IDLs — (must match your filesystem: src/assets/solana/idl/*.json)
7
- import DepositIDL from '../../assets/solana/idl/deposit.json';
8
- import DistributionIDL from '../../assets/solana/idl/distribution.json';
9
- import LiqSolTokenIDL from '../../assets/solana/idl/liq_sol_token.json';
10
- import StakeControllerIDL from '../../assets/solana/idl/stake_controller.json';
11
- import StakeRegistryIDL from '../../assets/solana/idl/stake_registry.json';
12
- import TreasuryIDL from '../../assets/solana/idl/treasury.json';
13
- import ValidatorLeaderboardIDL from '../../assets/solana/idl/validator_leaderboard.json';
14
- import ValidatorRegistryIDL from '../../assets/solana/idl/validator_registry.json';
15
- import YieldOracleIDL from '../../assets/solana/idl/yield_oracle.json';
16
-
17
- // Types for your clients
18
- import type { Deposit } from '../../assets/solana/types/deposit';
19
- import type { Distribution } from '../../assets/solana/types/distribution';
20
- import type { ValidatorLeaderboard } from '../../assets/solana/types/validator_leaderboard';
21
- import type { LiqSolToken } from '../../assets/solana/types/liq_sol_token';
22
- import type { StakeController } from '../../assets/solana/types/stake_controller';
23
- import type { StakeRegistry } from '../../assets/solana/types/stake_registry';
24
- import type { Treasury } from '../../assets/solana/types/treasury';
25
- import type { ValidatorRegistry } from '../../assets/solana/types/validator_registry';
26
- import type { YieldOracle } from '../../assets/solana/types/yield_oracle';
27
-
28
- // Re-export for easy import elsewhere:
29
- export {
30
- Deposit,
31
- DepositIDL,
32
- Distribution,
33
- DistributionIDL,
34
- LiqSolToken,
35
- LiqSolTokenIDL,
36
- StakeController,
37
- StakeControllerIDL,
38
- StakeRegistry,
39
- StakeRegistryIDL,
40
- Treasury,
41
- TreasuryIDL,
42
- ValidatorLeaderboard,
43
- ValidatorLeaderboardIDL,
44
- ValidatorRegistry,
45
- ValidatorRegistryIDL,
46
- YieldOracle,
47
- YieldOracleIDL,
4
+ import liqsolCoreIDL from "../../assets/solana/idl/liqsol_core.json";
5
+ import liqSolTokenIDL from "../../assets/solana/idl/liqsol_token.json";
6
+ import validatorLeaderboardIDL from "../../assets/solana/idl/validator_leaderboard.json";
7
+
8
+ /**
9
+ * ---------------------------------------------------------------------------
10
+ * PROGRAM IDS
11
+ * ---------------------------------------------------------------------------
12
+ *
13
+ * These should match:
14
+ * - `metadata.address` in your Anchor IDLs under src/assets/solana/idl/*.json
15
+ * - The program IDs printed by your deploy scripts
16
+ */
17
+ // Extract program IDs from IDL files
18
+ export const PROGRAM_IDS = {
19
+ LIQSOL_CORE: new PublicKey(liqsolCoreIDL.address),
20
+ LIQSOL_TOKEN: new PublicKey(liqSolTokenIDL.address),
21
+ VALIDATOR_LEADERBOARD: new PublicKey(validatorLeaderboardIDL.address),
22
+ } as const;
23
+
24
+ // Export individual program IDs for convenience
25
+ export const {
26
+ LIQSOL_CORE,
27
+ LIQSOL_TOKEN,
28
+ VALIDATOR_LEADERBOARD,
29
+ } = PROGRAM_IDS;
30
+
31
+ /**
32
+ * ---------------------------------------------------------------------------
33
+ * PDA SEEDS (must match on-chain programs)
34
+ * ---------------------------------------------------------------------------
35
+ *
36
+ * These strings are baked into the on-chain programs and are already used in
37
+ * your test utils. We centralize them here so all clients share them.
38
+ */
39
+
40
+ export const PDA_SEEDS = {
41
+ // liqsol_core: deposit / stake controller
42
+ DEPOSIT_AUTHORITY: 'deposit_authority',
43
+ VAULT: 'vault',
44
+ RESERVE_POOL: 'reserve_pool',
45
+ STAKE_CONTROLLER_STATE: 'stake_controller',
46
+ PAYOUT_STATE: 'payout-state',
47
+
48
+ // liqsol_token: mint + bucket
49
+ LIQSOL_MINT: 'liqsol_mint',
50
+ LIQSOL_MINT_AUTHORITY: 'mint_authority',
51
+ BUCKET_AUTHORITY: 'liqsol_bucket',
52
+
53
+ // distribution program (embedded in liqsol_core)
54
+ DISTRIBUTION_STATE: 'distribution_state',
55
+ USER_RECORD: 'user_record',
56
+
57
+ // pay-rate history
58
+ PAY_RATE_HISTORY: 'pay_rate_history',
59
+
60
+ // validator leaderboard (state + records)
61
+ LEADERBOARD_STATE: 'leaderboard_state',
62
+ VALIDATOR_RECORD: 'validator',
63
+ GLOBAL_STAKE_INFO: 'global_stake_info',
64
+ } as const;
65
+
66
+ /**
67
+ * Helpers for PDA derivation so clients don’t duplicate logic.
68
+ */
69
+
70
+ export const deriveLiqsolMintPda = () =>
71
+ PublicKey.findProgramAddressSync(
72
+ [Buffer.from(PDA_SEEDS.LIQSOL_MINT)],
73
+ PROGRAM_IDS.LIQSOL_TOKEN,
74
+ )[0];
75
+
76
+ export const deriveLiqsolMintAuthorityPda = () =>
77
+ PublicKey.findProgramAddressSync(
78
+ [Buffer.from(PDA_SEEDS.LIQSOL_MINT_AUTHORITY)],
79
+ PROGRAM_IDS.LIQSOL_TOKEN,
80
+ )[0];
81
+
82
+ export const deriveDepositAuthorityPda = () =>
83
+ PublicKey.findProgramAddressSync(
84
+ [Buffer.from(PDA_SEEDS.DEPOSIT_AUTHORITY)],
85
+ PROGRAM_IDS.LIQSOL_CORE,
86
+ )[0];
87
+
88
+ export const deriveVaultPda = () =>
89
+ PublicKey.findProgramAddressSync(
90
+ [Buffer.from(PDA_SEEDS.VAULT)],
91
+ PROGRAM_IDS.LIQSOL_CORE,
92
+ )[0];
93
+
94
+ export const deriveReservePoolPda = () =>
95
+ PublicKey.findProgramAddressSync(
96
+ [Buffer.from(PDA_SEEDS.RESERVE_POOL)],
97
+ PROGRAM_IDS.LIQSOL_CORE,
98
+ )[0];
99
+
100
+ export const deriveStakeControllerStatePda = () =>
101
+ PublicKey.findProgramAddressSync(
102
+ [Buffer.from(PDA_SEEDS.STAKE_CONTROLLER_STATE)],
103
+ PROGRAM_IDS.LIQSOL_CORE,
104
+ )[0];
105
+
106
+ export const derivePayoutStatePda = () =>
107
+ PublicKey.findProgramAddressSync(
108
+ [Buffer.from(PDA_SEEDS.PAYOUT_STATE)],
109
+ PROGRAM_IDS.LIQSOL_CORE,
110
+ )[0];
111
+
112
+ export const deriveBucketAuthorityPda = () =>
113
+ PublicKey.findProgramAddressSync(
114
+ [Buffer.from(PDA_SEEDS.BUCKET_AUTHORITY)],
115
+ PROGRAM_IDS.LIQSOL_CORE,
116
+ )[0];
117
+
118
+ export const deriveDistributionStatePda = () =>
119
+ PublicKey.findProgramAddressSync(
120
+ [Buffer.from(PDA_SEEDS.DISTRIBUTION_STATE)],
121
+ PROGRAM_IDS.LIQSOL_CORE,
122
+ )[0];
123
+
124
+ export const deriveUserRecordPda = (user: PublicKey) =>
125
+ PublicKey.findProgramAddressSync(
126
+ [Buffer.from(PDA_SEEDS.USER_RECORD), user.toBuffer()],
127
+ PROGRAM_IDS.LIQSOL_CORE,
128
+ )[0];
129
+
130
+ export const derivePayRateHistoryPda = () =>
131
+ PublicKey.findProgramAddressSync(
132
+ [Buffer.from(PDA_SEEDS.PAY_RATE_HISTORY)],
133
+ PROGRAM_IDS.LIQSOL_CORE,
134
+ )[0];
135
+
136
+ // export const deriveGlobalStakeInfoPda = () =>
137
+ // PublicKey.findProgramAddressSync(
138
+ // [Buffer.from(PDA_SEEDS.GLOBAL_STAKE_INFO)],
139
+ // PROGRAM_IDS.LIQSOL_CORE,
140
+ // )[0];
141
+
142
+ export const deriveLeaderboardStatePda = () =>
143
+ PublicKey.findProgramAddressSync(
144
+ [Buffer.from(PDA_SEEDS.LEADERBOARD_STATE)],
145
+ PROGRAM_IDS.VALIDATOR_LEADERBOARD,
146
+ )[0];
147
+
148
+ export const deriveValidatorRecordPda = (voteAccount: PublicKey) =>
149
+ PublicKey.findProgramAddressSync(
150
+ [Buffer.from(PDA_SEEDS.VALIDATOR_RECORD), voteAccount.toBuffer()],
151
+ PROGRAM_IDS.VALIDATOR_LEADERBOARD,
152
+ )[0];
153
+
154
+ /**
155
+ * Stake controller vault PDA (reserve pool SOL vault).
156
+ * This is the same as VAULT, but named more explicitly for SDK callers.
157
+ */
158
+ export const deriveStakeControllerVaultPda = () =>
159
+ PublicKey.findProgramAddressSync(
160
+ [Buffer.from(PDA_SEEDS.VAULT)],
161
+ PROGRAM_IDS.LIQSOL_CORE,
162
+ )[0];
163
+
164
+ /**
165
+ * Ephemeral stake account address used per-deposit.
166
+ * On-chain convention: seed = `ephemeral_<u32>` under StakeProgram.programId.
167
+ */
168
+ export const deriveEphemeralStakeAddress = async (
169
+ user: PublicKey,
170
+ seed: any,
171
+ ): Promise<PublicKey> => {
172
+ const seedStr = `ephemeral_${seed}`;
173
+ return await PublicKey.createWithSeed(user, seedStr, StakeProgram.programId);
48
174
  };
49
175
 
50
- // — Program IDs — anchor “address” fields inside each IDL must match these:
51
- export const DEPOSIT_PROGRAM_ID = new PublicKey(DepositIDL.address);
52
- export const DISTRIBUTION_PROGRAM_ID = new PublicKey(DistributionIDL.address);
53
- export const LIQSOL_TOKEN_PROGRAM_ID = new PublicKey(LiqSolTokenIDL.address);
54
- export const STAKE_CONTROLLER_PROGRAM_ID = new PublicKey(StakeControllerIDL.address);
55
- export const STAKE_REGISTRY_PROGRAM_ID = new PublicKey(StakeRegistryIDL.address);
56
- export const TREASURY_PROGRAM_ID = new PublicKey(TreasuryIDL.address);
57
- export const VALIDATOR_LEADERBOARD_PROGRAM_ID = new PublicKey(ValidatorLeaderboardIDL.address);
58
- export const VALIDATOR_REGISTRY_PROGRAM_ID = new PublicKey(ValidatorRegistryIDL.address);
59
- export const YIELD_ORACLE_PROGRAM_ID = new PublicKey(YieldOracleIDL.address);
60
-
61
- // Protocol constants tweak as needed:
62
- export const MIN_SOL_TO_PARTICIPATE = 1_000_000_000; // 1 SOL in lamports
63
- export const MIN_FUNDS_THRESHOLD = 10_000_000_000; // 10 SOL in lamports
64
- export const RESERVE_FOR_FEES = 1_000_000_000; // 1 SOL
65
-
66
- // — Pre-derived PDA seeds for your convenience —
67
- // (you can still use your utils.ts helpers instead)
68
- export const TREASURY_WALLET_PDA = new PublicKey('9gLj1MRrm66GNYqnMLPGUzyYqYJpVLQgFSbtCQV9Ta4G');
69
- export const LIQSOL_MINT_ADDRESS = new PublicKey('B2XtJABkc6eUoYUNgSfZVb3kYckmbh2zxp4rp2hX2Xwa');
70
- export const STAKE_VAULT_PDA = new PublicKey('AY83EfU5LXJGDhbLeP45H3tLKisGZgSe2G4mGYfPimqN');
71
-
72
- // re-export SPL token constants:
73
- export { TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID };
176
+
177
+
178
+ /**
179
+ * ---------------------------------------------------------------------------
180
+ * ECONOMICS & MATH CONSTANTS
181
+ * ---------------------------------------------------------------------------
182
+ */
183
+
184
+ // Same scale factor used on-chain for pay-rate math
185
+ export const PAY_RATE_SCALE_FACTOR = BigInt(1_000_000_000_000); // 10^12
186
+
187
+ // Default pay rate fallback used in tests & utils
188
+ export const DEFAULT_AVERAGE_PAY_RATE = BigInt(191_780_821);
189
+
190
+ // How many history entries to average when computing expected fee
191
+ export const DEFAULT_PAY_RATE_LOOKBACK = 5;
192
+
193
+ // Rent exemption for ephemeral stake account (lamports)
194
+ // Mirrors EPHEMERAL_RENT_EXEMPTION = 2_282_880 used in tests
195
+ export const EPHEMERAL_RENT_EXEMPTION = 2_282_880;
196
+
197
+ // For convenience: lamports <-> SOL helpers (no RPC dependency)
198
+ export const LAMPORTS_PER_SOL = 1_000_000_000;
199
+
200
+ export const lamportsToSol = (lamports: number | bigint): number =>
201
+ Number(lamports) / LAMPORTS_PER_SOL;
202
+
203
+ export const solToLamports = (sol: number): number =>
204
+ Math.round(sol * LAMPORTS_PER_SOL);
205
+
206
+ /**
207
+ * ---------------------------------------------------------------------------
208
+ * CLUSTER / ENVIRONMENT CONFIG (optional but handy)
209
+ * ---------------------------------------------------------------------------
210
+ */
211
+
212
+ export type SolanaCluster = 'localnet' | 'devnet' | 'mainnet';
213
+
214
+ // export interface SolanaStakeProgramAddresses {
215
+ // liqsolCore: PublicKey;
216
+ // liqsolToken: PublicKey;
217
+ // validatorLeaderboard: PublicKey;
218
+ // }
219
+
220
+ // export const PROGRAMS_BY_CLUSTER: Record<SolanaCluster, SolanaStakeProgramAddresses> = {
221
+ // localnet: {
222
+ // liqsolCore: PROGRAM_IDS.LIQSOL_CORE,
223
+ // liqsolToken: PROGRAM_IDS.LIQSOL_TOKEN,
224
+ // validatorLeaderboard: PROGRAM_IDS.VALIDATOR_LEADERBOARD,
225
+ // },
226
+ // devnet: {
227
+ // liqsolCore: PROGRAM_IDS.LIQSOL_CORE,
228
+ // liqsolToken: PROGRAM_IDS.LIQSOL_TOKEN,
229
+ // validatorLeaderboard: PROGRAM_IDS.VALIDATOR_LEADERBOARD,
230
+ // },
231
+ // mainnet: {
232
+ // liqsolCore: PROGRAM_IDS.LIQSOL_CORE,
233
+ // liqsolToken: PROGRAM_IDS.LIQSOL_TOKEN,
234
+ // validatorLeaderboard: PROGRAM_IDS.VALIDATOR_LEADERBOARD,
235
+ // },
236
+ // };
237
+
238
+ // export const DEFAULT_CLUSTER: SolanaCluster = 'localnet';
239
+
240
+ // export function getProgramIds(cluster: SolanaCluster = DEFAULT_CLUSTER): SolanaStakeProgramAddresses {
241
+ // return PROGRAMS_BY_CLUSTER[cluster];
242
+ // }