@human-protocol/sdk 3.0.8 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/constants.d.ts +4 -1
  2. package/dist/constants.d.ts.map +1 -1
  3. package/dist/constants.js +11 -151
  4. package/dist/decorators.js +1 -1
  5. package/dist/encryption.d.ts +21 -29
  6. package/dist/encryption.d.ts.map +1 -1
  7. package/dist/encryption.js +17 -29
  8. package/dist/enums.d.ts +5 -12
  9. package/dist/enums.d.ts.map +1 -1
  10. package/dist/enums.js +6 -12
  11. package/dist/error.d.ts +31 -28
  12. package/dist/error.d.ts.map +1 -1
  13. package/dist/error.js +36 -33
  14. package/dist/escrow.d.ts +104 -88
  15. package/dist/escrow.d.ts.map +1 -1
  16. package/dist/escrow.js +192 -131
  17. package/dist/graphql/queries/operator.d.ts.map +1 -1
  18. package/dist/graphql/queries/operator.js +15 -5
  19. package/dist/interfaces.d.ts +12 -2
  20. package/dist/interfaces.d.ts.map +1 -1
  21. package/dist/kvstore.d.ts +15 -15
  22. package/dist/kvstore.d.ts.map +1 -1
  23. package/dist/kvstore.js +15 -15
  24. package/dist/operator.d.ts +11 -10
  25. package/dist/operator.d.ts.map +1 -1
  26. package/dist/operator.js +23 -11
  27. package/dist/staking.d.ts +38 -21
  28. package/dist/staking.d.ts.map +1 -1
  29. package/dist/staking.js +62 -21
  30. package/dist/statistics.d.ts +10 -29
  31. package/dist/statistics.d.ts.map +1 -1
  32. package/dist/statistics.js +18 -37
  33. package/dist/storage.d.ts +13 -18
  34. package/dist/storage.d.ts.map +1 -1
  35. package/dist/storage.js +13 -18
  36. package/dist/transaction.d.ts.map +1 -1
  37. package/dist/transaction.js +3 -5
  38. package/dist/types.d.ts +6 -2
  39. package/dist/types.d.ts.map +1 -1
  40. package/dist/types.js +1 -1
  41. package/dist/utils.d.ts +7 -1
  42. package/dist/utils.d.ts.map +1 -1
  43. package/dist/utils.js +11 -2
  44. package/package.json +1 -1
  45. package/src/constants.ts +11 -174
  46. package/src/decorators.ts +1 -1
  47. package/src/encryption.ts +21 -29
  48. package/src/enums.ts +5 -11
  49. package/src/error.ts +39 -37
  50. package/src/escrow.ts +257 -151
  51. package/src/graphql/queries/operator.ts +15 -5
  52. package/src/interfaces.ts +13 -2
  53. package/src/kvstore.ts +16 -16
  54. package/src/operator.ts +26 -12
  55. package/src/staking.ts +71 -22
  56. package/src/statistics.ts +19 -38
  57. package/src/storage.ts +13 -18
  58. package/src/transaction.ts +5 -7
  59. package/src/types.ts +6 -2
  60. package/src/utils.ts +10 -1
@@ -22,26 +22,36 @@ const LEADER_FRAGMENT = gql`
22
22
  registrationNeeded
23
23
  registrationInstructions
24
24
  reputationNetworks
25
+ name
26
+ category
25
27
  }
26
28
  `;
27
29
 
28
30
  export const GET_LEADERS_QUERY = (filter: ILeadersFilter) => {
29
- const { role } = filter;
31
+ const { roles, minAmountStaked } = filter;
30
32
 
31
33
  const WHERE_CLAUSE = `
32
34
  where: {
33
- ${role ? `role: $role` : ''}
35
+ ${minAmountStaked ? `amountStaked_gte: $minAmountStaked` : ''}
36
+ ${roles ? `role_in: $roles` : ''}
34
37
  }
35
38
  `;
36
39
 
37
40
  return gql`
38
41
  query getLeaders(
39
- $role: String
42
+ $minAmountStaked: Int,
43
+ $roles: [String!]
44
+ $first: Int
45
+ $skip: Int
46
+ $orderBy: String
47
+ $orderDirection: String
40
48
  ) {
41
49
  leaders(
42
50
  ${WHERE_CLAUSE}
43
- orderBy: amountStaked,
44
- orderDirection: desc,
51
+ first: $first
52
+ skip: $skip
53
+ orderBy: $orderBy
54
+ orderDirection: $orderDirection
45
55
  ) {
46
56
  ...LeaderFields
47
57
  }
package/src/interfaces.ts CHANGED
@@ -27,6 +27,8 @@ export interface ILeader {
27
27
  registrationNeeded?: boolean;
28
28
  registrationInstructions?: string;
29
29
  reputationNetworks?: string[];
30
+ name?: string;
31
+ category?: string;
30
32
  }
31
33
 
32
34
  export interface ILeaderSubgraph
@@ -35,9 +37,11 @@ export interface ILeaderSubgraph
35
37
  reputationNetworks?: { address: string }[];
36
38
  }
37
39
 
38
- export interface ILeadersFilter {
40
+ export interface ILeadersFilter extends IPagination {
39
41
  chainId: ChainId;
40
- role?: string;
42
+ roles?: string[];
43
+ minAmountStaked?: number;
44
+ orderBy?: string;
41
45
  }
42
46
 
43
47
  export interface IReputationNetwork {
@@ -154,3 +158,10 @@ export interface IPagination {
154
158
  skip?: number;
155
159
  orderDirection?: OrderDirection;
156
160
  }
161
+
162
+ export interface StakerInfo {
163
+ stakedAmount: bigint;
164
+ lockedAmount: bigint;
165
+ lockedUntil: bigint;
166
+ withdrawableAmount: bigint;
167
+ }
package/src/kvstore.ts CHANGED
@@ -29,19 +29,19 @@ import { IKVStore } from './interfaces';
29
29
  /**
30
30
  * ## Introduction
31
31
  *
32
- * This client enables to perform actions on KVStore contract and obtain information from both the contracts and subgraph.
32
+ * This client enables performing actions on KVStore contract and obtaining information from both the contracts and subgraph.
33
33
  *
34
34
  * Internally, the SDK will use one network or another according to the network ID of the `runner`.
35
35
  * To use this client, it is recommended to initialize it using the static `build` method.
36
36
  *
37
37
  * ```ts
38
- * static async build(runner: ContractRunner);
38
+ * static async build(runner: ContractRunner): Promise<KVStoreClient>;
39
39
  * ```
40
40
  *
41
41
  * A `Signer` or a `Provider` should be passed depending on the use case of this module:
42
42
  *
43
- * - **Signer**: when the user wants to use this model in order to send transactions caling the contract functions.
44
- * - **Provider**: when the user wants to use this model in order to get information from the contracts or subgraph.
43
+ * - **Signer**: when the user wants to use this model to send transactions calling the contract functions.
44
+ * - **Provider**: when the user wants to use this model to get information from the contracts or subgraph.
45
45
  *
46
46
  * ## Installation
47
47
  *
@@ -59,21 +59,21 @@ import { IKVStore } from './interfaces';
59
59
  *
60
60
  * ### Signer
61
61
  *
62
- * **Using private key(backend)**
62
+ * **Using private key (backend)**
63
63
  *
64
64
  * ```ts
65
65
  * import { KVStoreClient } from '@human-protocol/sdk';
66
66
  * import { Wallet, providers } from 'ethers';
67
67
  *
68
68
  * const rpcUrl = 'YOUR_RPC_URL';
69
- * const privateKey = 'YOUR_PRIVATE_KEY'
69
+ * const privateKey = 'YOUR_PRIVATE_KEY';
70
70
  *
71
71
  * const provider = new providers.JsonRpcProvider(rpcUrl);
72
72
  * const signer = new Wallet(privateKey, provider);
73
73
  * const kvstoreClient = await KVStoreClient.build(signer);
74
74
  * ```
75
75
  *
76
- * **Using Wagmi(frontend)**
76
+ * **Using Wagmi (frontend)**
77
77
  *
78
78
  * ```ts
79
79
  * import { useSigner, useChainId } from 'wagmi';
@@ -92,7 +92,7 @@ import { IKVStore } from './interfaces';
92
92
  * const rpcUrl = 'YOUR_RPC_URL';
93
93
  *
94
94
  * const provider = new providers.JsonRpcProvider(rpcUrl);
95
- * const kvstoreClient = await KVStoreClient.build(signer);
95
+ * const kvstoreClient = await KVStoreClient.build(provider);
96
96
  * ```
97
97
  */
98
98
 
@@ -123,7 +123,7 @@ export class KVStoreClient extends BaseEthersClient {
123
123
  * @throws {ErrorProviderDoesNotExist} - Thrown if the provider does not exist for the provided Signer
124
124
  * @throws {ErrorUnsupportedChainID} - Thrown if the network's chainId is not supported
125
125
  */
126
- public static async build(runner: ContractRunner) {
126
+ public static async build(runner: ContractRunner): Promise<KVStoreClient> {
127
127
  if (!runner.provider) {
128
128
  throw ErrorProviderDoesNotExist;
129
129
  }
@@ -158,7 +158,7 @@ export class KVStoreClient extends BaseEthersClient {
158
158
  * import { KVStoreClient } from '@human-protocol/sdk';
159
159
  *
160
160
  * const rpcUrl = 'YOUR_RPC_URL';
161
- * const privateKey = 'YOUR_PRIVATE_KEY'
161
+ * const privateKey = 'YOUR_PRIVATE_KEY';
162
162
  *
163
163
  * const provider = new providers.JsonRpcProvider(rpcUrl);
164
164
  * const signer = new Wallet(privateKey, provider);
@@ -199,7 +199,7 @@ export class KVStoreClient extends BaseEthersClient {
199
199
  * import { KVStoreClient } from '@human-protocol/sdk';
200
200
  *
201
201
  * const rpcUrl = 'YOUR_RPC_URL';
202
- * const privateKey = 'YOUR_PRIVATE_KEY'
202
+ * const privateKey = 'YOUR_PRIVATE_KEY';
203
203
  *
204
204
  * const provider = new providers.JsonRpcProvider(rpcUrl);
205
205
  * const signer = new Wallet(privateKey, provider);
@@ -207,7 +207,7 @@ export class KVStoreClient extends BaseEthersClient {
207
207
  *
208
208
  * const keys = ['role', 'webhook_url'];
209
209
  * const values = ['RecordingOracle', 'http://localhost'];
210
- * await kvstoreClient.set(keys, values);
210
+ * await kvstoreClient.setBulk(keys, values);
211
211
  * ```
212
212
  */
213
213
  @requiresSigner
@@ -243,14 +243,14 @@ export class KVStoreClient extends BaseEthersClient {
243
243
  * import { KVStoreClient } from '@human-protocol/sdk';
244
244
  *
245
245
  * const rpcUrl = 'YOUR_RPC_URL';
246
- * const privateKey = 'YOUR_PRIVATE_KEY'
246
+ * const privateKey = 'YOUR_PRIVATE_KEY';
247
247
  *
248
248
  * const provider = new providers.JsonRpcProvider(rpcUrl);
249
249
  * const signer = new Wallet(privateKey, provider);
250
250
  * const kvstoreClient = await KVStoreClient.build(signer);
251
251
  *
252
252
  * await kvstoreClient.setFileUrlAndHash('example.com');
253
- * await kvstoreClient.setFileUrlAndHash('linkedin.com/example', 'linkedin_url);
253
+ * await kvstoreClient.setFileUrlAndHash('linkedin.com/example', 'linkedin_url');
254
254
  * ```
255
255
  */
256
256
  @requiresSigner
@@ -309,9 +309,9 @@ export class KVStoreClient extends BaseEthersClient {
309
309
  * ```ts
310
310
  * import { ChainId, KVStoreUtils } from '@human-protocol/sdk';
311
311
  *
312
- * const KVStoreAddresses = new KVStoreUtils.getKVStoreData({
312
+ * const KVStoreAddresses = await KVStoreUtils.getKVStoreData(
313
313
  * ChainId.POLYGON_AMOY,
314
- * "0x1234567890123456789012345678901234567890",
314
+ * "0x1234567890123456789012345678901234567890"
315
315
  * );
316
316
  * ```
317
317
  */
package/src/operator.ts CHANGED
@@ -22,16 +22,16 @@ import {
22
22
  ErrorUnsupportedChainID,
23
23
  } from './error';
24
24
  import { getSubgraphUrl } from './utils';
25
- import { ChainId } from './enums';
25
+ import { ChainId, OrderDirection } from './enums';
26
26
  import { NETWORKS } from './constants';
27
27
 
28
28
  export class OperatorUtils {
29
29
  /**
30
30
  * This function returns the leader data for the given address.
31
31
  *
32
+ * @param {ChainId} chainId Network in which the leader is deployed
32
33
  * @param {string} address Leader address.
33
- * @returns {ILeader} Returns the leader details.
34
- *
34
+ * @returns {Promise<ILeader>} Returns the leader details.
35
35
  *
36
36
  * **Code example**
37
37
  *
@@ -91,13 +91,12 @@ export class OperatorUtils {
91
91
  * This function returns all the leader details of the protocol.
92
92
  *
93
93
  * @param {ILeadersFilter} filter Filter for the leaders.
94
- * @returns {ILeader[]} Returns an array with all the leader details.
95
- *
94
+ * @returns {Promise<ILeader[]>} Returns an array with all the leader details.
96
95
  *
97
96
  * **Code example**
98
97
  *
99
98
  * ```ts
100
- * import { OperatorUtils } from '@human-protocol/sdk';
99
+ * import { OperatorUtils, ChainId } from '@human-protocol/sdk';
101
100
  *
102
101
  * const filter: ILeadersFilter = {
103
102
  * chainId: ChainId.POLYGON
@@ -108,6 +107,14 @@ export class OperatorUtils {
108
107
  public static async getLeaders(filter: ILeadersFilter): Promise<ILeader[]> {
109
108
  let leaders_data: ILeader[] = [];
110
109
 
110
+ const first =
111
+ filter.first !== undefined && filter.first > 0
112
+ ? Math.min(filter.first, 1000)
113
+ : 10;
114
+ const skip =
115
+ filter.skip !== undefined && filter.skip >= 0 ? filter.skip : 0;
116
+ const orderDirection = filter.orderDirection || OrderDirection.DESC;
117
+
111
118
  const networkData = NETWORKS[filter.chainId];
112
119
 
113
120
  if (!networkData) {
@@ -117,7 +124,12 @@ export class OperatorUtils {
117
124
  const { leaders } = await gqlFetch<{
118
125
  leaders: ILeaderSubgraph[];
119
126
  }>(getSubgraphUrl(networkData), GET_LEADERS_QUERY(filter), {
120
- role: filter?.role,
127
+ minAmountStaked: filter?.minAmountStaked,
128
+ roles: filter?.roles,
129
+ orderBy: filter?.orderBy,
130
+ orderDirection: orderDirection,
131
+ first: first,
132
+ skip: skip,
121
133
  });
122
134
 
123
135
  if (!leaders) {
@@ -158,12 +170,14 @@ export class OperatorUtils {
158
170
  /**
159
171
  * Retrieves the reputation network operators of the specified address.
160
172
  *
161
- * @param {string} address - Address of the reputation oracle.
173
+ * @param {ChainId} chainId Network in which the reputation network is deployed
174
+ * @param {string} address Address of the reputation oracle.
162
175
  * @param {string} [role] - (Optional) Role of the operator.
163
176
  * @returns {Promise<IOperator[]>} - Returns an array of operator details.
164
177
  *
165
- * @example
166
- * ```typescript
178
+ * **Code example**
179
+ *
180
+ * ```ts
167
181
  * import { OperatorUtils, ChainId } from '@human-protocol/sdk';
168
182
  *
169
183
  * const operators = await OperatorUtils.getReputationNetworkOperators(ChainId.POLYGON_AMOY, '0x62dD51230A30401C455c8398d06F85e4EaB6309f');
@@ -207,9 +221,9 @@ export class OperatorUtils {
207
221
  /**
208
222
  * This function returns information about the rewards for a given slasher address.
209
223
  *
224
+ * @param {ChainId} chainId Network in which the rewards are deployed
210
225
  * @param {string} slasherAddress Slasher address.
211
- * @returns {IReward[]} Returns an array of Reward objects that contain the rewards earned by the user through slashing other users.
212
- *
226
+ * @returns {Promise<IReward[]>} Returns an array of Reward objects that contain the rewards earned by the user through slashing other users.
213
227
  *
214
228
  * **Code example**
215
229
  *
package/src/staking.ts CHANGED
@@ -23,23 +23,24 @@ import {
23
23
  } from './error';
24
24
  import { NetworkData } from './types';
25
25
  import { throwError } from './utils';
26
+ import { StakerInfo } from './interfaces';
26
27
 
27
28
  /**
28
29
  * ## Introduction
29
30
  *
30
- * This client enables to perform actions on staking contracts and obtain staking information from both the contracts and subgraph.
31
+ * This client enables performing actions on staking contracts and obtaining staking information from both the contracts and subgraph.
31
32
  *
32
33
  * Internally, the SDK will use one network or another according to the network ID of the `runner`.
33
34
  * To use this client, it is recommended to initialize it using the static `build` method.
34
35
  *
35
36
  * ```ts
36
- * static async build(runner: ContractRunner);
37
+ * static async build(runner: ContractRunner): Promise<StakingClient>;
37
38
  * ```
38
39
  *
39
40
  * A `Signer` or a `Provider` should be passed depending on the use case of this module:
40
41
  *
41
- * - **Signer**: when the user wants to use this model in order to send transactions caling the contract functions.
42
- * - **Provider**: when the user wants to use this model in order to get information from the contracts or subgraph.
42
+ * - **Signer**: when the user wants to use this model to send transactions calling the contract functions.
43
+ * - **Provider**: when the user wants to use this model to get information from the contracts or subgraph.
43
44
  *
44
45
  * ## Installation
45
46
  *
@@ -57,21 +58,21 @@ import { throwError } from './utils';
57
58
  *
58
59
  * ### Signer
59
60
  *
60
- * **Using private key(backend)**
61
+ * **Using private key (backend)**
61
62
  *
62
63
  * ```ts
63
64
  * import { StakingClient } from '@human-protocol/sdk';
64
65
  * import { Wallet, providers } from 'ethers';
65
66
  *
66
67
  * const rpcUrl = 'YOUR_RPC_URL';
67
- * const privateKey = 'YOUR_PRIVATE_KEY'
68
+ * const privateKey = 'YOUR_PRIVATE_KEY';
68
69
  *
69
70
  * const provider = new providers.JsonRpcProvider(rpcUrl);
70
71
  * const signer = new Wallet(privateKey, provider);
71
72
  * const stakingClient = await StakingClient.build(signer);
72
73
  * ```
73
74
  *
74
- * **Using Wagmi(frontend)**
75
+ * **Using Wagmi (frontend)**
75
76
  *
76
77
  * ```ts
77
78
  * import { useSigner, useChainId } from 'wagmi';
@@ -132,7 +133,7 @@ export class StakingClient extends BaseEthersClient {
132
133
  * @throws {ErrorProviderDoesNotExist} - Thrown if the provider does not exist for the provided Signer
133
134
  * @throws {ErrorUnsupportedChainID} - Thrown if the network's chainId is not supported
134
135
  */
135
- public static async build(runner: ContractRunner) {
136
+ public static async build(runner: ContractRunner): Promise<StakingClient> {
136
137
  if (!runner.provider) {
137
138
  throw ErrorProviderDoesNotExist;
138
139
  }
@@ -171,7 +172,6 @@ export class StakingClient extends BaseEthersClient {
171
172
  * @param {Overrides} [txOptions] - Additional transaction parameters (optional, defaults to an empty object).
172
173
  * @returns Returns void if successful. Throws error if any.
173
174
  *
174
- *
175
175
  * **Code example**
176
176
  *
177
177
  * ```ts
@@ -179,7 +179,7 @@ export class StakingClient extends BaseEthersClient {
179
179
  * import { StakingClient } from '@human-protocol/sdk';
180
180
  *
181
181
  * const rpcUrl = 'YOUR_RPC_URL';
182
- * const privateKey = 'YOUR_PRIVATE_KEY'
182
+ * const privateKey = 'YOUR_PRIVATE_KEY';
183
183
  *
184
184
  * const provider = new providers.JsonRpcProvider(rpcUrl);
185
185
  * const signer = new Wallet(privateKey, provider);
@@ -225,7 +225,6 @@ export class StakingClient extends BaseEthersClient {
225
225
  * @param {Overrides} [txOptions] - Additional transaction parameters (optional, defaults to an empty object).
226
226
  * @returns Returns void if successful. Throws error if any.
227
227
  *
228
- *
229
228
  * **Code example**
230
229
  *
231
230
  * ```ts
@@ -233,7 +232,7 @@ export class StakingClient extends BaseEthersClient {
233
232
  * import { StakingClient } from '@human-protocol/sdk';
234
233
  *
235
234
  * const rpcUrl = 'YOUR_RPC_URL';
236
- * const privateKey = 'YOUR_PRIVATE_KEY'
235
+ * const privateKey = 'YOUR_PRIVATE_KEY';
237
236
  *
238
237
  * const provider = new providers.JsonRpcProvider(rpcUrl);
239
238
  * const signer = new Wallet(privateKey, provider);
@@ -241,7 +240,7 @@ export class StakingClient extends BaseEthersClient {
241
240
  *
242
241
  * const amount = ethers.parseUnits(5, 'ether'); //convert from ETH to WEI
243
242
  * await stakingClient.approveStake(amount); // if it was already approved before, this is not necessary
244
- * await stakingClient.approveStake(amount);
243
+ * await stakingClient.stake(amount);
245
244
  * ```
246
245
  */
247
246
  @requiresSigner
@@ -271,7 +270,6 @@ export class StakingClient extends BaseEthersClient {
271
270
  * @param {Overrides} [txOptions] - Additional transaction parameters (optional, defaults to an empty object).
272
271
  * @returns Returns void if successful. Throws error if any.
273
272
  *
274
- *
275
273
  * **Code example**
276
274
  *
277
275
  * ```ts
@@ -279,7 +277,7 @@ export class StakingClient extends BaseEthersClient {
279
277
  * import { StakingClient } from '@human-protocol/sdk';
280
278
  *
281
279
  * const rpcUrl = 'YOUR_RPC_URL';
282
- * const privateKey = 'YOUR_PRIVATE_KEY'
280
+ * const privateKey = 'YOUR_PRIVATE_KEY';
283
281
  *
284
282
  * const provider = new providers.JsonRpcProvider(rpcUrl);
285
283
  * const signer = new Wallet(privateKey, provider);
@@ -311,14 +309,13 @@ export class StakingClient extends BaseEthersClient {
311
309
  }
312
310
 
313
311
  /**
314
- * This function withdraws unstaked and non locked tokens form staking contract to the user wallet.
312
+ * This function withdraws unstaked and non-locked tokens from staking contract to the user wallet.
315
313
  *
316
314
  * > Must have tokens available to withdraw
317
315
  *
318
316
  * @param {Overrides} [txOptions] - Additional transaction parameters (optional, defaults to an empty object).
319
317
  * @returns Returns void if successful. Throws error if any.
320
318
  *
321
- *
322
319
  * **Code example**
323
320
  *
324
321
  * ```ts
@@ -326,7 +323,7 @@ export class StakingClient extends BaseEthersClient {
326
323
  * import { StakingClient } from '@human-protocol/sdk';
327
324
  *
328
325
  * const rpcUrl = 'YOUR_RPC_URL';
329
- * const privateKey = 'YOUR_PRIVATE_KEY'
326
+ * const privateKey = 'YOUR_PRIVATE_KEY';
330
327
  *
331
328
  * const provider = new providers.JsonRpcProvider(rpcUrl);
332
329
  * const signer = new Wallet(privateKey, provider);
@@ -346,16 +343,15 @@ export class StakingClient extends BaseEthersClient {
346
343
  }
347
344
 
348
345
  /**
349
- * This function reduces the allocated amount by an staker in an escrow and transfers those tokens to the reward pool. This allows the slasher to claim them later.
346
+ * This function reduces the allocated amount by a staker in an escrow and transfers those tokens to the reward pool. This allows the slasher to claim them later.
350
347
  *
351
348
  * @param {string} slasher Wallet address from who requested the slash
352
349
  * @param {string} staker Wallet address from who is going to be slashed
353
350
  * @param {string} escrowAddress Address of the escrow that the slash is made
351
+ * @param {bigint} amount Amount in WEI of tokens to slash.
354
352
  * @param {Overrides} [txOptions] - Additional transaction parameters (optional, defaults to an empty object).
355
- * @param {bigint} amount Amount in WEI of tokens to unstake.
356
353
  * @returns Returns void if successful. Throws error if any.
357
354
  *
358
- *
359
355
  * **Code example**
360
356
  *
361
357
  * ```ts
@@ -363,7 +359,7 @@ export class StakingClient extends BaseEthersClient {
363
359
  * import { StakingClient } from '@human-protocol/sdk';
364
360
  *
365
361
  * const rpcUrl = 'YOUR_RPC_URL';
366
- * const privateKey = 'YOUR_PRIVATE_KEY'
362
+ * const privateKey = 'YOUR_PRIVATE_KEY';
367
363
  *
368
364
  * const provider = new providers.JsonRpcProvider(rpcUrl);
369
365
  * const signer = new Wallet(privateKey, provider);
@@ -415,4 +411,57 @@ export class StakingClient extends BaseEthersClient {
415
411
  return throwError(e);
416
412
  }
417
413
  }
414
+
415
+ /**
416
+ * Retrieves comprehensive staking information for a staker.
417
+ *
418
+ * @param {string} stakerAddress - The address of the staker.
419
+ * @returns {Promise<StakerInfo>}
420
+ *
421
+ * **Code example**
422
+ *
423
+ * ```ts
424
+ * import { StakingClient } from '@human-protocol/sdk';
425
+ *
426
+ * const rpcUrl = 'YOUR_RPC_URL';
427
+ *
428
+ * const provider = new providers.JsonRpcProvider(rpcUrl);
429
+ * const stakingClient = await StakingClient.build(provider);
430
+ *
431
+ * const stakingInfo = await stakingClient.getStakerInfo('0xYourStakerAddress');
432
+ * console.log(stakingInfo.tokensStaked);
433
+ * ```
434
+ */
435
+ public async getStakerInfo(stakerAddress: string): Promise<StakerInfo> {
436
+ if (!ethers.isAddress(stakerAddress)) {
437
+ throw ErrorInvalidStakerAddressProvided;
438
+ }
439
+
440
+ try {
441
+ const stakerInfo = await this.stakingContract.stakes(stakerAddress);
442
+ const currentBlock = await this.runner.provider!.getBlockNumber();
443
+
444
+ const tokensWithdrawable =
445
+ stakerInfo.tokensLockedUntil !== 0n &&
446
+ currentBlock >= stakerInfo.tokensLockedUntil
447
+ ? stakerInfo.tokensLocked
448
+ : 0n;
449
+
450
+ const adjustedLockedAmount =
451
+ stakerInfo.tokensLockedUntil !== 0n &&
452
+ currentBlock >= stakerInfo.tokensLockedUntil
453
+ ? 0n
454
+ : stakerInfo.tokensLocked;
455
+
456
+ return {
457
+ stakedAmount: stakerInfo.tokensStaked,
458
+ lockedAmount: adjustedLockedAmount,
459
+ lockedUntil:
460
+ adjustedLockedAmount === 0n ? 0n : stakerInfo.tokensLockedUntil,
461
+ withdrawableAmount: tokensWithdrawable,
462
+ };
463
+ } catch (error) {
464
+ return throwError(error);
465
+ }
466
+ }
418
467
  }