@jpool/bond-sdk 0.9.0-next.0 → 0.9.0-next.2

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.js CHANGED
@@ -11,6 +11,11 @@ var bs58__default = /*#__PURE__*/_interopDefault(bs58);
11
11
  // src/client.ts
12
12
 
13
13
  // src/constants.ts
14
+ var Seeds = /* @__PURE__ */ ((Seeds2) => {
15
+ Seeds2["GlobalState"] = "global_state";
16
+ Seeds2["ValidatorBond"] = "validator_bond";
17
+ return Seeds2;
18
+ })(Seeds || {});
14
19
  var ENV_PROGRAM_ID = {
15
20
  // [BondClientEnv.DEV]: new PublicKey('...'),
16
21
  };
@@ -1080,14 +1085,14 @@ var JBondClient = class _JBondClient {
1080
1085
  pda = {
1081
1086
  globalState: () => {
1082
1087
  return web3_js.PublicKey.findProgramAddressSync(
1083
- [Buffer.from("global_state")],
1088
+ [Buffer.from("global_state" /* GlobalState */)],
1084
1089
  this.programId
1085
1090
  );
1086
1091
  },
1087
1092
  validatorBond: (vote) => {
1088
1093
  return web3_js.PublicKey.findProgramAddressSync(
1089
1094
  [
1090
- Buffer.from("validator_bond"),
1095
+ Buffer.from("validator_bond" /* ValidatorBond */),
1091
1096
  new web3_js.PublicKey(vote).toBuffer()
1092
1097
  ],
1093
1098
  this.programId
@@ -1100,7 +1105,7 @@ var JBondClient = class _JBondClient {
1100
1105
  */
1101
1106
  async initialize(props) {
1102
1107
  const ix = await this.buildInitializeInstruction(props);
1103
- return await this.provider.sendAndConfirm(new web3_js.Transaction().add(ix));
1108
+ return this.provider.sendAndConfirm?.(new web3_js.Transaction().add(ix));
1104
1109
  }
1105
1110
  /**
1106
1111
  * Register a new validator
@@ -1108,7 +1113,7 @@ var JBondClient = class _JBondClient {
1108
1113
  */
1109
1114
  async registerValidator(props) {
1110
1115
  const ix = await this.buildRegisterValidatorInstruction(props);
1111
- return await this.provider.sendAndConfirm(new web3_js.Transaction().add(ix));
1116
+ return this.provider.sendAndConfirm?.(new web3_js.Transaction().add(ix));
1112
1117
  }
1113
1118
  /**
1114
1119
  * Top up collateral
@@ -1116,7 +1121,7 @@ var JBondClient = class _JBondClient {
1116
1121
  */
1117
1122
  async topUpCollateral(props) {
1118
1123
  const ix = await this.buildTopUpCollateralInstruction(props);
1119
- return await this.provider.sendAndConfirm(new web3_js.Transaction().add(ix));
1124
+ return this.provider.sendAndConfirm?.(new web3_js.Transaction().add(ix));
1120
1125
  }
1121
1126
  /**
1122
1127
  * Withdraw collateral
@@ -1126,7 +1131,7 @@ var JBondClient = class _JBondClient {
1126
1131
  */
1127
1132
  async withdrawCollateral(props) {
1128
1133
  const ix = await this.buildWithdrawCollateralInstruction(props);
1129
- return await this.provider.sendAndConfirm(new web3_js.Transaction().add(ix));
1134
+ return this.provider.sendAndConfirm?.(new web3_js.Transaction().add(ix));
1130
1135
  }
1131
1136
  /**
1132
1137
  * Claim compensation
@@ -1135,7 +1140,7 @@ var JBondClient = class _JBondClient {
1135
1140
  */
1136
1141
  async claimCompensation(props) {
1137
1142
  const ix = await this.buildClaimInstruction(props);
1138
- return await this.provider.sendAndConfirm(new web3_js.Transaction().add(ix));
1143
+ return this.provider.sendAndConfirm?.(new web3_js.Transaction().add(ix));
1139
1144
  }
1140
1145
  /**
1141
1146
  * Update global configuration for the program
@@ -1145,7 +1150,7 @@ var JBondClient = class _JBondClient {
1145
1150
  */
1146
1151
  async configure(props) {
1147
1152
  const ix = await this.buildConfigureInstruction(props);
1148
- return await this.provider.sendAndConfirm(new web3_js.Transaction().add(ix));
1153
+ return this.provider.sendAndConfirm?.(new web3_js.Transaction().add(ix));
1149
1154
  }
1150
1155
  /**
1151
1156
  * Set withdrawal authority for validator bond
@@ -1155,7 +1160,7 @@ var JBondClient = class _JBondClient {
1155
1160
  */
1156
1161
  async setWithdrawAuthority(props) {
1157
1162
  const ix = await this.buildSetWithdrawAuthorityInstruction(props);
1158
- return await this.provider.sendAndConfirm(new web3_js.Transaction().add(ix));
1163
+ return this.provider.sendAndConfirm?.(new web3_js.Transaction().add(ix));
1159
1164
  }
1160
1165
  /**
1161
1166
  * Build initialize instruction
@@ -1163,7 +1168,7 @@ var JBondClient = class _JBondClient {
1163
1168
  async buildInitializeInstruction(props) {
1164
1169
  const [globalState] = this.pda.globalState();
1165
1170
  const { reserve } = props;
1166
- const authority = props.authority ?? this.provider.wallet.publicKey;
1171
+ const authority = props.authority ?? this.provider.wallet?.publicKey;
1167
1172
  return this.program.methods.initialize().accountsPartial({
1168
1173
  globalState,
1169
1174
  authority,
@@ -1178,7 +1183,7 @@ var JBondClient = class _JBondClient {
1178
1183
  const [globalState] = this.pda.globalState();
1179
1184
  const [validatorBond] = this.pda.validatorBond(voteAccount);
1180
1185
  const lamports = new anchor.BN(initialCollateral * web3_js.LAMPORTS_PER_SOL);
1181
- const creator = props.creator ?? this.provider.wallet.publicKey;
1186
+ const creator = props.creator ?? this.provider.wallet?.publicKey;
1182
1187
  return this.program.methods.register(lamports).accountsPartial({
1183
1188
  creator,
1184
1189
  globalState,
@@ -1194,7 +1199,7 @@ var JBondClient = class _JBondClient {
1194
1199
  const { voteAccount, amount } = props;
1195
1200
  const [validatorBond] = this.pda.validatorBond(voteAccount);
1196
1201
  const lamports = new anchor.BN(amount * web3_js.LAMPORTS_PER_SOL);
1197
- const payer = props.payer ?? this.provider.wallet.publicKey;
1202
+ const payer = props.payer ?? this.provider.wallet?.publicKey;
1198
1203
  return this.program.methods.topUp(lamports).accountsPartial({
1199
1204
  validatorBond,
1200
1205
  payer
@@ -1207,8 +1212,8 @@ var JBondClient = class _JBondClient {
1207
1212
  const { voteAccount, amount } = props;
1208
1213
  const [validatorBond] = this.pda.validatorBond(voteAccount);
1209
1214
  const lamports = new anchor.BN(amount * web3_js.LAMPORTS_PER_SOL);
1210
- const withdrawalAuthority = props.withdrawalAuthority ?? this.provider.wallet.publicKey;
1211
- const destination = props.destination ?? this.provider.wallet.publicKey;
1215
+ const withdrawalAuthority = props.withdrawalAuthority ?? this.provider.wallet?.publicKey;
1216
+ const destination = props.destination ?? this.provider.wallet?.publicKey;
1212
1217
  return this.program.methods.withdraw(lamports).accountsPartial({
1213
1218
  validatorBond,
1214
1219
  withdrawalAuthority,
@@ -1223,7 +1228,7 @@ var JBondClient = class _JBondClient {
1223
1228
  const [globalState] = this.pda.globalState();
1224
1229
  const [validatorBond] = this.pda.validatorBond(props.voteAccount);
1225
1230
  const lamports = new anchor.BN(props.amount * web3_js.LAMPORTS_PER_SOL);
1226
- const authority = props.authority ?? this.provider.wallet.publicKey;
1231
+ const authority = props.authority ?? this.provider.wallet?.publicKey;
1227
1232
  let reserve = props.reserve;
1228
1233
  if (!reserve) {
1229
1234
  const globalStateData = await this.getGlobalState();
@@ -1244,7 +1249,7 @@ var JBondClient = class _JBondClient {
1244
1249
  */
1245
1250
  async buildConfigureInstruction(props) {
1246
1251
  const [globalState] = this.pda.globalState();
1247
- const authority = props.authority ?? this.provider.wallet.publicKey;
1252
+ const authority = props.authority ?? this.provider.wallet?.publicKey;
1248
1253
  return this.program.methods.configure({
1249
1254
  newAuthority: props.newAuthority ?? null,
1250
1255
  newReserve: props.newReserve ?? null
@@ -1259,7 +1264,7 @@ var JBondClient = class _JBondClient {
1259
1264
  async buildSetWithdrawAuthorityInstruction(props) {
1260
1265
  const { voteAccount, newWithdrawAuthority } = props;
1261
1266
  const [validatorBond] = this.pda.validatorBond(voteAccount);
1262
- const identity = props.identity ?? this.provider.wallet.publicKey;
1267
+ const identity = props.identity ?? this.provider.wallet?.publicKey;
1263
1268
  return this.program.methods.setWithdrawAuthority().accountsPartial({
1264
1269
  validatorBond,
1265
1270
  identity,
@@ -1297,167 +1302,82 @@ var JBondClient = class _JBondClient {
1297
1302
  const availableBalance = Math.max(0, lamports - rentExempt);
1298
1303
  return availableBalance / web3_js.LAMPORTS_PER_SOL;
1299
1304
  }
1300
- /**
1301
- * Get transaction history grouped by epochs
1302
- * @param vote - The vote account to get history for
1303
- * @param epochsCount - Number of recent epochs to return (default: 10)
1304
- * @returns Array of epoch history items sorted by epoch (descending)
1305
- */
1306
- async getHistoryGroupedByEpochs(vote, epochsCount = 10) {
1307
- const epochInfo = await this.connection.getEpochInfo();
1308
- const fullHistory = await this.getFullHistory(new web3_js.PublicKey(vote));
1309
- const epochMap = /* @__PURE__ */ new Map();
1310
- for (const item of fullHistory) {
1311
- if (item.epoch < epochInfo.epoch - epochsCount + 1) {
1312
- continue;
1313
- }
1314
- if (!epochMap.has(item.epoch)) {
1315
- epochMap.set(item.epoch, {
1316
- epoch: item.epoch,
1317
- deposits: 0,
1318
- withdrawals: 0,
1319
- balanceChange: 0,
1320
- signatures: []
1321
- });
1322
- }
1323
- const epochData = epochMap.get(item.epoch);
1324
- if (item.type === "deposit") {
1325
- epochData.deposits += item.amount;
1326
- } else if (item.type === "withdrawal") {
1327
- epochData.withdrawals += item.amount;
1328
- }
1329
- if (!epochData.signatures.includes(item.signature)) {
1330
- epochData.signatures.push(item.signature);
1331
- }
1332
- }
1333
- for (const epochData of epochMap.values()) {
1334
- epochData.balanceChange = epochData.deposits - epochData.withdrawals;
1335
- }
1336
- return [...epochMap.values()].toSorted((a, b) => b.epoch - a.epoch);
1337
- }
1338
1305
  /**
1339
1306
  * Get transaction history for a specific validator bond account
1340
1307
  */
1341
1308
  async getHistory(vote, options) {
1342
- const [ValidatorBondAccount] = this.pda.validatorBond(new web3_js.PublicKey(vote));
1343
- const signatures = (await this.connection.getSignaturesForAddress(
1344
- ValidatorBondAccount,
1345
- {
1346
- limit: options?.limit || 1e3,
1347
- before: options?.before,
1348
- until: options?.until
1349
- }
1350
- )).filter((sig) => !sig.err);
1351
- const signatureStrings = signatures.map((sig) => sig.signature);
1352
- const BATCH_SIZE = 100;
1353
- const allTransactions = [];
1354
- for (let i = 0; i < signatureStrings.length; i += BATCH_SIZE) {
1355
- const batch = signatureStrings.slice(i, i + BATCH_SIZE);
1356
- const transactions = await this.connection.getParsedTransactions(
1357
- batch,
1358
- {
1359
- maxSupportedTransactionVersion: 0
1309
+ const cluster = options?.cluster || "mainnet-beta";
1310
+ const [validatorBondAccount] = this.pda.validatorBond(vote);
1311
+ const signatures = await this.fetchSignaturesForValidator(validatorBondAccount, {
1312
+ limit: options?.limit,
1313
+ before: options?.before,
1314
+ until: options?.until
1315
+ });
1316
+ if (signatures.length === 0) {
1317
+ return [];
1318
+ }
1319
+ const signatureStrings = signatures.map((s) => s.signature);
1320
+ const parsedTxs = await this.fetchParsedTransactions(signatureStrings);
1321
+ const txBySig = /* @__PURE__ */ new Map();
1322
+ for (let i = 0; i < signatureStrings.length; i++) {
1323
+ const requestedSig = signatureStrings[i];
1324
+ const tx = parsedTxs[i] ?? null;
1325
+ if (tx && tx.transaction && Array.isArray(tx.transaction.signatures) && tx.transaction.signatures[0]) {
1326
+ const txSig = tx.transaction.signatures[0];
1327
+ if (txSig !== requestedSig) {
1328
+ const found = parsedTxs.find((t) => t && t.transaction && t.transaction.signatures && t.transaction.signatures[0] === requestedSig) ?? null;
1329
+ txBySig.set(requestedSig, found);
1330
+ continue;
1360
1331
  }
1361
- );
1362
- allTransactions.push(...transactions);
1332
+ }
1333
+ txBySig.set(requestedSig, tx);
1363
1334
  }
1364
- const cluster = options?.cluster || "mainnet-beta";
1365
1335
  const history = [];
1366
- for (const [idx, tx] of allTransactions.entries()) {
1367
- const sigInfo = signatures[idx];
1336
+ for (const sigInfo of signatures) {
1337
+ const sig = sigInfo.signature;
1338
+ const tx = txBySig.get(sig) ?? null;
1368
1339
  if (!tx || !tx.meta || tx.meta.err !== null) {
1369
1340
  continue;
1370
1341
  }
1371
1342
  try {
1372
- const slot = tx.slot || 0;
1343
+ const slot = tx.slot ?? 0;
1373
1344
  const instructions = tx.transaction.message.instructions;
1374
1345
  for (const instruction of instructions) {
1375
- if ("programId" in instruction && instruction.programId.equals(this.options.programId ?? this.program.programId)) {
1376
- const ixData = instruction;
1377
- if ("parsed" in ixData && ixData.parsed) {
1378
- continue;
1379
- }
1380
- const data = ixData.data;
1381
- if (!data) {
1382
- continue;
1383
- }
1384
- let type = null;
1385
- let amount = 0;
1386
- try {
1387
- const dataBuffer = bs58__default.default.decode(data);
1388
- if (dataBuffer.length >= 16) {
1389
- const discriminator = dataBuffer.slice(0, 8);
1390
- const bondInitDiscriminator = this.getInstructionDiscriminator("register");
1391
- const bondTopUpDiscriminator = this.getInstructionDiscriminator("topUp");
1392
- const withdrawCompensationDiscriminator = this.getInstructionDiscriminator("claim");
1393
- const bondWithdrawDiscriminator = this.getInstructionDiscriminator("withdraw");
1394
- const amountBytes = dataBuffer.slice(8, 16);
1395
- const amountBN = new anchor.BN(amountBytes, "le");
1396
- amount = amountBN.toNumber() / web3_js.LAMPORTS_PER_SOL;
1397
- if (Buffer.from(discriminator).equals(Buffer.from(bondInitDiscriminator))) {
1398
- type = "deposit" /* Deposit */;
1399
- } else if (Buffer.from(discriminator).equals(Buffer.from(bondTopUpDiscriminator))) {
1400
- type = "deposit" /* Deposit */;
1401
- } else if (Buffer.from(discriminator).equals(Buffer.from(withdrawCompensationDiscriminator))) {
1402
- type = "compensation" /* Compensation */;
1403
- } else if (Buffer.from(discriminator).equals(Buffer.from(bondWithdrawDiscriminator))) {
1404
- type = "withdrawal" /* Withdrawal */;
1405
- }
1406
- }
1407
- } catch {
1408
- console.warn("Failed to decode instruction data");
1409
- }
1410
- if (type && amount > 0) {
1411
- let beforeBalance;
1412
- let afterBalance;
1413
- const accountIndex = tx.transaction.message.accountKeys.findIndex(
1414
- (key) => key.pubkey.equals(ValidatorBondAccount)
1415
- );
1416
- if (accountIndex !== -1 && tx.meta.preBalances && tx.meta.postBalances) {
1417
- beforeBalance = Number(tx.meta.preBalances[accountIndex] || 0) / web3_js.LAMPORTS_PER_SOL;
1418
- afterBalance = Number(tx.meta.postBalances[accountIndex] || 0) / web3_js.LAMPORTS_PER_SOL;
1419
- }
1420
- history.push({
1421
- signature: sigInfo.signature,
1422
- slot,
1423
- epoch: slotToEpoch(slot, cluster),
1424
- type,
1425
- amount,
1426
- beforeBalance,
1427
- afterBalance
1428
- });
1429
- }
1346
+ if (!("programId" in instruction)) {
1347
+ continue;
1348
+ }
1349
+ if (!instruction.programId.equals(this.options.programId ?? this.program.programId)) {
1350
+ continue;
1351
+ }
1352
+ if (instruction.parsed) {
1353
+ continue;
1430
1354
  }
1355
+ const { type, amount } = this.decodeInstructionData(instruction.data);
1356
+ if (!type || amount <= 0) {
1357
+ continue;
1358
+ }
1359
+ let beforeBalance;
1360
+ let afterBalance;
1361
+ const accountIndex = tx.transaction.message.accountKeys.findIndex((k) => k.pubkey.equals(validatorBondAccount));
1362
+ if (accountIndex !== -1 && tx.meta.preBalances && tx.meta.postBalances) {
1363
+ beforeBalance = Number(tx.meta.preBalances[accountIndex] || 0) / web3_js.LAMPORTS_PER_SOL;
1364
+ afterBalance = Number(tx.meta.postBalances[accountIndex] || 0) / web3_js.LAMPORTS_PER_SOL;
1365
+ }
1366
+ history.push({
1367
+ signature: sigInfo.signature,
1368
+ slot,
1369
+ epoch: slotToEpoch(slot, cluster),
1370
+ type,
1371
+ amount,
1372
+ beforeBalance,
1373
+ afterBalance
1374
+ });
1431
1375
  }
1432
1376
  } catch (error) {
1433
1377
  console.error(`Error processing transaction ${sigInfo.signature}:`, error);
1434
1378
  }
1435
1379
  }
1436
- return history.toSorted((a, b) => b.slot - a.slot);
1437
- }
1438
- /**
1439
- * Get full transaction history by paginating through results
1440
- * @param voteAccount
1441
- * @param pageSize
1442
- */
1443
- async getFullHistory(voteAccount, pageSize = 100) {
1444
- const allHistory = [];
1445
- let before;
1446
- while (true) {
1447
- const batch = await this.getHistory(voteAccount, {
1448
- limit: pageSize,
1449
- before
1450
- });
1451
- if (batch.length === 0) {
1452
- break;
1453
- }
1454
- allHistory.push(...batch);
1455
- before = batch.at(-1)?.signature;
1456
- if (batch.length < pageSize) {
1457
- break;
1458
- }
1459
- }
1460
- return allHistory;
1380
+ return history.sort((a, b) => b.slot - a.slot);
1461
1381
  }
1462
1382
  /**
1463
1383
  * Get instruction discriminator from IDL
@@ -1474,6 +1394,69 @@ var JBondClient = class _JBondClient {
1474
1394
  }
1475
1395
  return new Uint8Array(instruction.discriminator);
1476
1396
  }
1397
+ async fetchSignaturesForValidator(validatorBondAccount, options) {
1398
+ const sigs = await this.connection.getSignaturesForAddress(
1399
+ validatorBondAccount,
1400
+ {
1401
+ limit: options?.limit || 1e3,
1402
+ before: options?.before,
1403
+ until: options?.until
1404
+ }
1405
+ );
1406
+ return sigs.filter((s) => !s.err);
1407
+ }
1408
+ // Fetch parsed transactions in batches to avoid rate limits
1409
+ async fetchParsedTransactions(signatureStrings, batchSize = 100) {
1410
+ const allTxs = [];
1411
+ for (let i = 0; i < signatureStrings.length; i += batchSize) {
1412
+ const batch = signatureStrings.slice(i, i + batchSize);
1413
+ const txs = await this.connection.getParsedTransactions(batch, {
1414
+ maxSupportedTransactionVersion: 0
1415
+ });
1416
+ allTxs.push(...txs);
1417
+ }
1418
+ return allTxs;
1419
+ }
1420
+ /**
1421
+ * Decode instruction data to determine transaction type and amount
1422
+ * @param data
1423
+ * @private
1424
+ */
1425
+ decodeInstructionData(data) {
1426
+ if (!data) {
1427
+ return { type: null, amount: 0 };
1428
+ }
1429
+ try {
1430
+ const dataBuffer = bs58__default.default.decode(data);
1431
+ if (dataBuffer.length < 16) {
1432
+ return { type: null, amount: 0 };
1433
+ }
1434
+ const discriminator = dataBuffer.slice(0, 8);
1435
+ const amountBytes = dataBuffer.slice(8, 16);
1436
+ const amountBN = new anchor.BN(amountBytes, "le");
1437
+ const amount = amountBN.toNumber() / web3_js.LAMPORTS_PER_SOL;
1438
+ const bondInitDiscriminator = this.getInstructionDiscriminator("register");
1439
+ const bondTopUpDiscriminator = this.getInstructionDiscriminator("topUp");
1440
+ const withdrawCompensationDiscriminator = this.getInstructionDiscriminator("claim");
1441
+ const bondWithdrawDiscriminator = this.getInstructionDiscriminator("withdraw");
1442
+ if (Buffer.from(discriminator).equals(Buffer.from(bondInitDiscriminator))) {
1443
+ return { type: "deposit" /* Deposit */, amount };
1444
+ }
1445
+ if (Buffer.from(discriminator).equals(Buffer.from(bondTopUpDiscriminator))) {
1446
+ return { type: "deposit" /* Deposit */, amount };
1447
+ }
1448
+ if (Buffer.from(discriminator).equals(Buffer.from(withdrawCompensationDiscriminator))) {
1449
+ return { type: "compensation" /* Compensation */, amount };
1450
+ }
1451
+ if (Buffer.from(discriminator).equals(Buffer.from(bondWithdrawDiscriminator))) {
1452
+ return { type: "withdrawal" /* Withdrawal */, amount };
1453
+ }
1454
+ return { type: null, amount: 0 };
1455
+ } catch (err) {
1456
+ console.warn("Failed to decode instruction data", err);
1457
+ return { type: null, amount: 0 };
1458
+ }
1459
+ }
1477
1460
  };
1478
1461
 
1479
1462
  exports.BondClientEnv = BondClientEnv;
@@ -1481,5 +1464,6 @@ exports.BondTransactionType = BondTransactionType;
1481
1464
  exports.ENV_PROGRAM_ID = ENV_PROGRAM_ID;
1482
1465
  exports.JBondClient = JBondClient;
1483
1466
  exports.NodeWallet = NodeWallet;
1467
+ exports.Seeds = Seeds;
1484
1468
  //# sourceMappingURL=index.js.map
1485
1469
  //# sourceMappingURL=index.js.map