@human-protocol/sdk 1.0.2 → 1.0.3

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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/constants.d.ts +46 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/constants.js +203 -0
  5. package/dist/decorators.d.ts +2 -0
  6. package/dist/decorators.d.ts.map +1 -0
  7. package/dist/decorators.js +17 -0
  8. package/dist/enums.d.ts +17 -0
  9. package/dist/enums.d.ts.map +1 -0
  10. package/dist/enums.js +20 -0
  11. package/dist/error.d.ts +196 -0
  12. package/dist/error.d.ts.map +1 -0
  13. package/dist/error.js +229 -0
  14. package/dist/escrow.d.ts +176 -0
  15. package/dist/escrow.d.ts.map +1 -0
  16. package/dist/escrow.js +590 -0
  17. package/dist/index.d.ts +10 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +33 -0
  20. package/dist/init.d.ts +13 -0
  21. package/dist/init.d.ts.map +1 -0
  22. package/dist/init.js +35 -0
  23. package/dist/interfaces.d.ts +44 -0
  24. package/dist/interfaces.d.ts.map +1 -0
  25. package/dist/interfaces.js +2 -0
  26. package/dist/kvstore.d.ts +40 -0
  27. package/dist/kvstore.d.ts.map +1 -0
  28. package/dist/kvstore.js +106 -0
  29. package/dist/queries.d.ts +4 -0
  30. package/dist/queries.d.ts.map +1 -0
  31. package/dist/queries.js +22 -0
  32. package/dist/staking.d.ts +121 -0
  33. package/dist/staking.d.ts.map +1 -0
  34. package/dist/staking.js +381 -0
  35. package/dist/storage.d.ts +48 -0
  36. package/dist/storage.d.ts.map +1 -0
  37. package/dist/storage.js +164 -0
  38. package/dist/types.d.ts +123 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +35 -0
  41. package/dist/utils.d.ts +32 -0
  42. package/dist/utils.d.ts.map +1 -0
  43. package/dist/utils.js +99 -0
  44. package/package.json +4 -7
  45. package/src/constants.ts +221 -4
  46. package/src/decorators.ts +21 -0
  47. package/src/enums.ts +16 -0
  48. package/src/error.ts +295 -18
  49. package/src/escrow.ts +754 -0
  50. package/src/index.ts +14 -1
  51. package/src/init.ts +45 -0
  52. package/src/interfaces.ts +50 -0
  53. package/src/kvstore.ts +93 -0
  54. package/src/queries.ts +18 -0
  55. package/src/staking.ts +421 -0
  56. package/src/storage.ts +159 -131
  57. package/src/types.ts +36 -586
  58. package/src/utils.ts +80 -142
  59. package/test/escrow.test.ts +1339 -0
  60. package/test/init.test.ts +88 -0
  61. package/test/kvstore.test.ts +208 -0
  62. package/test/staking.test.ts +640 -0
  63. package/test/storage.test.ts +422 -0
  64. package/test/utils/constants.ts +38 -1
  65. package/example/simple-existing-job.ts +0 -86
  66. package/example/simple-new-job-public.ts +0 -74
  67. package/example/simple-new-job.ts +0 -72
  68. package/src/job.ts +0 -977
  69. package/src/logger.ts +0 -29
  70. package/test/job.test.ts +0 -716
  71. package/test/utils/manifest.ts +0 -33
package/src/index.ts CHANGED
@@ -1,4 +1,17 @@
1
- export { Job } from './job';
1
+ import InitClient from './init';
2
+ import StakingClient from './staking';
3
+ import StorageClient from './storage';
4
+ import KVStoreClient from './kvstore';
5
+ import EscrowClient from './escrow';
2
6
 
3
7
  export * from './constants';
4
8
  export * from './types';
9
+ export * from './enums';
10
+
11
+ export {
12
+ InitClient,
13
+ StakingClient,
14
+ StorageClient,
15
+ KVStoreClient,
16
+ EscrowClient,
17
+ };
package/src/init.ts ADDED
@@ -0,0 +1,45 @@
1
+ import { Provider } from '@ethersproject/abstract-provider';
2
+ import { Network } from '@ethersproject/networks';
3
+ import { Signer } from 'ethers';
4
+ import { NETWORKS } from './constants';
5
+ import { IClientParams } from './interfaces';
6
+ import {
7
+ ErrorInitProviderDoesNotExist,
8
+ ErrorInitUnsupportedChainID,
9
+ } from './error';
10
+ import { ChainId } from './enums';
11
+
12
+ export default class InitClient {
13
+ /**
14
+ * **Get init client parameters**
15
+ *
16
+ * @param {Signer | Provider} providerOrSigner - Ethereum signer or provider
17
+ * @returns {Promise<IClientParams>} - Init client parameters
18
+ */
19
+ static async getParams(
20
+ signerOrProvider: Signer | Provider
21
+ ): Promise<IClientParams> {
22
+ let network: Network;
23
+ if (signerOrProvider instanceof Signer) {
24
+ if (!signerOrProvider.provider) {
25
+ throw ErrorInitProviderDoesNotExist;
26
+ }
27
+
28
+ network = await signerOrProvider.provider.getNetwork();
29
+ } else {
30
+ network = await signerOrProvider.getNetwork();
31
+ }
32
+
33
+ const chainId: ChainId = network.chainId;
34
+ const networkData = NETWORKS[chainId];
35
+
36
+ if (!networkData) {
37
+ throw ErrorInitUnsupportedChainID;
38
+ }
39
+
40
+ return {
41
+ signerOrProvider: signerOrProvider,
42
+ network: networkData,
43
+ };
44
+ }
45
+ }
@@ -0,0 +1,50 @@
1
+ import { BigNumber, Signer } from 'ethers';
2
+ import { Provider } from '@ethersproject/abstract-provider';
3
+ import { NetworkData } from './types';
4
+
5
+ export interface IClientParams {
6
+ signerOrProvider: Signer | Provider;
7
+ network: NetworkData;
8
+ }
9
+
10
+ export interface IAllocation {
11
+ escrowAddress: string;
12
+ staker: string;
13
+ tokens: BigNumber;
14
+ createdAt: BigNumber;
15
+ closedAt: BigNumber;
16
+ }
17
+
18
+ export interface IReward {
19
+ escrowAddress: string;
20
+ amount: BigNumber;
21
+ }
22
+
23
+ export interface IStaker {
24
+ tokensStaked: BigNumber;
25
+ tokensAllocated: BigNumber;
26
+ tokensLocked: BigNumber;
27
+ tokensLockedUntil: BigNumber;
28
+ tokensAvailable: BigNumber;
29
+ }
30
+
31
+ export interface IEscrowsFilter {
32
+ address: string;
33
+ role?: number;
34
+ status?: number;
35
+ from?: Date;
36
+ to?: Date;
37
+ }
38
+
39
+ export interface IEscrowConfig {
40
+ recordingOracle: string;
41
+ reputationOracle: string;
42
+ recordingOracleFee: BigNumber;
43
+ reputationOracleFee: BigNumber;
44
+ manifestUrl: string;
45
+ hash: string;
46
+ }
47
+
48
+ export interface ILauncherEscrowsResult {
49
+ id: string;
50
+ }
package/src/kvstore.ts ADDED
@@ -0,0 +1,93 @@
1
+ import {
2
+ KVStore,
3
+ KVStore__factory,
4
+ } from '@human-protocol/core/typechain-types';
5
+ import { Signer, ethers } from 'ethers';
6
+ import { Provider } from '@ethersproject/abstract-provider';
7
+ import {
8
+ ErrorInvalidAddress,
9
+ ErrorKVStoreArrayLength,
10
+ ErrorKVStoreEmptyKey,
11
+ ErrorSigner,
12
+ } from './error';
13
+ import { IClientParams } from './interfaces';
14
+ import { requiresSigner } from './decorators';
15
+
16
+ export default class KVStoreClient {
17
+ private contract: KVStore;
18
+ private signerOrProvider: Signer | Provider;
19
+
20
+ /**
21
+ * **KVStore constructor**
22
+ *
23
+ * * @param {IClientParams} clientParams - Init client parameters
24
+ */
25
+ constructor(readonly clientParams: IClientParams) {
26
+ this.contract = KVStore__factory.connect(
27
+ clientParams.network.kvstoreAddress,
28
+ clientParams.signerOrProvider
29
+ );
30
+ this.signerOrProvider = clientParams.signerOrProvider;
31
+ }
32
+
33
+ /**
34
+ * Sets a key-value pair in the contract
35
+ *
36
+ * @param {string} key - The key of the key-value pair to set
37
+ * @param {string} value - The value of the key-value pair to set
38
+ * @returns {Promise<void>}
39
+ * @throws {Error} - An error object if an error occurred
40
+ */
41
+ @requiresSigner
42
+ public async set(key: string, value: string) {
43
+ if (!Signer.isSigner(this.signerOrProvider)) throw ErrorSigner;
44
+ if (key === '') throw ErrorKVStoreEmptyKey;
45
+ try {
46
+ await this.contract?.set(key, value);
47
+ } catch (e) {
48
+ if (e instanceof Error) throw Error(`Failed to set value: ${e.message}`);
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Sets multiple key-value pairs in the contract
54
+ *
55
+ * @param {string[]} keys - An array of keys to set
56
+ * @param {string[]} values - An array of values to set
57
+ * @returns {Promise<void>}
58
+ * @throws {Error} - An error object if an error occurred
59
+ */
60
+ @requiresSigner
61
+ public async setBulk(keys: string[], values: string[]) {
62
+ if (!Signer.isSigner(this.signerOrProvider)) throw ErrorSigner;
63
+ if (keys.length !== values.length) throw ErrorKVStoreArrayLength;
64
+ if (keys.includes('')) throw ErrorKVStoreEmptyKey;
65
+
66
+ try {
67
+ await this.contract?.setBulk(keys, values);
68
+ } catch (e) {
69
+ if (e instanceof Error)
70
+ throw Error(`Failed to set bulk values: ${e.message}`);
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Gets the value of a key-value pair in the contract
76
+ *
77
+ * @param {string} address - The Ethereum address associated with the key-value pair
78
+ * @param {string} key - The key of the key-value pair to get
79
+ * @returns {string} - The value of the key-value pair if it exists
80
+ * @throws {Error} - An error object if an error occurred
81
+ */
82
+ public async get(address: string, key: string) {
83
+ if (key === '') throw ErrorKVStoreEmptyKey;
84
+ if (!ethers.utils.isAddress(address)) throw ErrorInvalidAddress;
85
+
86
+ try {
87
+ const result = await this.contract?.get(address, key);
88
+ return result;
89
+ } catch (e) {
90
+ if (e instanceof Error) throw Error(`Failed to get value: ${e.message}`);
91
+ }
92
+ }
93
+ }
package/src/queries.ts ADDED
@@ -0,0 +1,18 @@
1
+ export const RAW_REWARDS_QUERY = (slasherAddress: string) => `{
2
+ rewardAddedEvents(id: "${slasherAddress}") {
3
+ escrow,
4
+ amount
5
+ }
6
+ }`;
7
+
8
+ export const RAW_LAUNCHED_ESCROWS_QUERY = () => `{
9
+ launchedEscrows(where: { from: $address }) {
10
+ id
11
+ }
12
+ }`;
13
+
14
+ export const RAW_LAUNCHED_ESCROWS_FILTERED_QUERY = () => `{
15
+ launchedEscrows(where: { from: $address, status: $status, timestamp_gte: $from, timestamp_lte: $to }) {
16
+ id
17
+ }
18
+ }`;
package/src/staking.ts ADDED
@@ -0,0 +1,421 @@
1
+ import { Provider } from '@ethersproject/abstract-provider';
2
+ import {
3
+ Staking__factory,
4
+ HMToken__factory,
5
+ HMToken,
6
+ Staking,
7
+ RewardPool__factory,
8
+ RewardPool,
9
+ EscrowFactory,
10
+ EscrowFactory__factory,
11
+ } from '@human-protocol/core/typechain-types';
12
+ import { BigNumber, ethers, Signer } from 'ethers';
13
+ import { NetworkData } from './types';
14
+ import { IAllocation, IClientParams, IReward, IStaker } from './interfaces';
15
+ import {
16
+ ErrorEscrowAddressIsNotProvidedByFactory,
17
+ ErrorInvalidEscrowAddressProvided,
18
+ ErrorInvalidSlasherAddressProvided,
19
+ ErrorInvalidStakerAddressProvided,
20
+ ErrorInvalidStakingValueSign,
21
+ ErrorInvalidStakingValueType,
22
+ ErrorStakingGetStakers,
23
+ } from './error';
24
+ import { gqlFetch, throwError } from './utils';
25
+ import { RAW_REWARDS_QUERY } from './queries';
26
+ import { requiresSigner } from './decorators';
27
+
28
+ export default class StakingClient {
29
+ public signerOrProvider: Signer | Provider;
30
+ public network: NetworkData;
31
+ public tokenContract: HMToken;
32
+ public stakingContract: Staking;
33
+ public escrowFactoryContract: EscrowFactory;
34
+
35
+ /**
36
+ * **Staking constructor**
37
+ *
38
+ * @param {IClientParams} clientParams - Init client parameters
39
+ */
40
+ constructor(readonly clientParams: IClientParams) {
41
+ this.signerOrProvider = clientParams.signerOrProvider;
42
+ this.network = clientParams.network;
43
+
44
+ this.stakingContract = Staking__factory.connect(
45
+ this.network.stakingAddress,
46
+ this.signerOrProvider
47
+ );
48
+
49
+ this.escrowFactoryContract = EscrowFactory__factory.connect(
50
+ this.network.factoryAddress,
51
+ this.signerOrProvider
52
+ );
53
+
54
+ this.tokenContract = HMToken__factory.connect(
55
+ this.network.hmtAddress,
56
+ this.signerOrProvider
57
+ );
58
+ }
59
+
60
+ /**
61
+ * **Approves the staking contract to transfer a specified amount of tokens when the user stakes.
62
+ * **It increases the allowance for the staking contract.*
63
+ *
64
+ * @param {BigNumber} amount - Amount of tokens to approve for stake
65
+ * @returns {Promise<void>}
66
+ * @throws {Error} - An error object if an error occurred, void otherwise
67
+ */
68
+ @requiresSigner
69
+ public async approveStake(amount: BigNumber): Promise<void> {
70
+ if (!BigNumber.isBigNumber(amount)) {
71
+ throw ErrorInvalidStakingValueType;
72
+ }
73
+
74
+ if (amount.isNegative()) {
75
+ throw ErrorInvalidStakingValueSign;
76
+ }
77
+
78
+ try {
79
+ await this.tokenContract.approve(this.stakingContract.address, amount);
80
+ return;
81
+ } catch (e) {
82
+ return throwError(e);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * **Stakes a specified amount of tokens on a specific network.*
88
+ *
89
+ * @param {BigNumber} amount - Amount of tokens to stake
90
+ * @returns {Promise<void>}
91
+ * @throws {Error} - An error object if an error occurred, void otherwise
92
+ */
93
+ @requiresSigner
94
+ public async stake(amount: BigNumber): Promise<void> {
95
+ if (!BigNumber.isBigNumber(amount)) {
96
+ throw ErrorInvalidStakingValueType;
97
+ }
98
+
99
+ if (amount.isNegative()) {
100
+ throw ErrorInvalidStakingValueSign;
101
+ }
102
+
103
+ try {
104
+ await this.stakingContract.stake(amount);
105
+ return;
106
+ } catch (e) {
107
+ return throwError(e);
108
+ }
109
+ }
110
+
111
+ /**
112
+ * **Unstakes tokens from staking contract.
113
+ * **The unstaked tokens stay locked for a period of time.*
114
+ *
115
+ * @param {BigNumber} amount - Amount of tokens to unstake
116
+ * @returns {Promise<void>}
117
+ * @throws {Error} - An error object if an error occurred, void otherwise
118
+ */
119
+ @requiresSigner
120
+ public async unstake(amount: BigNumber): Promise<void> {
121
+ if (!BigNumber.isBigNumber(amount)) {
122
+ throw ErrorInvalidStakingValueType;
123
+ }
124
+
125
+ if (amount.isNegative()) {
126
+ throw ErrorInvalidStakingValueSign;
127
+ }
128
+
129
+ try {
130
+ await this.stakingContract.unstake(amount);
131
+ return;
132
+ } catch (e) {
133
+ return throwError(e);
134
+ }
135
+ }
136
+
137
+ /**
138
+ * **Withdraws unstaked and non locked tokens form staking contract to the user wallet.*
139
+ *
140
+ * @returns {Promise<void>}
141
+ * @throws {Error} - An error object if an error occurred, void otherwise
142
+ */
143
+ @requiresSigner
144
+ public async withdraw(): Promise<void> {
145
+ try {
146
+ await this.stakingContract.withdraw();
147
+ return;
148
+ } catch (e) {
149
+ return throwError(e);
150
+ }
151
+ }
152
+
153
+ /**
154
+ * **Slash the allocated amount by an staker in an escrow and transfers those tokens to the reward pool.
155
+ * **This allows the slasher to claim them later.*
156
+ *
157
+ * @param {string} slasher - Wallet address from who requested the slash
158
+ * @param {string} staker - Wallet address from who is going to be slashed
159
+ * @param {string} escrowAddress - Address of the escrow which allocation will be slashed
160
+ * @param {BigNumber} amount - Amount of tokens to slash
161
+ * @returns {Promise<void>}
162
+ * @throws {Error} - An error object if an error occurred, void otherwise
163
+ */
164
+ @requiresSigner
165
+ public async slash(
166
+ slasher: string,
167
+ staker: string,
168
+ escrowAddress: string,
169
+ amount: BigNumber
170
+ ): Promise<void> {
171
+ if (!BigNumber.isBigNumber(amount)) {
172
+ throw ErrorInvalidStakingValueType;
173
+ }
174
+
175
+ if (amount.isNegative()) {
176
+ throw ErrorInvalidStakingValueSign;
177
+ }
178
+
179
+ if (!ethers.utils.isAddress(slasher)) {
180
+ throw ErrorInvalidSlasherAddressProvided;
181
+ }
182
+
183
+ if (!ethers.utils.isAddress(staker)) {
184
+ throw ErrorInvalidStakerAddressProvided;
185
+ }
186
+
187
+ if (!ethers.utils.isAddress(escrowAddress)) {
188
+ throw ErrorInvalidEscrowAddressProvided;
189
+ }
190
+
191
+ if (!(await this.escrowFactoryContract.hasEscrow(escrowAddress))) {
192
+ throw ErrorEscrowAddressIsNotProvidedByFactory;
193
+ }
194
+
195
+ try {
196
+ await this.stakingContract.slash(slasher, staker, escrowAddress, amount);
197
+
198
+ return;
199
+ } catch (e) {
200
+ return throwError(e);
201
+ }
202
+ }
203
+
204
+ /**
205
+ * **Allocates a portion of the staked tokens to a specific escrow.*
206
+ *
207
+ * @param {string} escrowAddress - Address of the escrow contract
208
+ * @param {BigNumber} amount - Amount of tokens to allocate
209
+ * @returns {Promise<void>}
210
+ * @throws {Error} - An error object if an error occurred, void otherwise
211
+ */
212
+ @requiresSigner
213
+ public async allocate(
214
+ escrowAddress: string,
215
+ amount: BigNumber
216
+ ): Promise<void> {
217
+ if (!BigNumber.isBigNumber(amount)) {
218
+ throw ErrorInvalidStakingValueType;
219
+ }
220
+
221
+ if (amount.isNegative()) {
222
+ throw ErrorInvalidStakingValueSign;
223
+ }
224
+
225
+ if (!ethers.utils.isAddress(escrowAddress)) {
226
+ throw ErrorInvalidEscrowAddressProvided;
227
+ }
228
+
229
+ if (!(await this.escrowFactoryContract.hasEscrow(escrowAddress))) {
230
+ throw ErrorEscrowAddressIsNotProvidedByFactory;
231
+ }
232
+
233
+ try {
234
+ await this.stakingContract.allocate(escrowAddress, amount);
235
+ return;
236
+ } catch (e) {
237
+ return throwError(e);
238
+ }
239
+ }
240
+
241
+ /**
242
+ * **Drops the allocation from a specific escrow.*
243
+ *
244
+ * @param {string} escrowAddress - Address of the escrow contract.
245
+ * @returns {Promise<void>}
246
+ * @throws {Error} - An error object if an error occurred, void otherwise
247
+ */
248
+ @requiresSigner
249
+ public async closeAllocation(escrowAddress: string): Promise<void> {
250
+ if (!ethers.utils.isAddress(escrowAddress)) {
251
+ throw ErrorInvalidEscrowAddressProvided;
252
+ }
253
+
254
+ if (!(await this.escrowFactoryContract.hasEscrow(escrowAddress))) {
255
+ throw ErrorEscrowAddressIsNotProvidedByFactory;
256
+ }
257
+
258
+ try {
259
+ await this.stakingContract.closeAllocation(escrowAddress);
260
+ return;
261
+ } catch (e) {
262
+ return throwError(e);
263
+ }
264
+ }
265
+
266
+ /**
267
+ * **Pays out rewards to the slashers for the specified escrow address.*
268
+ *
269
+ * @param {string} escrowAddress - Escrow address from which rewards are distributed.
270
+ * @returns {Promise<void>}
271
+ * @throws {Error} - An error object if an error occurred, void otherwise
272
+ */
273
+ @requiresSigner
274
+ public async distributeRewards(escrowAddress: string): Promise<void> {
275
+ if (!ethers.utils.isAddress(escrowAddress)) {
276
+ throw ErrorInvalidEscrowAddressProvided;
277
+ }
278
+
279
+ if (!(await this.escrowFactoryContract.hasEscrow(escrowAddress))) {
280
+ throw ErrorEscrowAddressIsNotProvidedByFactory;
281
+ }
282
+
283
+ try {
284
+ const rewardPoolContract: RewardPool = RewardPool__factory.connect(
285
+ await this.stakingContract.rewardPool(),
286
+ this.signerOrProvider
287
+ );
288
+
289
+ await rewardPoolContract.distributeReward(escrowAddress);
290
+ return;
291
+ } catch (e) {
292
+ return throwError(e);
293
+ }
294
+ }
295
+
296
+ /**
297
+ * **Returns the staking information about an staker address.*
298
+ *
299
+ * @param {string} staker - Address of the staker
300
+ * @returns {Promise<IStaker>} - Return staking information of the specified address
301
+ * @throws {Error} - An error object if an error occurred, result otherwise
302
+ */
303
+ public async getStaker(staker: string): Promise<IStaker> {
304
+ if (!ethers.utils.isAddress(staker)) {
305
+ throw ErrorInvalidStakerAddressProvided;
306
+ }
307
+
308
+ try {
309
+ const result = await this.stakingContract.getStaker(staker);
310
+
311
+ const tokensStaked = BigNumber.from(result.tokensStaked),
312
+ tokensAllocated = BigNumber.from(result.tokensAllocated),
313
+ tokensLocked = BigNumber.from(result.tokensLocked),
314
+ tokensLockedUntil = BigNumber.from(result.tokensLockedUntil);
315
+
316
+ const tokensAvailable = tokensStaked
317
+ .sub(tokensAllocated)
318
+ .sub(tokensLocked);
319
+
320
+ return {
321
+ tokensStaked,
322
+ tokensAllocated,
323
+ tokensLocked,
324
+ tokensLockedUntil,
325
+ tokensAvailable,
326
+ };
327
+ } catch (e) {
328
+ return throwError(e);
329
+ }
330
+ }
331
+
332
+ /**
333
+ * **Returns the staking information about all stakers of the protocol.*
334
+ *
335
+ * @returns {Promise<IStakerInfo>} - Return an array with all stakers information
336
+ * @throws {Error} - An error object if an error occurred, results otherwise
337
+ */
338
+ public async getAllStakers(): Promise<IStaker[]> {
339
+ try {
340
+ const result = await this.stakingContract.getListOfStakers();
341
+
342
+ if (result[1].length === 0) {
343
+ throw ErrorStakingGetStakers;
344
+ }
345
+
346
+ return result[1].map((staker: any) => {
347
+ const tokensStaked = BigNumber.from(staker.tokensStaked),
348
+ tokensAllocated = BigNumber.from(staker.tokensAllocated),
349
+ tokensLocked = BigNumber.from(staker.tokensLocked),
350
+ tokensLockedUntil = BigNumber.from(staker.tokensLockedUntil);
351
+
352
+ const tokensAvailable = tokensStaked
353
+ .sub(tokensAllocated)
354
+ .sub(tokensLocked);
355
+
356
+ return {
357
+ tokensStaked,
358
+ tokensAllocated,
359
+ tokensLocked,
360
+ tokensLockedUntil,
361
+ tokensAvailable,
362
+ };
363
+ });
364
+ } catch (e) {
365
+ return throwError(e);
366
+ }
367
+ }
368
+
369
+ /**
370
+ * **Returns information about the allocation of the specified escrow.*
371
+ *
372
+ * @param {string} escrowAddress - The escrow address for the received allocation data
373
+ * @returns {Promise<IAllocation>} - Returns allocation info if exists
374
+ * @throws {Error} - An error object if an error occurred, result otherwise
375
+ */
376
+ public async getAllocation(escrowAddress: string): Promise<IAllocation> {
377
+ if (!ethers.utils.isAddress(escrowAddress)) {
378
+ throw ErrorInvalidEscrowAddressProvided;
379
+ }
380
+
381
+ if (!(await this.escrowFactoryContract.hasEscrow(escrowAddress))) {
382
+ throw ErrorEscrowAddressIsNotProvidedByFactory;
383
+ }
384
+
385
+ try {
386
+ const result = await this.stakingContract.getAllocation(escrowAddress);
387
+ return result;
388
+ } catch (e) {
389
+ return throwError(e);
390
+ }
391
+ }
392
+
393
+ /**
394
+ * **Returns information about the rewards for a given escrow address.*
395
+ *
396
+ * @param {string} slasherAddress - Address of the slasher
397
+ * @returns {Promise<IReward[]>} - Returns rewards info if exists
398
+ * @throws {Error} - An error object if an error occurred, results otherwise
399
+ */
400
+ public async getRewards(slasherAddress: string): Promise<IReward[]> {
401
+ if (!ethers.utils.isAddress(slasherAddress)) {
402
+ throw ErrorInvalidSlasherAddressProvided;
403
+ }
404
+
405
+ try {
406
+ const { data } = await gqlFetch(
407
+ this.network.subgraphUrl,
408
+ RAW_REWARDS_QUERY(slasherAddress)
409
+ );
410
+
411
+ return data.rewardAddedEvents.map((reward: any) => {
412
+ return {
413
+ escrowAddress: reward.escrow,
414
+ amount: reward.amount,
415
+ };
416
+ });
417
+ } catch (e) {
418
+ return throwError(e);
419
+ }
420
+ }
421
+ }