@jpool/bond-sdk 0.5.0-next.1 → 0.5.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/dist/index.mjs CHANGED
@@ -1,46 +1,43 @@
1
- import { Program, AnchorProvider, BN } from '@coral-xyz/anchor';
2
- import { PublicKey, Transaction, LAMPORTS_PER_SOL, SYSVAR_EPOCH_SCHEDULE_PUBKEY } from '@solana/web3.js';
1
+ import { AnchorProvider, Program, BN } from '@coral-xyz/anchor';
2
+ import { PublicKey, Connection, SystemProgram, LAMPORTS_PER_SOL, SYSVAR_EPOCH_SCHEDULE_PUBKEY, Transaction } from '@solana/web3.js';
3
3
  import bs58 from 'bs58';
4
4
 
5
5
  // src/client.ts
6
+ var PROGRAM_ID = new PublicKey("8vrqsFHnDdjMYMwahytRzmmYgRqCMmka8X6DJUXGQzWr");
7
+ var DEV_PROGRAM_ID = new PublicKey("8vrqsFHnDdjMYMwahytRzmmYgRqCMmka8X6DJUXGQzWr");
6
8
 
7
- // src/constants.ts
8
- var ENV_PROGRAM_ID = {
9
- // [BondClientEnv.DEV]: new PublicKey('...'),
10
- };
9
+ // src/helpers.ts
10
+ var SLOTS_PER_EPOCH_MAINNET = 432e3;
11
+ var SLOTS_PER_EPOCH_DEVNET = 4e5;
12
+ function slotToEpoch(slot, cluster) {
13
+ const slotsPerEpoch = cluster === "mainnet-beta" ? SLOTS_PER_EPOCH_MAINNET : SLOTS_PER_EPOCH_DEVNET;
14
+ return Math.floor(slot / slotsPerEpoch);
15
+ }
11
16
 
12
17
  // src/idl/jbond.json
13
18
  var jbond_default = {
14
- address: "BondQ7KqZreTcW2UbeTNDcLCJQ3aXAtLn2Fm6ftaJDU",
19
+ address: "8vrqsFHnDdjMYMwahytRzmmYgRqCMmka8X6DJUXGQzWr",
15
20
  metadata: {
16
21
  name: "jbond",
17
- version: "0.2.0",
22
+ version: "0.1.0",
18
23
  spec: "0.1.0",
19
- description: "Jpool Bond Program"
24
+ description: "Validator compensation program for boosting APR"
20
25
  },
21
26
  instructions: [
22
27
  {
23
- name: "claim",
28
+ name: "bond_init",
24
29
  docs: [
25
- "Claims compensation for a validator.",
26
- "Transfers funds from the validator's bond account to reserve.",
27
- "",
28
- "# Arguments",
29
- "* `amount` - Amount of compensation to claim (must be positive).",
30
- "",
31
- "# Errors",
32
- "Fails if the authority is invalid, if the validator is not active,",
33
- "if the amount is zero, or if there are insufficient funds."
30
+ "Register validator and fund initial collateral"
34
31
  ],
35
32
  discriminator: [
36
- 62,
37
- 198,
38
- 214,
39
- 193,
40
- 213,
41
- 159,
33
+ 220,
42
34
  108,
43
- 210
35
+ 156,
36
+ 81,
37
+ 16,
38
+ 185,
39
+ 144,
40
+ 157
44
41
  ],
45
42
  accounts: [
46
43
  {
@@ -69,7 +66,7 @@ var jbond_default = {
69
66
  }
70
67
  },
71
68
  {
72
- name: "validator_bond",
69
+ name: "validator_bond_account",
73
70
  writable: true,
74
71
  pda: {
75
72
  seeds: [
@@ -94,21 +91,23 @@ var jbond_default = {
94
91
  },
95
92
  {
96
93
  kind: "account",
97
- path: "validator_bond.vote_account",
98
- account: "ValidatorBond"
94
+ path: "vote_account"
99
95
  }
100
96
  ]
101
97
  }
102
98
  },
103
99
  {
104
- name: "reserve",
105
- writable: true
100
+ name: "identity"
106
101
  },
107
102
  {
108
- name: "authority",
103
+ name: "vote_account"
104
+ },
105
+ {
106
+ name: "creator",
109
107
  docs: [
110
- "Authority that can trigger claims"
108
+ "The account creating the bond (pays for account creation and initial collateral)"
111
109
  ],
110
+ writable: true,
112
111
  signer: true
113
112
  },
114
113
  {
@@ -118,124 +117,97 @@ var jbond_default = {
118
117
  ],
119
118
  args: [
120
119
  {
121
- name: "amount",
120
+ name: "initial_collateral",
122
121
  type: "u64"
122
+ },
123
+ {
124
+ name: "withdrawal_authority",
125
+ type: {
126
+ option: "pubkey"
127
+ }
123
128
  }
124
129
  ]
125
130
  },
126
131
  {
127
- name: "initialize",
132
+ name: "bond_top_up",
128
133
  docs: [
129
- "Initializes the global state for the bonding program.",
130
- "Sets the authority and reserve account for managing validator bonds.",
131
- "",
132
- "# Errors",
133
- "Fails if the global state account is already initialized or if the payer lacks",
134
- "sufficient funds."
134
+ "Top up collateral for existing validator"
135
135
  ],
136
136
  discriminator: [
137
- 175,
138
- 175,
139
- 109,
140
- 31,
141
- 13,
137
+ 132,
138
+ 225,
139
+ 254,
140
+ 187,
142
141
  152,
143
- 155,
144
- 237
142
+ 162,
143
+ 176,
144
+ 66
145
145
  ],
146
146
  accounts: [
147
147
  {
148
- name: "global_state",
148
+ name: "validator_bond_account",
149
149
  writable: true,
150
150
  pda: {
151
151
  seeds: [
152
152
  {
153
153
  kind: "const",
154
154
  value: [
155
- 103,
156
- 108,
157
- 111,
158
- 98,
155
+ 118,
159
156
  97,
160
157
  108,
161
- 95,
162
- 115,
163
- 116,
158
+ 105,
159
+ 100,
164
160
  97,
165
161
  116,
166
- 101
162
+ 111,
163
+ 114,
164
+ 95,
165
+ 98,
166
+ 111,
167
+ 110,
168
+ 100
167
169
  ]
170
+ },
171
+ {
172
+ kind: "account",
173
+ path: "validator_bond_account.vote_account",
174
+ account: "ValidatorBondAccount"
168
175
  }
169
176
  ]
170
177
  }
171
178
  },
172
179
  {
173
- name: "authority",
180
+ name: "depositor",
174
181
  writable: true,
175
182
  signer: true
176
183
  },
177
- {
178
- name: "reserve"
179
- },
180
184
  {
181
185
  name: "system_program",
182
186
  address: "11111111111111111111111111111111"
183
187
  }
184
188
  ],
185
- args: []
189
+ args: [
190
+ {
191
+ name: "amount",
192
+ type: "u64"
193
+ }
194
+ ]
186
195
  },
187
196
  {
188
- name: "register",
189
- docs: [
190
- "Registers a new validator with the bonding program.",
191
- "Sets up the validator's bond account and deposits initial collateral.",
192
- "",
193
- "# Arguments",
194
- "* `initial_collateral` - Amount of collateral to lock (must be positive).",
195
- "* `withdrawal_authority` - Optional key that can withdraw collateral later.",
196
- "",
197
- "# Errors",
198
- "Fails if the validator is already registered, if the vote account is invalid,",
199
- "or if the initial collateral transfer fails."
200
- ],
197
+ name: "bond_withdraw",
201
198
  discriminator: [
202
- 211,
203
- 124,
204
- 67,
205
- 15,
206
- 211,
207
- 194,
199
+ 99,
200
+ 64,
201
+ 127,
208
202
  178,
209
- 240
203
+ 53,
204
+ 117,
205
+ 70,
206
+ 204
210
207
  ],
211
208
  accounts: [
212
209
  {
213
- name: "global_state",
214
- writable: true,
215
- pda: {
216
- seeds: [
217
- {
218
- kind: "const",
219
- value: [
220
- 103,
221
- 108,
222
- 111,
223
- 98,
224
- 97,
225
- 108,
226
- 95,
227
- 115,
228
- 116,
229
- 97,
230
- 116,
231
- 101
232
- ]
233
- }
234
- ]
235
- }
236
- },
237
- {
238
- name: "validator_bond",
210
+ name: "validator_bond_account",
239
211
  writable: true,
240
212
  pda: {
241
213
  seeds: [
@@ -260,24 +232,24 @@ var jbond_default = {
260
232
  },
261
233
  {
262
234
  kind: "account",
263
- path: "vote_account"
235
+ path: "validator_bond_account.vote_account",
236
+ account: "ValidatorBondAccount"
264
237
  }
265
238
  ]
266
239
  }
267
240
  },
268
241
  {
269
- name: "identity"
242
+ name: "withdrawal_authority",
243
+ writable: true,
244
+ signer: true
270
245
  },
271
246
  {
272
- name: "vote_account"
247
+ name: "destination",
248
+ writable: true
273
249
  },
274
250
  {
275
- name: "creator",
276
- docs: [
277
- "The account creating the bond (pays for account creation and initial collateral)"
278
- ],
279
- writable: true,
280
- signer: true
251
+ name: "epoch_schedule",
252
+ address: "SysvarEpochSchedu1e111111111111111111111111"
281
253
  },
282
254
  {
283
255
  name: "system_program",
@@ -286,28 +258,71 @@ var jbond_default = {
286
258
  ],
287
259
  args: [
288
260
  {
289
- name: "initial_collateral",
261
+ name: "amount",
290
262
  type: "u64"
291
- },
263
+ }
264
+ ]
265
+ },
266
+ {
267
+ name: "initialize",
268
+ docs: [
269
+ "Initialize the global state and reserve vault"
270
+ ],
271
+ discriminator: [
272
+ 175,
273
+ 175,
274
+ 109,
275
+ 31,
276
+ 13,
277
+ 152,
278
+ 155,
279
+ 237
280
+ ],
281
+ accounts: [
292
282
  {
293
- name: "withdrawal_authority",
294
- type: {
295
- option: "pubkey"
283
+ name: "global_state",
284
+ writable: true,
285
+ pda: {
286
+ seeds: [
287
+ {
288
+ kind: "const",
289
+ value: [
290
+ 103,
291
+ 108,
292
+ 111,
293
+ 98,
294
+ 97,
295
+ 108,
296
+ 95,
297
+ 115,
298
+ 116,
299
+ 97,
300
+ 116,
301
+ 101
302
+ ]
303
+ }
304
+ ]
296
305
  }
306
+ },
307
+ {
308
+ name: "authority",
309
+ writable: true,
310
+ signer: true
311
+ },
312
+ {
313
+ name: "reserve"
314
+ },
315
+ {
316
+ name: "system_program",
317
+ address: "11111111111111111111111111111111"
297
318
  }
298
- ]
319
+ ],
320
+ args: []
299
321
  },
300
322
  {
301
323
  name: "set_authority",
302
324
  docs: [
303
- "Sets a new withdrawal authority for a validator's bond account.",
304
- "Allows changing who can withdraw collateral in the future.",
305
- "",
306
- "# Arguments",
307
- "* `new_authority` - Optional new authority key (None to restrict to identity).",
308
- "",
309
- "# Errors",
310
- "Fails if the signer is not authorized to change the authority."
325
+ "Change the bond authority"
311
326
  ],
312
327
  discriminator: [
313
328
  133,
@@ -359,105 +374,48 @@ var jbond_default = {
359
374
  args: []
360
375
  },
361
376
  {
362
- name: "top_up",
377
+ name: "withdraw_compensation",
363
378
  docs: [
364
- "Adds additional collateral to an existing validator's bond.",
365
- "Increases the collateral balance, enhancing the validator's stake.",
366
- "",
367
- "# Arguments",
368
- "* `amount` - Amount to add.",
369
- "",
370
- "# Errors",
371
- "Fails if the validator is not active, if the amount is zero,",
372
- "or if the transfer of funds fails."
379
+ "Withdraw compensation from validator to reserve (oracle only)"
373
380
  ],
374
381
  discriminator: [
375
- 236,
376
- 225,
377
- 96,
378
- 9,
379
- 60,
380
- 106,
381
- 77,
382
- 208
382
+ 10,
383
+ 228,
384
+ 22,
385
+ 213,
386
+ 205,
387
+ 117,
388
+ 181,
389
+ 75
383
390
  ],
384
391
  accounts: [
385
392
  {
386
- name: "validator_bond",
393
+ name: "global_state",
387
394
  writable: true,
388
395
  pda: {
389
396
  seeds: [
390
397
  {
391
398
  kind: "const",
392
399
  value: [
393
- 118,
400
+ 103,
401
+ 108,
402
+ 111,
403
+ 98,
394
404
  97,
395
405
  108,
396
- 105,
397
- 100,
406
+ 95,
407
+ 115,
408
+ 116,
398
409
  97,
399
410
  116,
400
- 111,
401
- 114,
402
- 95,
403
- 98,
404
- 111,
405
- 110,
406
- 100
411
+ 101
407
412
  ]
408
- },
409
- {
410
- kind: "account",
411
- path: "validator_bond.vote_account",
412
- account: "ValidatorBond"
413
413
  }
414
414
  ]
415
415
  }
416
416
  },
417
417
  {
418
- name: "payer",
419
- writable: true,
420
- signer: true
421
- },
422
- {
423
- name: "system_program",
424
- address: "11111111111111111111111111111111"
425
- }
426
- ],
427
- args: [
428
- {
429
- name: "amount",
430
- type: "u64"
431
- }
432
- ]
433
- },
434
- {
435
- name: "withdraw",
436
- docs: [
437
- "Withdraws collateral from a validator's bond.",
438
- "Decreases the collateral balance, allowing the validator to reclaim funds.",
439
- "",
440
- "# Arguments",
441
- "* `amount` - Amount to withdraw (must not exceed available balance).",
442
- "",
443
- "# Errors",
444
- "Fails if the validator is not active, if the amount is zero,",
445
- "if the withdrawal authority is invalid, or if the withdrawal would",
446
- "leave insufficient collateral."
447
- ],
448
- discriminator: [
449
- 183,
450
- 18,
451
- 70,
452
- 156,
453
- 148,
454
- 109,
455
- 161,
456
- 34
457
- ],
458
- accounts: [
459
- {
460
- name: "validator_bond",
418
+ name: "validator_bond_account",
461
419
  writable: true,
462
420
  pda: {
463
421
  seeds: [
@@ -482,24 +440,22 @@ var jbond_default = {
482
440
  },
483
441
  {
484
442
  kind: "account",
485
- path: "validator_bond.vote_account",
486
- account: "ValidatorBond"
443
+ path: "validator_bond_account.vote_account",
444
+ account: "ValidatorBondAccount"
487
445
  }
488
446
  ]
489
447
  }
490
448
  },
491
449
  {
492
- name: "withdrawal_authority",
493
- writable: true,
494
- signer: true
495
- },
496
- {
497
- name: "destination",
450
+ name: "reserve",
498
451
  writable: true
499
452
  },
500
453
  {
501
- name: "epoch_schedule",
502
- address: "SysvarEpochSchedu1e111111111111111111111111"
454
+ name: "authority",
455
+ docs: [
456
+ "Authority that can trigger claims"
457
+ ],
458
+ signer: true
503
459
  },
504
460
  {
505
461
  name: "system_program",
@@ -529,16 +485,16 @@ var jbond_default = {
529
485
  ]
530
486
  },
531
487
  {
532
- name: "ValidatorBond",
488
+ name: "ValidatorBondAccount",
533
489
  discriminator: [
534
- 82,
535
- 127,
536
- 243,
537
- 208,
538
- 195,
539
- 42,
540
- 80,
541
- 35
490
+ 25,
491
+ 67,
492
+ 241,
493
+ 227,
494
+ 226,
495
+ 104,
496
+ 108,
497
+ 73
542
498
  ]
543
499
  }
544
500
  ],
@@ -663,7 +619,7 @@ var jbond_default = {
663
619
  type: "u64"
664
620
  },
665
621
  {
666
- name: "post_balance",
622
+ name: "new_total",
667
623
  type: "u64"
668
624
  },
669
625
  {
@@ -687,7 +643,7 @@ var jbond_default = {
687
643
  type: "u64"
688
644
  },
689
645
  {
690
- name: "post_balance",
646
+ name: "remaining_collateral",
691
647
  type: "u64"
692
648
  },
693
649
  {
@@ -711,7 +667,11 @@ var jbond_default = {
711
667
  type: "u64"
712
668
  },
713
669
  {
714
- name: "post_balance",
670
+ name: "remaining_collateral",
671
+ type: "u64"
672
+ },
673
+ {
674
+ name: "total_withdrawn",
715
675
  type: "u64"
716
676
  },
717
677
  {
@@ -732,117 +692,68 @@ var jbond_default = {
732
692
  fields: [
733
693
  {
734
694
  name: "authority",
735
- docs: [
736
- "The authority allowed to manage the program"
737
- ],
738
695
  type: "pubkey"
739
696
  },
740
697
  {
741
698
  name: "reserve",
742
- docs: [
743
- "The reserve vault holding SOL for bonding and compensation"
744
- ],
745
699
  type: "pubkey"
746
700
  },
747
701
  {
748
702
  name: "total_validators",
749
- docs: [
750
- "Total number of registered validators"
751
- ],
752
- type: "u16"
703
+ type: "u32"
753
704
  },
754
705
  {
755
- name: "total_compensation_amount",
756
- docs: [
757
- "Total compensation amount paid out"
758
- ],
706
+ name: "total_withdrawn",
759
707
  type: "u64"
760
708
  },
761
709
  {
762
710
  name: "bump",
763
- docs: [
764
- "Bump for the PDA"
765
- ],
766
711
  type: "u8"
767
712
  }
768
713
  ]
769
714
  }
770
715
  },
771
716
  {
772
- name: "ValidatorBond",
717
+ name: "ValidatorBondAccount",
773
718
  type: {
774
719
  kind: "struct",
775
720
  fields: [
776
721
  {
777
722
  name: "identity",
778
- docs: [
779
- "The validator identity pubkey"
780
- ],
781
723
  type: "pubkey"
782
724
  },
783
725
  {
784
726
  name: "vote_account",
785
- docs: [
786
- "The validator vote account pubkey"
787
- ],
788
727
  type: "pubkey"
789
728
  },
790
729
  {
791
730
  name: "creator",
792
- docs: [
793
- "Creator of the validator bond account"
794
- ],
795
731
  type: "pubkey"
796
732
  },
797
733
  {
798
734
  name: "withdrawal_authority",
799
- docs: [
800
- "Authority allowed to withdraw funds (if None, only identity can withdraw)"
801
- ],
802
735
  type: {
803
736
  option: "pubkey"
804
737
  }
805
738
  },
806
739
  {
807
- name: "total_compensation_amount",
808
- docs: [
809
- "Total compensation claimed for the validator"
810
- ],
740
+ name: "total_withdrawn",
811
741
  type: "u64"
812
742
  },
813
743
  {
814
- name: "last_compensation_amount",
815
- docs: [
816
- "Last compensation amount claimed"
817
- ],
744
+ name: "last_withdrawal_epoch",
818
745
  type: "u64"
819
746
  },
820
747
  {
821
- name: "last_compensation_epoch",
822
- docs: [
823
- "Last epoch when compensation was claimed"
824
- ],
825
- type: "u64"
748
+ name: "is_active",
749
+ type: "bool"
826
750
  },
827
751
  {
828
752
  name: "created_at",
829
- docs: [
830
- "Timestamp when the bond account was created"
831
- ],
832
753
  type: "i64"
833
754
  },
834
- {
835
- name: "is_active",
836
- docs: [
837
- "Whether the validator is currently active"
838
- ],
839
- type: "bool"
840
- },
841
755
  {
842
756
  name: "bump",
843
- docs: [
844
- "Bump for the PDA"
845
- ],
846
757
  type: "u8"
847
758
  }
848
759
  ]
@@ -854,7 +765,7 @@ var jbond_default = {
854
765
  kind: "struct",
855
766
  fields: [
856
767
  {
857
- name: "identity",
768
+ name: "validator",
858
769
  type: "pubkey"
859
770
  },
860
771
  {
@@ -862,7 +773,7 @@ var jbond_default = {
862
773
  type: "pubkey"
863
774
  },
864
775
  {
865
- name: "initial_collateral",
776
+ name: "collateral_amount",
866
777
  type: "u64"
867
778
  },
868
779
  {
@@ -914,65 +825,54 @@ var NodeWallet = class {
914
825
  }
915
826
  };
916
827
 
917
- // src/utils/index.ts
918
- var SLOTS_PER_EPOCH_MAINNET = 432e3;
919
- var SLOTS_PER_EPOCH_DEVNET = 4e5;
920
- function slotToEpoch(slot, cluster) {
921
- const slotsPerEpoch = cluster === "mainnet-beta" ? SLOTS_PER_EPOCH_MAINNET : SLOTS_PER_EPOCH_DEVNET;
922
- return Math.floor(slot / slotsPerEpoch);
923
- }
924
-
925
828
  // src/client.ts
926
829
  var BondClientEnv = /* @__PURE__ */ ((BondClientEnv2) => {
927
830
  BondClientEnv2["DEV"] = "dev";
928
- BondClientEnv2["STAGE"] = "stage";
929
831
  BondClientEnv2["PROD"] = "prod";
930
832
  return BondClientEnv2;
931
833
  })(BondClientEnv || {});
932
834
  var JBondClient = class _JBondClient {
933
- constructor(provider, options) {
934
- this.provider = provider;
935
- this.options = options ?? {};
835
+ connection;
836
+ program;
837
+ provider;
838
+ options;
839
+ constructor(options, wallet) {
840
+ this.connection = new Connection(options.rpcUrl, "confirmed");
841
+ this.options = options;
842
+ this.provider = new AnchorProvider(
843
+ this.connection,
844
+ // @ts-expect-error support anonymous
845
+ wallet ?? { publicKey: PublicKey.default },
846
+ AnchorProvider.defaultOptions()
847
+ );
936
848
  this.program = new Program(jbond_default, this.provider);
937
849
  }
938
- options;
939
- program;
940
850
  /**
941
851
  * Creates an instance of `JBondClient` using a provided connection and wallet.
942
852
  */
943
- static fromWallet(connection, wallet, options) {
944
- return new this(
945
- new AnchorProvider(
946
- connection,
947
- wallet ?? { publicKey: PublicKey.default },
948
- AnchorProvider.defaultOptions()
949
- ),
950
- options
951
- );
853
+ static fromWallet(options, wallet) {
854
+ return new this(options, wallet);
952
855
  }
953
856
  /**
954
857
  * Creates an instance of `JBondClient` using the provided connection and keypair.
955
858
  */
956
- static fromKeypair(connection, keypair, options) {
957
- return _JBondClient.fromWallet(connection, new NodeWallet(keypair), options);
859
+ static fromKeypair(options, keypair) {
860
+ return _JBondClient.fromWallet(options, new NodeWallet(keypair));
958
861
  }
959
862
  /**
960
863
  * Get the current program ID.
961
864
  */
962
865
  get programId() {
963
- return this.options.programId ?? this.program.programId;
964
- }
965
- /**
966
- * Get the current connection.
967
- */
968
- get connection() {
969
- return this.provider.connection;
866
+ return this.options.programId ?? PROGRAM_ID;
970
867
  }
971
868
  /**
972
869
  * Set the environment.
973
870
  */
974
871
  env(env) {
975
- return this.configure("programId", ENV_PROGRAM_ID[env]);
872
+ if (env === "prod" /* PROD */) {
873
+ return this.configure("programId", PROGRAM_ID);
874
+ }
875
+ return this.configure("programId", DEV_PROGRAM_ID);
976
876
  }
977
877
  /**
978
878
  * Configure a specific option.
@@ -981,215 +881,235 @@ var JBondClient = class _JBondClient {
981
881
  this.options[key] = val;
982
882
  return this;
983
883
  }
984
- /**
985
- * Program Derived Addresses (PDAs)
986
- */
987
- pda = {
988
- globalState: () => {
989
- return PublicKey.findProgramAddressSync(
990
- [Buffer.from("global_state")],
991
- this.programId
992
- );
993
- },
994
- validatorBond: (vote) => {
995
- return PublicKey.findProgramAddressSync(
996
- [
997
- Buffer.from("validator_bond"),
998
- new PublicKey(vote).toBuffer()
999
- ],
1000
- this.programId
1001
- );
1002
- }
1003
- };
1004
- /**
1005
- * Initialize the program
1006
- * Default authority is the provider's wallet
1007
- */
1008
- async initialize(props) {
1009
- const ix = await this.buildInitializeInstruction(props);
1010
- return await this.provider.sendAndConfirm(new Transaction().add(ix));
1011
- }
1012
- /**
1013
- * Register a new validator
1014
- * Default creator is the provider's wallet
1015
- */
1016
- async registerValidator(props) {
1017
- const ix = await this.buildRegisterValidatorInstruction(props);
1018
- return await this.provider.sendAndConfirm(new Transaction().add(ix));
1019
- }
1020
- /**
1021
- * Top up collateral
1022
- * Default payer is the provider's wallet
1023
- */
1024
- async topUpCollateral(props) {
1025
- const ix = await this.buildTopUpCollateralInstruction(props);
1026
- return await this.provider.sendAndConfirm(new Transaction().add(ix));
1027
- }
1028
- /**
1029
- * Withdraw collateral
1030
- * Default withdrawal authority is the provider's wallet
1031
- * Default destination is the provider's wallet
1032
- * @return Transaction signature
1033
- */
1034
- async withdrawCollateral(props) {
1035
- const ix = await this.buildWithdrawCollateralInstruction(props);
1036
- return await this.provider.sendAndConfirm(new Transaction().add(ix));
1037
- }
1038
- /**
1039
- * Claim compensation
1040
- * Default authority is the provider's wallet
1041
- * @return Transaction signature
1042
- */
1043
- async claimCompensation(props) {
1044
- const ix = await this.buildClaimInstruction(props);
1045
- return await this.provider.sendAndConfirm(new Transaction().add(ix));
884
+ // Get PDA for global state
885
+ getGlobalStatePDA() {
886
+ return PublicKey.findProgramAddressSync(
887
+ [Buffer.from("global_state")],
888
+ this.options.programId ?? this.program.programId
889
+ );
1046
890
  }
1047
- /**
1048
- * Set a new authority for the program
1049
- * Default authority is the provider's wallet
1050
- * @return Transaction signature
1051
- */
1052
- async setAuthority(props) {
1053
- const ix = await this.buildSetAuthorityInstruction(props);
1054
- return await this.provider.sendAndConfirm(new Transaction().add(ix));
891
+ // Get PDA for validator bond account
892
+ getValidatorBondPDA(voteAccount) {
893
+ return PublicKey.findProgramAddressSync(
894
+ [
895
+ Buffer.from("validator_bond"),
896
+ voteAccount.toBuffer()
897
+ ],
898
+ this.options.programId ?? this.program.programId
899
+ );
1055
900
  }
1056
- /**
1057
- * Build initialize instruction
1058
- */
901
+ // Build initialize instruction
1059
902
  async buildInitializeInstruction(props) {
1060
- const [globalState] = this.pda.globalState();
1061
- const { reserve } = props;
1062
- const authority = props.authority ?? this.provider.wallet.publicKey;
1063
- return this.program.methods.initialize().accountsPartial({
903
+ const [globalState] = this.getGlobalStatePDA();
904
+ const { authority, reserveAddress } = props;
905
+ return this.program.methods.initialize().accountsStrict({
1064
906
  globalState,
1065
907
  authority,
1066
- reserve
908
+ reserve: reserveAddress,
909
+ systemProgram: SystemProgram.programId
1067
910
  }).instruction();
1068
911
  }
1069
- /**
1070
- * Build register validator instruction
1071
- */
912
+ // Build register validator instruction
1072
913
  async buildRegisterValidatorInstruction(props) {
1073
- const { identity, voteAccount, initialCollateral, withdrawalAuthority } = props;
1074
- const [globalState] = this.pda.globalState();
1075
- const [validatorBond] = this.pda.validatorBond(voteAccount);
1076
- const lamports = new BN(initialCollateral * LAMPORTS_PER_SOL);
1077
- const creator = props.creator ?? this.provider.wallet.publicKey;
1078
- return this.program.methods.register(lamports, withdrawalAuthority ?? null).accountsPartial({
914
+ const { creator, identity, voteAccount, initialCollateral, withdrawalAuthority } = props;
915
+ const [validatorBondAccountAddress] = this.getValidatorBondPDA(voteAccount);
916
+ const accountInfo = await this.connection.getAccountInfo(validatorBondAccountAddress);
917
+ if (accountInfo) {
918
+ throw new Error("Validator bond account already exists");
919
+ }
920
+ const [globalState] = this.getGlobalStatePDA();
921
+ const collateralLamports = new BN(initialCollateral * LAMPORTS_PER_SOL);
922
+ return this.program.methods.bondInit(collateralLamports, withdrawalAuthority ?? null).accountsStrict({
1079
923
  creator,
1080
924
  globalState,
1081
- validatorBond,
925
+ validatorBondAccount: validatorBondAccountAddress,
1082
926
  identity,
1083
- voteAccount
927
+ voteAccount,
928
+ systemProgram: SystemProgram.programId
1084
929
  }).instruction();
1085
930
  }
1086
- /**
1087
- * Build top up collateral instruction
1088
- */
1089
- async buildTopUpCollateralInstruction(props) {
1090
- const { voteAccount, amount } = props;
1091
- const [validatorBond] = this.pda.validatorBond(voteAccount);
1092
- const lamports = new BN(amount * LAMPORTS_PER_SOL);
1093
- const payer = props.payer ?? this.provider.wallet.publicKey;
1094
- return this.program.methods.topUp(lamports).accountsPartial({
1095
- validatorBond,
1096
- payer
931
+ // Build top up collateral instruction
932
+ buildTopUpCollateralInstruction(props) {
933
+ const { user, voteAccount, amount } = props;
934
+ const [validatorBondAccountAddress] = this.getValidatorBondPDA(voteAccount);
935
+ const amountLamports = new BN(amount * LAMPORTS_PER_SOL);
936
+ return this.program.methods.bondTopUp(amountLamports).accountsStrict({
937
+ validatorBondAccount: validatorBondAccountAddress,
938
+ depositor: user,
939
+ systemProgram: SystemProgram.programId
1097
940
  }).instruction();
1098
941
  }
1099
- /**
1100
- * Build withdraw collateral instruction
1101
- */
1102
942
  async buildWithdrawCollateralInstruction(props) {
1103
- const { voteAccount, amount } = props;
1104
- const [validatorBond] = this.pda.validatorBond(voteAccount);
1105
- const lamports = new BN(amount * LAMPORTS_PER_SOL);
1106
- const withdrawalAuthority = props.withdrawalAuthority ?? this.provider.wallet.publicKey;
1107
- const destination = props.destination ?? this.provider.wallet.publicKey;
1108
- return this.program.methods.withdraw(lamports).accountsPartial({
1109
- validatorBond,
1110
- withdrawalAuthority,
943
+ const { withdrawalAuthority: user, voteAccount, destination, amount } = props;
944
+ const [validatorBondAccountAddress] = this.getValidatorBondPDA(voteAccount);
945
+ const amountLamports = new BN(amount * LAMPORTS_PER_SOL);
946
+ return this.program.methods.bondWithdraw(amountLamports).accountsStrict({
947
+ validatorBondAccount: validatorBondAccountAddress,
948
+ withdrawalAuthority: user,
949
+ destination,
1111
950
  epochSchedule: SYSVAR_EPOCH_SCHEDULE_PUBKEY,
1112
- destination
951
+ systemProgram: SystemProgram.programId
1113
952
  }).instruction();
1114
953
  }
1115
- /**
1116
- * Build claim compensation instruction
1117
- */
1118
- async buildClaimInstruction(props) {
1119
- const [globalState] = this.pda.globalState();
1120
- const [validatorBond] = this.pda.validatorBond(props.voteAccount);
1121
- const lamports = new BN(props.amount * LAMPORTS_PER_SOL);
1122
- const authority = props.authority ?? this.provider.wallet.publicKey;
1123
- let reserve = props.reserve;
1124
- if (!reserve) {
1125
- const globalStateData = await this.getGlobalState();
1126
- reserve = globalStateData.reserve;
1127
- if (!reserve) {
1128
- throw new Error("Reserve address is not set in the global state. The program might not be initialized yet.");
1129
- }
954
+ // Build withdraw compensation instruction
955
+ async buildWithdrawCompensationInstruction(props) {
956
+ const { authority, voteAccount, amount } = props;
957
+ const [globalState] = this.getGlobalStatePDA();
958
+ const [validatorBondAccountAddress] = this.getValidatorBondPDA(voteAccount);
959
+ const amountLamports = new BN(amount * LAMPORTS_PER_SOL);
960
+ const reserveAddress = (await this.getGlobalState())?.reserveAddress;
961
+ if (!reserveAddress) {
962
+ throw new Error("Reserve address is not set in the global state. The program might not be initialized yet.");
1130
963
  }
1131
- return this.program.methods.claim(lamports).accountsPartial({
964
+ return this.program.methods.withdrawCompensation(amountLamports).accountsStrict({
1132
965
  globalState,
1133
- validatorBond,
1134
- reserve,
1135
- authority
966
+ validatorBondAccount: validatorBondAccountAddress,
967
+ reserve: reserveAddress,
968
+ authority,
969
+ systemProgram: SystemProgram.programId
1136
970
  }).instruction();
1137
971
  }
1138
- /**
1139
- * Build set authority instruction
1140
- */
972
+ // Build multiple withdraw compensation instructions
973
+ buildWithdrawCompensationsInstructions(authority, withdrawals) {
974
+ return Promise.all(
975
+ withdrawals.map(
976
+ ({ voteAccount, amount }) => this.buildWithdrawCompensationInstruction({ authority, voteAccount, amount })
977
+ )
978
+ );
979
+ }
980
+ // Get validator bond account state
981
+ async getValidatorBondAccount(voteAccount) {
982
+ const [validatorBondAccountAddress] = this.getValidatorBondPDA(voteAccount);
983
+ try {
984
+ const account = await this.program.account.validatorBondAccount.fetch(validatorBondAccountAddress);
985
+ return {
986
+ identity: account.identity.toString(),
987
+ voteAccount: account.voteAccount.toString(),
988
+ withdrawalAuthority: account.withdrawalAuthority ? account.withdrawalAuthority.toString() : null,
989
+ totalWithdrawn: account.totalWithdrawn.toNumber() / LAMPORTS_PER_SOL,
990
+ lastWithdrawalEpoch: account.lastWithdrawalEpoch.toNumber(),
991
+ isActive: account.isActive,
992
+ createdAt: account.createdAt.toNumber() * 1e3,
993
+ // TODO
994
+ bump: account.bump
995
+ };
996
+ } catch {
997
+ return null;
998
+ }
999
+ }
1000
+ // Build set authority instruction
1141
1001
  async buildSetAuthorityInstruction(props) {
1142
- const [globalState] = this.pda.globalState();
1143
- const authority = props.authority ?? this.provider.wallet.publicKey;
1002
+ const [globalState] = this.getGlobalStatePDA();
1144
1003
  return this.program.methods.setAuthority().accountsStrict({
1145
1004
  globalState,
1146
- authority,
1005
+ authority: props.authority,
1147
1006
  newAuthority: props.newAuthority
1148
1007
  }).instruction();
1149
1008
  }
1150
1009
  /**
1151
- * Fetch global state or throw if not found
1010
+ * Get the collateral balance of a validator bond account
1011
+ * @param voteAccount - The vote account public key
1012
+ * @returns The available collateral balance in SOL (excluding rent-exempt amount)
1152
1013
  */
1153
- async getGlobalState() {
1154
- const [globalState] = this.pda.globalState();
1155
- return await this.program.account.globalState.fetch(globalState);
1156
- }
1157
- /**
1158
- * Fetch validator bond data or null if not found
1159
- * @param vote
1160
- */
1161
- async getValidatorBond(vote) {
1162
- const [address] = this.pda.validatorBond(new PublicKey(vote));
1163
- return await this.program.account.validatorBond.fetchNullable(address);
1164
- }
1165
- /**
1166
- * Get validator bond account balance (in SOL)
1167
- * @param vote - Vote account public key
1168
- * @return Balance in SOL
1169
- */
1170
- async getValidatorBondBalance(vote) {
1171
- const [address] = this.pda.validatorBond(new PublicKey(vote));
1172
- const accountInfo = await this.connection.getAccountInfo(address);
1014
+ async getValidatorCollateralBalance(voteAccount) {
1015
+ const [validatorBondAccountAddress] = this.getValidatorBondPDA(voteAccount);
1016
+ const accountInfo = await this.connection.getAccountInfo(validatorBondAccountAddress);
1173
1017
  if (!accountInfo) {
1174
1018
  return 0;
1175
1019
  }
1176
- const { data, lamports } = accountInfo;
1177
- const rentExempt = await this.connection.getMinimumBalanceForRentExemption(data.length);
1178
- const availableBalance = Math.max(0, lamports - rentExempt);
1020
+ const rentExempt = await this.connection.getMinimumBalanceForRentExemption(
1021
+ accountInfo.data.length
1022
+ );
1023
+ const availableBalance = Math.max(0, accountInfo.lamports - rentExempt);
1179
1024
  return availableBalance / LAMPORTS_PER_SOL;
1180
1025
  }
1026
+ // Get global state state
1027
+ async getGlobalState() {
1028
+ const [globalState] = this.getGlobalStatePDA();
1029
+ try {
1030
+ const account = await this.program.account.globalState.fetch(globalState);
1031
+ return {
1032
+ authority: account.authority.toString(),
1033
+ totalValidators: account.totalValidators,
1034
+ totalWithdrawn: account.totalWithdrawn.toNumber() / LAMPORTS_PER_SOL,
1035
+ reserveAddress: account.reserve.toString()
1036
+ };
1037
+ } catch {
1038
+ return null;
1039
+ }
1040
+ }
1041
+ // Get current epoch
1042
+ async getCurrentEpoch() {
1043
+ const epochInfo = await this.connection.getEpochInfo();
1044
+ return epochInfo.epoch;
1045
+ }
1046
+ // Helper methods for backward compatibility (can be removed if not needed)
1047
+ async initialize(reserveAddress, authority) {
1048
+ const authorityPubkey = authority || this.provider.wallet.publicKey;
1049
+ const ix = await this.buildInitializeInstruction({ authority: authorityPubkey, reserveAddress });
1050
+ const tx = await this.provider.sendAndConfirm(
1051
+ new Transaction().add(ix),
1052
+ []
1053
+ );
1054
+ return tx;
1055
+ }
1056
+ // Note: this method will be removed or changed in the future (CLI only)
1057
+ async registerValidator(voteAccount, initialCollateral, withdrawalAuthority, identity) {
1058
+ const identityPubkey = identity ?? this.provider.wallet.publicKey;
1059
+ const ix = await this.buildRegisterValidatorInstruction(
1060
+ { creator: identityPubkey, identity: identityPubkey, voteAccount, initialCollateral, withdrawalAuthority }
1061
+ );
1062
+ const tx = await this.provider.sendAndConfirm(
1063
+ new Transaction().add(ix),
1064
+ []
1065
+ );
1066
+ return tx;
1067
+ }
1068
+ async topUpCollateral(voteAccount, amount, validator) {
1069
+ const userPubkey = validator ?? this.provider.wallet.publicKey;
1070
+ const ix = await this.buildTopUpCollateralInstruction(
1071
+ { user: userPubkey, voteAccount, amount }
1072
+ );
1073
+ const tx = await this.provider.sendAndConfirm(
1074
+ new Transaction().add(ix),
1075
+ []
1076
+ );
1077
+ return tx;
1078
+ }
1079
+ async withdrawCollateral(voteAccount, destination, amount, withdrawalAuthority) {
1080
+ const authorityPubkey = withdrawalAuthority ?? this.provider.wallet.publicKey;
1081
+ const ix = await this.buildWithdrawCollateralInstruction(
1082
+ { withdrawalAuthority: authorityPubkey, voteAccount, destination, amount }
1083
+ );
1084
+ const tx = await this.provider.sendAndConfirm(
1085
+ new Transaction().add(ix),
1086
+ []
1087
+ );
1088
+ return tx;
1089
+ }
1090
+ async claimCompensation(voteAccount, amount, authority) {
1091
+ const authorityPubkey = authority ?? this.provider.wallet.publicKey;
1092
+ const ix = await this.buildWithdrawCompensationInstruction(
1093
+ { authority: authorityPubkey, voteAccount, amount }
1094
+ );
1095
+ const tx = await this.provider.sendAndConfirm(
1096
+ new Transaction().add(ix),
1097
+ []
1098
+ );
1099
+ return tx;
1100
+ }
1181
1101
  /**
1182
1102
  * Get transaction history grouped by epochs
1183
- * @param vote - The vote account to get history for
1103
+ * @param voteAccount - The vote account to get history for
1184
1104
  * @param epochsCount - Number of recent epochs to return (default: 10)
1185
1105
  * @returns Array of epoch history items sorted by epoch (descending)
1186
1106
  */
1187
- async getHistoryGroupedByEpochs(vote, epochsCount = 10) {
1188
- const epochInfo = await this.connection.getEpochInfo();
1189
- const fullHistory = await this.getFullHistory(new PublicKey(vote));
1107
+ async getHistoryGroupedByEpochs(voteAccount, epochsCount = 10) {
1108
+ const currentEpoch = await this.getCurrentEpoch();
1109
+ const fullHistory = await this.getFullHistory(voteAccount);
1190
1110
  const epochMap = /* @__PURE__ */ new Map();
1191
1111
  for (const item of fullHistory) {
1192
- if (item.epoch < epochInfo.epoch - epochsCount + 1) {
1112
+ if (item.epoch < currentEpoch - epochsCount + 1) {
1193
1113
  continue;
1194
1114
  }
1195
1115
  if (!epochMap.has(item.epoch)) {
@@ -1214,13 +1134,11 @@ var JBondClient = class _JBondClient {
1214
1134
  for (const epochData of epochMap.values()) {
1215
1135
  epochData.balanceChange = epochData.deposits - epochData.withdrawals;
1216
1136
  }
1217
- return [...epochMap.values()].toSorted((a, b) => b.epoch - a.epoch);
1137
+ const result = [...epochMap.values()].toSorted((a, b) => b.epoch - a.epoch);
1138
+ return result;
1218
1139
  }
1219
- /**
1220
- * Get transaction history for a specific validator bond account
1221
- */
1222
- async getHistory(vote, options) {
1223
- const [ValidatorBondAccount] = this.pda.validatorBond(new PublicKey(vote));
1140
+ async getHistory(voteAccount, options) {
1141
+ const [ValidatorBondAccount] = this.getValidatorBondPDA(voteAccount);
1224
1142
  const signatures = await this.connection.getSignaturesForAddress(
1225
1143
  ValidatorBondAccount,
1226
1144
  {
@@ -1268,10 +1186,10 @@ var JBondClient = class _JBondClient {
1268
1186
  const dataBuffer = bs58.decode(data);
1269
1187
  if (dataBuffer.length >= 16) {
1270
1188
  const discriminator = dataBuffer.slice(0, 8);
1271
- const bondInitDiscriminator = this.getInstructionDiscriminator("register");
1272
- const bondTopUpDiscriminator = this.getInstructionDiscriminator("topUp");
1273
- const withdrawCompensationDiscriminator = this.getInstructionDiscriminator("claim");
1274
- const bondWithdrawDiscriminator = this.getInstructionDiscriminator("withdraw");
1189
+ const bondInitDiscriminator = this.getInstructionDiscriminator("bondInit");
1190
+ const bondTopUpDiscriminator = this.getInstructionDiscriminator("bondTopUp");
1191
+ const withdrawCompensationDiscriminator = this.getInstructionDiscriminator("withdrawCompensation");
1192
+ const bondWithdrawDiscriminator = this.getInstructionDiscriminator("bondWithdraw");
1275
1193
  const amountBytes = dataBuffer.slice(8, 16);
1276
1194
  const amountBN = new BN(amountBytes, "le");
1277
1195
  amount = amountBN.toNumber() / LAMPORTS_PER_SOL;
@@ -1316,11 +1234,7 @@ var JBondClient = class _JBondClient {
1316
1234
  }
1317
1235
  return history.toSorted((a, b) => b.slot - a.slot);
1318
1236
  }
1319
- /**
1320
- * Get full transaction history by paginating through results
1321
- * @param voteAccount
1322
- * @param pageSize
1323
- */
1237
+ // Helper method to get paginated history
1324
1238
  async getFullHistory(voteAccount, pageSize = 100) {
1325
1239
  const allHistory = [];
1326
1240
  let before;
@@ -1340,11 +1254,6 @@ var JBondClient = class _JBondClient {
1340
1254
  }
1341
1255
  return allHistory;
1342
1256
  }
1343
- /**
1344
- * Get instruction discriminator from IDL
1345
- * @param instructionName
1346
- * @private
1347
- */
1348
1257
  getInstructionDiscriminator(instructionName) {
1349
1258
  const instruction = this.program.idl.instructions.find((ix) => ix.name === instructionName);
1350
1259
  if (!instruction) {
@@ -1357,6 +1266,6 @@ var JBondClient = class _JBondClient {
1357
1266
  }
1358
1267
  };
1359
1268
 
1360
- export { BondClientEnv, BondTransactionType, ENV_PROGRAM_ID, JBondClient, NodeWallet };
1269
+ export { BondClientEnv, BondTransactionType, DEV_PROGRAM_ID, JBondClient, PROGRAM_ID };
1361
1270
  //# sourceMappingURL=index.mjs.map
1362
1271
  //# sourceMappingURL=index.mjs.map