@human-protocol/sdk 2.1.3 → 3.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.
- package/README.md +23 -80
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +56 -24
- package/dist/enums.d.ts +7 -2
- package/dist/enums.d.ts.map +1 -1
- package/dist/enums.js +8 -2
- package/dist/error.d.ts +16 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +18 -2
- package/dist/escrow.d.ts +91 -7
- package/dist/escrow.d.ts.map +1 -1
- package/dist/escrow.js +154 -39
- package/dist/graphql/queries/escrow.d.ts +1 -0
- package/dist/graphql/queries/escrow.d.ts.map +1 -1
- package/dist/graphql/queries/escrow.js +50 -9
- package/dist/graphql/queries/hmtoken.d.ts +1 -1
- package/dist/graphql/queries/hmtoken.d.ts.map +1 -1
- package/dist/graphql/queries/hmtoken.js +23 -7
- package/dist/graphql/queries/kvstore.d.ts +2 -0
- package/dist/graphql/queries/kvstore.d.ts.map +1 -0
- package/dist/graphql/queries/kvstore.js +28 -0
- package/dist/graphql/queries/statistics.d.ts.map +1 -1
- package/dist/graphql/queries/statistics.js +2 -0
- package/dist/graphql/queries/transaction.d.ts +4 -0
- package/dist/graphql/queries/transaction.d.ts.map +1 -0
- package/dist/graphql/queries/transaction.js +64 -0
- package/dist/graphql/types.d.ts +19 -0
- package/dist/graphql/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/interfaces.d.ts +35 -4
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/kvstore.d.ts +84 -0
- package/dist/kvstore.d.ts.map +1 -1
- package/dist/kvstore.js +103 -1
- package/dist/operator.d.ts +5 -2
- package/dist/operator.d.ts.map +1 -1
- package/dist/operator.js +68 -57
- package/dist/statistics.d.ts +29 -2
- package/dist/statistics.d.ts.map +1 -1
- package/dist/statistics.js +53 -7
- package/dist/transaction.d.ts +75 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +130 -0
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +21 -1
- package/package.json +7 -6
- package/src/constants.ts +73 -23
- package/src/enums.ts +7 -1
- package/src/error.ts +23 -0
- package/src/escrow.ts +199 -51
- package/src/graphql/queries/escrow.ts +53 -8
- package/src/graphql/queries/hmtoken.ts +23 -7
- package/src/graphql/queries/kvstore.ts +23 -0
- package/src/graphql/queries/statistics.ts +2 -0
- package/src/graphql/queries/transaction.ts +64 -0
- package/src/graphql/types.ts +22 -0
- package/src/index.ts +2 -0
- package/src/interfaces.ts +40 -4
- package/src/kvstore.ts +114 -1
- package/src/operator.ts +90 -69
- package/src/statistics.ts +63 -9
- package/src/transaction.ts +152 -0
- package/src/types.ts +4 -0
- package/src/utils.ts +25 -0
package/src/kvstore.ts
CHANGED
|
@@ -16,8 +16,12 @@ import {
|
|
|
16
16
|
ErrorProviderDoesNotExist,
|
|
17
17
|
ErrorUnsupportedChainID,
|
|
18
18
|
} from './error';
|
|
19
|
+
import gqlFetch from 'graphql-request';
|
|
19
20
|
import { NetworkData } from './types';
|
|
20
|
-
import { isValidUrl } from './utils';
|
|
21
|
+
import { getSubgraphUrl, isValidUrl } from './utils';
|
|
22
|
+
import { GET_KVSTORE_BY_ADDRESS_QUERY } from './graphql/queries/kvstore';
|
|
23
|
+
import { KVStoreData } from './graphql';
|
|
24
|
+
import { IKVStore } from './interfaces';
|
|
21
25
|
/**
|
|
22
26
|
* ## Introduction
|
|
23
27
|
*
|
|
@@ -410,3 +414,112 @@ export class KVStoreClient extends BaseEthersClient {
|
|
|
410
414
|
return publicKey;
|
|
411
415
|
}
|
|
412
416
|
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* ## Introduction
|
|
420
|
+
*
|
|
421
|
+
* Utility class for KVStore-related operations.
|
|
422
|
+
*
|
|
423
|
+
* ## Installation
|
|
424
|
+
*
|
|
425
|
+
* ### npm
|
|
426
|
+
* ```bash
|
|
427
|
+
* npm install @human-protocol/sdk
|
|
428
|
+
* ```
|
|
429
|
+
*
|
|
430
|
+
* ### yarn
|
|
431
|
+
* ```bash
|
|
432
|
+
* yarn install @human-protocol/sdk
|
|
433
|
+
* ```
|
|
434
|
+
*
|
|
435
|
+
* ## Code example
|
|
436
|
+
*
|
|
437
|
+
* ### Signer
|
|
438
|
+
*
|
|
439
|
+
* **Using private key (backend)**
|
|
440
|
+
*
|
|
441
|
+
* ```ts
|
|
442
|
+
* import { ChainId, KVStoreUtils } from '@human-protocol/sdk';
|
|
443
|
+
*
|
|
444
|
+
* const KVStoreAddresses = new KVStoreUtils.getData({
|
|
445
|
+
* network: ChainId.POLYGON_AMOY
|
|
446
|
+
* });
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
export class KVStoreUtils {
|
|
450
|
+
/**
|
|
451
|
+
* This function returns the KVStore data for a given address.
|
|
452
|
+
*
|
|
453
|
+
* > This uses Subgraph
|
|
454
|
+
*
|
|
455
|
+
* **Input parameters**
|
|
456
|
+
*
|
|
457
|
+
* ```ts
|
|
458
|
+
* enum ChainId {
|
|
459
|
+
* ALL = -1,
|
|
460
|
+
* MAINNET = 1,
|
|
461
|
+
* RINKEBY = 4,
|
|
462
|
+
* GOERLI = 5,
|
|
463
|
+
* BSC_MAINNET = 56,
|
|
464
|
+
* BSC_TESTNET = 97,
|
|
465
|
+
* POLYGON = 137,
|
|
466
|
+
* POLYGON_MUMBAI = 80001,
|
|
467
|
+
* POLYGON_AMOY = 80002,
|
|
468
|
+
* MOONBEAM = 1284,
|
|
469
|
+
* MOONBASE_ALPHA = 1287,
|
|
470
|
+
* AVALANCHE = 43114,
|
|
471
|
+
* AVALANCHE_TESTNET = 43113,
|
|
472
|
+
* CELO = 42220,
|
|
473
|
+
* CELO_ALFAJORES = 44787,
|
|
474
|
+
* LOCALHOST = 1338,
|
|
475
|
+
* }
|
|
476
|
+
* ```
|
|
477
|
+
*
|
|
478
|
+
* ```ts
|
|
479
|
+
* interface IKVStore {
|
|
480
|
+
* key: string;
|
|
481
|
+
* value: string;
|
|
482
|
+
* }
|
|
483
|
+
* ```
|
|
484
|
+
*
|
|
485
|
+
* @param {ChainId} chainId Network in which the KVStore is deployed
|
|
486
|
+
* @param {string} address Address of the KVStore
|
|
487
|
+
* @returns {Promise<IKVStore[]>} KVStore data
|
|
488
|
+
*
|
|
489
|
+
* **Code example**
|
|
490
|
+
*
|
|
491
|
+
* ```ts
|
|
492
|
+
* import { ChainId, KVStoreUtils } from '@human-protocol/sdk';
|
|
493
|
+
*
|
|
494
|
+
* const kvStoreData = await KVStoreUtils.getKVStoreData(ChainId.POLYGON_AMOY, "0x1234567890123456789012345678901234567890");
|
|
495
|
+
* console.log(kvStoreData);
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
public static async getKVStoreData(
|
|
499
|
+
chainId: ChainId,
|
|
500
|
+
address: string
|
|
501
|
+
): Promise<IKVStore[]> {
|
|
502
|
+
const networkData = NETWORKS[chainId];
|
|
503
|
+
|
|
504
|
+
if (!networkData) {
|
|
505
|
+
throw ErrorUnsupportedChainID;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (address && !ethers.isAddress(address)) {
|
|
509
|
+
throw ErrorInvalidAddress;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const { kvstores } = await gqlFetch<{ kvstores: KVStoreData[] }>(
|
|
513
|
+
getSubgraphUrl(networkData),
|
|
514
|
+
GET_KVSTORE_BY_ADDRESS_QUERY(),
|
|
515
|
+
{ address: address.toLowerCase() }
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
const kvStoreData = kvstores.map((item) => ({
|
|
519
|
+
key: item.key,
|
|
520
|
+
value: item.value,
|
|
521
|
+
}));
|
|
522
|
+
|
|
523
|
+
return kvStoreData || [];
|
|
524
|
+
}
|
|
525
|
+
}
|
package/src/operator.ts
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
ErrorInvalidStakerAddressProvided,
|
|
22
22
|
ErrorUnsupportedChainID,
|
|
23
23
|
} from './error';
|
|
24
|
-
import {
|
|
24
|
+
import { getSubgraphUrl } from './utils';
|
|
25
25
|
import { ChainId } from './enums';
|
|
26
26
|
import { NETWORKS } from './constants';
|
|
27
27
|
|
|
@@ -54,20 +54,28 @@ export class OperatorUtils {
|
|
|
54
54
|
throw ErrorUnsupportedChainID;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
});
|
|
57
|
+
const { leader } = await gqlFetch<{
|
|
58
|
+
leader: ILeaderSubgraph;
|
|
59
|
+
}>(getSubgraphUrl(networkData), GET_LEADER_QUERY, {
|
|
60
|
+
address: address.toLowerCase(),
|
|
61
|
+
});
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
if (!leader) {
|
|
64
|
+
return (leader as ILeader) || null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let jobTypes: string[] = [];
|
|
68
|
+
|
|
69
|
+
if (typeof leader.jobTypes === 'string') {
|
|
70
|
+
jobTypes = leader.jobTypes.split(',');
|
|
71
|
+
} else if (Array.isArray(leader.jobTypes)) {
|
|
72
|
+
jobTypes = leader.jobTypes;
|
|
70
73
|
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
...leader,
|
|
77
|
+
jobTypes,
|
|
78
|
+
};
|
|
71
79
|
}
|
|
72
80
|
|
|
73
81
|
/**
|
|
@@ -82,37 +90,48 @@ export class OperatorUtils {
|
|
|
82
90
|
* ```ts
|
|
83
91
|
* import { OperatorUtils } from '@human-protocol/sdk';
|
|
84
92
|
*
|
|
85
|
-
* const
|
|
93
|
+
* const filter: ILeadersFilter = {
|
|
94
|
+
* chainId: ChainId.POLYGON
|
|
95
|
+
* };
|
|
96
|
+
* const leaders = await OperatorUtils.getLeaders(filter);
|
|
86
97
|
* ```
|
|
87
98
|
*/
|
|
88
|
-
public static async getLeaders(
|
|
89
|
-
|
|
90
|
-
): Promise<ILeader[]> {
|
|
91
|
-
try {
|
|
92
|
-
let leaders_data: ILeader[] = [];
|
|
93
|
-
for (const chainId of filter.networks) {
|
|
94
|
-
const networkData = NETWORKS[chainId];
|
|
95
|
-
|
|
96
|
-
if (!networkData) {
|
|
97
|
-
throw ErrorUnsupportedChainID;
|
|
98
|
-
}
|
|
99
|
-
const { leaders } = await gqlFetch<{
|
|
100
|
-
leaders: ILeaderSubgraph[];
|
|
101
|
-
}>(networkData.subgraphUrl, GET_LEADERS_QUERY(filter), {
|
|
102
|
-
role: filter.role,
|
|
103
|
-
});
|
|
104
|
-
leaders_data = leaders_data.concat(
|
|
105
|
-
leaders.map((leader) => ({
|
|
106
|
-
...leader,
|
|
107
|
-
jobTypes: leader.jobTypes?.split(','),
|
|
108
|
-
}))
|
|
109
|
-
);
|
|
110
|
-
}
|
|
99
|
+
public static async getLeaders(filter: ILeadersFilter): Promise<ILeader[]> {
|
|
100
|
+
let leaders_data: ILeader[] = [];
|
|
111
101
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
102
|
+
const networkData = NETWORKS[filter.chainId];
|
|
103
|
+
|
|
104
|
+
if (!networkData) {
|
|
105
|
+
throw ErrorUnsupportedChainID;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const { leaders } = await gqlFetch<{
|
|
109
|
+
leaders: ILeaderSubgraph[];
|
|
110
|
+
}>(getSubgraphUrl(networkData), GET_LEADERS_QUERY(filter), {
|
|
111
|
+
role: filter?.role,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (!leaders) {
|
|
115
|
+
return [];
|
|
115
116
|
}
|
|
117
|
+
|
|
118
|
+
leaders_data = leaders_data.concat(
|
|
119
|
+
leaders.map((leader) => {
|
|
120
|
+
let jobTypes: string[] = [];
|
|
121
|
+
|
|
122
|
+
if (typeof leader.jobTypes === 'string') {
|
|
123
|
+
jobTypes = leader.jobTypes.split(',');
|
|
124
|
+
} else if (Array.isArray(leader.jobTypes)) {
|
|
125
|
+
jobTypes = leader.jobTypes;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
...leader,
|
|
130
|
+
jobTypes,
|
|
131
|
+
};
|
|
132
|
+
})
|
|
133
|
+
);
|
|
134
|
+
return leaders_data;
|
|
116
135
|
}
|
|
117
136
|
|
|
118
137
|
/**
|
|
@@ -139,21 +158,27 @@ export class OperatorUtils {
|
|
|
139
158
|
if (!networkData) {
|
|
140
159
|
throw ErrorUnsupportedChainID;
|
|
141
160
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
161
|
+
const { reputationNetwork } = await gqlFetch<{
|
|
162
|
+
reputationNetwork: IReputationNetworkSubgraph;
|
|
163
|
+
}>(getSubgraphUrl(networkData), GET_REPUTATION_NETWORK_QUERY(role), {
|
|
164
|
+
address: address.toLowerCase(),
|
|
165
|
+
role: role,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return reputationNetwork.operators.map((operator) => {
|
|
169
|
+
let jobTypes: string[] = [];
|
|
170
|
+
|
|
171
|
+
if (typeof operator.jobTypes === 'string') {
|
|
172
|
+
jobTypes = operator.jobTypes.split(',');
|
|
173
|
+
} else if (Array.isArray(operator.jobTypes)) {
|
|
174
|
+
jobTypes = operator.jobTypes;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return {
|
|
151
178
|
...operator,
|
|
152
|
-
jobTypes
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return throwError(e);
|
|
156
|
-
}
|
|
179
|
+
jobTypes,
|
|
180
|
+
};
|
|
181
|
+
});
|
|
157
182
|
}
|
|
158
183
|
|
|
159
184
|
/**
|
|
@@ -184,21 +209,17 @@ export class OperatorUtils {
|
|
|
184
209
|
throw ErrorUnsupportedChainID;
|
|
185
210
|
}
|
|
186
211
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
});
|
|
212
|
+
const { rewardAddedEvents } = await gqlFetch<{
|
|
213
|
+
rewardAddedEvents: RewardAddedEventData[];
|
|
214
|
+
}>(getSubgraphUrl(networkData), GET_REWARD_ADDED_EVENTS_QUERY, {
|
|
215
|
+
slasherAddress: slasherAddress.toLowerCase(),
|
|
216
|
+
});
|
|
193
217
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
} catch (e) {
|
|
201
|
-
return throwError(e);
|
|
202
|
-
}
|
|
218
|
+
return rewardAddedEvents.map((reward: any) => {
|
|
219
|
+
return {
|
|
220
|
+
escrowAddress: reward.escrow,
|
|
221
|
+
amount: reward.amount,
|
|
222
|
+
};
|
|
223
|
+
});
|
|
203
224
|
}
|
|
204
225
|
}
|
package/src/statistics.ts
CHANGED
|
@@ -15,10 +15,11 @@ import {
|
|
|
15
15
|
PaymentStatistics,
|
|
16
16
|
WorkerStatistics,
|
|
17
17
|
HMTHolderData,
|
|
18
|
+
HMTHolder,
|
|
18
19
|
} from './graphql';
|
|
19
|
-
import { IStatisticsParams } from './interfaces';
|
|
20
|
+
import { IHMTHoldersParams, IStatisticsParams } from './interfaces';
|
|
20
21
|
import { NetworkData } from './types';
|
|
21
|
-
import { throwError } from './utils';
|
|
22
|
+
import { getSubgraphUrl, throwError } from './utils';
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* ## Introduction
|
|
@@ -59,6 +60,7 @@ import { throwError } from './utils';
|
|
|
59
60
|
*/
|
|
60
61
|
export class StatisticsClient {
|
|
61
62
|
public networkData: NetworkData;
|
|
63
|
+
public subgraphUrl: string;
|
|
62
64
|
|
|
63
65
|
/**
|
|
64
66
|
* **StatisticsClient constructor**
|
|
@@ -67,6 +69,7 @@ export class StatisticsClient {
|
|
|
67
69
|
*/
|
|
68
70
|
constructor(networkData: NetworkData) {
|
|
69
71
|
this.networkData = networkData;
|
|
72
|
+
this.subgraphUrl = getSubgraphUrl(networkData);
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
/**
|
|
@@ -124,11 +127,11 @@ export class StatisticsClient {
|
|
|
124
127
|
try {
|
|
125
128
|
const { escrowStatistics } = await gqlFetch<{
|
|
126
129
|
escrowStatistics: EscrowStatisticsData;
|
|
127
|
-
}>(this.
|
|
130
|
+
}>(this.subgraphUrl, GET_ESCROW_STATISTICS_QUERY);
|
|
128
131
|
|
|
129
132
|
const { eventDayDatas } = await gqlFetch<{
|
|
130
133
|
eventDayDatas: EventDayData[];
|
|
131
|
-
}>(this.
|
|
134
|
+
}>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
|
|
132
135
|
from: params.from ? params.from.getTime() / 1000 : undefined,
|
|
133
136
|
to: params.to ? params.to.getTime() / 1000 : undefined,
|
|
134
137
|
});
|
|
@@ -199,7 +202,7 @@ export class StatisticsClient {
|
|
|
199
202
|
try {
|
|
200
203
|
const { eventDayDatas } = await gqlFetch<{
|
|
201
204
|
eventDayDatas: EventDayData[];
|
|
202
|
-
}>(this.
|
|
205
|
+
}>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
|
|
203
206
|
from: params.from ? params.from.getTime() / 1000 : undefined,
|
|
204
207
|
to: params.to ? params.to.getTime() / 1000 : undefined,
|
|
205
208
|
});
|
|
@@ -288,7 +291,7 @@ export class StatisticsClient {
|
|
|
288
291
|
try {
|
|
289
292
|
const { eventDayDatas } = await gqlFetch<{
|
|
290
293
|
eventDayDatas: EventDayData[];
|
|
291
|
-
}>(this.
|
|
294
|
+
}>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
|
|
292
295
|
from: params.from ? params.from.getTime() / 1000 : undefined,
|
|
293
296
|
to: params.to ? params.to.getTime() / 1000 : undefined,
|
|
294
297
|
});
|
|
@@ -397,15 +400,15 @@ export class StatisticsClient {
|
|
|
397
400
|
try {
|
|
398
401
|
const { hmtokenStatistics } = await gqlFetch<{
|
|
399
402
|
hmtokenStatistics: HMTStatisticsData;
|
|
400
|
-
}>(this.
|
|
403
|
+
}>(this.subgraphUrl, GET_HMTOKEN_STATISTICS_QUERY);
|
|
401
404
|
|
|
402
405
|
const { holders } = await gqlFetch<{
|
|
403
406
|
holders: HMTHolderData[];
|
|
404
|
-
}>(this.
|
|
407
|
+
}>(this.subgraphUrl, GET_HOLDERS_QUERY());
|
|
405
408
|
|
|
406
409
|
const { eventDayDatas } = await gqlFetch<{
|
|
407
410
|
eventDayDatas: EventDayData[];
|
|
408
|
-
}>(this.
|
|
411
|
+
}>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
|
|
409
412
|
from: params.from ? params.from.getTime() / 1000 : undefined,
|
|
410
413
|
to: params.to ? params.to.getTime() / 1000 : undefined,
|
|
411
414
|
});
|
|
@@ -426,10 +429,61 @@ export class StatisticsClient {
|
|
|
426
429
|
eventDayData.dailyHMTTransferAmount
|
|
427
430
|
),
|
|
428
431
|
totalTransactionCount: +eventDayData.dailyHMTTransferCount,
|
|
432
|
+
dailyUniqueSenders: +eventDayData.dailyUniqueSenders,
|
|
433
|
+
dailyUniqueReceivers: +eventDayData.dailyUniqueReceivers,
|
|
429
434
|
})),
|
|
430
435
|
};
|
|
431
436
|
} catch (e: any) {
|
|
432
437
|
return throwError(e);
|
|
433
438
|
}
|
|
434
439
|
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* This function returns the holders of the HMToken with optional filters and ordering.
|
|
443
|
+
*
|
|
444
|
+
* **Input parameters**
|
|
445
|
+
*
|
|
446
|
+
* @param {IHMTHoldersParams} params HMT Holders params with filters and ordering
|
|
447
|
+
* @returns {HMTHolder[]} List of HMToken holders.
|
|
448
|
+
*
|
|
449
|
+
* **Code example**
|
|
450
|
+
*
|
|
451
|
+
* ```ts
|
|
452
|
+
* import { StatisticsClient, ChainId, NETWORKS } from '@human-protocol/sdk';
|
|
453
|
+
*
|
|
454
|
+
* const statisticsClient = new StatisticsClient(NETWORKS[ChainId.POLYGON_AMOY]);
|
|
455
|
+
*
|
|
456
|
+
* const hmtHolders = await statisticsClient.getHMTHolders({
|
|
457
|
+
* orderDirection: 'asc',
|
|
458
|
+
* });
|
|
459
|
+
*
|
|
460
|
+
* console.log('HMT holders:', hmtHolders.map((h) => ({
|
|
461
|
+
* ...h,
|
|
462
|
+
* balance: h.balance.toString(),
|
|
463
|
+
* })));
|
|
464
|
+
* ```
|
|
465
|
+
*/
|
|
466
|
+
async getHMTHolders(params: IHMTHoldersParams = {}): Promise<HMTHolder[]> {
|
|
467
|
+
try {
|
|
468
|
+
const { address, orderDirection } = params;
|
|
469
|
+
const query = GET_HOLDERS_QUERY(address);
|
|
470
|
+
|
|
471
|
+
const { holders } = await gqlFetch<{ holders: HMTHolderData[] }>(
|
|
472
|
+
this.subgraphUrl,
|
|
473
|
+
query,
|
|
474
|
+
{
|
|
475
|
+
address,
|
|
476
|
+
orderBy: 'balance',
|
|
477
|
+
orderDirection,
|
|
478
|
+
}
|
|
479
|
+
);
|
|
480
|
+
|
|
481
|
+
return holders.map((holder) => ({
|
|
482
|
+
address: holder.address,
|
|
483
|
+
balance: ethers.toBigInt(holder.balance),
|
|
484
|
+
}));
|
|
485
|
+
} catch (e: any) {
|
|
486
|
+
return throwError(e);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
435
489
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { ethers } from 'ethers';
|
|
3
|
+
import gqlFetch from 'graphql-request';
|
|
4
|
+
import { NETWORKS } from './constants';
|
|
5
|
+
import { ChainId, OrderDirection } from './enums';
|
|
6
|
+
import {
|
|
7
|
+
ErrorCannotUseDateAndBlockSimultaneously,
|
|
8
|
+
ErrorInvalidHahsProvided,
|
|
9
|
+
ErrorUnsupportedChainID,
|
|
10
|
+
} from './error';
|
|
11
|
+
import {
|
|
12
|
+
GET_TRANSACTIONS_QUERY,
|
|
13
|
+
GET_TRANSACTION_QUERY,
|
|
14
|
+
} from './graphql/queries/transaction';
|
|
15
|
+
import { ITransaction, ITransactionsFilter } from './interfaces';
|
|
16
|
+
import { getSubgraphUrl } from './utils';
|
|
17
|
+
|
|
18
|
+
export class TransactionUtils {
|
|
19
|
+
/**
|
|
20
|
+
* This function returns the transaction data for the given hash.
|
|
21
|
+
*
|
|
22
|
+
* @param {ChainId} chainId The chain ID.
|
|
23
|
+
* @param {string} hash The transaction hash.
|
|
24
|
+
* @returns {Promise<ITransaction>} Returns the transaction details.
|
|
25
|
+
*
|
|
26
|
+
* **Code example**
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { TransactionUtils, ChainId } from '@human-protocol/sdk';
|
|
30
|
+
*
|
|
31
|
+
* const transaction = await TransactionUtils.getTransaction(ChainId.POLYGON, '0x62dD51230A30401C455c8398d06F85e4EaB6309f');
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
public static async getTransaction(
|
|
35
|
+
chainId: ChainId,
|
|
36
|
+
hash: string
|
|
37
|
+
): Promise<ITransaction> {
|
|
38
|
+
if (!ethers.isHexString(hash)) {
|
|
39
|
+
throw ErrorInvalidHahsProvided;
|
|
40
|
+
}
|
|
41
|
+
const networkData = NETWORKS[chainId];
|
|
42
|
+
|
|
43
|
+
if (!networkData) {
|
|
44
|
+
throw ErrorUnsupportedChainID;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { transaction } = await gqlFetch<{
|
|
48
|
+
transaction: ITransaction;
|
|
49
|
+
}>(getSubgraphUrl(networkData), GET_TRANSACTION_QUERY, {
|
|
50
|
+
hash: hash.toLowerCase(),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return transaction;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* This function returns all transaction details based on the provided filter.
|
|
58
|
+
*
|
|
59
|
+
* > This uses Subgraph
|
|
60
|
+
*
|
|
61
|
+
* **Input parameters**
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* interface ITransactionsFilter {
|
|
65
|
+
* chainId: ChainId; // List of chain IDs to query.
|
|
66
|
+
* fromAddress?: string; // (Optional) The address from which transactions are sent.
|
|
67
|
+
* toAddress?: string; // (Optional) The address to which transactions are sent.
|
|
68
|
+
* startDate?: Date; // (Optional) The start date to filter transactions (inclusive).
|
|
69
|
+
* endDate?: Date; // (Optional) The end date to filter transactions (inclusive).
|
|
70
|
+
* startBlock?: number; // (Optional) The start block number to filter transactions (inclusive).
|
|
71
|
+
* endBlock?: number; // (Optional) The end block number to filter transactions (inclusive).
|
|
72
|
+
* first?: number; // (Optional) Number of transactions per page. Default is 10.
|
|
73
|
+
* skip?: number; // (Optional) Number of transactions to skip. Default is 0.
|
|
74
|
+
* orderDirection?: OrderDirection; // (Optional) Order of the results. Default is DESC.
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* ```ts
|
|
79
|
+
* type ITransaction = {
|
|
80
|
+
* block: number;
|
|
81
|
+
* txHash: string;
|
|
82
|
+
* from: string;
|
|
83
|
+
* to: string;
|
|
84
|
+
* timestamp: number;
|
|
85
|
+
* value: string;
|
|
86
|
+
* method: string;
|
|
87
|
+
* };
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @param {ITransactionsFilter} filter Filter for the transactions.
|
|
91
|
+
* @returns {Promise<ITransaction[]>} Returns an array with all the transaction details.
|
|
92
|
+
*
|
|
93
|
+
* **Code example**
|
|
94
|
+
*
|
|
95
|
+
* ```ts
|
|
96
|
+
* import { TransactionUtils, ChainId, OrderDirection } from '@human-protocol/sdk';
|
|
97
|
+
*
|
|
98
|
+
* const filter: ITransactionsFilter = {
|
|
99
|
+
* chainId: ChainId.POLYGON,
|
|
100
|
+
* startDate: new Date('2022-01-01'),
|
|
101
|
+
* endDate: new Date('2022-12-31'),
|
|
102
|
+
* first: 10,
|
|
103
|
+
* skip: 0,
|
|
104
|
+
* orderDirection: OrderDirection.DESC,
|
|
105
|
+
* };
|
|
106
|
+
* const transactions = await TransactionUtils.getTransactions(filter);
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
public static async getTransactions(
|
|
110
|
+
filter: ITransactionsFilter
|
|
111
|
+
): Promise<ITransaction[]> {
|
|
112
|
+
if (
|
|
113
|
+
(!!filter.startDate || !!filter.endDate) &&
|
|
114
|
+
(!!filter.startBlock || !!filter.endBlock)
|
|
115
|
+
) {
|
|
116
|
+
throw ErrorCannotUseDateAndBlockSimultaneously;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const first =
|
|
120
|
+
filter.first !== undefined ? Math.min(filter.first, 1000) : 10;
|
|
121
|
+
const skip = filter.skip || 0;
|
|
122
|
+
const orderDirection = filter.orderDirection || OrderDirection.DESC;
|
|
123
|
+
|
|
124
|
+
const networkData = NETWORKS[filter.chainId];
|
|
125
|
+
if (!networkData) {
|
|
126
|
+
throw ErrorUnsupportedChainID;
|
|
127
|
+
}
|
|
128
|
+
const { transactions } = await gqlFetch<{
|
|
129
|
+
transactions: ITransaction[];
|
|
130
|
+
}>(getSubgraphUrl(networkData), GET_TRANSACTIONS_QUERY(filter), {
|
|
131
|
+
fromAddress: filter?.fromAddress,
|
|
132
|
+
toAddress: filter?.toAddress,
|
|
133
|
+
startDate: filter?.startDate
|
|
134
|
+
? Math.floor(filter?.startDate.getTime() / 1000)
|
|
135
|
+
: undefined,
|
|
136
|
+
endDate: filter.endDate
|
|
137
|
+
? Math.floor(filter.endDate.getTime() / 1000)
|
|
138
|
+
: undefined,
|
|
139
|
+
startBlock: filter.startBlock ? filter.startBlock : undefined,
|
|
140
|
+
endBlock: filter.endBlock ? filter.endBlock : undefined,
|
|
141
|
+
orderDirection: orderDirection,
|
|
142
|
+
first: first,
|
|
143
|
+
skip: skip,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
if (!transactions) {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return transactions;
|
|
151
|
+
}
|
|
152
|
+
}
|
package/src/types.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -9,7 +9,10 @@ import {
|
|
|
9
9
|
NumericFault,
|
|
10
10
|
ReplacementUnderpriced,
|
|
11
11
|
TransactionReplaced,
|
|
12
|
+
WarnSubgraphApiKeyNotProvided,
|
|
12
13
|
} from './error';
|
|
14
|
+
import { NetworkData } from './types';
|
|
15
|
+
import { SUBGRAPH_API_KEY_PLACEHOLDER } from './constants';
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
18
|
* **Handle and throw the error.*
|
|
@@ -49,3 +52,25 @@ export const isValidUrl = (url: string) => {
|
|
|
49
52
|
return false;
|
|
50
53
|
}
|
|
51
54
|
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* **Get the subgraph URL.*
|
|
58
|
+
*
|
|
59
|
+
* @param {NetworkData} networkData
|
|
60
|
+
* @param {string} apiKey
|
|
61
|
+
* @returns
|
|
62
|
+
*/
|
|
63
|
+
export const getSubgraphUrl = (networkData: NetworkData) => {
|
|
64
|
+
let subgraphUrl = networkData.subgraphUrl;
|
|
65
|
+
if (process.env.SUBGRAPH_API_KEY) {
|
|
66
|
+
subgraphUrl = networkData.subgraphUrlApiKey.replace(
|
|
67
|
+
SUBGRAPH_API_KEY_PLACEHOLDER,
|
|
68
|
+
process.env.SUBGRAPH_API_KEY
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
// eslint-disable-next-line no-console
|
|
72
|
+
console.warn(WarnSubgraphApiKeyNotProvided);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return subgraphUrl;
|
|
76
|
+
};
|