@jpool/bond-sdk 0.9.0-next.9 → 0.10.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,8 +1,9 @@
1
1
  import { Program, AnchorProvider, BN } from '@coral-xyz/anchor';
2
+ import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
2
3
  import { getStakePoolAccount, STAKE_POOL_PROGRAM_ID, StakePoolInstruction } from '@solana/spl-stake-pool';
3
- import { TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync } from '@solana/spl-token';
4
- import { PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL, StakeProgram } from '@solana/web3.js';
5
- import bs58 from 'bs58';
4
+ import { TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync, ACCOUNT_SIZE, AccountLayout } from '@solana/spl-token';
5
+ import { PublicKey, Transaction, SystemProgram, LAMPORTS_PER_SOL } from '@solana/web3.js';
6
+ import bs58$1 from 'bs58';
6
7
 
7
8
  var __create = Object.create;
8
9
  var __defProp = Object.defineProperty;
@@ -4553,7 +4554,7 @@ var Seeds = /* @__PURE__ */ ((Seeds2) => {
4553
4554
  Seeds2["GlobalState"] = "global_state";
4554
4555
  Seeds2["BondState"] = "bond_state";
4555
4556
  Seeds2["ValidatorBond"] = "validator_bond";
4556
- Seeds2["PerformanceBond"] = "performance";
4557
+ Seeds2["StandardBond"] = "standard";
4557
4558
  Seeds2["CrowdFundingBond"] = "crowdfunding";
4558
4559
  return Seeds2;
4559
4560
  })(Seeds || {});
@@ -4563,13 +4564,17 @@ var ENV_PROGRAM_ID = {
4563
4564
 
4564
4565
  // src/types/index.ts
4565
4566
  var bondTypeToSeed = {
4566
- performance: "performance" /* PerformanceBond */,
4567
+ standard: "standard" /* StandardBond */,
4567
4568
  crowdfunding: "crowdfunding" /* CrowdFundingBond */
4568
4569
  };
4569
4570
  var BondTypeVariant = {
4570
- Performance: { performance: {} },
4571
+ Standard: { standard: {} },
4571
4572
  Crowdfunding: { crowdfunding: {} }
4572
4573
  };
4574
+ var BondStateStatusVariant = {
4575
+ Active: { active: {} },
4576
+ Disabled: { disabled: {} }
4577
+ };
4573
4578
  var BondTransactionType = /* @__PURE__ */ ((BondTransactionType2) => {
4574
4579
  BondTransactionType2["Deposit"] = "deposit";
4575
4580
  BondTransactionType2["Withdrawal"] = "withdrawal";
@@ -4712,23 +4717,12 @@ var HistoryManager = class {
4712
4717
  if (!type || amount <= 0) {
4713
4718
  continue;
4714
4719
  }
4715
- let beforeBalance;
4716
- let afterBalance;
4717
- const accIdx = tx.transaction.message.accountKeys.findIndex(
4718
- (k) => k.pubkey.equals(validatorBondAccount)
4719
- );
4720
- if (accIdx !== -1 && tx.meta.preBalances && tx.meta.postBalances) {
4721
- beforeBalance = Number(tx.meta.preBalances[accIdx] ?? 0) / LAMPORTS_PER_SOL;
4722
- afterBalance = Number(tx.meta.postBalances[accIdx] ?? 0) / LAMPORTS_PER_SOL;
4723
- }
4724
4720
  history.push({
4725
4721
  signature: sig,
4726
4722
  slot,
4727
4723
  epoch: slotToEpoch(slot, cluster),
4728
4724
  type,
4729
- amount,
4730
- beforeBalance,
4731
- afterBalance
4725
+ amount
4732
4726
  });
4733
4727
  }
4734
4728
  }
@@ -4771,7 +4765,7 @@ var HistoryManager = class {
4771
4765
  return { type: null, amount: 0 };
4772
4766
  }
4773
4767
  try {
4774
- const buf = bs58.decode(data);
4768
+ const buf = bs58$1.decode(data);
4775
4769
  if (buf.length < 16) {
4776
4770
  return { type: null, amount: 0 };
4777
4771
  }
@@ -4803,7 +4797,7 @@ var HistoryManager = class {
4803
4797
 
4804
4798
  // src/idl/jbond.json
4805
4799
  var jbond_default = {
4806
- address: "DBuUGWbLz8CkAMQiagMfrQzj8SSg1rHQJWrTSc97HWfR",
4800
+ address: "BondQ7KqZreTcW2UbeTNDcLCJQ3aXAtLn2Fm6ftaJDU",
4807
4801
  metadata: {
4808
4802
  name: "jbond",
4809
4803
  version: "0.2.1",
@@ -4980,10 +4974,6 @@ var jbond_default = {
4980
4974
  210
4981
4975
  ],
4982
4976
  accounts: [
4983
- {
4984
- name: "global_state",
4985
- writable: true
4986
- },
4987
4977
  {
4988
4978
  name: "bond_state",
4989
4979
  writable: true,
@@ -5516,9 +5506,6 @@ var jbond_default = {
5516
5506
  },
5517
5507
  {
5518
5508
  name: "global_initialize",
5519
- docs: [
5520
- "----------------------------- Global Instructions ----------------------------"
5521
- ],
5522
5509
  discriminator: [
5523
5510
  30,
5524
5511
  79,
@@ -5567,6 +5554,111 @@ var jbond_default = {
5567
5554
  ],
5568
5555
  args: []
5569
5556
  },
5557
+ {
5558
+ name: "migrate_bond",
5559
+ docs: [
5560
+ "Migrates validator bond data from legacy structure to new structure."
5561
+ ],
5562
+ discriminator: [
5563
+ 107,
5564
+ 119,
5565
+ 59,
5566
+ 110,
5567
+ 76,
5568
+ 18,
5569
+ 37,
5570
+ 163
5571
+ ],
5572
+ accounts: [
5573
+ {
5574
+ name: "bond_state",
5575
+ writable: true
5576
+ },
5577
+ {
5578
+ name: "legacy_validator_bond",
5579
+ writable: true
5580
+ },
5581
+ {
5582
+ name: "legacy_vote_account"
5583
+ },
5584
+ {
5585
+ name: "validator_bond",
5586
+ writable: true,
5587
+ pda: {
5588
+ seeds: [
5589
+ {
5590
+ kind: "const",
5591
+ value: [
5592
+ 118,
5593
+ 97,
5594
+ 108,
5595
+ 105,
5596
+ 100,
5597
+ 97,
5598
+ 116,
5599
+ 111,
5600
+ 114,
5601
+ 95,
5602
+ 98,
5603
+ 111,
5604
+ 110,
5605
+ 100
5606
+ ]
5607
+ },
5608
+ {
5609
+ kind: "account",
5610
+ path: "bond_state"
5611
+ },
5612
+ {
5613
+ kind: "account",
5614
+ path: "legacy_vote_account"
5615
+ }
5616
+ ]
5617
+ }
5618
+ },
5619
+ {
5620
+ name: "creator",
5621
+ writable: true,
5622
+ signer: true
5623
+ },
5624
+ {
5625
+ name: "system_program",
5626
+ address: "11111111111111111111111111111111"
5627
+ }
5628
+ ],
5629
+ args: []
5630
+ },
5631
+ {
5632
+ name: "session_finish",
5633
+ docs: [
5634
+ "Finishes a bond, preventing further deposits and withdrawals."
5635
+ ],
5636
+ discriminator: [
5637
+ 230,
5638
+ 209,
5639
+ 54,
5640
+ 205,
5641
+ 127,
5642
+ 141,
5643
+ 137,
5644
+ 113
5645
+ ],
5646
+ accounts: [
5647
+ {
5648
+ name: "bond_state",
5649
+ writable: true
5650
+ },
5651
+ {
5652
+ name: "authority",
5653
+ writable: true,
5654
+ signer: true,
5655
+ relations: [
5656
+ "bond_state"
5657
+ ]
5658
+ }
5659
+ ],
5660
+ args: []
5661
+ },
5570
5662
  {
5571
5663
  name: "session_start",
5572
5664
  docs: [
@@ -5835,6 +5927,16 @@ var jbond_default = {
5835
5927
  code: 6021,
5836
5928
  name: "InvalidArgument",
5837
5929
  msg: "Invalid argument provided"
5930
+ },
5931
+ {
5932
+ code: 6022,
5933
+ name: "BondNotDisabled",
5934
+ msg: "Bond is not disabled"
5935
+ },
5936
+ {
5937
+ code: 6023,
5938
+ name: "BondNotEnabled",
5939
+ msg: "Bond is not enabled"
5838
5940
  }
5839
5941
  ],
5840
5942
  types: [
@@ -5843,6 +5945,16 @@ var jbond_default = {
5843
5945
  type: {
5844
5946
  kind: "struct",
5845
5947
  fields: [
5948
+ {
5949
+ name: "status",
5950
+ type: {
5951
+ option: {
5952
+ defined: {
5953
+ name: "BondStatus"
5954
+ }
5955
+ }
5956
+ }
5957
+ },
5846
5958
  {
5847
5959
  name: "new_reserve",
5848
5960
  type: {
@@ -5945,7 +6057,7 @@ var jbond_default = {
5945
6057
  {
5946
6058
  name: "bond_type",
5947
6059
  docs: [
5948
- "The type of bond (e.g., Performance, Crowdfunding)"
6060
+ "The type of bond (e.g., Standard, Crowdfunding)"
5949
6061
  ],
5950
6062
  type: {
5951
6063
  defined: {
@@ -6013,6 +6125,17 @@ var jbond_default = {
6013
6125
  ],
6014
6126
  type: "i64"
6015
6127
  },
6128
+ {
6129
+ name: "status",
6130
+ docs: [
6131
+ "Current status of the bond"
6132
+ ],
6133
+ type: {
6134
+ defined: {
6135
+ name: "BondStatus"
6136
+ }
6137
+ }
6138
+ },
6016
6139
  {
6017
6140
  name: "bump",
6018
6141
  docs: [
@@ -6023,6 +6146,20 @@ var jbond_default = {
6023
6146
  ]
6024
6147
  }
6025
6148
  },
6149
+ {
6150
+ name: "BondStatus",
6151
+ type: {
6152
+ kind: "enum",
6153
+ variants: [
6154
+ {
6155
+ name: "Active"
6156
+ },
6157
+ {
6158
+ name: "Disabled"
6159
+ }
6160
+ ]
6161
+ }
6162
+ },
6026
6163
  {
6027
6164
  name: "BondType",
6028
6165
  docs: [
@@ -6032,7 +6169,7 @@ var jbond_default = {
6032
6169
  kind: "enum",
6033
6170
  variants: [
6034
6171
  {
6035
- name: "Performance"
6172
+ name: "Standard"
6036
6173
  },
6037
6174
  {
6038
6175
  name: "Crowdfunding"
@@ -6158,15 +6295,6 @@ var jbond_default = {
6158
6295
  type: {
6159
6296
  kind: "struct",
6160
6297
  fields: [
6161
- {
6162
- name: "bonds",
6163
- docs: [
6164
- "List of all registered bonds"
6165
- ],
6166
- type: {
6167
- vec: "pubkey"
6168
- }
6169
- },
6170
6298
  {
6171
6299
  name: "authority",
6172
6300
  docs: [
@@ -6190,7 +6318,7 @@ var jbond_default = {
6190
6318
  kind: "struct",
6191
6319
  fields: [
6192
6320
  {
6193
- name: "bond",
6321
+ name: "state",
6194
6322
  type: "pubkey"
6195
6323
  },
6196
6324
  {
@@ -6211,26 +6339,10 @@ var jbond_default = {
6211
6339
  option: "pubkey"
6212
6340
  }
6213
6341
  },
6214
- {
6215
- name: "total_compensation_amount",
6216
- type: "u64"
6217
- },
6218
- {
6219
- name: "last_compensation_amount",
6220
- type: "u64"
6221
- },
6222
- {
6223
- name: "last_compensation_epoch",
6224
- type: "u64"
6225
- },
6226
6342
  {
6227
6343
  name: "created_at",
6228
6344
  type: "i64"
6229
6345
  },
6230
- {
6231
- name: "is_active",
6232
- type: "bool"
6233
- },
6234
6346
  {
6235
6347
  name: "bump",
6236
6348
  type: "u8"
@@ -6527,10 +6639,8 @@ var JBondClient = class _JBondClient {
6527
6639
  * Build initialize instruction
6528
6640
  */
6529
6641
  async buildBondInitializeIx(props) {
6530
- const [globalState] = this.pda.globalState();
6531
6642
  const [bondState] = this.pda.bondState(props.bondType, props.name);
6532
6643
  const accounts = {
6533
- globalState,
6534
6644
  bondState,
6535
6645
  authority: props.authority ?? this.program.provider.wallet?.publicKey,
6536
6646
  reserve: props.reserve,
@@ -6545,8 +6655,6 @@ var JBondClient = class _JBondClient {
6545
6655
  token: (mint) => {
6546
6656
  accounts.reserveTokenAccount = getAssociatedTokenAddressSync(mint, props.reserve);
6547
6657
  accounts.mint = mint;
6548
- },
6549
- stakeAccount: () => {
6550
6658
  }
6551
6659
  });
6552
6660
  return this.program.methods.bondInitialize({
@@ -6561,6 +6669,7 @@ var JBondClient = class _JBondClient {
6561
6669
  async buildConfigureIx(props) {
6562
6670
  const [bondState] = this.pda.bondState(props.bondType, props.name);
6563
6671
  return this.program.methods.bondConfigure({
6672
+ status: props.bondStateStatus ?? null,
6564
6673
  newReserve: props.newReserve ?? null,
6565
6674
  newAuthority: props.newAuthority ?? null
6566
6675
  }).accountsStrict({
@@ -6576,7 +6685,7 @@ var JBondClient = class _JBondClient {
6576
6685
  if (!creator) {
6577
6686
  throw new Error("Missing creator");
6578
6687
  }
6579
- const collateralType = (await this.getBondState(bondType, name)).collateralType;
6688
+ const collateralType = (await this.getBondState(bondType, name)).bondState.collateralType;
6580
6689
  const accounts = {
6581
6690
  bondState,
6582
6691
  validatorBond,
@@ -6595,9 +6704,6 @@ var JBondClient = class _JBondClient {
6595
6704
  token: (mint) => {
6596
6705
  accounts.bondTokenAccount = getAssociatedTokenAddressSync(mint, validatorBond, true);
6597
6706
  Object.assign(accounts, { mint, bondTokenAccount: accounts.bondTokenAccount });
6598
- },
6599
- stakeAccount: () => {
6600
- throw new Error("Stake account collateral type is not currently supported");
6601
6707
  }
6602
6708
  });
6603
6709
  return this.program.methods.bondRegister(bondType, name).accountsPartial(accounts).instruction();
@@ -6611,16 +6717,18 @@ var JBondClient = class _JBondClient {
6611
6717
  const instructions = [];
6612
6718
  const [bondState] = this.pda.bondState(bondType, name);
6613
6719
  const [validatorBond] = this.pda.validatorBond(bondType, name, voteAccount);
6720
+ console.log("Top up collateral for bond:", { bondState: bondState.toBase58(), validatorBond: validatorBond.toBase58() });
6614
6721
  const bond = await this.getValidatorBond(props.bondType, props.name, props.voteAccount);
6615
6722
  if (!bond) {
6616
6723
  instructions.push(await this.buildRegisterIx({
6617
6724
  bondType: props.bondType,
6618
6725
  name: props.name,
6619
6726
  voteAccount: props.voteAccount,
6620
- identity: props.identity
6727
+ identity: props.identity,
6728
+ creator: props.payer
6621
6729
  }));
6622
6730
  }
6623
- const collateralType = (await this.getBondState(bondType, name)).collateralType;
6731
+ const collateralType = (await this.getBondState(bondType, name)).bondState.collateralType;
6624
6732
  const accounts = {
6625
6733
  bondState,
6626
6734
  validatorBond,
@@ -6641,13 +6749,6 @@ var JBondClient = class _JBondClient {
6641
6749
  accounts.bondTokenAccount = getAssociatedTokenAddressSync(mint, validatorBond, true);
6642
6750
  accounts.tokenProgram = TOKEN_PROGRAM_ID;
6643
6751
  accounts.associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID;
6644
- },
6645
- stakeAccount: () => {
6646
- if (!collateral.stakeAccount) {
6647
- throw new Error("Missing stakeAccount for stake collateral");
6648
- }
6649
- accounts.stakeAccount = collateral.stakeAccount;
6650
- accounts.stakeProgram = StakeProgram.programId;
6651
6752
  }
6652
6753
  });
6653
6754
  instructions.push(
@@ -6664,7 +6765,7 @@ var JBondClient = class _JBondClient {
6664
6765
  if (!payer || !destination) {
6665
6766
  throw new Error("Missing payer/destination");
6666
6767
  }
6667
- const collateralType = (await this.getBondState(bondType, name)).collateralType;
6768
+ const collateralType = (await this.getBondState(bondType, name)).bondState.collateralType;
6668
6769
  const accounts = {
6669
6770
  bondState,
6670
6771
  validatorBond,
@@ -6684,27 +6785,20 @@ var JBondClient = class _JBondClient {
6684
6785
  accounts.destinationTokenAccount = getAssociatedTokenAddressSync(mint, destination, true);
6685
6786
  accounts.bondTokenAccount = getAssociatedTokenAddressSync(mint, validatorBond, true);
6686
6787
  accounts.tokenProgram = TOKEN_PROGRAM_ID;
6687
- },
6688
- stakeAccount: () => {
6689
- if (!withdraw.stakeAccount) {
6690
- throw new Error("Missing stakeAccount for stake collateral");
6691
- }
6692
- accounts.stakeAccount = withdraw.stakeAccount;
6693
- accounts.stakeProgram = StakeProgram.programId;
6694
6788
  }
6695
6789
  });
6696
6790
  return this.program.methods.bondWithdraw(this.lamports(withdraw.amount)).accountsPartial(accounts).instruction();
6697
6791
  }
6698
6792
  async buildClaimIx(props) {
6699
- const { claim, bondType, name } = props;
6793
+ const { bondType, name } = props;
6700
6794
  const [bondState] = this.pda.bondState(bondType, name);
6701
6795
  const [validatorBond] = this.pda.validatorBond(bondType, name, props.voteAccount);
6702
- const reserve = props.reserve ?? (await this.getBondState(bondType, name)).reserve;
6796
+ const reserve = props.reserve ?? (await this.getBondState(bondType, name)).bondState.reserve;
6703
6797
  const authority = props.authority ?? this.program.provider.wallet?.publicKey;
6704
6798
  if (!reserve) {
6705
6799
  throw new Error("Reserve not set");
6706
6800
  }
6707
- const collateralType = (await this.getBondState(bondType, name)).collateralType;
6801
+ const collateralType = (await this.getBondState(bondType, name)).bondState.collateralType;
6708
6802
  const accounts = {
6709
6803
  bondState,
6710
6804
  validatorBond,
@@ -6725,13 +6819,6 @@ var JBondClient = class _JBondClient {
6725
6819
  accounts.bondTokenAccount = getAssociatedTokenAddressSync(mint, validatorBond, true);
6726
6820
  accounts.reserveTokenAccount = getAssociatedTokenAddressSync(mint, reserve, true);
6727
6821
  accounts.tokenProgram = TOKEN_PROGRAM_ID;
6728
- },
6729
- stakeAccount: () => {
6730
- if (!claim.stakeAccount) {
6731
- throw new Error("Missing stakeAccount for stake collateral");
6732
- }
6733
- accounts.stakeAccount = claim.stakeAccount;
6734
- accounts.stakeProgram = StakeProgram.programId;
6735
6822
  }
6736
6823
  });
6737
6824
  return this.program.methods.bondClaim(this.lamports(props.claim.amount)).accountsPartial(
@@ -6746,8 +6833,34 @@ var JBondClient = class _JBondClient {
6746
6833
  newWithdrawAuthority: props.newWithdrawAuthority ?? null
6747
6834
  }).instruction();
6748
6835
  }
6749
- async buildBondFinishIx(_props) {
6750
- throw new Error("Crowdfunding bond currently does not support finish operation");
6836
+ async buildBondFinishIx(props) {
6837
+ const [bondState] = this.pda.bondState(props.bondType, props.name);
6838
+ return this.program.methods.sessionFinish().accountsPartial({
6839
+ bondState,
6840
+ authority: this.program.provider.wallet?.publicKey
6841
+ }).instruction();
6842
+ }
6843
+ async migrateBond(props) {
6844
+ const ix = await this.buildBondMigrateIx(props);
6845
+ return this.provider.sendAndConfirm?.(new Transaction().add(ix));
6846
+ }
6847
+ async buildBondMigrateIx(props) {
6848
+ const [bondState] = this.pda.bondState(props.bondType, props.name);
6849
+ const [legacyValidatorBond] = PublicKey.findProgramAddressSync(
6850
+ [
6851
+ Buffer.from("validator_bond"),
6852
+ new PublicKey(props.voteAccount).toBuffer()
6853
+ ],
6854
+ this.programId
6855
+ );
6856
+ const [validatorBond] = this.pda.validatorBond(props.bondType, props.name, props.voteAccount);
6857
+ return this.program.methods.migrateBond().accountsPartial({
6858
+ bondState,
6859
+ legacyValidatorBond,
6860
+ legacyVoteAccount: new PublicKey(props.voteAccount),
6861
+ validatorBond,
6862
+ creator: this.program.provider.wallet?.publicKey
6863
+ }).instruction();
6751
6864
  }
6752
6865
  async buildBondStartIx(props) {
6753
6866
  const [bondState] = this.pda.bondState(props.bondType, props.name);
@@ -6763,38 +6876,47 @@ var JBondClient = class _JBondClient {
6763
6876
  const [globalState] = this.pda.globalState();
6764
6877
  return await this.program.account.globalState.fetch(globalState);
6765
6878
  }
6766
- async getBondState(bondType, bondName) {
6767
- const [bondState] = this.pda.bondState(bondType, bondName);
6768
- return await this.program.account.bondState.fetch(bondState);
6879
+ /**
6880
+ * Fetch bond state with stats
6881
+ * @param bondType - Type of the bond
6882
+ * @param bondName - Name of the bond
6883
+ * @param withStats
6884
+ */
6885
+ async getBondState(bondType, bondName, withStats = false) {
6886
+ const bondState = await this.program.account.bondState.fetch(this.pda.bondState(bondType, bondName)[0]);
6887
+ return {
6888
+ bondState,
6889
+ stateStats: withStats ? await this.getBondStateStats(bondState) : null
6890
+ };
6769
6891
  }
6770
6892
  /**
6771
6893
  * Get all bond states with total collected collateral
6772
6894
  */
6773
- async getAllBondStates(bondType) {
6895
+ async getAllBondStates(bondType, sessionStatus) {
6774
6896
  const bondStates = [];
6775
6897
  const bondStateAccounts = await this.program.account.bondState.all();
6776
- for (const { account: state } of bondStateAccounts) {
6898
+ for (const { publicKey, account: state } of bondStateAccounts) {
6777
6899
  if (!sameVariant(state.bondType, bondType)) {
6778
6900
  continue;
6779
6901
  }
6780
- const validatorBonds = await this.getValidatorBondsByState(state.bondType, state.name);
6781
- const balances = await Promise.all(
6782
- validatorBonds.map(
6783
- (vb) => this.getValidatorBondBalance(state.bondType, state.name, vb.voteAccount).then((v) => v ?? 0)
6784
- )
6902
+ if (sessionStatus !== void 0 && this.getBondStateSessionStatus(state) !== sessionStatus) {
6903
+ continue;
6904
+ }
6905
+ const bondStateStats = await this.getBondStateStats(state);
6906
+ bondStates.push(
6907
+ {
6908
+ publicKey,
6909
+ bondState: state,
6910
+ stateStats: bondStateStats
6911
+ }
6785
6912
  );
6786
- const bondStateStats = {
6787
- totalCollected: balances.reduce((sum, v) => sum + v, 0),
6788
- status: await this.getBondStateSessionStatus(state)
6789
- };
6790
- bondStates.push([state, bondStateStats]);
6791
6913
  }
6792
6914
  return bondStates;
6793
6915
  }
6794
6916
  /**
6795
6917
  * Get session status for bond state
6796
6918
  */
6797
- async getBondStateSessionStatus(bondState) {
6919
+ getBondStateSessionStatus(bondState) {
6798
6920
  const now = Math.floor(Date.now() / 1e3);
6799
6921
  if (bondState.sessionFinishTs.toNumber() > now) {
6800
6922
  return 0 /* Live */;
@@ -6802,7 +6924,9 @@ var JBondClient = class _JBondClient {
6802
6924
  return 1 /* Finished */;
6803
6925
  }
6804
6926
  }
6805
- /** Get all validator bonds for a given bond state */
6927
+ /**
6928
+ * Get all validator bonds for a given bond state
6929
+ */
6806
6930
  async getValidatorBondsByState(bondType, bondName) {
6807
6931
  const validatorBonds = [];
6808
6932
  const bondStatePda = this.pda.bondState(bondType, bondName)[0];
@@ -6821,9 +6945,6 @@ var JBondClient = class _JBondClient {
6821
6945
  }
6822
6946
  /**
6823
6947
  * Fetch validator bond data or null if not found
6824
- * @param bondType
6825
- * @param bondName
6826
- * @param vote
6827
6948
  */
6828
6949
  async getValidatorBond(bondType, bondName, vote) {
6829
6950
  const [address] = this.pda.validatorBond(bondType, bondName, new PublicKey(vote));
@@ -6838,7 +6959,7 @@ var JBondClient = class _JBondClient {
6838
6959
  */
6839
6960
  async getBondCollateralType(bondType, bondName) {
6840
6961
  const bondState = await this.getBondState(bondType, bondName);
6841
- return bondState.collateralType;
6962
+ return bondState.bondState.collateralType;
6842
6963
  }
6843
6964
  /**
6844
6965
  * Get validator bond account balance (in SOL)
@@ -6850,7 +6971,7 @@ var JBondClient = class _JBondClient {
6850
6971
  async getValidatorBondBalance(bondType, bondName, vote) {
6851
6972
  const [address] = this.pda.validatorBond(bondType, bondName, new PublicKey(vote));
6852
6973
  const bondStateData = await this.getBondState(bondType, bondName);
6853
- const bondStateCollateralType = bondStateData.collateralType;
6974
+ const bondStateCollateralType = bondStateData.bondState.collateralType;
6854
6975
  return await matchVariant(bondStateCollateralType, {
6855
6976
  native: async () => {
6856
6977
  const accountInfo = await this.connection.getAccountInfo(address).catch(() => null);
@@ -6865,22 +6986,267 @@ var JBondClient = class _JBondClient {
6865
6986
  const tokenAccount = getAssociatedTokenAddressSync(mint, address, true);
6866
6987
  try {
6867
6988
  const balance = await this.connection.getTokenAccountBalance(tokenAccount);
6868
- return Number(balance.value.uiAmount ?? 0);
6989
+ return Number(balance.value.uiAmount ?? 0) * LAMPORTS_PER_SOL;
6869
6990
  } catch {
6870
6991
  return 0;
6871
6992
  }
6993
+ }
6994
+ });
6995
+ }
6996
+ /**
6997
+ * Get total collected collateral for a bond state
6998
+ */
6999
+ async getBondStateTotalCollected(bondType, bondName, votes) {
7000
+ const bondStateData = await this.getBondState(bondType, bondName);
7001
+ const bondStateCollateralType = bondStateData.bondState.collateralType;
7002
+ const chunk = (arr, n = 100) => {
7003
+ const res = [];
7004
+ for (let i = 0; i < arr.length; i += n) {
7005
+ res.push(arr.slice(i, i + n));
7006
+ }
7007
+ return res;
7008
+ };
7009
+ return await matchVariant(bondStateCollateralType, {
7010
+ native: async () => {
7011
+ const addresses = votes.map((vote) => {
7012
+ const [address] = this.pda.validatorBond(bondType, bondName, new PublicKey(vote));
7013
+ return address;
7014
+ });
7015
+ const accountInfos = await this.connection.getMultipleAccountsInfo(addresses);
7016
+ const balances = await Promise.all(
7017
+ accountInfos.map(async (accountInfo) => {
7018
+ if (!accountInfo) {
7019
+ return 0;
7020
+ }
7021
+ const { lamports } = accountInfo;
7022
+ return lamports;
7023
+ })
7024
+ );
7025
+ return balances.reduce((sum, v) => sum + v, 0);
6872
7026
  },
6873
- stakeAccount: async () => {
6874
- const accountInfo = await this.connection.getAccountInfo(address).catch(() => null);
6875
- if (!accountInfo) {
7027
+ token: async (mint) => {
7028
+ const tokenAccounts = votes.map((vote) => {
7029
+ const [validatorBondAddress] = this.pda.validatorBond(bondType, bondName, new PublicKey(vote));
7030
+ return getAssociatedTokenAddressSync(mint, validatorBondAddress, true);
7031
+ });
7032
+ if (tokenAccounts.length === 0) {
6876
7033
  return 0;
6877
7034
  }
6878
- const { data, lamports } = accountInfo;
6879
- const rentExempt = await this.connection.getMinimumBalanceForRentExemption(data.length);
6880
- return Math.max(0, lamports - rentExempt);
7035
+ let total = 0n;
7036
+ for (const part of chunk(tokenAccounts, 100)) {
7037
+ const infos = await this.connection.getMultipleAccountsInfo(part).catch(() => []);
7038
+ for (let i = 0; i < infos.length; i++) {
7039
+ const info = infos[i];
7040
+ if (!info) {
7041
+ continue;
7042
+ }
7043
+ if (info.data.length !== ACCOUNT_SIZE) {
7044
+ continue;
7045
+ }
7046
+ try {
7047
+ const acc = AccountLayout.decode(info.data);
7048
+ const raw = BigInt(acc.amount.toString());
7049
+ total += raw;
7050
+ } catch {
7051
+ }
7052
+ }
7053
+ }
7054
+ const asNumber = Number(total);
7055
+ return Number.isFinite(asNumber) ? asNumber : Number.MAX_SAFE_INTEGER;
6881
7056
  }
6882
7057
  });
6883
7058
  }
7059
+ /**
7060
+ * Get transaction history for a specific validator bond account
7061
+ */
7062
+ async getHistory(bondType, bondName, vote, options) {
7063
+ const [legacyValidatorBondAccount] = PublicKey.findProgramAddressSync(
7064
+ [
7065
+ Buffer.from("validator_bond" /* ValidatorBond */),
7066
+ new PublicKey(vote).toBuffer()
7067
+ ],
7068
+ this.programId
7069
+ );
7070
+ const validatorBond = this.pda.validatorBond(bondType, bondName, vote);
7071
+ const legacySignatures = (await this.connection.getSignaturesForAddress(
7072
+ legacyValidatorBondAccount,
7073
+ {
7074
+ limit: options?.limit || 1e3,
7075
+ before: options?.before,
7076
+ until: options?.until
7077
+ },
7078
+ "confirmed"
7079
+ )).filter((sig) => !sig.err);
7080
+ const newSignatures = (await this.connection.getSignaturesForAddress(
7081
+ validatorBond[0],
7082
+ {
7083
+ limit: options?.limit || 1e3,
7084
+ before: options?.before,
7085
+ until: options?.until
7086
+ },
7087
+ "confirmed"
7088
+ )).filter((sig) => !sig.err);
7089
+ const signatureStrings = legacySignatures.map((sig) => sig.signature);
7090
+ signatureStrings.push(...newSignatures.map((sig) => sig.signature));
7091
+ const signatures = [...legacySignatures, ...newSignatures];
7092
+ const BATCH_SIZE = 100;
7093
+ const allTransactions = [];
7094
+ for (let i = 0; i < signatureStrings.length; i += BATCH_SIZE) {
7095
+ const batch = signatureStrings.slice(i, i + BATCH_SIZE);
7096
+ const transactions = await this.connection.getParsedTransactions(
7097
+ batch,
7098
+ {
7099
+ maxSupportedTransactionVersion: 0,
7100
+ commitment: "confirmed"
7101
+ }
7102
+ );
7103
+ allTransactions.push(...transactions);
7104
+ }
7105
+ const cluster = options?.cluster || "mainnet-beta";
7106
+ const history = [];
7107
+ for (const [idx, tx] of allTransactions.entries()) {
7108
+ const sigInfo = signatures[idx];
7109
+ if (!tx || !tx.meta || tx.meta.err !== null) {
7110
+ continue;
7111
+ }
7112
+ try {
7113
+ const slot = tx.slot || 0;
7114
+ const instructions = tx.transaction.message.instructions;
7115
+ for (const instruction of instructions) {
7116
+ if ("programId" in instruction && instruction.programId.equals(this.options.programId ?? this.program.programId)) {
7117
+ const ixData = instruction;
7118
+ if ("parsed" in ixData && ixData.parsed) {
7119
+ continue;
7120
+ }
7121
+ const data = ixData.data;
7122
+ if (!data) {
7123
+ continue;
7124
+ }
7125
+ let type = null;
7126
+ let amount = 0;
7127
+ try {
7128
+ const dataBuffer = bs58.decode(data);
7129
+ if (dataBuffer.length >= 8) {
7130
+ const discriminator = dataBuffer.subarray(0, 8);
7131
+ const legacyRegisterDiscriminator = this.getInstructionDiscriminator("register");
7132
+ const legacyTopUpDiscriminator = this.getInstructionDiscriminator("topUp");
7133
+ const legacyClaimDiscriminator = this.getInstructionDiscriminator("claim");
7134
+ const legacyWithdrawDiscriminator = this.getInstructionDiscriminator("withdraw");
7135
+ const bondRegisterDiscriminator = this.getInstructionDiscriminator("bondRegister");
7136
+ const bondTopUpDiscriminator = this.getInstructionDiscriminator("bondTopUp");
7137
+ const bondClaimDiscriminator = this.getInstructionDiscriminator("bondClaim");
7138
+ const bondWithdrawDiscriminator = this.getInstructionDiscriminator("bondWithdraw");
7139
+ console.log("Discriminator:", Buffer.from(discriminator).toString("hex"));
7140
+ if (Buffer.from(discriminator).equals(Buffer.from(legacyRegisterDiscriminator)) || Buffer.from(discriminator).equals(Buffer.from(bondRegisterDiscriminator))) {
7141
+ type = "deposit" /* Deposit */;
7142
+ if (dataBuffer.length >= 16 && Buffer.from(discriminator).equals(Buffer.from(legacyRegisterDiscriminator))) {
7143
+ const amountBytes = dataBuffer.subarray(8, 16);
7144
+ const amountBN = new import_bn2.BN(amountBytes, "le");
7145
+ amount = amountBN.toNumber() / LAMPORTS_PER_SOL;
7146
+ }
7147
+ } else if (dataBuffer.length >= 16) {
7148
+ const amountBytes = dataBuffer.subarray(8, 16);
7149
+ const amountBN = new import_bn2.BN(amountBytes, "le");
7150
+ amount = amountBN.toNumber() / LAMPORTS_PER_SOL;
7151
+ if (Buffer.from(discriminator).equals(Buffer.from(legacyTopUpDiscriminator)) || Buffer.from(discriminator).equals(Buffer.from(bondTopUpDiscriminator))) {
7152
+ type = "deposit" /* Deposit */;
7153
+ } else if (Buffer.from(discriminator).equals(Buffer.from(legacyClaimDiscriminator)) || Buffer.from(discriminator).equals(Buffer.from(bondClaimDiscriminator))) {
7154
+ type = "compensation" /* Compensation */;
7155
+ } else if (Buffer.from(discriminator).equals(Buffer.from(legacyWithdrawDiscriminator)) || Buffer.from(discriminator).equals(Buffer.from(bondWithdrawDiscriminator))) {
7156
+ type = "withdrawal" /* Withdrawal */;
7157
+ }
7158
+ }
7159
+ }
7160
+ } catch (e) {
7161
+ console.warn("Failed to decode instruction data:", e);
7162
+ }
7163
+ if (type && (amount > 0 || type === "deposit" /* Deposit */)) {
7164
+ history.push({
7165
+ signature: sigInfo.signature,
7166
+ slot,
7167
+ epoch: slotToEpoch(slot, cluster),
7168
+ type,
7169
+ amount
7170
+ });
7171
+ }
7172
+ }
7173
+ }
7174
+ } catch (error) {
7175
+ console.error(`Error processing transaction ${sigInfo.signature}:`, error);
7176
+ }
7177
+ }
7178
+ return history.toSorted((a, b) => b.slot - a.slot);
7179
+ }
7180
+ /**
7181
+ * Get full transaction history by paginating through results
7182
+ * @param bondType
7183
+ * @param bondName
7184
+ * @param voteAccount
7185
+ * @param pageSize
7186
+ */
7187
+ async getFullHistory(bondType, bondName, voteAccount, pageSize = 100) {
7188
+ const allHistory = [];
7189
+ let before;
7190
+ while (true) {
7191
+ const batch = await this.getHistory(bondType, bondName, voteAccount, {
7192
+ limit: pageSize,
7193
+ before
7194
+ });
7195
+ if (batch.length === 0) {
7196
+ break;
7197
+ }
7198
+ allHistory.push(...batch);
7199
+ before = batch.at(-1)?.signature;
7200
+ if (batch.length < pageSize) {
7201
+ break;
7202
+ }
7203
+ }
7204
+ return allHistory;
7205
+ }
7206
+ /**
7207
+ * Get instruction discriminator from IDL
7208
+ * @param instructionName
7209
+ * @private
7210
+ */
7211
+ getInstructionDiscriminator(instructionName) {
7212
+ const legacyDiscriminators = {
7213
+ register: [211, 124, 67, 15, 211, 194, 178, 240],
7214
+ topUp: [181, 157, 89, 67, 143, 182, 52, 72],
7215
+ claim: [62, 198, 214, 193, 213, 159, 108, 210],
7216
+ withdraw: [183, 18, 70, 156, 148, 109, 161, 34]
7217
+ };
7218
+ if (legacyDiscriminators[instructionName]) {
7219
+ return new Uint8Array(legacyDiscriminators[instructionName]);
7220
+ }
7221
+ if (instructionName.startsWith("bond")) {
7222
+ const instruction = this.program.idl.instructions.find((ix) => ix.name === instructionName);
7223
+ if (!instruction) {
7224
+ throw new Error(`Instruction ${instructionName} not found in IDL`);
7225
+ }
7226
+ if (!instruction.discriminator || !Array.isArray(instruction.discriminator)) {
7227
+ throw new Error(`Discriminator not found for instruction ${instructionName}`);
7228
+ }
7229
+ return new Uint8Array(instruction.discriminator);
7230
+ }
7231
+ throw new Error(`Unknown instruction: ${instructionName}`);
7232
+ }
7233
+ /**
7234
+ * Get bond state stats
7235
+ * @param state
7236
+ * @private
7237
+ */
7238
+ async getBondStateStats(state) {
7239
+ const validatorBonds = await this.getValidatorBondsByState(state.bondType, state.name);
7240
+ const totalCollected = await this.getBondStateTotalCollected(
7241
+ state.bondType,
7242
+ state.name,
7243
+ validatorBonds.map((vb) => vb.voteAccount)
7244
+ );
7245
+ return {
7246
+ totalCollected,
7247
+ status: this.getBondStateSessionStatus(state)
7248
+ };
7249
+ }
6884
7250
  /**
6885
7251
  * Load stake pool account and cache it if not already cached
6886
7252
  * @private
@@ -6926,6 +7292,6 @@ buffer/index.js:
6926
7292
  *)
6927
7293
  */
6928
7294
 
6929
- export { BondClientEnv, BondTransactionType, BondTypeVariant, ENV_PROGRAM_ID, JBondClient, JPOOL_STAKE_POOL, NodeWallet, Seeds, SessionStatus, bondTypeToSeed };
7295
+ export { BondClientEnv, BondStateStatusVariant, BondTransactionType, BondTypeVariant, ENV_PROGRAM_ID, JBondClient, JPOOL_STAKE_POOL, NodeWallet, Seeds, SessionStatus, bondTypeToSeed };
6930
7296
  //# sourceMappingURL=index.mjs.map
6931
7297
  //# sourceMappingURL=index.mjs.map