genlayer-js 0.18.4 → 0.18.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/CLAUDE.md +66 -0
  3. package/README.md +52 -1
  4. package/dist/chains/index.cjs +2 -2
  5. package/dist/chains/index.d.cts +2 -2
  6. package/dist/chains/index.d.ts +2 -2
  7. package/dist/chains/index.js +1 -1
  8. package/dist/{chains-BIe_Q0mF.d.cts → chains-B7B7UXdn.d.cts} +6 -2
  9. package/dist/{chains-BIe_Q0mF.d.ts → chains-B7B7UXdn.d.ts} +6 -2
  10. package/dist/{chunk-NO75TOQL.js → chunk-KVHGQTAI.js} +539 -4
  11. package/dist/{chunk-SMGWE7OH.cjs → chunk-QAAO2WJL.cjs} +540 -5
  12. package/dist/index-3leEwFoq.d.cts +1389 -0
  13. package/dist/index-BBh1NZjP.d.ts +1389 -0
  14. package/dist/{index-C5zeayBB.d.cts → index-BVDASTaU.d.cts} +1 -1
  15. package/dist/{index-BpFWfpio.d.ts → index-ucNO2REF.d.ts} +1 -1
  16. package/dist/index.cjs +551 -38
  17. package/dist/index.d.cts +17 -5
  18. package/dist/index.d.ts +17 -5
  19. package/dist/index.js +528 -15
  20. package/dist/types/index.cjs +2 -2
  21. package/dist/types/index.d.cts +2 -2
  22. package/dist/types/index.d.ts +2 -2
  23. package/dist/types/index.js +1 -1
  24. package/package.json +1 -1
  25. package/src/abi/index.ts +1 -0
  26. package/src/abi/staking.ts +525 -0
  27. package/src/chains/localnet.ts +2 -1
  28. package/src/chains/studionet.ts +1 -0
  29. package/src/chains/testnetAsimov.ts +10 -3
  30. package/src/client/client.ts +17 -15
  31. package/src/index.ts +1 -0
  32. package/src/staking/actions.ts +609 -0
  33. package/src/staking/index.ts +2 -0
  34. package/src/staking/utils.ts +22 -0
  35. package/src/types/chains.ts +6 -2
  36. package/src/types/clients.ts +6 -6
  37. package/src/types/index.ts +1 -0
  38. package/src/types/staking.ts +228 -0
  39. package/tsconfig.vitest-temp.json +41 -0
  40. package/dist/index-B2AY6_eD.d.ts +0 -407
  41. package/dist/index-BYma5s90.d.cts +0 -407
  42. /package/dist/{chunk-FPZNF3JH.cjs → chunk-W4V73RPN.cjs} +0 -0
  43. /package/dist/{chunk-47QDX7IX.js → chunk-ZHBOSLFN.js} +0 -0
package/dist/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as viem from 'viem';
2
2
  import { Account, Address, Hex } from 'viem';
3
- import { G as GenLayerChain } from './chains-BIe_Q0mF.cjs';
4
- import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement } from './index-BYma5s90.cjs';
3
+ import { G as GenLayerChain } from './chains-B7B7UXdn.cjs';
4
+ import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement, S as STAKING_ABI, V as VALIDATOR_WALLET_ABI } from './index-3leEwFoq.cjs';
5
5
  import * as abitype from 'abitype';
6
6
  import * as viem__types_types_authorization from 'viem/_types/types/authorization';
7
7
  import * as viem_accounts from 'viem/accounts';
8
- export { i as chains } from './index-C5zeayBB.cjs';
8
+ export { i as chains } from './index-BVDASTaU.cjs';
9
9
 
10
10
  interface ClientConfig {
11
11
  chain?: {
@@ -88,10 +88,22 @@ declare namespace tx {
88
88
  declare const calldata: typeof cd;
89
89
  declare const transactions: typeof tx;
90
90
 
91
+ declare const index_STAKING_ABI: typeof STAKING_ABI;
92
+ declare const index_VALIDATOR_WALLET_ABI: typeof VALIDATOR_WALLET_ABI;
91
93
  declare const index_calldata: typeof calldata;
92
94
  declare const index_transactions: typeof transactions;
93
95
  declare namespace index {
94
- export { index_calldata as calldata, index_transactions as transactions };
96
+ export { index_STAKING_ABI as STAKING_ABI, index_VALIDATOR_WALLET_ABI as VALIDATOR_WALLET_ABI, index_calldata as calldata, index_transactions as transactions };
95
97
  }
96
98
 
97
- export { index as abi, createAccount, createClient, decodeInputData, decodeLocalnetTransaction, decodeTransaction, generatePrivateKey, simplifyTransactionReceipt };
99
+ /**
100
+ * Parse staking amount. Use "gen" suffix for GEN tokens (e.g. "42gen"),
101
+ * otherwise value is treated as wei (e.g. "42000000000000000000" = 42 GEN).
102
+ */
103
+ declare function parseStakingAmount(amount: string | bigint): bigint;
104
+ /**
105
+ * Format bigint amount to human-readable GEN string.
106
+ */
107
+ declare function formatStakingAmount(amount: bigint): string;
108
+
109
+ export { index as abi, createAccount, createClient, decodeInputData, decodeLocalnetTransaction, decodeTransaction, formatStakingAmount, generatePrivateKey, parseStakingAmount, simplifyTransactionReceipt };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as viem from 'viem';
2
2
  import { Account, Address, Hex } from 'viem';
3
- import { G as GenLayerChain } from './chains-BIe_Q0mF.js';
4
- import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement } from './index-B2AY6_eD.js';
3
+ import { G as GenLayerChain } from './chains-B7B7UXdn.js';
4
+ import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement, S as STAKING_ABI, V as VALIDATOR_WALLET_ABI } from './index-BBh1NZjP.js';
5
5
  import * as abitype from 'abitype';
6
6
  import * as viem__types_types_authorization from 'viem/_types/types/authorization';
7
7
  import * as viem_accounts from 'viem/accounts';
8
- export { i as chains } from './index-BpFWfpio.js';
8
+ export { i as chains } from './index-ucNO2REF.js';
9
9
 
10
10
  interface ClientConfig {
11
11
  chain?: {
@@ -88,10 +88,22 @@ declare namespace tx {
88
88
  declare const calldata: typeof cd;
89
89
  declare const transactions: typeof tx;
90
90
 
91
+ declare const index_STAKING_ABI: typeof STAKING_ABI;
92
+ declare const index_VALIDATOR_WALLET_ABI: typeof VALIDATOR_WALLET_ABI;
91
93
  declare const index_calldata: typeof calldata;
92
94
  declare const index_transactions: typeof transactions;
93
95
  declare namespace index {
94
- export { index_calldata as calldata, index_transactions as transactions };
96
+ export { index_STAKING_ABI as STAKING_ABI, index_VALIDATOR_WALLET_ABI as VALIDATOR_WALLET_ABI, index_calldata as calldata, index_transactions as transactions };
95
97
  }
96
98
 
97
- export { index as abi, createAccount, createClient, decodeInputData, decodeLocalnetTransaction, decodeTransaction, generatePrivateKey, simplifyTransactionReceipt };
99
+ /**
100
+ * Parse staking amount. Use "gen" suffix for GEN tokens (e.g. "42gen"),
101
+ * otherwise value is treated as wei (e.g. "42000000000000000000" = 42 GEN).
102
+ */
103
+ declare function parseStakingAmount(amount: string | bigint): bigint;
104
+ /**
105
+ * Format bigint amount to human-readable GEN string.
106
+ */
107
+ declare function formatStakingAmount(amount: bigint): string;
108
+
109
+ export { index as abi, createAccount, createClient, decodeInputData, decodeLocalnetTransaction, decodeTransaction, formatStakingAmount, generatePrivateKey, parseStakingAmount, simplifyTransactionReceipt };
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import {
2
+ STAKING_ABI,
3
+ VALIDATOR_WALLET_ABI,
2
4
  chains_exports,
3
5
  localnet,
4
6
  studionet,
5
7
  testnetAsimov
6
- } from "./chunk-NO75TOQL.js";
8
+ } from "./chunk-KVHGQTAI.js";
7
9
  import {
8
10
  CalldataAddress,
9
11
  isDecidedState,
@@ -11,7 +13,7 @@ import {
11
13
  transactionsStatusNameToNumber,
12
14
  transactionsStatusNumberToName,
13
15
  voteTypeNumberToName
14
- } from "./chunk-47QDX7IX.js";
16
+ } from "./chunk-ZHBOSLFN.js";
15
17
  import {
16
18
  __export
17
19
  } from "./chunk-MLKGABMK.js";
@@ -413,6 +415,8 @@ import { fromHex, toHex as toHex3, zeroAddress, encodeFunctionData, parseEventLo
413
415
  // src/abi/index.ts
414
416
  var abi_exports = {};
415
417
  __export(abi_exports, {
418
+ STAKING_ABI: () => STAKING_ABI,
419
+ VALIDATOR_WALLET_ABI: () => VALIDATOR_WALLET_ABI,
416
420
  calldata: () => calldata,
417
421
  transactions: () => transactions
418
422
  });
@@ -681,13 +685,13 @@ var contractActions = (client, publicClient) => {
681
685
  }
682
686
  };
683
687
  };
684
- var validateAccount = (Account3) => {
685
- if (!Account3) {
688
+ var validateAccount = (Account4) => {
689
+ if (!Account4) {
686
690
  throw new Error(
687
691
  "No account set. Configure the client with an account or pass an account to this function."
688
692
  );
689
693
  }
690
- return Account3;
694
+ return Account4;
691
695
  };
692
696
  var _encodeAddTransactionData = ({
693
697
  client,
@@ -1212,6 +1216,509 @@ function walletActions(client) {
1212
1216
  };
1213
1217
  }
1214
1218
 
1219
+ // src/staking/actions.ts
1220
+ import { getContract, decodeEventLog, toHex as toHex4, encodeFunctionData as encodeFunctionData2, BaseError, ContractFunctionRevertedError } from "viem";
1221
+
1222
+ // src/staking/utils.ts
1223
+ import { parseEther, formatEther } from "viem";
1224
+ function parseStakingAmount(amount) {
1225
+ if (typeof amount === "bigint") return amount;
1226
+ const trimmed = amount.trim();
1227
+ const lower = trimmed.toLowerCase();
1228
+ if (lower.endsWith("gen")) {
1229
+ return parseEther(lower.slice(0, -3).trim());
1230
+ }
1231
+ return BigInt(trimmed);
1232
+ }
1233
+ function formatStakingAmount(amount) {
1234
+ return `${formatEther(amount)} GEN`;
1235
+ }
1236
+
1237
+ // src/staking/actions.ts
1238
+ var FALLBACK_GAS = 1000000n;
1239
+ var GAS_BUFFER_MULTIPLIER = 2n;
1240
+ function extractRevertReason(err) {
1241
+ if (err instanceof BaseError) {
1242
+ const revertError = err.walk((e) => e instanceof ContractFunctionRevertedError);
1243
+ if (revertError instanceof ContractFunctionRevertedError) {
1244
+ return revertError.data?.errorName || revertError.reason || "Unknown reason";
1245
+ }
1246
+ if (err.shortMessage) return err.shortMessage;
1247
+ }
1248
+ if (err instanceof Error) return err.message;
1249
+ return "Unknown reason";
1250
+ }
1251
+ var stakingActions = (client, publicClient) => {
1252
+ const executeWrite = async (options) => {
1253
+ if (!client.account) {
1254
+ throw new Error("Account is required for write operations. Initialize client with a wallet account.");
1255
+ }
1256
+ const account = client.account;
1257
+ try {
1258
+ await publicClient.call({
1259
+ account,
1260
+ to: options.to,
1261
+ data: options.data,
1262
+ value: options.value
1263
+ });
1264
+ } catch (err) {
1265
+ const revertReason = extractRevertReason(err);
1266
+ throw new Error(`Transaction would revert: ${revertReason}`);
1267
+ }
1268
+ let gasLimit = options.gas;
1269
+ if (!gasLimit) {
1270
+ try {
1271
+ const estimated = await publicClient.estimateGas({
1272
+ account,
1273
+ to: options.to,
1274
+ data: options.data,
1275
+ value: options.value
1276
+ });
1277
+ gasLimit = estimated * GAS_BUFFER_MULTIPLIER;
1278
+ } catch {
1279
+ gasLimit = FALLBACK_GAS;
1280
+ }
1281
+ }
1282
+ const nonce = await publicClient.getTransactionCount({ address: account.address });
1283
+ const txRequest = await publicClient.prepareTransactionRequest({
1284
+ account,
1285
+ to: options.to,
1286
+ data: options.data,
1287
+ value: options.value,
1288
+ type: "legacy",
1289
+ nonce,
1290
+ gas: gasLimit,
1291
+ chain: client.chain
1292
+ });
1293
+ const signTransaction = account.signTransaction;
1294
+ if (!signTransaction) {
1295
+ throw new Error("Account does not support signing transactions");
1296
+ }
1297
+ const serializedTx = await signTransaction(txRequest);
1298
+ const hash = await publicClient.sendRawTransaction({ serializedTransaction: serializedTx });
1299
+ const receipt = await publicClient.waitForTransactionReceipt({ hash });
1300
+ if (receipt.status === "reverted") {
1301
+ let revertReason = "Unknown reason";
1302
+ try {
1303
+ await publicClient.call({
1304
+ account,
1305
+ to: options.to,
1306
+ data: options.data,
1307
+ value: options.value,
1308
+ blockNumber: receipt.blockNumber
1309
+ });
1310
+ const gasUsed = receipt.gasUsed;
1311
+ if (gasUsed >= gasLimit - 1000n) {
1312
+ revertReason = `Out of gas (used ${gasUsed}, limit ${gasLimit})`;
1313
+ } else {
1314
+ revertReason = `Unknown (simulation passes but tx reverts). Gas: ${gasUsed}/${gasLimit}`;
1315
+ }
1316
+ } catch (err) {
1317
+ revertReason = extractRevertReason(err);
1318
+ }
1319
+ throw new Error(`Transaction reverted: ${revertReason} (tx: ${hash})`);
1320
+ }
1321
+ return {
1322
+ transactionHash: receipt.transactionHash,
1323
+ blockNumber: receipt.blockNumber,
1324
+ gasUsed: receipt.gasUsed
1325
+ };
1326
+ };
1327
+ const getStakingAddress = () => {
1328
+ const stakingConfig = client.chain.stakingContract;
1329
+ if (!stakingConfig?.address || stakingConfig.address === "0x0000000000000000000000000000000000000000") {
1330
+ throw new Error("Staking is not supported on studio-based networks. Use testnet-asimov for staking operations.");
1331
+ }
1332
+ return stakingConfig.address;
1333
+ };
1334
+ const getStakingContract = () => {
1335
+ const address = getStakingAddress();
1336
+ return getContract({
1337
+ address,
1338
+ abi: STAKING_ABI,
1339
+ client: { public: publicClient, wallet: client }
1340
+ });
1341
+ };
1342
+ const getReadOnlyStakingContract = () => {
1343
+ const address = getStakingAddress();
1344
+ return getContract({
1345
+ address,
1346
+ abi: STAKING_ABI,
1347
+ client: publicClient
1348
+ });
1349
+ };
1350
+ return {
1351
+ validatorJoin: async (options) => {
1352
+ const amount = parseStakingAmount(options.amount);
1353
+ const stakingAddress = getStakingAddress();
1354
+ const data = options.operator ? encodeFunctionData2({
1355
+ abi: STAKING_ABI,
1356
+ functionName: "validatorJoin",
1357
+ args: [options.operator]
1358
+ }) : encodeFunctionData2({
1359
+ abi: STAKING_ABI,
1360
+ functionName: "validatorJoin"
1361
+ });
1362
+ const result = await executeWrite({ to: stakingAddress, data, value: amount });
1363
+ const receipt = await publicClient.getTransactionReceipt({ hash: result.transactionHash });
1364
+ let validatorWallet;
1365
+ let eventFound = false;
1366
+ for (const log of receipt.logs) {
1367
+ try {
1368
+ const decoded = decodeEventLog({ abi: STAKING_ABI, data: log.data, topics: log.topics });
1369
+ if (decoded.eventName === "ValidatorJoin") {
1370
+ validatorWallet = decoded.args.validator;
1371
+ eventFound = true;
1372
+ break;
1373
+ }
1374
+ } catch {
1375
+ }
1376
+ }
1377
+ if (!eventFound) {
1378
+ throw new Error(
1379
+ `ValidatorJoin event not found in transaction ${result.transactionHash}. Transaction succeeded but validator wallet address could not be determined.`
1380
+ );
1381
+ }
1382
+ return {
1383
+ transactionHash: receipt.transactionHash,
1384
+ blockNumber: receipt.blockNumber,
1385
+ gasUsed: receipt.gasUsed,
1386
+ validatorWallet,
1387
+ operator: options.operator || client.account.address,
1388
+ amount: formatStakingAmount(amount),
1389
+ amountRaw: amount
1390
+ };
1391
+ },
1392
+ validatorDeposit: async (options) => {
1393
+ const amount = parseStakingAmount(options.amount);
1394
+ const data = encodeFunctionData2({
1395
+ abi: STAKING_ABI,
1396
+ functionName: "validatorDeposit"
1397
+ });
1398
+ return executeWrite({ to: getStakingAddress(), data, value: amount });
1399
+ },
1400
+ validatorExit: async (options) => {
1401
+ const shares = typeof options.shares === "string" ? BigInt(options.shares) : options.shares;
1402
+ const data = encodeFunctionData2({
1403
+ abi: STAKING_ABI,
1404
+ functionName: "validatorExit",
1405
+ args: [shares]
1406
+ });
1407
+ return executeWrite({ to: getStakingAddress(), data });
1408
+ },
1409
+ validatorClaim: async (options) => {
1410
+ if (!options?.validator && !client.account) {
1411
+ throw new Error("Either provide validator address or initialize client with an account");
1412
+ }
1413
+ const validatorAddress = options?.validator || client.account.address;
1414
+ const data = encodeFunctionData2({
1415
+ abi: STAKING_ABI,
1416
+ functionName: "validatorClaim",
1417
+ args: [validatorAddress]
1418
+ });
1419
+ const result = await executeWrite({ to: getStakingAddress(), data });
1420
+ return { ...result, claimedAmount: 0n };
1421
+ },
1422
+ validatorPrime: async (options) => {
1423
+ const data = encodeFunctionData2({
1424
+ abi: STAKING_ABI,
1425
+ functionName: "validatorPrime",
1426
+ args: [options.validator]
1427
+ });
1428
+ return executeWrite({ to: getStakingAddress(), data });
1429
+ },
1430
+ setOperator: async (options) => {
1431
+ const data = encodeFunctionData2({
1432
+ abi: VALIDATOR_WALLET_ABI,
1433
+ functionName: "setOperator",
1434
+ args: [options.operator]
1435
+ });
1436
+ return executeWrite({ to: options.validator, data });
1437
+ },
1438
+ setIdentity: async (options) => {
1439
+ let extraCidBytes = "0x";
1440
+ if (options.extraCid) {
1441
+ if (options.extraCid.startsWith("0x")) {
1442
+ extraCidBytes = options.extraCid;
1443
+ } else {
1444
+ extraCidBytes = toHex4(new TextEncoder().encode(options.extraCid));
1445
+ }
1446
+ }
1447
+ const data = encodeFunctionData2({
1448
+ abi: VALIDATOR_WALLET_ABI,
1449
+ functionName: "setIdentity",
1450
+ args: [
1451
+ options.moniker,
1452
+ options.logoUri || "",
1453
+ options.website || "",
1454
+ options.description || "",
1455
+ options.email || "",
1456
+ options.twitter || "",
1457
+ options.telegram || "",
1458
+ options.github || "",
1459
+ extraCidBytes
1460
+ ]
1461
+ });
1462
+ return executeWrite({ to: options.validator, data });
1463
+ },
1464
+ delegatorJoin: async (options) => {
1465
+ const amount = parseStakingAmount(options.amount);
1466
+ const data = encodeFunctionData2({
1467
+ abi: STAKING_ABI,
1468
+ functionName: "delegatorJoin",
1469
+ args: [options.validator]
1470
+ });
1471
+ const result = await executeWrite({ to: getStakingAddress(), data, value: amount });
1472
+ return {
1473
+ ...result,
1474
+ validator: options.validator,
1475
+ delegator: client.account.address,
1476
+ amount: formatStakingAmount(amount),
1477
+ amountRaw: amount
1478
+ };
1479
+ },
1480
+ delegatorExit: async (options) => {
1481
+ const shares = typeof options.shares === "string" ? BigInt(options.shares) : options.shares;
1482
+ const data = encodeFunctionData2({
1483
+ abi: STAKING_ABI,
1484
+ functionName: "delegatorExit",
1485
+ args: [options.validator, shares]
1486
+ });
1487
+ return executeWrite({ to: getStakingAddress(), data });
1488
+ },
1489
+ delegatorClaim: async (options) => {
1490
+ if (!options.delegator && !client.account) {
1491
+ throw new Error("Either provide delegator address or initialize client with an account");
1492
+ }
1493
+ const delegatorAddress = options.delegator || client.account.address;
1494
+ const data = encodeFunctionData2({
1495
+ abi: STAKING_ABI,
1496
+ functionName: "delegatorClaim",
1497
+ args: [delegatorAddress, options.validator]
1498
+ });
1499
+ return executeWrite({ to: getStakingAddress(), data });
1500
+ },
1501
+ isValidator: async (address) => {
1502
+ const contract = getReadOnlyStakingContract();
1503
+ return contract.read.isValidator([address]);
1504
+ },
1505
+ getValidatorInfo: async (validator) => {
1506
+ const contract = getReadOnlyStakingContract();
1507
+ const isVal = await contract.read.isValidator([validator]);
1508
+ if (!isVal) {
1509
+ throw new Error(`Address ${validator} is not a validator`);
1510
+ }
1511
+ const walletContract = getContract({
1512
+ address: validator,
1513
+ abi: VALIDATOR_WALLET_ABI,
1514
+ client: publicClient
1515
+ });
1516
+ const [view, owner, operator, identityRaw, currentEpoch] = await Promise.all([
1517
+ contract.read.validatorView([validator]),
1518
+ walletContract.read.owner(),
1519
+ walletContract.read.operator(),
1520
+ walletContract.read.getIdentity().catch(() => null),
1521
+ contract.read.epoch()
1522
+ ]);
1523
+ let identity;
1524
+ if (identityRaw && identityRaw.moniker) {
1525
+ identity = {
1526
+ moniker: identityRaw.moniker,
1527
+ logoUri: identityRaw.logoUri,
1528
+ website: identityRaw.website,
1529
+ description: identityRaw.description,
1530
+ email: identityRaw.email,
1531
+ twitter: identityRaw.twitter,
1532
+ telegram: identityRaw.telegram,
1533
+ github: identityRaw.github,
1534
+ extraCid: identityRaw.extraCid ? toHex4(identityRaw.extraCid) : ""
1535
+ };
1536
+ }
1537
+ const needsPriming = currentEpoch > 0n && view.ePrimed < currentEpoch - 1n;
1538
+ const depositLen = await contract.read.validatorDepositLen([validator]);
1539
+ const pendingDeposits = [];
1540
+ for (let i = 0n; i < depositLen; i++) {
1541
+ const [epoch, commit] = await contract.read.validatorDeposit([validator, i]);
1542
+ pendingDeposits.push({
1543
+ epoch,
1544
+ stake: formatStakingAmount(commit.input),
1545
+ stakeRaw: commit.input,
1546
+ shares: commit.output
1547
+ });
1548
+ }
1549
+ const withdrawalLen = await contract.read.validatorWithdrawalLen([validator]);
1550
+ const pendingWithdrawals = [];
1551
+ for (let i = 0n; i < withdrawalLen; i++) {
1552
+ const [epoch, commit] = await contract.read.validatorWithdrawal([validator, i]);
1553
+ pendingWithdrawals.push({
1554
+ epoch,
1555
+ shares: commit.input,
1556
+ stake: formatStakingAmount(commit.output),
1557
+ stakeRaw: commit.output
1558
+ });
1559
+ }
1560
+ return {
1561
+ address: validator,
1562
+ owner,
1563
+ operator,
1564
+ vStake: formatStakingAmount(view.vStake),
1565
+ vStakeRaw: view.vStake,
1566
+ vShares: view.vShares,
1567
+ dStake: formatStakingAmount(view.dStake),
1568
+ dStakeRaw: view.dStake,
1569
+ dShares: view.dShares,
1570
+ vDeposit: formatStakingAmount(view.vDeposit),
1571
+ vDepositRaw: view.vDeposit,
1572
+ vWithdrawal: formatStakingAmount(view.vWithdrawal),
1573
+ vWithdrawalRaw: view.vWithdrawal,
1574
+ ePrimed: view.ePrimed,
1575
+ live: view.live,
1576
+ banned: view.eBanned > 0n,
1577
+ bannedEpoch: view.eBanned > 0n ? view.eBanned : void 0,
1578
+ needsPriming,
1579
+ identity,
1580
+ pendingDeposits,
1581
+ pendingWithdrawals
1582
+ };
1583
+ },
1584
+ getStakeInfo: async (delegator, validator) => {
1585
+ const contract = getReadOnlyStakingContract();
1586
+ const shares = await contract.read.sharesOf([delegator, validator]);
1587
+ let stake = 0n;
1588
+ if (shares > 0n) {
1589
+ stake = await contract.read.stakeOf([delegator, validator]);
1590
+ }
1591
+ const depositLen = await contract.read.delegatorDepositLen([
1592
+ delegator,
1593
+ validator
1594
+ ]);
1595
+ const pendingDeposits = [];
1596
+ for (let i = 0n; i < depositLen; i++) {
1597
+ const [claim, commit] = await contract.read.delegatorDeposit([
1598
+ delegator,
1599
+ validator,
1600
+ i
1601
+ ]);
1602
+ pendingDeposits.push({
1603
+ epoch: commit.epoch,
1604
+ stake: formatStakingAmount(commit.input),
1605
+ stakeRaw: commit.input,
1606
+ shares: claim.quantity
1607
+ });
1608
+ }
1609
+ const withdrawalLen = await contract.read.delegatorWithdrawalLen([
1610
+ delegator,
1611
+ validator
1612
+ ]);
1613
+ const pendingWithdrawals = [];
1614
+ for (let i = 0n; i < withdrawalLen; i++) {
1615
+ const [claim, commit] = await contract.read.delegatorWithdrawal([
1616
+ delegator,
1617
+ validator,
1618
+ i
1619
+ ]);
1620
+ pendingWithdrawals.push({
1621
+ epoch: commit.epoch,
1622
+ shares: claim.quantity,
1623
+ stake: formatStakingAmount(commit.output),
1624
+ stakeRaw: commit.output
1625
+ });
1626
+ }
1627
+ return {
1628
+ delegator,
1629
+ validator,
1630
+ shares,
1631
+ stake: formatStakingAmount(stake),
1632
+ stakeRaw: stake,
1633
+ pendingDeposits,
1634
+ pendingWithdrawals
1635
+ };
1636
+ },
1637
+ getEpochInfo: async () => {
1638
+ const contract = getReadOnlyStakingContract();
1639
+ const [
1640
+ epoch,
1641
+ validatorMinStake,
1642
+ delegatorMinStake,
1643
+ activeCount,
1644
+ epochMinDuration,
1645
+ epochZeroMinDuration,
1646
+ epochOdd,
1647
+ epochEven
1648
+ ] = await Promise.all([
1649
+ contract.read.epoch(),
1650
+ contract.read.validatorMinStake(),
1651
+ contract.read.delegatorMinStake(),
1652
+ contract.read.activeValidatorsCount(),
1653
+ contract.read.epochMinDuration(),
1654
+ contract.read.epochZeroMinDuration(),
1655
+ contract.read.epochOdd(),
1656
+ contract.read.epochEven()
1657
+ ]);
1658
+ const currentEpochData = epoch % 2n === 0n ? epochEven : epochOdd;
1659
+ const currentEpochStart = new Date(Number(currentEpochData.start) * 1e3);
1660
+ const currentEpochEnd = currentEpochData.end > 0n ? new Date(Number(currentEpochData.end) * 1e3) : null;
1661
+ let nextEpochEstimate = null;
1662
+ if (!currentEpochEnd) {
1663
+ const duration = epoch === 0n ? epochZeroMinDuration : epochMinDuration;
1664
+ const estimatedEndMs = Number(currentEpochData.start + duration) * 1e3;
1665
+ nextEpochEstimate = new Date(estimatedEndMs);
1666
+ }
1667
+ return {
1668
+ currentEpoch: epoch,
1669
+ validatorMinStake: formatStakingAmount(validatorMinStake),
1670
+ validatorMinStakeRaw: validatorMinStake,
1671
+ delegatorMinStake: formatStakingAmount(delegatorMinStake),
1672
+ delegatorMinStakeRaw: delegatorMinStake,
1673
+ activeValidatorsCount: activeCount,
1674
+ epochMinDuration,
1675
+ currentEpochStart,
1676
+ currentEpochEnd,
1677
+ nextEpochEstimate,
1678
+ inflation: formatStakingAmount(currentEpochData.inflation),
1679
+ inflationRaw: currentEpochData.inflation,
1680
+ totalWeight: currentEpochData.weight,
1681
+ totalClaimed: formatStakingAmount(currentEpochData.claimed),
1682
+ totalClaimedRaw: currentEpochData.claimed
1683
+ };
1684
+ },
1685
+ getActiveValidators: async () => {
1686
+ const contract = getReadOnlyStakingContract();
1687
+ const validators = await contract.read.activeValidators();
1688
+ return validators.filter((v) => v !== "0x0000000000000000000000000000000000000000");
1689
+ },
1690
+ getActiveValidatorsCount: async () => {
1691
+ const contract = getReadOnlyStakingContract();
1692
+ return contract.read.activeValidatorsCount();
1693
+ },
1694
+ getQuarantinedValidators: async () => {
1695
+ const contract = getReadOnlyStakingContract();
1696
+ return contract.read.getQuarantinedValidators();
1697
+ },
1698
+ getBannedValidators: async (startIndex = 0n, size = 100n) => {
1699
+ const contract = getReadOnlyStakingContract();
1700
+ const result = await contract.read.getAllBannedValidators([startIndex, size]);
1701
+ return result.map((v) => ({
1702
+ validator: v.validator,
1703
+ untilEpoch: v.untilEpochBanned,
1704
+ permanentlyBanned: v.permanentlyBanned
1705
+ }));
1706
+ },
1707
+ getQuarantinedValidatorsDetailed: async (startIndex = 0n, size = 100n) => {
1708
+ const contract = getReadOnlyStakingContract();
1709
+ const result = await contract.read.getAllQuarantinedValidators([startIndex, size]);
1710
+ return result.map((v) => ({
1711
+ validator: v.validator,
1712
+ untilEpoch: v.untilEpochBanned,
1713
+ permanentlyBanned: v.permanentlyBanned
1714
+ }));
1715
+ },
1716
+ getStakingContract,
1717
+ parseStakingAmount,
1718
+ formatStakingAmount
1719
+ };
1720
+ };
1721
+
1215
1722
  // src/chains/actions.ts
1216
1723
  function chainActions(client) {
1217
1724
  return {
@@ -1249,17 +1756,17 @@ var getCustomTransportConfig = (config) => {
1249
1756
  return {
1250
1757
  async request({ method, params = [] }) {
1251
1758
  if (method.startsWith("eth_") && isAddress) {
1252
- try {
1253
- const provider = config.provider || window.ethereum;
1254
- if (!provider) {
1255
- throw new Error("No wallet provider available");
1759
+ const provider = config.provider || (typeof window !== "undefined" ? window.ethereum : void 0);
1760
+ if (provider) {
1761
+ try {
1762
+ return await provider.request({ method, params });
1763
+ } catch (err) {
1764
+ console.warn(`Error using provider for method ${method}:`, err);
1765
+ throw err;
1256
1766
  }
1257
- return await provider.request({ method, params });
1258
- } catch (err) {
1259
- console.warn(`Error using provider for method ${method}:`, err);
1260
- throw err;
1261
1767
  }
1262
- } else {
1768
+ }
1769
+ {
1263
1770
  if (!config.chain) {
1264
1771
  throw new Error("Chain is not set");
1265
1772
  }
@@ -1314,10 +1821,14 @@ var createClient = (config = { chain: localnet }) => {
1314
1821
  ...clientWithTransactionActions,
1315
1822
  ...contractActions(clientWithTransactionActions, publicClient)
1316
1823
  };
1317
- const finalClient = {
1824
+ const clientWithReceiptActions = {
1318
1825
  ...clientWithAllActions,
1319
1826
  ...receiptActions(clientWithAllActions, publicClient)
1320
1827
  };
1828
+ const finalClient = {
1829
+ ...clientWithReceiptActions,
1830
+ ...stakingActions(clientWithReceiptActions, publicClient)
1831
+ };
1321
1832
  finalClient.initializeConsensusSmartContract().catch((error) => {
1322
1833
  console.error("Failed to initialize consensus smart contract:", error);
1323
1834
  });
@@ -1343,6 +1854,8 @@ export {
1343
1854
  decodeInputData,
1344
1855
  decodeLocalnetTransaction,
1345
1856
  decodeTransaction,
1857
+ formatStakingAmount,
1346
1858
  generatePrivateKey,
1859
+ parseStakingAmount,
1347
1860
  simplifyTransactionReceipt
1348
1861
  };