@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.
Files changed (70) hide show
  1. package/README.md +23 -80
  2. package/dist/constants.d.ts +1 -0
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +56 -24
  5. package/dist/enums.d.ts +7 -2
  6. package/dist/enums.d.ts.map +1 -1
  7. package/dist/enums.js +8 -2
  8. package/dist/error.d.ts +16 -0
  9. package/dist/error.d.ts.map +1 -1
  10. package/dist/error.js +18 -2
  11. package/dist/escrow.d.ts +91 -7
  12. package/dist/escrow.d.ts.map +1 -1
  13. package/dist/escrow.js +154 -39
  14. package/dist/graphql/queries/escrow.d.ts +1 -0
  15. package/dist/graphql/queries/escrow.d.ts.map +1 -1
  16. package/dist/graphql/queries/escrow.js +50 -9
  17. package/dist/graphql/queries/hmtoken.d.ts +1 -1
  18. package/dist/graphql/queries/hmtoken.d.ts.map +1 -1
  19. package/dist/graphql/queries/hmtoken.js +23 -7
  20. package/dist/graphql/queries/kvstore.d.ts +2 -0
  21. package/dist/graphql/queries/kvstore.d.ts.map +1 -0
  22. package/dist/graphql/queries/kvstore.js +28 -0
  23. package/dist/graphql/queries/statistics.d.ts.map +1 -1
  24. package/dist/graphql/queries/statistics.js +2 -0
  25. package/dist/graphql/queries/transaction.d.ts +4 -0
  26. package/dist/graphql/queries/transaction.d.ts.map +1 -0
  27. package/dist/graphql/queries/transaction.js +64 -0
  28. package/dist/graphql/types.d.ts +19 -0
  29. package/dist/graphql/types.d.ts.map +1 -1
  30. package/dist/index.d.ts +2 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -1
  33. package/dist/interfaces.d.ts +35 -4
  34. package/dist/interfaces.d.ts.map +1 -1
  35. package/dist/kvstore.d.ts +84 -0
  36. package/dist/kvstore.d.ts.map +1 -1
  37. package/dist/kvstore.js +103 -1
  38. package/dist/operator.d.ts +5 -2
  39. package/dist/operator.d.ts.map +1 -1
  40. package/dist/operator.js +68 -57
  41. package/dist/statistics.d.ts +29 -2
  42. package/dist/statistics.d.ts.map +1 -1
  43. package/dist/statistics.js +53 -7
  44. package/dist/transaction.d.ts +75 -0
  45. package/dist/transaction.d.ts.map +1 -0
  46. package/dist/transaction.js +130 -0
  47. package/dist/types.d.ts +4 -0
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/utils.d.ts +9 -0
  50. package/dist/utils.d.ts.map +1 -1
  51. package/dist/utils.js +21 -1
  52. package/package.json +7 -6
  53. package/src/constants.ts +73 -23
  54. package/src/enums.ts +7 -1
  55. package/src/error.ts +23 -0
  56. package/src/escrow.ts +199 -51
  57. package/src/graphql/queries/escrow.ts +53 -8
  58. package/src/graphql/queries/hmtoken.ts +23 -7
  59. package/src/graphql/queries/kvstore.ts +23 -0
  60. package/src/graphql/queries/statistics.ts +2 -0
  61. package/src/graphql/queries/transaction.ts +64 -0
  62. package/src/graphql/types.ts +22 -0
  63. package/src/index.ts +2 -0
  64. package/src/interfaces.ts +40 -4
  65. package/src/kvstore.ts +114 -1
  66. package/src/operator.ts +90 -69
  67. package/src/statistics.ts +63 -9
  68. package/src/transaction.ts +152 -0
  69. package/src/types.ts +4 -0
  70. 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 { throwError } from './utils';
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
- try {
58
- const { leader } = await gqlFetch<{
59
- leader: ILeaderSubgraph;
60
- }>(networkData.subgraphUrl, GET_LEADER_QUERY, {
61
- address: address.toLowerCase(),
62
- });
57
+ const { leader } = await gqlFetch<{
58
+ leader: ILeaderSubgraph;
59
+ }>(getSubgraphUrl(networkData), GET_LEADER_QUERY, {
60
+ address: address.toLowerCase(),
61
+ });
63
62
 
64
- return {
65
- ...leader,
66
- jobTypes: leader.jobTypes?.split(','),
67
- };
68
- } catch (e) {
69
- return throwError(e);
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 leaders = await OperatorUtils.getLeaders();
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
- filter: ILeadersFilter = { networks: [ChainId.POLYGON_AMOY] }
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
- return leaders_data;
113
- } catch (e) {
114
- return throwError(e);
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
- try {
143
- const { reputationNetwork } = await gqlFetch<{
144
- reputationNetwork: IReputationNetworkSubgraph;
145
- }>(networkData.subgraphUrl, GET_REPUTATION_NETWORK_QUERY(role), {
146
- address: address.toLowerCase(),
147
- role: role,
148
- });
149
-
150
- return reputationNetwork.operators.map((operator) => ({
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: operator.jobTypes?.split(','),
153
- }));
154
- } catch (e) {
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
- try {
188
- const { rewardAddedEvents } = await gqlFetch<{
189
- rewardAddedEvents: RewardAddedEventData[];
190
- }>(networkData.subgraphUrl, GET_REWARD_ADDED_EVENTS_QUERY, {
191
- slasherAddress: slasherAddress.toLowerCase(),
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
- return rewardAddedEvents.map((reward: any) => {
195
- return {
196
- escrowAddress: reward.escrow,
197
- amount: reward.amount,
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.networkData.subgraphUrl, GET_ESCROW_STATISTICS_QUERY);
130
+ }>(this.subgraphUrl, GET_ESCROW_STATISTICS_QUERY);
128
131
 
129
132
  const { eventDayDatas } = await gqlFetch<{
130
133
  eventDayDatas: EventDayData[];
131
- }>(this.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
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.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
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.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
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.networkData.subgraphUrl, GET_HMTOKEN_STATISTICS_QUERY);
403
+ }>(this.subgraphUrl, GET_HMTOKEN_STATISTICS_QUERY);
401
404
 
402
405
  const { holders } = await gqlFetch<{
403
406
  holders: HMTHolderData[];
404
- }>(this.networkData.subgraphUrl, GET_HOLDERS_QUERY);
407
+ }>(this.subgraphUrl, GET_HOLDERS_QUERY());
405
408
 
406
409
  const { eventDayDatas } = await gqlFetch<{
407
410
  eventDayDatas: EventDayData[];
408
- }>(this.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
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
@@ -127,6 +127,10 @@ export type NetworkData = {
127
127
  * Subgraph URL
128
128
  */
129
129
  subgraphUrl: string;
130
+ /**
131
+ * Subgraph URL
132
+ */
133
+ subgraphUrlApiKey: string;
130
134
  /**
131
135
  * Old subgraph URL
132
136
  */
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
+ };