@wireio/stake 0.7.3 → 0.9.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.
@@ -1,7 +1,8 @@
1
1
  import { PublicKey as PublicKey$1, KeyType, SolChainID, EvmChainID } from '@wireio/core';
2
- import { PublicKey, StakeProgram, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SYSVAR_RENT_PUBKEY, Transaction, Keypair, Connection, ComputeBudgetProgram } from '@solana/web3.js';
2
+ import { PublicKey, StakeProgram, SystemProgram, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_CLOCK_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, SYSVAR_RENT_PUBKEY, TransactionMessage, Transaction, Keypair, Connection, ComputeBudgetProgram } from '@solana/web3.js';
3
3
  import { Program, BN, AnchorProvider } from '@coral-xyz/anchor';
4
- import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress } from '@solana/spl-token';
4
+ import { getAssociatedTokenAddressSync, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress, createAssociatedTokenAccountInstruction } from '@solana/spl-token';
5
+ import * as multisig from '@sqds/multisig';
5
6
  import { ethers, Contract, BigNumber } from 'ethers';
6
7
 
7
8
  var address$3 = "5nBtmutQLrRKBUxNfHJPDjiW5u8id6QM9Hhjg1D1g1XH";
@@ -12,68 +13,6 @@ var metadata$3 = {
12
13
  description: "Created with Anchor"
13
14
  };
14
15
  var instructions$3 = [
15
- {
16
- name: "accumulate_unstake_request",
17
- docs: [
18
- "Accumulate unstake requests to be processed in next allocation cycle",
19
- "Multiple requests can be accumulated before calculating allocations",
20
- "Returns the target epoch when this unstake request will be processed",
21
- "We should not be able to call this without development feature enabled",
22
- ""
23
- ],
24
- discriminator: [
25
- 24,
26
- 73,
27
- 69,
28
- 139,
29
- 36,
30
- 209,
31
- 105,
32
- 252
33
- ],
34
- accounts: [
35
- {
36
- name: "admin",
37
- writable: true,
38
- signer: true
39
- },
40
- {
41
- name: "stake_allocation_state",
42
- docs: [
43
- "Stake allocation state - to accumulate pending unstake requests"
44
- ],
45
- writable: true
46
- },
47
- {
48
- name: "stake_metrics",
49
- docs: [
50
- "Stake metrics - to validate total unstake amount is available"
51
- ]
52
- },
53
- {
54
- name: "maintenance_ledger",
55
- docs: [
56
- "Maintenance ledger - to determine target processing epoch"
57
- ]
58
- },
59
- {
60
- name: "global_config",
61
- docs: [
62
- "Global config for min_unstake_request setting"
63
- ]
64
- },
65
- {
66
- name: "clock"
67
- }
68
- ],
69
- args: [
70
- {
71
- name: "amount",
72
- type: "u64"
73
- }
74
- ],
75
- returns: "u64"
76
- },
77
16
  {
78
17
  name: "add_top_performers_batch",
79
18
  docs: [
@@ -127,74 +66,6 @@ var instructions$3 = [
127
66
  args: [
128
67
  ]
129
68
  },
130
- {
131
- name: "add_validator_v2",
132
- docs: [
133
- "Add a new validator bbypassing the looking at leaderboard and getting validators form there"
134
- ],
135
- discriminator: [
136
- 217,
137
- 158,
138
- 30,
139
- 19,
140
- 123,
141
- 99,
142
- 110,
143
- 30
144
- ],
145
- accounts: [
146
- {
147
- name: "authority",
148
- writable: true,
149
- signer: true
150
- },
151
- {
152
- name: "active_list",
153
- docs: [
154
- "Active list - will add the validator here"
155
- ],
156
- writable: true
157
- },
158
- {
159
- name: "validator_info",
160
- docs: [
161
- "Create the validator info account"
162
- ],
163
- writable: true
164
- },
165
- {
166
- name: "validator_transient",
167
- docs: [
168
- "Create the validator transient account"
169
- ],
170
- writable: true
171
- },
172
- {
173
- name: "stake_allocation_state",
174
- docs: [
175
- "Stake allocation state - to update total_active_vpp when adding validator"
176
- ],
177
- writable: true
178
- },
179
- {
180
- name: "system_program"
181
- }
182
- ],
183
- args: [
184
- {
185
- name: "vote_account",
186
- type: "pubkey"
187
- },
188
- {
189
- name: "name",
190
- type: "string"
191
- },
192
- {
193
- name: "performance_score",
194
- type: "u8"
195
- }
196
- ]
197
- },
198
69
  {
199
70
  name: "aggregate_stake_metrics",
200
71
  docs: [
@@ -234,43 +105,6 @@ var instructions$3 = [
234
105
  args: [
235
106
  ]
236
107
  },
237
- {
238
- name: "blacklist_validator",
239
- docs: [
240
- "Blacklist a validator (user-facing, maintenance will handle graveyard movement)",
241
- "UnderPerforming is set automatically when score is updated",
242
- "Another serious emergency stop function"
243
- ],
244
- discriminator: [
245
- 125,
246
- 42,
247
- 36,
248
- 229,
249
- 27,
250
- 38,
251
- 226,
252
- 62
253
- ],
254
- accounts: [
255
- {
256
- name: "validator_info",
257
- writable: true
258
- },
259
- {
260
- name: "stake_allocation_state",
261
- docs: [
262
- "Stake allocation state - to update total_active_vpp when VPP changes"
263
- ],
264
- writable: true
265
- }
266
- ],
267
- args: [
268
- {
269
- name: "vote_account",
270
- type: "pubkey"
271
- }
272
- ]
273
- },
274
108
  {
275
109
  name: "bond_role",
276
110
  discriminator: [
@@ -2860,147 +2694,6 @@ var instructions$3 = [
2860
2694
  }
2861
2695
  ]
2862
2696
  },
2863
- {
2864
- name: "reset_distribution_state",
2865
- discriminator: [
2866
- 159,
2867
- 183,
2868
- 162,
2869
- 74,
2870
- 228,
2871
- 135,
2872
- 157,
2873
- 79
2874
- ],
2875
- accounts: [
2876
- {
2877
- name: "admin",
2878
- signer: true
2879
- },
2880
- {
2881
- name: "distribution_state",
2882
- writable: true
2883
- }
2884
- ],
2885
- args: [
2886
- ]
2887
- },
2888
- {
2889
- name: "reset_global_state",
2890
- discriminator: [
2891
- 252,
2892
- 41,
2893
- 117,
2894
- 110,
2895
- 248,
2896
- 165,
2897
- 48,
2898
- 88
2899
- ],
2900
- accounts: [
2901
- {
2902
- name: "admin",
2903
- signer: true
2904
- },
2905
- {
2906
- name: "global_config"
2907
- },
2908
- {
2909
- name: "global_state",
2910
- writable: true
2911
- },
2912
- {
2913
- name: "pool_authority"
2914
- },
2915
- {
2916
- name: "liqsol_mint"
2917
- },
2918
- {
2919
- name: "liqsol_pool_ata",
2920
- writable: true
2921
- },
2922
- {
2923
- name: "token_program"
2924
- },
2925
- {
2926
- name: "associated_token_program"
2927
- }
2928
- ],
2929
- args: [
2930
- ]
2931
- },
2932
- {
2933
- name: "reset_price_history",
2934
- discriminator: [
2935
- 213,
2936
- 231,
2937
- 155,
2938
- 139,
2939
- 248,
2940
- 60,
2941
- 67,
2942
- 199
2943
- ],
2944
- accounts: [
2945
- {
2946
- name: "admin",
2947
- writable: true,
2948
- signer: true
2949
- },
2950
- {
2951
- name: "global_config"
2952
- },
2953
- {
2954
- name: "tranche_state",
2955
- writable: true
2956
- },
2957
- {
2958
- name: "price_history",
2959
- writable: true
2960
- },
2961
- {
2962
- name: "system_program"
2963
- }
2964
- ],
2965
- args: [
2966
- ]
2967
- },
2968
- {
2969
- name: "reset_tranche_state",
2970
- discriminator: [
2971
- 106,
2972
- 102,
2973
- 143,
2974
- 40,
2975
- 152,
2976
- 173,
2977
- 165,
2978
- 168
2979
- ],
2980
- accounts: [
2981
- {
2982
- name: "admin",
2983
- writable: true,
2984
- signer: true
2985
- },
2986
- {
2987
- name: "global_config"
2988
- },
2989
- {
2990
- name: "tranche_state",
2991
- writable: true
2992
- },
2993
- {
2994
- name: "price_history",
2995
- writable: true
2996
- },
2997
- {
2998
- name: "system_program"
2999
- }
3000
- ],
3001
- args: [
3002
- ]
3003
- },
3004
2697
  {
3005
2698
  name: "set_admin",
3006
2699
  discriminator: [
@@ -3023,8 +2716,7 @@ var instructions$3 = [
3023
2716
  signer: true
3024
2717
  },
3025
2718
  {
3026
- name: "new_authority",
3027
- signer: true
2719
+ name: "new_authority"
3028
2720
  }
3029
2721
  ],
3030
2722
  args: [
@@ -3052,52 +2744,12 @@ var instructions$3 = [
3052
2744
  signer: true
3053
2745
  },
3054
2746
  {
3055
- name: "new_authority",
3056
- signer: true
2747
+ name: "new_authority"
3057
2748
  }
3058
2749
  ],
3059
2750
  args: [
3060
2751
  ]
3061
2752
  },
3062
- {
3063
- name: "set_last_state_change_epoch",
3064
- docs: [
3065
- "Admin function to directly set last_state_change_epoch (useful for testing cooldowns)"
3066
- ],
3067
- discriminator: [
3068
- 94,
3069
- 57,
3070
- 139,
3071
- 195,
3072
- 123,
3073
- 224,
3074
- 227,
3075
- 106
3076
- ],
3077
- accounts: [
3078
- {
3079
- name: "validator_info",
3080
- writable: true
3081
- },
3082
- {
3083
- name: "stake_allocation_state",
3084
- docs: [
3085
- "Stake allocation state - to update total_active_vpp when VPP changes"
3086
- ],
3087
- writable: true
3088
- }
3089
- ],
3090
- args: [
3091
- {
3092
- name: "vote_account",
3093
- type: "pubkey"
3094
- },
3095
- {
3096
- name: "epoch",
3097
- type: "u16"
3098
- }
3099
- ]
3100
- },
3101
2753
  {
3102
2754
  name: "set_paused",
3103
2755
  discriminator: [
@@ -3587,35 +3239,6 @@ var instructions$3 = [
3587
3239
  }
3588
3240
  ]
3589
3241
  },
3590
- {
3591
- name: "test_clear_active_list",
3592
- discriminator: [
3593
- 17,
3594
- 195,
3595
- 59,
3596
- 174,
3597
- 184,
3598
- 137,
3599
- 149,
3600
- 144
3601
- ],
3602
- accounts: [
3603
- {
3604
- name: "active_list",
3605
- writable: true
3606
- },
3607
- {
3608
- name: "processing_state",
3609
- writable: true
3610
- },
3611
- {
3612
- name: "authority",
3613
- signer: true
3614
- }
3615
- ],
3616
- args: [
3617
- ]
3618
- },
3619
3242
  {
3620
3243
  name: "update_config_bool",
3621
3244
  discriminator: [
@@ -4293,8 +3916,118 @@ var events = [
4293
3916
  var errors$3 = [
4294
3917
  {
4295
3918
  code: 6000,
4296
- name: "AccountBorrowFailed",
4297
- msg: "Util Acc borrow Failed"
3919
+ name: "DestinationAccountDoesNotExist",
3920
+ msg: "Destination stake account does not exist"
3921
+ },
3922
+ {
3923
+ code: 6001,
3924
+ name: "SourceAccountDoesNotExist",
3925
+ msg: "Source stake account does not exist"
3926
+ },
3927
+ {
3928
+ code: 6002,
3929
+ name: "InvalidDestinationOwner",
3930
+ msg: "Destination account not owned by stake program"
3931
+ },
3932
+ {
3933
+ code: 6003,
3934
+ name: "InvalidSourceOwner",
3935
+ msg: "Source account not owned by stake program"
3936
+ },
3937
+ {
3938
+ code: 6004,
3939
+ name: "ClockBorrowFailed",
3940
+ msg: "Failed to borrow clock data"
3941
+ },
3942
+ {
3943
+ code: 6005,
3944
+ name: "ClockDeserializeFailed",
3945
+ msg: "Failed to deserialize clock"
3946
+ },
3947
+ {
3948
+ code: 6006,
3949
+ name: "DestinationAnalysisFailed",
3950
+ msg: "Failed to analyze destination stake account"
3951
+ },
3952
+ {
3953
+ code: 6007,
3954
+ name: "SourceAnalysisFailed",
3955
+ msg: "Failed to analyze source stake account"
3956
+ },
3957
+ {
3958
+ code: 6008,
3959
+ name: "DestinationStillActivating",
3960
+ msg: "Destination stake is still activating"
3961
+ },
3962
+ {
3963
+ code: 6009,
3964
+ name: "DestinationDeactivating",
3965
+ msg: "Destination stake is deactivating"
3966
+ },
3967
+ {
3968
+ code: 6010,
3969
+ name: "SourceStillActivating",
3970
+ msg: "Source stake is still activating"
3971
+ },
3972
+ {
3973
+ code: 6011,
3974
+ name: "SourceDeactivating",
3975
+ msg: "Source stake is deactivating"
3976
+ },
3977
+ {
3978
+ code: 6012,
3979
+ name: "DestinationBorrowFailed",
3980
+ msg: "Failed to borrow destination account data"
3981
+ },
3982
+ {
3983
+ code: 6013,
3984
+ name: "DestinationParseFailed",
3985
+ msg: "Failed to parse destination stake state"
3986
+ },
3987
+ {
3988
+ code: 6014,
3989
+ name: "SourceBorrowFailed",
3990
+ msg: "Failed to borrow source account data"
3991
+ },
3992
+ {
3993
+ code: 6015,
3994
+ name: "SourceParseFailed",
3995
+ msg: "Failed to parse source stake state"
3996
+ },
3997
+ {
3998
+ code: 6016,
3999
+ name: "DifferentValidators",
4000
+ msg: "Stakes are delegated to different validators"
4001
+ },
4002
+ {
4003
+ code: 6017,
4004
+ name: "DifferentStakers",
4005
+ msg: "Stakes have different staker authorities"
4006
+ },
4007
+ {
4008
+ code: 6018,
4009
+ name: "DifferentWithdrawers",
4010
+ msg: "Stakes have different withdrawer authorities"
4011
+ },
4012
+ {
4013
+ code: 6019,
4014
+ name: "AuthoritiesNotFound",
4015
+ msg: "Could not extract authorities from accounts"
4016
+ },
4017
+ {
4018
+ code: 6020,
4019
+ name: "MergeInstructionFailed",
4020
+ msg: "Merge instruction failed"
4021
+ },
4022
+ {
4023
+ code: 6021,
4024
+ name: "EpochRewardsActive",
4025
+ msg: "Epoch rewards distribution is active - stake operations blocked"
4026
+ },
4027
+ {
4028
+ code: 6022,
4029
+ name: "DifferentCreditsObserved",
4030
+ msg: "Stakes have different credits_observed - cannot merge until both earn same rewards"
4298
4031
  }
4299
4032
  ];
4300
4033
  var types$5 = [
@@ -6747,153 +6480,6 @@ var instructions$1 = [
6747
6480
  args: [
6748
6481
  ]
6749
6482
  },
6750
- {
6751
- name: "test_clear_leaderboard",
6752
- discriminator: [
6753
- 118,
6754
- 207,
6755
- 26,
6756
- 205,
6757
- 180,
6758
- 7,
6759
- 75,
6760
- 244
6761
- ],
6762
- accounts: [
6763
- {
6764
- name: "leaderboard_state",
6765
- writable: true
6766
- },
6767
- {
6768
- name: "authority",
6769
- signer: true
6770
- }
6771
- ],
6772
- args: [
6773
- ]
6774
- },
6775
- {
6776
- name: "test_force_register_validator",
6777
- discriminator: [
6778
- 136,
6779
- 156,
6780
- 132,
6781
- 32,
6782
- 96,
6783
- 240,
6784
- 7,
6785
- 115
6786
- ],
6787
- accounts: [
6788
- {
6789
- name: "registrant",
6790
- writable: true,
6791
- signer: true
6792
- },
6793
- {
6794
- name: "vote_account"
6795
- },
6796
- {
6797
- name: "validator_record",
6798
- writable: true
6799
- },
6800
- {
6801
- name: "leaderboard_state",
6802
- writable: true
6803
- },
6804
- {
6805
- name: "system_program"
6806
- },
6807
- {
6808
- name: "clock"
6809
- }
6810
- ],
6811
- args: [
6812
- {
6813
- name: "vpp",
6814
- type: "u8"
6815
- }
6816
- ]
6817
- },
6818
- {
6819
- name: "test_force_update_vpp",
6820
- discriminator: [
6821
- 67,
6822
- 51,
6823
- 28,
6824
- 174,
6825
- 200,
6826
- 214,
6827
- 203,
6828
- 162
6829
- ],
6830
- accounts: [
6831
- {
6832
- name: "registrant",
6833
- writable: true,
6834
- signer: true
6835
- },
6836
- {
6837
- name: "vote_account"
6838
- },
6839
- {
6840
- name: "validator_record",
6841
- writable: true
6842
- },
6843
- {
6844
- name: "leaderboard_state",
6845
- writable: true
6846
- }
6847
- ],
6848
- args: [
6849
- {
6850
- name: "vpp",
6851
- type: "u8"
6852
- }
6853
- ]
6854
- },
6855
- {
6856
- name: "test_seed_random_validators",
6857
- discriminator: [
6858
- 48,
6859
- 155,
6860
- 181,
6861
- 112,
6862
- 163,
6863
- 242,
6864
- 43,
6865
- 146
6866
- ],
6867
- accounts: [
6868
- {
6869
- name: "registrant",
6870
- writable: true,
6871
- signer: true
6872
- },
6873
- {
6874
- name: "leaderboard_state",
6875
- writable: true
6876
- }
6877
- ],
6878
- args: [
6879
- {
6880
- name: "count",
6881
- type: "u16"
6882
- },
6883
- {
6884
- name: "seed",
6885
- type: "u64"
6886
- },
6887
- {
6888
- name: "min_vpp",
6889
- type: "u8"
6890
- },
6891
- {
6892
- name: "max_vpp",
6893
- type: "u8"
6894
- }
6895
- ]
6896
- },
6897
6483
  {
6898
6484
  name: "update_commission",
6899
6485
  discriminator: [
@@ -7807,7 +7393,7 @@ const deriveEphemeralStakeAddress = async (user, seed) => {
7807
7393
  return PublicKey.createWithSeed(user, seedStr, StakeProgram.programId);
7808
7394
  };
7809
7395
  const CHAINLINK_FEED = new PublicKey(
7810
- "99B2bTijsU6f1GCT73HmdR7HCFFjGMBcPZY6jZ96ynrR"
7396
+ "CH31Xns5z3M1cTAbKW34jcxPPciazARpijcHj9rxtemt"
7811
7397
  );
7812
7398
  const CHAINLINK_PROGRAM = new PublicKey(
7813
7399
  "HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny"
@@ -7855,6 +7441,9 @@ class DepositClient {
7855
7441
  const svc = new SolanaProgramService(provider);
7856
7442
  this.program = svc.getProgram("liqsolCore");
7857
7443
  }
7444
+ get connection() {
7445
+ return this.provider.connection;
7446
+ }
7858
7447
  get wallet() {
7859
7448
  return this.provider.wallet;
7860
7449
  }
@@ -7882,7 +7471,7 @@ class DepositClient {
7882
7471
  const userAta = getAssociatedTokenAddressSync(
7883
7472
  liqsolMint,
7884
7473
  user,
7885
- false,
7474
+ true,
7886
7475
  TOKEN_2022_PROGRAM_ID
7887
7476
  );
7888
7477
  const distributionState = deriveDistributionStatePda();
@@ -7895,7 +7484,7 @@ class DepositClient {
7895
7484
  );
7896
7485
  const seed = Math.floor(Math.random() * 2 ** 32);
7897
7486
  const ephemeralStake = await deriveEphemeralStakeAddress(user, seed);
7898
- const ix = await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
7487
+ return await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
7899
7488
  user,
7900
7489
  depositAuthority,
7901
7490
  systemProgram: SystemProgram.programId,
@@ -7922,7 +7511,58 @@ class DepositClient {
7922
7511
  rent: SYSVAR_RENT_PUBKEY,
7923
7512
  globalConfig
7924
7513
  }).instruction();
7925
- return new Transaction().add(ix);
7514
+ }
7515
+ async buildSquadsDepositProposalTx(params) {
7516
+ const { connection, multisigPda, amountLamports, wallet } = params;
7517
+ const vaultIndex = params.vaultIndex ?? 0;
7518
+ if (!wallet?.publicKey) throw new Error("wallet.publicKey missing");
7519
+ if (!amountLamports || amountLamports <= BigInt(0)) throw new Error("amountLamports must be > 0");
7520
+ const [vaultPda] = multisig.getVaultPda({ multisigPda, index: vaultIndex });
7521
+ const depositBuilt = await this.buildDepositIxForUser(amountLamports, vaultPda);
7522
+ const ms = await multisig.accounts.Multisig.fromAccountAddress(connection, multisigPda);
7523
+ const current = BigInt(ms.transactionIndex?.toString?.() ?? 0);
7524
+ const transactionIndex = current + BigInt(1);
7525
+ const { blockhash } = await connection.getLatestBlockhash("confirmed");
7526
+ const message = new TransactionMessage({
7527
+ payerKey: vaultPda,
7528
+ recentBlockhash: blockhash,
7529
+ instructions: [depositBuilt.ix]
7530
+ });
7531
+ const createVaultTxIx = await multisig.instructions.vaultTransactionCreate({
7532
+ multisigPda,
7533
+ transactionIndex,
7534
+ creator: wallet.publicKey,
7535
+ vaultIndex,
7536
+ ephemeralSigners: 0,
7537
+ transactionMessage: message
7538
+ });
7539
+ console.log("createVaultTxIx", createVaultTxIx);
7540
+ const tx = new Transaction().add(createVaultTxIx);
7541
+ return { tx, transactionIndex, vaultPda };
7542
+ }
7543
+ async buildSquadsDepositProposalTx2(params) {
7544
+ const { connection, multisigPda, amountLamports, wallet } = params;
7545
+ const vaultIndex = params.vaultIndex ?? 0;
7546
+ if (!wallet?.publicKey) throw new Error("wallet.publicKey missing");
7547
+ if (!amountLamports || amountLamports <= BigInt(0)) throw new Error("amountLamports must be > 0");
7548
+ const [vaultPda] = multisig.getVaultPda({ multisigPda, index: vaultIndex });
7549
+ const depositBuilt = await this.buildDepositIxForUser(amountLamports, vaultPda);
7550
+ const ms = await multisig.accounts.Multisig.fromAccountAddress(connection, multisigPda);
7551
+ const current = BigInt(ms.transactionIndex?.toString?.() ?? 0);
7552
+ const transactionIndex = current + BigInt(1);
7553
+ const { blockhash } = await connection.getLatestBlockhash("confirmed");
7554
+ new TransactionMessage({
7555
+ payerKey: vaultPda,
7556
+ recentBlockhash: blockhash,
7557
+ instructions: [depositBuilt.ix]
7558
+ });
7559
+ const createProposalIx = await multisig.instructions.proposalCreate({
7560
+ multisigPda,
7561
+ transactionIndex,
7562
+ creator: wallet.publicKey
7563
+ });
7564
+ const tx = new Transaction().add(createProposalIx);
7565
+ return { tx, transactionIndex, vaultPda };
7926
7566
  }
7927
7567
  async buildWithdrawTx(amount, user = this.wallet.publicKey) {
7928
7568
  if (!user) {
@@ -7939,7 +7579,7 @@ class DepositClient {
7939
7579
  const userAta = getAssociatedTokenAddressSync(
7940
7580
  liqsolMint,
7941
7581
  user,
7942
- false,
7582
+ true,
7943
7583
  TOKEN_2022_PROGRAM_ID
7944
7584
  );
7945
7585
  const userRecord = deriveUserRecordPda(userAta);
@@ -7972,7 +7612,7 @@ class DepositClient {
7972
7612
  const nftAta = getAssociatedTokenAddressSync(
7973
7613
  nftMint,
7974
7614
  owner,
7975
- false,
7615
+ true,
7976
7616
  TOKEN_2022_PROGRAM_ID
7977
7617
  );
7978
7618
  const bucketAuthority = deriveBucketAuthorityPda();
@@ -8010,6 +7650,68 @@ class DepositClient {
8010
7650
  }).instruction();
8011
7651
  return new Transaction().add(ix);
8012
7652
  }
7653
+ async buildDepositIxForUser(amount, user) {
7654
+ if (!user) {
7655
+ throw new Error("buildDepositIxForUser: user is required");
7656
+ }
7657
+ if (!amount || amount <= BigInt(0)) {
7658
+ throw new Error("buildDepositIxForUser: amount must be > 0");
7659
+ }
7660
+ const depositAuthority = deriveDepositAuthorityPda();
7661
+ const liqsolMint = deriveLiqsolMintPda();
7662
+ const liqsolMintAuthority = deriveLiqsolMintAuthorityPda();
7663
+ const reservePool = deriveReservePoolPda();
7664
+ const vault = deriveVaultPda();
7665
+ const controllerState = deriveStakeControllerStatePda();
7666
+ const payoutState = derivePayoutStatePda();
7667
+ const bucketAuthority = deriveBucketAuthorityPda();
7668
+ const payRateHistory = derivePayRateHistoryPda();
7669
+ const globalConfig = deriveGlobalConfigPda();
7670
+ const userAta = getAssociatedTokenAddressSync(
7671
+ liqsolMint,
7672
+ user,
7673
+ true,
7674
+ TOKEN_2022_PROGRAM_ID
7675
+ );
7676
+ const distributionState = deriveDistributionStatePda();
7677
+ const userRecord = deriveUserRecordPda(userAta);
7678
+ const bucketTokenAccount = getAssociatedTokenAddressSync(
7679
+ liqsolMint,
7680
+ bucketAuthority,
7681
+ true,
7682
+ TOKEN_2022_PROGRAM_ID
7683
+ );
7684
+ const seed = Math.floor(Math.random() * 2 ** 32);
7685
+ const ephemeralStake = await deriveEphemeralStakeAddress(user, seed);
7686
+ const ix = await this.program.methods.deposit(new BN(amount.toString()), seed).accounts({
7687
+ user,
7688
+ depositAuthority,
7689
+ systemProgram: SystemProgram.programId,
7690
+ tokenProgram: TOKEN_2022_PROGRAM_ID,
7691
+ associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
7692
+ liqsolProgram: PROGRAM_IDS.LIQSOL_TOKEN,
7693
+ stakeProgram: StakeProgram.programId,
7694
+ liqsolMint,
7695
+ userAta,
7696
+ liqsolMintAuthority,
7697
+ reservePool,
7698
+ vault,
7699
+ ephemeralStake,
7700
+ controllerState,
7701
+ payoutState,
7702
+ bucketAuthority,
7703
+ bucketTokenAccount,
7704
+ userRecord,
7705
+ distributionState,
7706
+ payRateHistory,
7707
+ instructionsSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
7708
+ clock: SYSVAR_CLOCK_PUBKEY,
7709
+ stakeHistory: SYSVAR_STAKE_HISTORY_PUBKEY,
7710
+ rent: SYSVAR_RENT_PUBKEY,
7711
+ globalConfig
7712
+ }).instruction();
7713
+ return { ix, seed, userAta, ephemeralStake };
7714
+ }
8013
7715
  }
8014
7716
 
8015
7717
  const INDEX_SCALE = BigInt(1e12);
@@ -8498,7 +8200,7 @@ class DistributionClient {
8498
8200
  const ata = getAssociatedTokenAddressSync(
8499
8201
  liqsolMint,
8500
8202
  ownerOrAta,
8501
- false,
8203
+ true,
8502
8204
  TOKEN_2022_PROGRAM_ID
8503
8205
  );
8504
8206
  const pdaFromWallet = deriveUserRecordPda(ata);
@@ -8777,7 +8479,7 @@ class OutpostClient {
8777
8479
  };
8778
8480
  }
8779
8481
  static tokensToShares(amount, currentIndex) {
8780
- const numerator = amount.mul(INDEX_SCALE$1);
8482
+ const numerator = amount.mul(new BN(INDEX_SCALE$1));
8781
8483
  const shares = numerator.div(currentIndex);
8782
8484
  const remainder = numerator.mod(currentIndex);
8783
8485
  return remainder.eqn(0) ? shares : shares.addn(1);
@@ -8976,196 +8678,331 @@ const _SolanaStakingClient = class _SolanaStakingClient {
8976
8678
  get network() {
8977
8679
  return this.config.network;
8978
8680
  }
8681
+ get feePayer() {
8682
+ if (this.signer) return this.signer;
8683
+ if (this.anchor.wallet.publicKey) return this.anchor.wallet.publicKey;
8684
+ throw new Error("No signing authority available");
8685
+ }
8686
+ get squadsX() {
8687
+ const config = this.config.extras?.squadsX;
8688
+ return config ?? null;
8689
+ }
8690
+ async createVaultLiqsolAtaOneShot(params) {
8691
+ const { connection, payer, vaultPda } = params;
8692
+ const liqsolMint = deriveLiqsolMintPda();
8693
+ const vaultAta = getAssociatedTokenAddressSync(
8694
+ liqsolMint,
8695
+ vaultPda,
8696
+ true,
8697
+ TOKEN_2022_PROGRAM_ID,
8698
+ ASSOCIATED_TOKEN_PROGRAM_ID
8699
+ );
8700
+ const info = await connection.getAccountInfo(vaultAta, "confirmed");
8701
+ console.log("info?", info);
8702
+ if (info) return null;
8703
+ const ix = createAssociatedTokenAccountInstruction(
8704
+ payer,
8705
+ vaultAta,
8706
+ vaultPda,
8707
+ liqsolMint,
8708
+ TOKEN_2022_PROGRAM_ID,
8709
+ ASSOCIATED_TOKEN_PROGRAM_ID
8710
+ );
8711
+ const tx = new Transaction().add(ix);
8712
+ return { tx, vaultAta };
8713
+ }
8714
+ async prepSquadsIxs(ix) {
8715
+ if (!this.squadsX) throw new Error("Attempting to wrap Squads instruction without SquadsX config");
8716
+ const multisigPda = this.squadsMultisigPDA;
8717
+ const vaultPda = this.squadsVaultPDA;
8718
+ const vaultIndex = this.squadsX?.vaultIndex ?? 0;
8719
+ const creator = this.solPubKey;
8720
+ const ms = await multisig.accounts.Multisig.fromAccountAddress(this.connection, multisigPda);
8721
+ const current = BigInt(ms.transactionIndex?.toString() ?? 0);
8722
+ const transactionIndex = current + BigInt(1);
8723
+ const { blockhash } = await this.connection.getLatestBlockhash("confirmed");
8724
+ const transactionMessage = new TransactionMessage({
8725
+ payerKey: vaultPda,
8726
+ recentBlockhash: blockhash,
8727
+ instructions: [ix]
8728
+ });
8729
+ const createVaultTxIx = await multisig.instructions.vaultTransactionCreate({
8730
+ multisigPda,
8731
+ transactionIndex,
8732
+ creator,
8733
+ vaultIndex,
8734
+ transactionMessage,
8735
+ ephemeralSigners: 0
8736
+ });
8737
+ const createProposalIx = await multisig.instructions.proposalCreate({
8738
+ multisigPda,
8739
+ transactionIndex,
8740
+ creator
8741
+ });
8742
+ return [createVaultTxIx, createProposalIx];
8743
+ }
8979
8744
  async deposit(amountLamports) {
8980
8745
  this.ensureUser();
8981
8746
  if (amountLamports <= BigInt(0)) {
8982
8747
  throw new Error("Deposit amount must be greater than zero.");
8983
8748
  }
8984
- const tx = await this.depositClient.buildDepositTx(amountLamports);
8985
- const { tx: prepared, blockhash, lastValidBlockHeight } = await this.prepareTx(tx);
8986
- const signed = await this.signTransaction(prepared);
8987
- return await this.sendAndConfirmHttp(signed, {
8988
- blockhash,
8989
- lastValidBlockHeight
8990
- });
8749
+ try {
8750
+ const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
8751
+ if (!!this.squadsX) {
8752
+ const createVaultTx = await this.createVaultLiqsolAtaOneShot({
8753
+ connection: this.connection,
8754
+ payer: this.solPubKey,
8755
+ vaultPda: this.squadsVaultPDA
8756
+ });
8757
+ if (createVaultTx !== null) {
8758
+ console.log("need to create vault ata first...");
8759
+ const tx0 = new Transaction().add(createVaultTx.tx);
8760
+ const prepared0 = await this.prepareTx(tx0);
8761
+ const signed0 = await this.signTransaction(prepared0.tx);
8762
+ const sent0 = await this.sendAndConfirmHttp(signed0, prepared0);
8763
+ console.log("create Vault ATA", sent0);
8764
+ }
8765
+ const ix = await this.depositClient.buildDepositTx(amountLamports, this.squadsVaultPDA);
8766
+ const squadIxs = await this.prepSquadsIxs(ix);
8767
+ const tx1 = new Transaction().add(cuIx, squadIxs[0]);
8768
+ const prepared1 = await this.prepareTx(tx1);
8769
+ const signed1 = await this.signTransaction(prepared1.tx);
8770
+ const sent1 = await this.sendAndConfirmHttp(signed1, prepared1);
8771
+ console.log("SENT 1", sent1);
8772
+ const tx2 = new Transaction().add(cuIx, squadIxs[1]);
8773
+ const prepared2 = await this.prepareTx(tx2);
8774
+ const signed2 = await this.signTransaction(prepared2.tx);
8775
+ const sent2 = await this.sendAndConfirmHttp(signed2, prepared2);
8776
+ console.log("SENT 2", sent2);
8777
+ return sent2;
8778
+ } else {
8779
+ const ix = await this.depositClient.buildDepositTx(amountLamports);
8780
+ const tx = new Transaction().add(ix);
8781
+ const prepared = await this.prepareTx(tx);
8782
+ const signed = await this.signTransaction(prepared.tx);
8783
+ return this.sendAndConfirmHttp(signed, prepared);
8784
+ }
8785
+ } catch (err) {
8786
+ throw new Error(`Failed to deposit Solana: ${err}`);
8787
+ }
8991
8788
  }
8992
8789
  async withdraw(amountLamports) {
8993
8790
  this.ensureUser();
8994
8791
  if (amountLamports <= BigInt(0)) {
8995
8792
  throw new Error("Withdraw amount must be greater than zero.");
8996
8793
  }
8997
- const tx = await this.depositClient.buildWithdrawTx(amountLamports);
8998
- const { tx: prepared, blockhash, lastValidBlockHeight } = await this.prepareTx(tx);
8999
- const signed = await this.signTransaction(prepared);
9000
- return await this.sendAndConfirmHttp(signed, {
9001
- blockhash,
9002
- lastValidBlockHeight
9003
- });
8794
+ try {
8795
+ const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
8796
+ const ix = await this.depositClient.buildWithdrawTx(amountLamports);
8797
+ const tx = new Transaction().add(cuIx, ix);
8798
+ const prepared = await this.prepareTx(tx);
8799
+ const signed = await this.signTransaction(prepared.tx);
8800
+ return this.sendAndConfirmHttp(signed, prepared);
8801
+ } catch (err) {
8802
+ throw new Error(`Failed to withdraw Solana: ${err}`);
8803
+ }
9004
8804
  }
9005
8805
  async stake(amountLamports) {
9006
8806
  this.ensureUser();
9007
8807
  if (!amountLamports || amountLamports <= BigInt(0)) {
9008
8808
  throw new Error("Stake amount must be greater than zero.");
9009
8809
  }
9010
- const user = this.solPubKey;
9011
- const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
9012
- const ix = await this.outpostClient.buildStakeIx(amountLamports, user);
9013
- const tx = new Transaction().add(cuIx, ix);
9014
- const prepared = await this.prepareTx(tx);
9015
- const signed = await this.signTransaction(prepared.tx);
9016
- return this.sendAndConfirmHttp(signed, prepared);
8810
+ try {
8811
+ const user = this.solPubKey;
8812
+ const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
8813
+ const ix = await this.outpostClient.buildStakeIx(amountLamports, user);
8814
+ const tx = new Transaction().add(cuIx, ix);
8815
+ const prepared = await this.prepareTx(tx);
8816
+ const signed = await this.signTransaction(prepared.tx);
8817
+ return this.sendAndConfirmHttp(signed, prepared);
8818
+ } catch (err) {
8819
+ throw new Error(`Failed to stake Solana: ${err}`);
8820
+ }
9017
8821
  }
9018
8822
  async unstake(amountLamports) {
9019
8823
  this.ensureUser();
9020
8824
  if (!amountLamports || amountLamports <= BigInt(0)) {
9021
8825
  throw new Error("Unstake amount must be greater than zero.");
9022
8826
  }
9023
- const user = this.solPubKey;
9024
- const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
9025
- const ix = await this.outpostClient.buildUnstakeIx(amountLamports, user);
9026
- const tx = new Transaction().add(cuIx, ix);
9027
- const prepared = await this.prepareTx(tx);
9028
- const signed = await this.signTransaction(prepared.tx);
9029
- return this.sendAndConfirmHttp(signed, prepared);
8827
+ try {
8828
+ const user = this.solPubKey;
8829
+ const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
8830
+ const ix = await this.outpostClient.buildUnstakeIx(amountLamports, user);
8831
+ const tx = new Transaction().add(cuIx, ix);
8832
+ const prepared = await this.prepareTx(tx);
8833
+ const signed = await this.signTransaction(prepared.tx);
8834
+ return this.sendAndConfirmHttp(signed, prepared);
8835
+ } catch (err) {
8836
+ throw new Error(`Failed to unstake Solana: ${err}`);
8837
+ }
9030
8838
  }
9031
8839
  async buy(amountLamports) {
9032
8840
  this.ensureUser();
9033
8841
  if (!amountLamports || amountLamports <= BigInt(0)) {
9034
8842
  throw new Error("liqSOL pretoken purchase requires a positive amount.");
9035
8843
  }
9036
- const user = this.solPubKey;
9037
- const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
9038
- const ix = await this.tokenClient.buildPurchaseIx(amountLamports, user);
9039
- const tx = new Transaction().add(cuIx, ix);
9040
- const { tx: prepared, blockhash, lastValidBlockHeight } = await this.prepareTx(tx);
9041
- const signed = await this.signTransaction(prepared);
9042
- return await this.sendAndConfirmHttp(signed, {
9043
- blockhash,
9044
- lastValidBlockHeight
9045
- });
8844
+ try {
8845
+ const user = this.solPubKey;
8846
+ const cuIx = ComputeBudgetProgram.setComputeUnitLimit({ units: 4e5 });
8847
+ const ix = await this.tokenClient.buildPurchaseIx(amountLamports, user);
8848
+ const tx = new Transaction().add(cuIx, ix);
8849
+ const prepared = await this.prepareTx(tx);
8850
+ const signed = await this.signTransaction(prepared.tx);
8851
+ return this.sendAndConfirmHttp(signed, prepared);
8852
+ } catch (err) {
8853
+ throw new Error(`Failed to buy liqSOL pretokens: ${err}`);
8854
+ }
9046
8855
  }
9047
8856
  async getPortfolio() {
9048
8857
  if (!this.pubKey) throw new Error("User pubKey is undefined");
9049
- const user = this.solPubKey;
9050
- const reservePoolPDA = deriveReservePoolPda();
9051
- const vaultPDA = deriveVaultPda();
9052
- const liqsolMint = deriveLiqsolMintPda();
9053
- const userLiqsolAta = getAssociatedTokenAddressSync(
9054
- liqsolMint,
9055
- user,
9056
- false,
9057
- TOKEN_2022_PROGRAM_ID,
9058
- ASSOCIATED_TOKEN_PROGRAM_ID
9059
- );
9060
- const [nativeLamports, actualBalResp, snapshot] = await Promise.all([
9061
- this.connection.getBalance(user, "confirmed"),
9062
- this.connection.getTokenAccountBalance(userLiqsolAta, "confirmed").catch(() => null),
9063
- this.outpostClient.fetchWireState(user).catch(() => null)
9064
- ]);
9065
- const LIQSOL_DECIMALS = 9;
9066
- const actualAmountStr = actualBalResp?.value?.amount ?? "0";
9067
- const globalState = snapshot?.globalState ?? null;
9068
- const outpostAccount = snapshot?.outpostAccount ?? null;
9069
- const trancheState = snapshot?.trancheState ?? null;
9070
- const userPretokenRecord = snapshot?.userPretokenRecord ?? null;
9071
- const stakedLiqsolStr = outpostAccount?.stakedLiqsol?.toString?.() ?? "0";
9072
- const wirePretokensStr = userPretokenRecord?.totalPretokensPurchased?.toString?.() ?? "0";
9073
- const currentIndexStr = globalState?.currentIndex?.toString?.() ?? "0";
9074
- const totalSharesStr = globalState?.totalShares?.toString?.() ?? "0";
9075
- const userSharesStr = outpostAccount?.stakedShares?.toString?.() ?? "0";
9076
- const stakedLiqsol = BigInt(stakedLiqsolStr);
9077
- const currentIndex = BigInt(currentIndexStr);
9078
- const totalShares = BigInt(totalSharesStr);
9079
- const userShares = BigInt(userSharesStr);
9080
- let estimatedClaim = BigInt(0);
9081
- let estimatedYield = BigInt(0);
9082
- if (userShares > BigInt(0) && currentIndex > BigInt(0)) {
9083
- estimatedClaim = userShares * currentIndex / INDEX_SCALE$1;
9084
- if (estimatedClaim > stakedLiqsol) {
9085
- estimatedYield = estimatedClaim - stakedLiqsol;
8858
+ try {
8859
+ const user = !!this.squadsX ? this.squadsVaultPDA : this.solPubKey;
8860
+ console.log("get portfolio for user", user.toBase58());
8861
+ const reservePoolPDA = deriveReservePoolPda();
8862
+ const vaultPDA = deriveVaultPda();
8863
+ const liqsolMint = deriveLiqsolMintPda();
8864
+ const userLiqsolAta = getAssociatedTokenAddressSync(
8865
+ liqsolMint,
8866
+ user,
8867
+ true,
8868
+ TOKEN_2022_PROGRAM_ID,
8869
+ ASSOCIATED_TOKEN_PROGRAM_ID
8870
+ );
8871
+ const [nativeLamports, actualBalResp, snapshot] = await Promise.all([
8872
+ this.connection.getBalance(user, "confirmed"),
8873
+ this.connection.getTokenAccountBalance(userLiqsolAta, "confirmed").catch(() => null),
8874
+ this.outpostClient.fetchWireState(user).catch(() => null)
8875
+ ]);
8876
+ const LIQSOL_DECIMALS = 9;
8877
+ const actualAmountStr = actualBalResp?.value?.amount ?? "0";
8878
+ const globalState = snapshot?.globalState ?? null;
8879
+ const outpostAccount = snapshot?.outpostAccount ?? null;
8880
+ const trancheState = snapshot?.trancheState ?? null;
8881
+ const userPretokenRecord = snapshot?.userPretokenRecord ?? null;
8882
+ const stakedLiqsolStr = outpostAccount?.stakedLiqsol?.toString?.() ?? "0";
8883
+ const wirePretokensStr = userPretokenRecord?.totalPretokensPurchased?.toString?.() ?? "0";
8884
+ const currentIndexStr = globalState?.currentIndex?.toString?.() ?? "0";
8885
+ const totalSharesStr = globalState?.totalShares?.toString?.() ?? "0";
8886
+ const userSharesStr = outpostAccount?.stakedShares?.toString?.() ?? "0";
8887
+ const stakedLiqsol = BigInt(stakedLiqsolStr);
8888
+ const currentIndex = BigInt(currentIndexStr);
8889
+ const totalShares = BigInt(totalSharesStr);
8890
+ const userShares = BigInt(userSharesStr);
8891
+ let estimatedClaim = BigInt(0);
8892
+ let estimatedYield = BigInt(0);
8893
+ if (userShares > BigInt(0) && currentIndex > BigInt(0)) {
8894
+ estimatedClaim = userShares * currentIndex / INDEX_SCALE$1;
8895
+ if (estimatedClaim > stakedLiqsol) {
8896
+ estimatedYield = estimatedClaim - stakedLiqsol;
8897
+ }
9086
8898
  }
8899
+ return {
8900
+ native: {
8901
+ amount: BigInt(nativeLamports),
8902
+ symbol: "SOL",
8903
+ decimals: 9
8904
+ },
8905
+ liq: {
8906
+ amount: BigInt(actualAmountStr),
8907
+ symbol: "LiqSOL",
8908
+ decimals: LIQSOL_DECIMALS,
8909
+ ata: userLiqsolAta
8910
+ },
8911
+ staked: {
8912
+ amount: stakedLiqsol,
8913
+ symbol: "LiqSOL",
8914
+ decimals: LIQSOL_DECIMALS
8915
+ },
8916
+ wire: {
8917
+ amount: BigInt(wirePretokensStr),
8918
+ symbol: "$WIRE",
8919
+ decimals: 8
8920
+ },
8921
+ yield: {
8922
+ currentIndex,
8923
+ indexScale: INDEX_SCALE$1,
8924
+ totalShares,
8925
+ userShares,
8926
+ estimatedClaim,
8927
+ estimatedYield
8928
+ },
8929
+ extras: {
8930
+ userLiqsolAta: userLiqsolAta.toBase58(),
8931
+ reservePoolPDA: reservePoolPDA.toBase58(),
8932
+ vaultPDA: vaultPDA.toBase58(),
8933
+ globalIndex: globalState?.currentIndex?.toString(),
8934
+ totalShares: globalState?.totalShares?.toString(),
8935
+ currentTrancheNumber: trancheState?.currentTrancheNumber?.toString(),
8936
+ currentTranchePriceUsd: trancheState?.currentTranchePriceUsd?.toString()
8937
+ },
8938
+ chainID: this.network.chainId
8939
+ };
8940
+ } catch (err) {
8941
+ throw new Error(`Failed to get Solana portfolio: ${err}`);
9087
8942
  }
9088
- return {
9089
- native: {
9090
- amount: BigInt(nativeLamports),
9091
- symbol: "SOL",
9092
- decimals: 9
9093
- },
9094
- liq: {
9095
- amount: BigInt(actualAmountStr),
9096
- symbol: "LiqSOL",
9097
- decimals: LIQSOL_DECIMALS,
9098
- ata: userLiqsolAta
9099
- },
9100
- staked: {
9101
- amount: stakedLiqsol,
9102
- symbol: "LiqSOL",
9103
- decimals: LIQSOL_DECIMALS
9104
- },
9105
- wire: {
9106
- amount: BigInt(wirePretokensStr),
9107
- symbol: "$WIRE",
9108
- decimals: 8
9109
- },
9110
- yield: {
9111
- currentIndex,
9112
- indexScale: INDEX_SCALE$1,
9113
- totalShares,
9114
- userShares,
9115
- estimatedClaim,
9116
- estimatedYield
9117
- },
9118
- extras: {
9119
- userLiqsolAta: userLiqsolAta.toBase58(),
9120
- reservePoolPDA: reservePoolPDA.toBase58(),
9121
- vaultPDA: vaultPDA.toBase58(),
9122
- globalIndex: globalState?.currentIndex?.toString(),
9123
- totalShares: globalState?.totalShares?.toString(),
9124
- currentTrancheNumber: trancheState?.currentTrancheNumber?.toString(),
9125
- currentTranchePriceUsd: trancheState?.currentTranchePriceUsd?.toString()
9126
- },
9127
- chainID: this.network.chainId
9128
- };
9129
8943
  }
9130
8944
  async getUserRecord() {
9131
8945
  if (!this.pubKey) throw new Error("User pubKey is undefined");
9132
8946
  return this.distributionClient.getUserRecord(this.solPubKey);
9133
8947
  }
8948
+ get squadsMultisigPDA() {
8949
+ if (!this.squadsX) return null;
8950
+ return new PublicKey(this.squadsX.multisigPDA);
8951
+ }
8952
+ get squadsVaultPDA() {
8953
+ if (!this.squadsX || !this.squadsMultisigPDA) return null;
8954
+ const multisigPda = this.squadsMultisigPDA;
8955
+ const index = this.squadsX.vaultIndex ?? 0;
8956
+ const pda = multisig.getVaultPda({ multisigPda, index });
8957
+ return pda[0];
8958
+ }
9134
8959
  async getTrancheSnapshot(options) {
9135
- const {
9136
- chainID = SolChainID.WireTestnet,
9137
- windowBefore,
9138
- windowAfter
9139
- } = options ?? {};
9140
- const [globalState, trancheState] = await Promise.all([
9141
- this.tokenClient.fetchGlobalState(),
9142
- this.tokenClient.fetchTrancheState()
9143
- ]);
9144
- const { price: solPriceUsd, timestamp } = await this.tokenClient.getSolPriceUsdSafe();
9145
- return buildSolanaTrancheSnapshot({
9146
- chainID,
9147
- globalState,
9148
- trancheState,
9149
- solPriceUsd,
9150
- nativePriceTimestamp: timestamp,
9151
- ladderWindowBefore: windowBefore,
9152
- ladderWindowAfter: windowAfter
9153
- });
8960
+ try {
8961
+ const {
8962
+ chainID = SolChainID.WireTestnet,
8963
+ windowBefore,
8964
+ windowAfter
8965
+ } = options ?? {};
8966
+ const [globalState, trancheState] = await Promise.all([
8967
+ this.tokenClient.fetchGlobalState(),
8968
+ this.tokenClient.fetchTrancheState()
8969
+ ]);
8970
+ const { price: solPriceUsd, timestamp } = await this.tokenClient.getSolPriceUsdSafe();
8971
+ return buildSolanaTrancheSnapshot({
8972
+ chainID,
8973
+ globalState,
8974
+ trancheState,
8975
+ solPriceUsd,
8976
+ nativePriceTimestamp: timestamp,
8977
+ ladderWindowBefore: windowBefore,
8978
+ ladderWindowAfter: windowAfter
8979
+ });
8980
+ } catch (err) {
8981
+ throw new Error(`Failed to build Solana tranche snapshot: ${err}`);
8982
+ }
9154
8983
  }
9155
8984
  async getSystemAPY() {
9156
- const ratePerEpoch = await this.getEpochRateDecimalFromProgram();
9157
- const epochsPerYear = await this.getEpochsPerYearFromCluster();
9158
- const apyDecimal = Math.pow(1 + ratePerEpoch, epochsPerYear) - 1;
9159
- const apyPercent = apyDecimal * 100;
9160
- return apyPercent;
8985
+ try {
8986
+ const ratePerEpoch = await this.getEpochRateDecimalFromProgram();
8987
+ const epochsPerYear = await this.getEpochsPerYearFromCluster();
8988
+ const apyDecimal = Math.pow(1 + ratePerEpoch, epochsPerYear) - 1;
8989
+ const apyPercent = apyDecimal * 100;
8990
+ return apyPercent;
8991
+ } catch (err) {
8992
+ throw new Error(`Failed to compute Solana system APY: ${err}`);
8993
+ }
9161
8994
  }
9162
8995
  async getEpochRateDecimalFromProgram() {
9163
- const liqSolCoreProgram = this.program.getProgram("liqsolCore");
9164
- const stakeMetricsPda = deriveStakeMetricsPda();
9165
- const stakeMetrics = await liqSolCoreProgram.account.stakeMetrics.fetch(stakeMetricsPda);
9166
- const raw = BigInt(stakeMetrics.solSystemPayRate.toString());
9167
- const rateDecimal = Number(raw) / Number(PAY_RATE_SCALE_FACTOR);
9168
- return rateDecimal;
8996
+ try {
8997
+ const liqSolCoreProgram = this.program.getProgram("liqsolCore");
8998
+ const stakeMetricsPda = deriveStakeMetricsPda();
8999
+ const stakeMetrics = await liqSolCoreProgram.account.stakeMetrics.fetch(stakeMetricsPda);
9000
+ const raw = BigInt(stakeMetrics.solSystemPayRate.toString());
9001
+ const rateDecimal = Number(raw) / Number(PAY_RATE_SCALE_FACTOR);
9002
+ return rateDecimal;
9003
+ } catch (err) {
9004
+ throw new Error(`Failed to read stakeMetrics from program: ${err}`);
9005
+ }
9169
9006
  }
9170
9007
  async getEpochsPerYearFromCluster() {
9171
9008
  const now = Date.now();
@@ -9225,8 +9062,7 @@ const _SolanaStakingClient = class _SolanaStakingClient {
9225
9062
  }
9226
9063
  async getDepositBuffer(options) {
9227
9064
  this.ensureUser();
9228
- const payer = this.solPubKey;
9229
- const balanceLamports = options?.balanceOverrideLamports ?? BigInt(await this.connection.getBalance(payer, commitment));
9065
+ const balanceLamports = options?.balanceOverrideLamports ?? BigInt(await this.connection.getBalance(this.feePayer, commitment));
9230
9066
  if (balanceLamports <= BigInt(0)) {
9231
9067
  return BigInt(0);
9232
9068
  }
@@ -9282,7 +9118,7 @@ const _SolanaStakingClient = class _SolanaStakingClient {
9282
9118
  if (this.cachedTxFee && now - this.cachedTxFee.fetchedAt < _SolanaStakingClient.FEE_CACHE_TTL_MS) {
9283
9119
  return this.cachedTxFee.value;
9284
9120
  }
9285
- const payer = this.solPubKey;
9121
+ const payer = this.feePayer;
9286
9122
  const dummyIx = SystemProgram.transfer({
9287
9123
  fromPubkey: payer,
9288
9124
  toPubkey: payer,
@@ -9337,17 +9173,16 @@ const _SolanaStakingClient = class _SolanaStakingClient {
9337
9173
  async prepareTx(tx) {
9338
9174
  const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash("confirmed");
9339
9175
  tx.recentBlockhash = blockhash;
9340
- tx.feePayer = this.solPubKey;
9176
+ tx.feePayer = this.feePayer;
9341
9177
  return { tx, blockhash, lastValidBlockHeight };
9342
9178
  }
9343
9179
  ensureUser() {
9344
- if (!this.pubKey || !this.anchor.wallet.publicKey) {
9345
- throw new Error("User Authorization required: pubKey is undefined");
9346
- }
9347
- if (this.solPubKey.toBase58() !== this.anchor.wallet.publicKey.toBase58()) {
9348
- throw new Error(
9349
- "Write access requires connected wallet to match pubKey"
9350
- );
9180
+ if (!this.pubKey) throw new Error("User pubKey is undefined");
9181
+ const wallet = this.anchor?.wallet;
9182
+ const pk = wallet?.publicKey;
9183
+ if (!pk) throw new Error("Wallet not connected");
9184
+ if (typeof wallet.signTransaction !== "function") {
9185
+ throw new Error("Wallet does not support signTransaction");
9351
9186
  }
9352
9187
  }
9353
9188
  };
@@ -34883,10 +34718,6 @@ const CONTRACTS = {
34883
34718
  address: ADDRESSES.ReceiptNFT,
34884
34719
  abi: ReceiptNFTArtifact.abi
34885
34720
  },
34886
- MockAggregator: {
34887
- address: ADDRESSES.MockAggregator,
34888
- abi: AggregatorArtifact.abi
34889
- },
34890
34721
  Pool: {
34891
34722
  address: ADDRESSES.Pool,
34892
34723
  abi: PoolArtifact.abi
@@ -34926,6 +34757,10 @@ const CONTRACTS = {
34926
34757
  Depositor: {
34927
34758
  address: ADDRESSES.Depositor,
34928
34759
  abi: DepositorArtifact.abi
34760
+ },
34761
+ MockAggregator: {
34762
+ address: ADDRESSES.MockAggregator,
34763
+ abi: AggregatorArtifact.abi
34929
34764
  }
34930
34765
  };
34931
34766
  class EthereumContractService {
@@ -35493,18 +35328,22 @@ class OPPClient {
35493
35328
  };
35494
35329
  }
35495
35330
  async getMessages(address) {
35496
- const oppMessageFilter = this.contract.OPP.filters.OPPMessage();
35497
- const events = await this.contract.OPP.queryFilter(oppMessageFilter, 0, "latest");
35498
- const allAssertions = [];
35499
- for (const event of events) {
35500
- const assertions = await this.extractAssertionsFromEvent(event);
35501
- allAssertions.push(...assertions);
35331
+ try {
35332
+ const oppMessageFilter = this.contract.OPP.filters.OPPMessage();
35333
+ const events = await this.contract.OPP.queryFilter(oppMessageFilter, 0, "latest");
35334
+ const allAssertions = [];
35335
+ for (const event of events) {
35336
+ const assertions = await this.extractAssertionsFromEvent(event);
35337
+ allAssertions.push(...assertions);
35338
+ }
35339
+ const normalized = address ? address.toLowerCase() : null;
35340
+ const filtered = allAssertions.filter(
35341
+ (a) => a.from && a.from.toLowerCase() === normalized || a.to && a.to.toLowerCase() === normalized
35342
+ );
35343
+ return filtered.reverse();
35344
+ } catch (error) {
35345
+ return [];
35502
35346
  }
35503
- const normalized = address ? address.toLowerCase() : null;
35504
- const filtered = allAssertions.filter(
35505
- (a) => a.from && a.from.toLowerCase() === normalized || a.to && a.to.toLowerCase() === normalized
35506
- );
35507
- return filtered.reverse();
35508
35347
  }
35509
35348
  async extractAssertionsFromEvent(event) {
35510
35349
  const header = event.args.header;
@@ -35740,7 +35579,12 @@ class ReceiptClient {
35740
35579
  return this.fetchPreLaunchReceipts(address);
35741
35580
  }
35742
35581
  async stakeReceipts(address) {
35743
- return this.fetchPreLaunchReceipts(address, ReceiptNFTKind.STAKE);
35582
+ try {
35583
+ const receipts = await this.fetchPreLaunchReceipts(address, ReceiptNFTKind.STAKE);
35584
+ return receipts;
35585
+ } catch (err) {
35586
+ return [];
35587
+ }
35744
35588
  }
35745
35589
  async pretokenReceipts(address) {
35746
35590
  return this.fetchPreLaunchReceipts(address, ReceiptNFTKind.PRETOKEN_PURCHASE);
@@ -35870,80 +35714,81 @@ class EthereumStakingClient {
35870
35714
  async buy(amount) {
35871
35715
  this.ensureUser();
35872
35716
  const buyer = await this.signer.getAddress();
35873
- const network = await this.provider.getNetwork();
35874
- const chainId = network.chainId;
35875
- const allowedTestChains = new Set([560048]);
35876
- if (allowedTestChains.has(chainId)) await this.updateMockAggregatorPrice();
35877
35717
  let result = await this.pretokenClient.purchasePretokensWithLiqETH(amount, buyer);
35878
35718
  return result && result.txHash ? result.txHash : "Error - no resulting txHash";
35879
35719
  }
35880
35720
  async getPortfolio() {
35881
- if (!this.signer) return Promise.resolve(null);
35882
- const walletAddress = await this.signer.getAddress();
35883
- const nativeBalance = await this.provider.getBalance(walletAddress);
35884
- const nativeDecimals = this.network?.nativeCurrency?.decimals ?? 18;
35885
- const nativeSymbol = this.network?.nativeCurrency?.symbol ?? "ETH";
35886
- const liqBalance = await this.contract.LiqEthToken.balanceOf(walletAddress);
35887
- const liqSymbol = "Liq" + (this.network?.nativeCurrency?.symbol ?? "ETH");
35888
- let stakeReceipts = await this.receiptClient.stakeReceipts(walletAddress);
35889
- let stakeBalanceBN = BigNumber.from(0);
35890
- for (let r of stakeReceipts) {
35891
- stakeBalanceBN = stakeBalanceBN.add(BigNumber.from(r.receipt.principal.amount));
35892
- }
35893
- let stakeSharesBN = BigNumber.from(0);
35894
- for (let r of stakeReceipts) {
35895
- stakeSharesBN = stakeSharesBN.add(BigNumber.from(r.receipt.shares.amount));
35896
- }
35897
- const wireBalance = await this.contract.Pretoken.balanceOf(walletAddress);
35898
- let currentIndex = BigInt(0);
35899
- let totalShares = BigInt(0);
35900
- let userShares = BigInt(0);
35901
- const indexScale = BigInt(1e27);
35902
35721
  try {
35903
- const [indexBn, totalSharesBn] = await Promise.all([
35904
- this.contract.Depositor.index().catch(() => BigNumber.from(0)),
35905
- this.contract.Depositor.totalShares().catch(() => BigNumber.from(0))
35906
- ]);
35907
- const userSharesBn = stakeSharesBN;
35908
- currentIndex = BigInt(indexBn.toString());
35909
- totalShares = BigInt(totalSharesBn.toString());
35910
- userShares = BigInt(userSharesBn.toString());
35911
- } catch {
35722
+ if (!this.signer) return Promise.resolve(null);
35723
+ const walletAddress = await this.signer.getAddress();
35724
+ const nativeBalance = await this.provider.getBalance(walletAddress);
35725
+ const nativeDecimals = this.network?.nativeCurrency?.decimals ?? 18;
35726
+ const nativeSymbol = this.network?.nativeCurrency?.symbol ?? "ETH";
35727
+ const liqBalance = await this.contract.LiqEthToken.balanceOf(walletAddress);
35728
+ const liqSymbol = "Liq" + (this.network?.nativeCurrency?.symbol ?? "ETH");
35729
+ let stakeReceipts = await this.receiptClient.stakeReceipts(walletAddress);
35730
+ let stakeBalanceBN = BigNumber.from(0);
35731
+ for (let r of stakeReceipts) {
35732
+ stakeBalanceBN = stakeBalanceBN.add(BigNumber.from(r.receipt.principal.amount));
35733
+ }
35734
+ let stakeSharesBN = BigNumber.from(0);
35735
+ for (let r of stakeReceipts) {
35736
+ stakeSharesBN = stakeSharesBN.add(BigNumber.from(r.receipt.shares.amount));
35737
+ }
35738
+ const wireBalance = await this.contract.Pretoken.balanceOf(walletAddress);
35739
+ let currentIndex = BigInt(0);
35740
+ let totalShares = BigInt(0);
35741
+ let userShares = BigInt(0);
35742
+ const indexScale = BigInt(1e27);
35743
+ try {
35744
+ const [indexBn, totalSharesBn] = await Promise.all([
35745
+ this.contract.Depositor.index().catch(() => BigNumber.from(0)),
35746
+ this.contract.Depositor.totalShares().catch(() => BigNumber.from(0))
35747
+ ]);
35748
+ const userSharesBn = stakeSharesBN;
35749
+ currentIndex = BigInt(indexBn.toString());
35750
+ totalShares = BigInt(totalSharesBn.toString());
35751
+ userShares = BigInt(userSharesBn.toString());
35752
+ } catch (error) {
35753
+ console.log("Error fetching staking index/shares:", error);
35754
+ }
35755
+ let estimatedClaim = BigInt(0);
35756
+ let estimatedYield = BigInt(0);
35757
+ const portfolio = {
35758
+ native: {
35759
+ amount: nativeBalance.toBigInt(),
35760
+ decimals: nativeDecimals,
35761
+ symbol: nativeSymbol
35762
+ },
35763
+ liq: {
35764
+ amount: liqBalance.toBigInt(),
35765
+ decimals: nativeDecimals,
35766
+ symbol: liqSymbol
35767
+ },
35768
+ staked: {
35769
+ amount: stakeBalanceBN.toBigInt(),
35770
+ decimals: nativeDecimals,
35771
+ symbol: liqSymbol
35772
+ },
35773
+ wire: {
35774
+ amount: wireBalance.toBigInt(),
35775
+ decimals: 18,
35776
+ symbol: "$WIRE"
35777
+ },
35778
+ yield: {
35779
+ currentIndex,
35780
+ indexScale,
35781
+ totalShares,
35782
+ userShares,
35783
+ estimatedClaim,
35784
+ estimatedYield
35785
+ },
35786
+ chainID: this.network.chainId
35787
+ };
35788
+ return portfolio;
35789
+ } catch (error) {
35790
+ throw error;
35912
35791
  }
35913
- let estimatedClaim = BigInt(0);
35914
- let estimatedYield = BigInt(0);
35915
- const portfolio = {
35916
- native: {
35917
- amount: nativeBalance.toBigInt(),
35918
- decimals: nativeDecimals,
35919
- symbol: nativeSymbol
35920
- },
35921
- liq: {
35922
- amount: liqBalance.toBigInt(),
35923
- decimals: nativeDecimals,
35924
- symbol: liqSymbol
35925
- },
35926
- staked: {
35927
- amount: stakeBalanceBN.toBigInt(),
35928
- decimals: nativeDecimals,
35929
- symbol: liqSymbol
35930
- },
35931
- wire: {
35932
- amount: wireBalance.toBigInt(),
35933
- decimals: 18,
35934
- symbol: "$WIRE"
35935
- },
35936
- yield: {
35937
- currentIndex,
35938
- indexScale,
35939
- totalShares,
35940
- userShares,
35941
- estimatedClaim,
35942
- estimatedYield
35943
- },
35944
- chainID: this.network.chainId
35945
- };
35946
- return portfolio;
35947
35792
  }
35948
35793
  async fetchPrelaunchReceipts(address) {
35949
35794
  this.ensureUser();
@@ -35987,7 +35832,7 @@ class EthereumStakingClient {
35987
35832
  }
35988
35833
  async getTrancheSnapshot(options) {
35989
35834
  const {
35990
- chainID = EvmChainID.Hoodi,
35835
+ chainID = EvmChainID.Ethereum,
35991
35836
  windowBefore,
35992
35837
  windowAfter
35993
35838
  } = options ?? {};
@@ -36008,10 +35853,8 @@ class EthereumStakingClient {
36008
35853
  ]);
36009
35854
  const totalTrancheSupply = BigInt(totalSupplyBn.toString()) / BigInt(1e10);
36010
35855
  const currentTrancheSupply = BigInt(trancheSupplyBn.toString()) / BigInt(1e10);
36011
- const [roundId, answer, startedAt, updatedAt, answeredInRound] = await this.contract.MockAggregator.latestRoundData();
36012
35856
  let ethPriceUsdBn = await this.contract.EthUsdPriceConsumer.getPrice18Decimals();
36013
35857
  let ethPriceUsd = BigInt(ethPriceUsdBn.toString()) / BigInt(1e10);
36014
- let nativePriceTimestamp = Number(updatedAt);
36015
35858
  const initialTrancheSupply = BigInt(INITIAL_TRANCHE_SUPPLY) * BigInt(1e8);
36016
35859
  return buildEthereumTrancheSnapshot({
36017
35860
  chainID,
@@ -36027,7 +35870,6 @@ class EthereumStakingClient {
36027
35870
  minPriceUsd,
36028
35871
  maxPriceUsd,
36029
35872
  ethPriceUsd,
36030
- nativePriceTimestamp,
36031
35873
  ladderWindowBefore: windowBefore,
36032
35874
  ladderWindowAfter: windowAfter
36033
35875
  });
@@ -36060,34 +35902,6 @@ class EthereumStakingClient {
36060
35902
  }
36061
35903
  return bufferWei;
36062
35904
  }
36063
- async updateMockAggregatorPrice() {
36064
- const aggregator = this.contract.MockAggregator;
36065
- const [roundId, answer, startedAt, updatedAt, answeredInRound] = await aggregator.latestRoundData();
36066
- const now = (await this.provider.getBlock("latest")).timestamp;
36067
- const ageSec = Number(now) - Number(updatedAt);
36068
- const ONE_HOUR = 1 * 3600;
36069
- if (ageSec > ONE_HOUR) {
36070
- const network = await this.provider.getNetwork();
36071
- const chainId = network.chainId;
36072
- const allowedTestChains = new Set([560048]);
36073
- if (!allowedTestChains.has(chainId)) {
36074
- console.warn(`MockAggregator is stale (${ageSec}s) but chainId ${chainId} is not a test/local network \u2014 skipping update.`);
36075
- return;
36076
- }
36077
- const res = await fetch("https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd");
36078
- const data = await res.json();
36079
- const ethUsd = data.ethereum.usd;
36080
- const currentEthPrice = ethers.utils.parseUnits(ethUsd.toString(), 8);
36081
- try {
36082
- const tx = await aggregator.updateAnswer(currentEthPrice);
36083
- const txreceipt = await tx.wait(1);
36084
- } catch (err) {
36085
- console.error("MockAggregator updateAnswer failed", err?.message || err);
36086
- }
36087
- } else {
36088
- console.log(`MockAggregator updated ${ageSec}s ago \u2014 no update needed`);
36089
- }
36090
- }
36091
35905
  }
36092
35906
 
36093
35907
  class Staker {
@@ -36098,10 +35912,8 @@ class Staker {
36098
35912
  config.forEach((cfg) => {
36099
35913
  switch (cfg.network.chainId) {
36100
35914
  case SolChainID.Devnet:
36101
- case SolChainID.WireTestnet:
36102
35915
  this.clients.set(cfg.network.chainId, new SolanaStakingClient(cfg));
36103
35916
  break;
36104
- case EvmChainID.Ethereum:
36105
35917
  case EvmChainID.Hoodi:
36106
35918
  this.clients.set(cfg.network.chainId, new EthereumStakingClient(cfg));
36107
35919
  break;
@@ -36142,7 +35954,6 @@ const CONTRACT_NAMES = [
36142
35954
  "Base58",
36143
35955
  "sysio_merkle",
36144
35956
  "ReceiptNFT",
36145
- "MockAggregator",
36146
35957
  "Pool",
36147
35958
  "OutpostManager",
36148
35959
  "sysio_write",
@@ -36152,7 +35963,8 @@ const CONTRACT_NAMES = [
36152
35963
  "OPP",
36153
35964
  "Pretoken",
36154
35965
  "OPPInbound",
36155
- "Depositor"
35966
+ "Depositor",
35967
+ "MockAggregator"
36156
35968
  ];
36157
35969
 
36158
35970
  var types$1 = /*#__PURE__*/Object.freeze({