@human-protocol/sdk 4.2.0 → 5.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.js +4 -4
- package/dist/error.d.ts +16 -4
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +18 -6
- package/dist/escrow.d.ts +238 -28
- package/dist/escrow.d.ts.map +1 -1
- package/dist/escrow.js +255 -152
- package/dist/graphql/queries/escrow.d.ts +3 -1
- package/dist/graphql/queries/escrow.d.ts.map +1 -1
- package/dist/graphql/queries/escrow.js +49 -1
- package/dist/graphql/queries/operator.d.ts.map +1 -1
- package/dist/graphql/queries/operator.js +11 -9
- package/dist/graphql/queries/staking.d.ts +4 -0
- package/dist/graphql/queries/staking.d.ts.map +1 -0
- package/dist/graphql/queries/staking.js +71 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/interfaces.d.ts +56 -16
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/operator.d.ts.map +1 -1
- package/dist/operator.js +53 -58
- package/dist/staking.d.ts +21 -1
- package/dist/staking.d.ts.map +1 -1
- package/dist/staking.js +84 -1
- package/dist/types.d.ts +39 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -0
- package/package.json +2 -2
- package/src/constants.ts +4 -4
- package/src/error.ts +25 -7
- package/src/escrow.ts +416 -113
- package/src/graphql/queries/escrow.ts +52 -1
- package/src/graphql/queries/operator.ts +11 -9
- package/src/graphql/queries/staking.ts +80 -0
- package/src/index.ts +2 -1
- package/src/interfaces.ts +63 -18
- package/src/operator.ts +62 -76
- package/src/staking.ts +106 -3
- package/src/types.ts +40 -15
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import gql from 'graphql-tag';
|
|
2
|
-
import { IEscrowsFilter } from '../../interfaces';
|
|
2
|
+
import { ICancellationRefundFilter, IEscrowsFilter } from '../../interfaces';
|
|
3
3
|
|
|
4
4
|
const ESCROW_FRAGMENT = gql`
|
|
5
5
|
fragment EscrowFields on Escrow {
|
|
@@ -25,6 +25,18 @@ const ESCROW_FRAGMENT = gql`
|
|
|
25
25
|
}
|
|
26
26
|
`;
|
|
27
27
|
|
|
28
|
+
const CANCELLATION_REFUND_FRAGMENT = gql`
|
|
29
|
+
fragment CancellationRefundFields on CancellationRefundEvent {
|
|
30
|
+
id
|
|
31
|
+
escrowAddress
|
|
32
|
+
receiver
|
|
33
|
+
amount
|
|
34
|
+
block
|
|
35
|
+
timestamp
|
|
36
|
+
txHash
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
|
|
28
40
|
export const GET_ESCROW_BY_ADDRESS_QUERY = () => gql`
|
|
29
41
|
query getEscrowByAddress($escrowAddress: String!) {
|
|
30
42
|
escrow(id: $escrowAddress) {
|
|
@@ -124,3 +136,42 @@ export const GET_STATUS_UPDATES_QUERY = (
|
|
|
124
136
|
}
|
|
125
137
|
`;
|
|
126
138
|
};
|
|
139
|
+
|
|
140
|
+
export const GET_CANCELLATION_REFUNDS_QUERY = (
|
|
141
|
+
filter: ICancellationRefundFilter
|
|
142
|
+
) => gql`
|
|
143
|
+
query CancellationRefundEvents(
|
|
144
|
+
$escrowAddress: Bytes
|
|
145
|
+
$receiver: Bytes
|
|
146
|
+
$from: Int
|
|
147
|
+
$to: Int
|
|
148
|
+
$first: Int
|
|
149
|
+
$skip: Int
|
|
150
|
+
$orderDirection: OrderDirection
|
|
151
|
+
) {
|
|
152
|
+
cancellationRefundEvents(
|
|
153
|
+
where: {
|
|
154
|
+
${filter.escrowAddress ? 'escrowAddress: $escrowAddress' : ''}
|
|
155
|
+
${filter.receiver ? 'receiver: $receiver' : ''}
|
|
156
|
+
${filter.from ? 'timestamp_gte: $from' : ''}
|
|
157
|
+
${filter.to ? 'timestamp_lte: $to' : ''}
|
|
158
|
+
}
|
|
159
|
+
first: $first
|
|
160
|
+
skip: $skip
|
|
161
|
+
orderBy: timestamp
|
|
162
|
+
orderDirection: $orderDirection
|
|
163
|
+
) {
|
|
164
|
+
...CancellationRefundFields
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
${CANCELLATION_REFUND_FRAGMENT}
|
|
168
|
+
`;
|
|
169
|
+
|
|
170
|
+
export const GET_CANCELLATION_REFUND_BY_ADDRESS_QUERY = () => gql`
|
|
171
|
+
query getCancellationRefundByAddress($escrowAddress: String!) {
|
|
172
|
+
cancellationRefundEvents(where: { escrowAddress: $escrowAddress }) {
|
|
173
|
+
...CancellationRefundFields
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
${CANCELLATION_REFUND_FRAGMENT}
|
|
177
|
+
`;
|
|
@@ -5,12 +5,6 @@ const LEADER_FRAGMENT = gql`
|
|
|
5
5
|
fragment OperatorFields on Operator {
|
|
6
6
|
id
|
|
7
7
|
address
|
|
8
|
-
amountStaked
|
|
9
|
-
amountLocked
|
|
10
|
-
lockedUntilTimestamp
|
|
11
|
-
amountWithdrawn
|
|
12
|
-
amountSlashed
|
|
13
|
-
reward
|
|
14
8
|
amountJobsProcessed
|
|
15
9
|
role
|
|
16
10
|
fee
|
|
@@ -24,22 +18,30 @@ const LEADER_FRAGMENT = gql`
|
|
|
24
18
|
reputationNetworks
|
|
25
19
|
name
|
|
26
20
|
category
|
|
21
|
+
staker {
|
|
22
|
+
stakedAmount
|
|
23
|
+
lockedAmount
|
|
24
|
+
withdrawnAmount
|
|
25
|
+
slashedAmount
|
|
26
|
+
lockedUntilTimestamp
|
|
27
|
+
lastDepositTimestamp
|
|
28
|
+
}
|
|
27
29
|
}
|
|
28
30
|
`;
|
|
29
31
|
|
|
30
32
|
export const GET_LEADERS_QUERY = (filter: IOperatorsFilter) => {
|
|
31
|
-
const { roles,
|
|
33
|
+
const { roles, minStakedAmount } = filter;
|
|
32
34
|
|
|
33
35
|
const WHERE_CLAUSE = `
|
|
34
36
|
where: {
|
|
35
|
-
${
|
|
37
|
+
${minStakedAmount ? `staker_: { stakedAmount_gte: $minStakedAmount }` : ''}
|
|
36
38
|
${roles ? `role_in: $roles` : ''}
|
|
37
39
|
}
|
|
38
40
|
`;
|
|
39
41
|
|
|
40
42
|
return gql`
|
|
41
43
|
query getOperators(
|
|
42
|
-
$
|
|
44
|
+
$minStakedAmount: Int,
|
|
43
45
|
$roles: [String!]
|
|
44
46
|
$first: Int
|
|
45
47
|
$skip: Int
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import gql from 'graphql-tag';
|
|
2
|
+
import { IStakersFilter } from '../../interfaces';
|
|
3
|
+
|
|
4
|
+
const STAKER_FRAGMENT = gql`
|
|
5
|
+
fragment StakerFields on Staker {
|
|
6
|
+
id
|
|
7
|
+
address
|
|
8
|
+
stakedAmount
|
|
9
|
+
lockedAmount
|
|
10
|
+
withdrawnAmount
|
|
11
|
+
slashedAmount
|
|
12
|
+
lockedUntilTimestamp
|
|
13
|
+
lastDepositTimestamp
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
export const GET_STAKERS_QUERY = (filter: IStakersFilter) => {
|
|
18
|
+
const {
|
|
19
|
+
minStakedAmount,
|
|
20
|
+
maxStakedAmount,
|
|
21
|
+
minLockedAmount,
|
|
22
|
+
maxLockedAmount,
|
|
23
|
+
minWithdrawnAmount,
|
|
24
|
+
maxWithdrawnAmount,
|
|
25
|
+
minSlashedAmount,
|
|
26
|
+
maxSlashedAmount,
|
|
27
|
+
} = filter;
|
|
28
|
+
|
|
29
|
+
const whereFields = [
|
|
30
|
+
minStakedAmount ? `stakedAmount_gte: $minStakedAmount` : '',
|
|
31
|
+
maxStakedAmount ? `stakedAmount_lte: $maxStakedAmount` : '',
|
|
32
|
+
minLockedAmount ? `lockedAmount_gte: $minLockedAmount` : '',
|
|
33
|
+
maxLockedAmount ? `lockedAmount_lte: $maxLockedAmount` : '',
|
|
34
|
+
minWithdrawnAmount ? `withdrawnAmount_gte: $minWithdrawnAmount` : '',
|
|
35
|
+
maxWithdrawnAmount ? `withdrawnAmount_lte: $maxWithdrawnAmount` : '',
|
|
36
|
+
minSlashedAmount ? `slashedAmount_gte: $minSlashedAmount` : '',
|
|
37
|
+
maxSlashedAmount ? `slashedAmount_lte: $maxSlashedAmount` : '',
|
|
38
|
+
].filter(Boolean);
|
|
39
|
+
|
|
40
|
+
const WHERE_CLAUSE = whereFields.length
|
|
41
|
+
? `where: { ${whereFields.join(', ')} }`
|
|
42
|
+
: '';
|
|
43
|
+
|
|
44
|
+
return gql`
|
|
45
|
+
query getStakers(
|
|
46
|
+
$minStakedAmount: BigInt
|
|
47
|
+
$maxStakedAmount: BigInt
|
|
48
|
+
$minLockedAmount: BigInt
|
|
49
|
+
$maxLockedAmount: BigInt
|
|
50
|
+
$minWithdrawnAmount: BigInt
|
|
51
|
+
$maxWithdrawnAmount: BigInt
|
|
52
|
+
$minSlashedAmount: BigInt
|
|
53
|
+
$maxSlashedAmount: BigInt
|
|
54
|
+
$orderBy: String
|
|
55
|
+
$orderDirection: OrderDirection
|
|
56
|
+
$first: Int
|
|
57
|
+
$skip: Int
|
|
58
|
+
) {
|
|
59
|
+
stakers(
|
|
60
|
+
${WHERE_CLAUSE}
|
|
61
|
+
orderBy: $orderBy
|
|
62
|
+
orderDirection: $orderDirection
|
|
63
|
+
first: $first
|
|
64
|
+
skip: $skip
|
|
65
|
+
) {
|
|
66
|
+
...StakerFields
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
${STAKER_FRAGMENT}
|
|
70
|
+
`;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const GET_STAKER_BY_ADDRESS_QUERY = gql`
|
|
74
|
+
query getStaker($id: String!) {
|
|
75
|
+
staker(id: $id) {
|
|
76
|
+
...StakerFields
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
${STAKER_FRAGMENT}
|
|
80
|
+
`;
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StakingClient } from './staking';
|
|
1
|
+
import { StakingClient, StakingUtils } from './staking';
|
|
2
2
|
import { StorageClient } from './storage';
|
|
3
3
|
import { KVStoreClient, KVStoreUtils } from './kvstore';
|
|
4
4
|
import { EscrowClient, EscrowUtils } from './escrow';
|
|
@@ -26,4 +26,5 @@ export {
|
|
|
26
26
|
OperatorUtils,
|
|
27
27
|
TransactionUtils,
|
|
28
28
|
WorkerUtils,
|
|
29
|
+
StakingUtils,
|
|
29
30
|
};
|
package/src/interfaces.ts
CHANGED
|
@@ -10,12 +10,11 @@ export interface IOperator {
|
|
|
10
10
|
id: string;
|
|
11
11
|
chainId: ChainId;
|
|
12
12
|
address: string;
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
stakedAmount: bigint;
|
|
14
|
+
lockedAmount: bigint;
|
|
15
15
|
lockedUntilTimestamp: bigint;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
reward: bigint;
|
|
16
|
+
withdrawnAmount: bigint;
|
|
17
|
+
slashedAmount: bigint;
|
|
19
18
|
amountJobsProcessed: bigint;
|
|
20
19
|
role?: string;
|
|
21
20
|
fee?: bigint;
|
|
@@ -31,16 +30,36 @@ export interface IOperator {
|
|
|
31
30
|
category?: string;
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
export interface IOperatorSubgraph
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
export interface IOperatorSubgraph {
|
|
34
|
+
id: string;
|
|
35
|
+
address: string;
|
|
36
|
+
amountJobsProcessed: bigint;
|
|
37
|
+
role?: string;
|
|
38
|
+
fee?: bigint;
|
|
39
|
+
publicKey?: string;
|
|
40
|
+
webhookUrl?: string;
|
|
41
|
+
website?: string;
|
|
42
|
+
url?: string;
|
|
43
|
+
registrationNeeded?: boolean;
|
|
44
|
+
registrationInstructions?: string;
|
|
45
|
+
name?: string;
|
|
46
|
+
category?: string;
|
|
47
|
+
jobTypes?: string | string[];
|
|
37
48
|
reputationNetworks?: { address: string }[];
|
|
49
|
+
staker?: {
|
|
50
|
+
stakedAmount: bigint;
|
|
51
|
+
lockedAmount: bigint;
|
|
52
|
+
lockedUntilTimestamp: bigint;
|
|
53
|
+
withdrawnAmount: bigint;
|
|
54
|
+
slashedAmount: bigint;
|
|
55
|
+
lastDepositTimestamp: bigint;
|
|
56
|
+
};
|
|
38
57
|
}
|
|
39
58
|
|
|
40
59
|
export interface IOperatorsFilter extends IPagination {
|
|
41
60
|
chainId: ChainId;
|
|
42
61
|
roles?: string[];
|
|
43
|
-
|
|
62
|
+
minStakedAmount?: number;
|
|
44
63
|
orderBy?: string;
|
|
45
64
|
}
|
|
46
65
|
|
|
@@ -55,15 +74,6 @@ export interface IReputationNetworkSubgraph
|
|
|
55
74
|
operators: IOperatorSubgraph[];
|
|
56
75
|
}
|
|
57
76
|
|
|
58
|
-
export interface IOperator {
|
|
59
|
-
address: string;
|
|
60
|
-
role?: string;
|
|
61
|
-
url?: string;
|
|
62
|
-
jobTypes?: string[];
|
|
63
|
-
registrationNeeded?: boolean;
|
|
64
|
-
registrationInstructions?: string;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
77
|
export interface IEscrow {
|
|
68
78
|
id: string;
|
|
69
79
|
address: string;
|
|
@@ -208,3 +218,38 @@ export interface IWorkersFilter extends IPagination {
|
|
|
208
218
|
address?: string;
|
|
209
219
|
orderBy?: string;
|
|
210
220
|
}
|
|
221
|
+
|
|
222
|
+
export interface IStaker {
|
|
223
|
+
address: string;
|
|
224
|
+
stakedAmount: bigint;
|
|
225
|
+
lockedAmount: bigint;
|
|
226
|
+
lockedUntil: bigint;
|
|
227
|
+
withdrawableAmount: bigint;
|
|
228
|
+
slashedAmount: bigint;
|
|
229
|
+
lastDepositTimestamp: bigint;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface IStakersFilter extends IPagination {
|
|
233
|
+
chainId: ChainId;
|
|
234
|
+
minStakedAmount?: string;
|
|
235
|
+
maxStakedAmount?: string;
|
|
236
|
+
minLockedAmount?: string;
|
|
237
|
+
maxLockedAmount?: string;
|
|
238
|
+
minWithdrawnAmount?: string;
|
|
239
|
+
maxWithdrawnAmount?: string;
|
|
240
|
+
minSlashedAmount?: string;
|
|
241
|
+
maxSlashedAmount?: string;
|
|
242
|
+
orderBy?:
|
|
243
|
+
| 'stakedAmount'
|
|
244
|
+
| 'lockedAmount'
|
|
245
|
+
| 'withdrawnAmount'
|
|
246
|
+
| 'slashedAmount'
|
|
247
|
+
| 'lastDepositTimestamp';
|
|
248
|
+
}
|
|
249
|
+
export interface ICancellationRefundFilter extends IPagination {
|
|
250
|
+
chainId: ChainId;
|
|
251
|
+
escrowAddress?: string;
|
|
252
|
+
receiver?: string;
|
|
253
|
+
from?: Date;
|
|
254
|
+
to?: Date;
|
|
255
|
+
}
|
package/src/operator.ts
CHANGED
|
@@ -60,33 +60,10 @@ export class OperatorUtils {
|
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
if (!operator) {
|
|
63
|
-
return
|
|
63
|
+
return null as any;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
let reputationNetworks: string[] = [];
|
|
68
|
-
|
|
69
|
-
if (typeof operator.jobTypes === 'string') {
|
|
70
|
-
jobTypes = operator.jobTypes.split(',');
|
|
71
|
-
} else if (Array.isArray(operator.jobTypes)) {
|
|
72
|
-
jobTypes = operator.jobTypes;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
operator.reputationNetworks &&
|
|
77
|
-
Array.isArray(operator.reputationNetworks)
|
|
78
|
-
) {
|
|
79
|
-
reputationNetworks = operator.reputationNetworks.map(
|
|
80
|
-
(network) => network.address
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
...operator,
|
|
86
|
-
jobTypes,
|
|
87
|
-
reputationNetworks,
|
|
88
|
-
chainId,
|
|
89
|
-
};
|
|
66
|
+
return mapOperator(operator, chainId);
|
|
90
67
|
}
|
|
91
68
|
|
|
92
69
|
/**
|
|
@@ -109,8 +86,6 @@ export class OperatorUtils {
|
|
|
109
86
|
public static async getOperators(
|
|
110
87
|
filter: IOperatorsFilter
|
|
111
88
|
): Promise<IOperator[]> {
|
|
112
|
-
let operators_data: IOperator[] = [];
|
|
113
|
-
|
|
114
89
|
const first =
|
|
115
90
|
filter.first !== undefined && filter.first > 0
|
|
116
91
|
? Math.min(filter.first, 1000)
|
|
@@ -119,6 +94,15 @@ export class OperatorUtils {
|
|
|
119
94
|
filter.skip !== undefined && filter.skip >= 0 ? filter.skip : 0;
|
|
120
95
|
const orderDirection = filter.orderDirection || OrderDirection.DESC;
|
|
121
96
|
|
|
97
|
+
let orderBy = filter.orderBy;
|
|
98
|
+
if (filter.orderBy === 'stakedAmount') orderBy = 'staker__stakedAmount';
|
|
99
|
+
else if (filter.orderBy === 'lockedAmount')
|
|
100
|
+
orderBy = 'staker__lockedAmount';
|
|
101
|
+
else if (filter.orderBy === 'withdrawnAmount')
|
|
102
|
+
orderBy = 'staker__withdrawnAmount';
|
|
103
|
+
else if (filter.orderBy === 'slashedAmount')
|
|
104
|
+
orderBy = 'staker__slashedAmount';
|
|
105
|
+
|
|
122
106
|
const networkData = NETWORKS[filter.chainId];
|
|
123
107
|
|
|
124
108
|
if (!networkData) {
|
|
@@ -128,9 +112,9 @@ export class OperatorUtils {
|
|
|
128
112
|
const { operators } = await gqlFetch<{
|
|
129
113
|
operators: IOperatorSubgraph[];
|
|
130
114
|
}>(getSubgraphUrl(networkData), GET_LEADERS_QUERY(filter), {
|
|
131
|
-
|
|
115
|
+
minStakedAmount: filter?.minStakedAmount,
|
|
132
116
|
roles: filter?.roles,
|
|
133
|
-
orderBy:
|
|
117
|
+
orderBy: orderBy,
|
|
134
118
|
orderDirection: orderDirection,
|
|
135
119
|
first: first,
|
|
136
120
|
skip: skip,
|
|
@@ -140,35 +124,7 @@ export class OperatorUtils {
|
|
|
140
124
|
return [];
|
|
141
125
|
}
|
|
142
126
|
|
|
143
|
-
|
|
144
|
-
operators.map((operator) => {
|
|
145
|
-
let jobTypes: string[] = [];
|
|
146
|
-
let reputationNetworks: string[] = [];
|
|
147
|
-
|
|
148
|
-
if (typeof operator.jobTypes === 'string') {
|
|
149
|
-
jobTypes = operator.jobTypes.split(',');
|
|
150
|
-
} else if (Array.isArray(operator.jobTypes)) {
|
|
151
|
-
jobTypes = operator.jobTypes;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (
|
|
155
|
-
operator.reputationNetworks &&
|
|
156
|
-
Array.isArray(operator.reputationNetworks)
|
|
157
|
-
) {
|
|
158
|
-
reputationNetworks = operator.reputationNetworks.map(
|
|
159
|
-
(network) => network.address
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
...operator,
|
|
165
|
-
jobTypes,
|
|
166
|
-
reputationNetworks,
|
|
167
|
-
chainId: filter.chainId,
|
|
168
|
-
};
|
|
169
|
-
})
|
|
170
|
-
);
|
|
171
|
-
return operators_data;
|
|
127
|
+
return operators.map((operator) => mapOperator(operator, filter.chainId));
|
|
172
128
|
}
|
|
173
129
|
|
|
174
130
|
/**
|
|
@@ -206,24 +162,9 @@ export class OperatorUtils {
|
|
|
206
162
|
|
|
207
163
|
if (!reputationNetwork) return [];
|
|
208
164
|
|
|
209
|
-
return reputationNetwork.operators.map((operator) =>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (typeof operator.jobTypes === 'string') {
|
|
213
|
-
jobTypes = operator.jobTypes.split(',');
|
|
214
|
-
} else if (Array.isArray(operator.jobTypes)) {
|
|
215
|
-
jobTypes = operator.jobTypes;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
chainId,
|
|
220
|
-
...operator,
|
|
221
|
-
jobTypes,
|
|
222
|
-
reputationNetworks: operator.reputationNetworks?.map(
|
|
223
|
-
(network) => network.address
|
|
224
|
-
),
|
|
225
|
-
};
|
|
226
|
-
});
|
|
165
|
+
return reputationNetwork.operators.map((operator) =>
|
|
166
|
+
mapOperator(operator, chainId)
|
|
167
|
+
);
|
|
227
168
|
}
|
|
228
169
|
|
|
229
170
|
/**
|
|
@@ -270,3 +211,48 @@ export class OperatorUtils {
|
|
|
270
211
|
});
|
|
271
212
|
}
|
|
272
213
|
}
|
|
214
|
+
|
|
215
|
+
function mapOperator(operator: IOperatorSubgraph, chainId: ChainId): IOperator {
|
|
216
|
+
const staker = operator?.staker;
|
|
217
|
+
let jobTypes: string[] = [];
|
|
218
|
+
let reputationNetworks: string[] = [];
|
|
219
|
+
|
|
220
|
+
if (typeof operator.jobTypes === 'string') {
|
|
221
|
+
jobTypes = operator.jobTypes.split(',');
|
|
222
|
+
} else if (Array.isArray(operator.jobTypes)) {
|
|
223
|
+
jobTypes = operator.jobTypes;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (
|
|
227
|
+
operator.reputationNetworks &&
|
|
228
|
+
Array.isArray(operator.reputationNetworks)
|
|
229
|
+
) {
|
|
230
|
+
reputationNetworks = operator.reputationNetworks.map(
|
|
231
|
+
(network) => network.address
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
id: operator.id,
|
|
237
|
+
chainId,
|
|
238
|
+
address: operator.address,
|
|
239
|
+
stakedAmount: BigInt(staker?.stakedAmount || 0),
|
|
240
|
+
lockedAmount: BigInt(staker?.lockedAmount || 0),
|
|
241
|
+
lockedUntilTimestamp: BigInt(staker?.lockedUntilTimestamp || 0),
|
|
242
|
+
withdrawnAmount: BigInt(staker?.withdrawnAmount || 0),
|
|
243
|
+
slashedAmount: BigInt(staker?.slashedAmount || 0),
|
|
244
|
+
amountJobsProcessed: BigInt(operator.amountJobsProcessed || 0),
|
|
245
|
+
role: operator.role,
|
|
246
|
+
fee: operator.fee ? BigInt(operator.fee) : undefined,
|
|
247
|
+
publicKey: operator.publicKey,
|
|
248
|
+
webhookUrl: operator.webhookUrl,
|
|
249
|
+
website: operator.website,
|
|
250
|
+
url: operator.url,
|
|
251
|
+
jobTypes,
|
|
252
|
+
registrationNeeded: operator.registrationNeeded,
|
|
253
|
+
registrationInstructions: operator.registrationInstructions,
|
|
254
|
+
reputationNetworks,
|
|
255
|
+
name: operator.name,
|
|
256
|
+
category: operator.category,
|
|
257
|
+
};
|
|
258
|
+
}
|
package/src/staking.ts
CHANGED
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
Staking__factory,
|
|
8
8
|
} from '@human-protocol/core/typechain-types';
|
|
9
9
|
import { ContractRunner, Overrides, ethers } from 'ethers';
|
|
10
|
+
import gqlFetch from 'graphql-request';
|
|
10
11
|
import { BaseEthersClient } from './base';
|
|
11
12
|
import { NETWORKS } from './constants';
|
|
12
13
|
import { requiresSigner } from './decorators';
|
|
13
|
-
import { ChainId } from './enums';
|
|
14
|
+
import { ChainId, OrderDirection } from './enums';
|
|
14
15
|
import {
|
|
15
16
|
ErrorEscrowAddressIsNotProvidedByFactory,
|
|
16
17
|
ErrorInvalidEscrowAddressProvided,
|
|
@@ -19,11 +20,16 @@ import {
|
|
|
19
20
|
ErrorInvalidStakingValueSign,
|
|
20
21
|
ErrorInvalidStakingValueType,
|
|
21
22
|
ErrorProviderDoesNotExist,
|
|
23
|
+
ErrorStakerNotFound,
|
|
22
24
|
ErrorUnsupportedChainID,
|
|
23
25
|
} from './error';
|
|
26
|
+
import { IStaker, IStakersFilter, StakerInfo } from './interfaces';
|
|
24
27
|
import { NetworkData } from './types';
|
|
25
|
-
import { throwError } from './utils';
|
|
26
|
-
import {
|
|
28
|
+
import { getSubgraphUrl, throwError } from './utils';
|
|
29
|
+
import {
|
|
30
|
+
GET_STAKER_BY_ADDRESS_QUERY,
|
|
31
|
+
GET_STAKERS_QUERY,
|
|
32
|
+
} from './graphql/queries/staking';
|
|
27
33
|
|
|
28
34
|
/**
|
|
29
35
|
* ## Introduction
|
|
@@ -439,6 +445,7 @@ export class StakingClient extends BaseEthersClient {
|
|
|
439
445
|
|
|
440
446
|
try {
|
|
441
447
|
const stakerInfo = await this.stakingContract.stakes(stakerAddress);
|
|
448
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
442
449
|
const currentBlock = await this.runner.provider!.getBlockNumber();
|
|
443
450
|
|
|
444
451
|
const tokensWithdrawable =
|
|
@@ -465,3 +472,99 @@ export class StakingClient extends BaseEthersClient {
|
|
|
465
472
|
}
|
|
466
473
|
}
|
|
467
474
|
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Utility class for Staking-related subgraph queries.
|
|
478
|
+
*/
|
|
479
|
+
export class StakingUtils {
|
|
480
|
+
/**
|
|
481
|
+
* Gets staking info for a staker from the subgraph.
|
|
482
|
+
*
|
|
483
|
+
* @param {ChainId} chainId Network in which the staking contract is deployed
|
|
484
|
+
* @param {string} stakerAddress Address of the staker
|
|
485
|
+
* @returns {Promise<IStaker>} Staker info from subgraph
|
|
486
|
+
*/
|
|
487
|
+
public static async getStaker(
|
|
488
|
+
chainId: ChainId,
|
|
489
|
+
stakerAddress: string
|
|
490
|
+
): Promise<IStaker> {
|
|
491
|
+
if (!ethers.isAddress(stakerAddress)) {
|
|
492
|
+
throw ErrorInvalidStakerAddressProvided;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
const networkData: NetworkData | undefined = NETWORKS[chainId];
|
|
496
|
+
if (!networkData) {
|
|
497
|
+
throw ErrorUnsupportedChainID;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const { staker } = await gqlFetch<{ staker: IStaker }>(
|
|
501
|
+
getSubgraphUrl(networkData),
|
|
502
|
+
GET_STAKER_BY_ADDRESS_QUERY,
|
|
503
|
+
{ id: stakerAddress.toLowerCase() }
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
if (!staker) {
|
|
507
|
+
throw ErrorStakerNotFound;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return staker;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Gets all stakers from the subgraph with filters, pagination and ordering.
|
|
515
|
+
*
|
|
516
|
+
* @returns {Promise<IStaker[]>} Array of stakers
|
|
517
|
+
*/
|
|
518
|
+
public static async getStakers(filter: IStakersFilter): Promise<IStaker[]> {
|
|
519
|
+
const first =
|
|
520
|
+
filter.first !== undefined ? Math.min(filter.first, 1000) : 10;
|
|
521
|
+
const skip = filter.skip || 0;
|
|
522
|
+
const orderDirection = filter.orderDirection || OrderDirection.DESC;
|
|
523
|
+
const orderBy = filter.orderBy || 'lastDepositTimestamp';
|
|
524
|
+
|
|
525
|
+
const networkData = NETWORKS[filter.chainId];
|
|
526
|
+
if (!networkData) {
|
|
527
|
+
throw ErrorUnsupportedChainID;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
const { stakers } = await gqlFetch<{ stakers: IStaker[] }>(
|
|
531
|
+
getSubgraphUrl(networkData),
|
|
532
|
+
GET_STAKERS_QUERY(filter),
|
|
533
|
+
{
|
|
534
|
+
minStakedAmount: filter.minStakedAmount
|
|
535
|
+
? filter.minStakedAmount
|
|
536
|
+
: undefined,
|
|
537
|
+
maxStakedAmount: filter.maxStakedAmount
|
|
538
|
+
? filter.maxStakedAmount
|
|
539
|
+
: undefined,
|
|
540
|
+
minLockedAmount: filter.minLockedAmount
|
|
541
|
+
? filter.minLockedAmount
|
|
542
|
+
: undefined,
|
|
543
|
+
maxLockedAmount: filter.maxLockedAmount
|
|
544
|
+
? filter.maxLockedAmount
|
|
545
|
+
: undefined,
|
|
546
|
+
minWithdrawnAmount: filter.minWithdrawnAmount
|
|
547
|
+
? filter.minWithdrawnAmount
|
|
548
|
+
: undefined,
|
|
549
|
+
maxWithdrawnAmount: filter.maxWithdrawnAmount
|
|
550
|
+
? filter.maxWithdrawnAmount
|
|
551
|
+
: undefined,
|
|
552
|
+
minSlashedAmount: filter.minSlashedAmount
|
|
553
|
+
? filter.minSlashedAmount
|
|
554
|
+
: undefined,
|
|
555
|
+
maxSlashedAmount: filter.maxSlashedAmount
|
|
556
|
+
? filter.maxSlashedAmount
|
|
557
|
+
: undefined,
|
|
558
|
+
orderBy: orderBy,
|
|
559
|
+
orderDirection: orderDirection,
|
|
560
|
+
first: first,
|
|
561
|
+
skip: skip,
|
|
562
|
+
}
|
|
563
|
+
);
|
|
564
|
+
if (!stakers) {
|
|
565
|
+
return [];
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return stakers;
|
|
569
|
+
}
|
|
570
|
+
}
|