@human-protocol/sdk 6.0.0 → 7.0.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.
Files changed (129) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/base.d.ts +4 -2
  3. package/dist/base.d.ts.map +1 -1
  4. package/dist/base.js +14 -0
  5. package/dist/constants.d.ts +0 -1
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +27 -16
  8. package/dist/encryption/encryption.d.ts +84 -0
  9. package/dist/encryption/encryption.d.ts.map +1 -0
  10. package/dist/{encryption.js → encryption/encryption.js} +3 -161
  11. package/dist/encryption/encryption_utils.d.ts +101 -0
  12. package/dist/encryption/encryption_utils.d.ts.map +1 -0
  13. package/dist/encryption/encryption_utils.js +191 -0
  14. package/dist/encryption/index.d.ts +4 -0
  15. package/dist/encryption/index.d.ts.map +1 -0
  16. package/dist/encryption/index.js +7 -0
  17. package/dist/encryption/types.d.ts +9 -0
  18. package/dist/encryption/types.d.ts.map +1 -0
  19. package/dist/encryption/types.js +9 -0
  20. package/dist/error.d.ts +6 -10
  21. package/dist/error.d.ts.map +1 -1
  22. package/dist/error.js +12 -14
  23. package/dist/{escrow.d.ts → escrow/escrow_client.d.ts} +16 -196
  24. package/dist/escrow/escrow_client.d.ts.map +1 -0
  25. package/dist/{escrow.js → escrow/escrow_client.js} +50 -430
  26. package/dist/escrow/escrow_utils.d.ts +172 -0
  27. package/dist/escrow/escrow_utils.d.ts.map +1 -0
  28. package/dist/escrow/escrow_utils.js +388 -0
  29. package/dist/escrow/index.d.ts +3 -0
  30. package/dist/escrow/index.d.ts.map +1 -0
  31. package/dist/escrow/index.js +7 -0
  32. package/dist/graphql/queries/statistics.d.ts +1 -0
  33. package/dist/graphql/queries/statistics.d.ts.map +1 -1
  34. package/dist/graphql/queries/statistics.js +36 -2
  35. package/dist/graphql/types.d.ts +3 -1
  36. package/dist/graphql/types.d.ts.map +1 -1
  37. package/dist/index.d.ts +10 -10
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +23 -22
  40. package/dist/interfaces.d.ts +2 -7
  41. package/dist/interfaces.d.ts.map +1 -1
  42. package/dist/kvstore/index.d.ts +3 -0
  43. package/dist/kvstore/index.d.ts.map +1 -0
  44. package/dist/kvstore/index.js +7 -0
  45. package/dist/{kvstore.d.ts → kvstore/kvstore_client.d.ts} +7 -112
  46. package/dist/kvstore/kvstore_client.d.ts.map +1 -0
  47. package/dist/{kvstore.js → kvstore/kvstore_client.js} +25 -187
  48. package/dist/kvstore/kvstore_utils.d.ts +105 -0
  49. package/dist/kvstore/kvstore_utils.d.ts.map +1 -0
  50. package/dist/kvstore/kvstore_utils.js +184 -0
  51. package/dist/operator/index.d.ts +2 -0
  52. package/dist/operator/index.d.ts.map +1 -0
  53. package/dist/operator/index.js +5 -0
  54. package/dist/{operator.d.ts → operator/operator_utils.d.ts} +3 -3
  55. package/dist/operator/operator_utils.d.ts.map +1 -0
  56. package/dist/{operator.js → operator/operator_utils.js} +6 -6
  57. package/dist/staking/index.d.ts +3 -0
  58. package/dist/staking/index.d.ts.map +1 -0
  59. package/dist/staking/index.js +7 -0
  60. package/dist/{staking.d.ts → staking/staking_client.d.ts} +10 -71
  61. package/dist/staking/staking_client.d.ts.map +1 -0
  62. package/dist/{staking.js → staking/staking_client.js} +11 -141
  63. package/dist/staking/staking_utils.d.ts +63 -0
  64. package/dist/staking/staking_utils.d.ts.map +1 -0
  65. package/dist/staking/staking_utils.js +137 -0
  66. package/dist/statistics/index.d.ts +2 -0
  67. package/dist/statistics/index.d.ts.map +1 -0
  68. package/dist/statistics/index.js +5 -0
  69. package/dist/{statistics.d.ts → statistics/statistics_utils.d.ts} +4 -13
  70. package/dist/statistics/statistics_utils.d.ts.map +1 -0
  71. package/dist/{statistics.js → statistics/statistics_utils.js} +8 -22
  72. package/dist/transaction/index.d.ts +2 -0
  73. package/dist/transaction/index.d.ts.map +1 -0
  74. package/dist/transaction/index.js +5 -0
  75. package/dist/{transaction.d.ts → transaction/transaction_utils.d.ts} +5 -5
  76. package/dist/transaction/transaction_utils.d.ts.map +1 -0
  77. package/dist/{transaction.js → transaction/transaction_utils.js} +9 -9
  78. package/dist/types.d.ts +22 -1
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/utils.d.ts +16 -1
  81. package/dist/utils.d.ts.map +1 -1
  82. package/dist/utils.js +72 -6
  83. package/dist/worker/index.d.ts +2 -0
  84. package/dist/worker/index.d.ts.map +1 -0
  85. package/dist/worker/index.js +5 -0
  86. package/dist/{worker.d.ts → worker/worker_utils.d.ts} +3 -3
  87. package/dist/worker/worker_utils.d.ts.map +1 -0
  88. package/dist/{worker.js → worker/worker_utils.js} +5 -5
  89. package/package.json +5 -5
  90. package/src/base.ts +38 -2
  91. package/src/constants.ts +38 -16
  92. package/src/{encryption.ts → encryption/encryption.ts} +1 -193
  93. package/src/encryption/encryption_utils.ts +179 -0
  94. package/src/encryption/index.ts +3 -0
  95. package/src/encryption/types.ts +15 -0
  96. package/src/error.ts +11 -17
  97. package/src/{escrow.ts → escrow/escrow_client.ts} +151 -659
  98. package/src/escrow/escrow_utils.ts +510 -0
  99. package/src/escrow/index.ts +2 -0
  100. package/src/graphql/queries/statistics.ts +37 -1
  101. package/src/graphql/types.ts +4 -1
  102. package/src/index.ts +11 -25
  103. package/src/interfaces.ts +2 -7
  104. package/src/kvstore/index.ts +2 -0
  105. package/src/kvstore/kvstore_client.ts +291 -0
  106. package/src/kvstore/kvstore_utils.ts +244 -0
  107. package/src/operator/index.ts +1 -0
  108. package/src/{operator.ts → operator/operator_utils.ts} +8 -8
  109. package/src/staking/index.ts +2 -0
  110. package/src/{staking.ts → staking/staking_client.ts} +49 -199
  111. package/src/staking/staking_utils.ts +170 -0
  112. package/src/statistics/index.ts +1 -0
  113. package/src/{statistics.ts → statistics/statistics_utils.ts} +14 -26
  114. package/src/transaction/index.ts +1 -0
  115. package/src/{transaction.ts → transaction/transaction_utils.ts} +11 -11
  116. package/src/types.ts +24 -1
  117. package/src/utils.ts +82 -9
  118. package/src/worker/index.ts +1 -0
  119. package/src/{worker.ts → worker/worker_utils.ts} +7 -7
  120. package/dist/encryption.d.ts +0 -189
  121. package/dist/encryption.d.ts.map +0 -1
  122. package/dist/escrow.d.ts.map +0 -1
  123. package/dist/kvstore.d.ts.map +0 -1
  124. package/dist/operator.d.ts.map +0 -1
  125. package/dist/staking.d.ts.map +0 -1
  126. package/dist/statistics.d.ts.map +0 -1
  127. package/dist/transaction.d.ts.map +0 -1
  128. package/dist/worker.d.ts.map +0 -1
  129. package/src/kvstore.ts +0 -497
@@ -0,0 +1,291 @@
1
+ import {
2
+ KVStore,
3
+ KVStore__factory,
4
+ } from '@human-protocol/core/typechain-types';
5
+ import { ContractRunner, ethers } from 'ethers';
6
+ import { BaseEthersClient } from '../base';
7
+ import { NETWORKS } from '../constants';
8
+ import { requiresSigner } from '../decorators';
9
+ import { ChainId } from '../enums';
10
+ import {
11
+ ErrorInvalidAddress,
12
+ ErrorInvalidUrl,
13
+ ErrorKVStoreArrayLength,
14
+ ErrorKVStoreEmptyKey,
15
+ ErrorProviderDoesNotExist,
16
+ ErrorUnsupportedChainID,
17
+ } from '../error';
18
+ import { NetworkData, TransactionOverrides } from '../types';
19
+ import { isValidUrl } from '../utils';
20
+ /**
21
+ * Client for interacting with the KVStore contract.
22
+ *
23
+ * Internally, the SDK will use one network or another according to the network ID of the `runner`.
24
+ * To use this client, it is recommended to initialize it using the static [`build`](/ts/classes/KVStoreClient/#build) method.
25
+ *
26
+ * ```ts
27
+ * static async build(runner: ContractRunner): Promise<KVStoreClient>;
28
+ * ```
29
+ *
30
+ * A `Signer` or a `Provider` should be passed depending on the use case of this module:
31
+ *
32
+ * - **Signer**: when the user wants to use this model to send transactions calling the contract functions.
33
+ * - **Provider**: when the user wants to use this model to get information from the contracts or subgraph.
34
+ *
35
+ * @example
36
+ *
37
+ * ###Using Signer
38
+ *
39
+ * ####Using private key (backend)
40
+ *
41
+ * ```ts
42
+ * import { KVStoreClient } from '@human-protocol/sdk';
43
+ * import { Wallet, JsonRpcProvider } from 'ethers';
44
+ *
45
+ * const rpcUrl = 'YOUR_RPC_URL';
46
+ * const privateKey = 'YOUR_PRIVATE_KEY';
47
+ *
48
+ * const provider = new JsonRpcProvider(rpcUrl);
49
+ * const signer = new Wallet(privateKey, provider);
50
+ * const kvstoreClient = await KVStoreClient.build(signer);
51
+ * ```
52
+ *
53
+ * ####Using Wagmi (frontend)
54
+ *
55
+ * ```ts
56
+ * import { useSigner, useChainId } from 'wagmi';
57
+ * import { KVStoreClient } from '@human-protocol/sdk';
58
+ *
59
+ * const { data: signer } = useSigner();
60
+ * const kvstoreClient = await KVStoreClient.build(signer);
61
+ * ```
62
+ *
63
+ * ###Using Provider
64
+ *
65
+ * ```ts
66
+ * import { KVStoreClient } from '@human-protocol/sdk';
67
+ * import { JsonRpcProvider } from 'ethers';
68
+ *
69
+ * const rpcUrl = 'YOUR_RPC_URL';
70
+ *
71
+ * const provider = new JsonRpcProvider(rpcUrl);
72
+ * const kvstoreClient = await KVStoreClient.build(provider);
73
+ * ```
74
+ */
75
+
76
+ export class KVStoreClient extends BaseEthersClient {
77
+ public contract: KVStore;
78
+
79
+ /**
80
+ * **KVStoreClient constructor**
81
+ *
82
+ * @param runner - The Runner object to interact with the Ethereum network
83
+ * @param networkData - The network information required to connect to the KVStore contract
84
+ */
85
+ constructor(runner: ContractRunner, networkData: NetworkData) {
86
+ super(runner, networkData);
87
+
88
+ this.contract = KVStore__factory.connect(
89
+ networkData.kvstoreAddress,
90
+ runner
91
+ );
92
+ }
93
+
94
+ /**
95
+ * Creates an instance of KVStoreClient from a runner.
96
+ *
97
+ * @param runner - The Runner object to interact with the Ethereum network
98
+ * @returns An instance of KVStoreClient
99
+ * @throws ErrorProviderDoesNotExist If the provider does not exist for the provided Signer
100
+ * @throws ErrorUnsupportedChainID If the network's chainId is not supported
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * import { KVStoreClient } from '@human-protocol/sdk';
105
+ * import { Wallet, JsonRpcProvider } from 'ethers';
106
+ *
107
+ * const rpcUrl = 'YOUR_RPC_URL';
108
+ * const privateKey = 'YOUR_PRIVATE_KEY';
109
+ *
110
+ * const provider = new JsonRpcProvider(rpcUrl);
111
+ * const signer = new Wallet(privateKey, provider);
112
+ * const kvstoreClient = await KVStoreClient.build(signer);
113
+ * ```
114
+ */
115
+ public static async build(runner: ContractRunner): Promise<KVStoreClient> {
116
+ if (!runner.provider) {
117
+ throw ErrorProviderDoesNotExist;
118
+ }
119
+
120
+ const network = await runner.provider?.getNetwork();
121
+
122
+ const chainId: ChainId = Number(network?.chainId);
123
+ const networkData = NETWORKS[chainId];
124
+
125
+ if (!networkData) {
126
+ throw ErrorUnsupportedChainID;
127
+ }
128
+
129
+ return new KVStoreClient(runner, networkData);
130
+ }
131
+
132
+ /**
133
+ * This function sets a key-value pair associated with the address that submits the transaction.
134
+ *
135
+ * @param key - Key of the key-value pair
136
+ * @param value - Value of the key-value pair
137
+ * @param txOptions - Additional transaction parameters (optional, defaults to an empty object).
138
+ * @returns -
139
+ * @throws ErrorKVStoreEmptyKey If the key is empty
140
+ * @throws Error If the transaction fails
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * await kvstoreClient.set('Role', 'RecordingOracle');
145
+ * ```
146
+ */
147
+ @requiresSigner
148
+ public async set(
149
+ key: string,
150
+ value: string,
151
+ txOptions: TransactionOverrides = {}
152
+ ): Promise<void> {
153
+ if (key === '') throw ErrorKVStoreEmptyKey;
154
+
155
+ try {
156
+ await this.sendTxAndWait(
157
+ (overrides) => this.contract.set(key, value, overrides),
158
+ txOptions
159
+ );
160
+ } catch (e) {
161
+ if (e instanceof Error) {
162
+ throw Error(`Failed to set value: ${e.message}`);
163
+ }
164
+ throw e;
165
+ }
166
+ }
167
+
168
+ /**
169
+ * This function sets key-value pairs in bulk associated with the address that submits the transaction.
170
+ *
171
+ * @param keys - Array of keys (keys and value must have the same order)
172
+ * @param values - Array of values
173
+ * @param txOptions - Additional transaction parameters (optional, defaults to an empty object).
174
+ * @returns -
175
+ * @throws ErrorKVStoreArrayLength If keys and values arrays have different lengths
176
+ * @throws ErrorKVStoreEmptyKey If any key is empty
177
+ * @throws Error If the transaction fails
178
+ *
179
+ * @example
180
+ * ```ts
181
+ * const keys = ['role', 'webhook_url'];
182
+ * const values = ['RecordingOracle', 'http://localhost'];
183
+ * await kvstoreClient.setBulk(keys, values);
184
+ * ```
185
+ */
186
+ @requiresSigner
187
+ public async setBulk(
188
+ keys: string[],
189
+ values: string[],
190
+ txOptions: TransactionOverrides = {}
191
+ ): Promise<void> {
192
+ if (keys.length !== values.length) throw ErrorKVStoreArrayLength;
193
+ if (keys.includes('')) throw ErrorKVStoreEmptyKey;
194
+
195
+ try {
196
+ await this.sendTxAndWait(
197
+ (overrides) => this.contract.setBulk(keys, values, overrides),
198
+ txOptions
199
+ );
200
+ } catch (e) {
201
+ if (e instanceof Error) {
202
+ throw Error(`Failed to set bulk values: ${e.message}`);
203
+ }
204
+ throw e;
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Sets a URL value for the address that submits the transaction, and its hash.
210
+ *
211
+ * @param url - URL to set
212
+ * @param urlKey - Configurable URL key. `url` by default.
213
+ * @param txOptions - Additional transaction parameters (optional, defaults to an empty object).
214
+ * @returns -
215
+ * @throws ErrorInvalidUrl If the URL is invalid
216
+ * @throws Error If the transaction fails
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * await kvstoreClient.setFileUrlAndHash('example.com');
221
+ * await kvstoreClient.setFileUrlAndHash('linkedin.com/example', 'linkedin_url');
222
+ * ```
223
+ */
224
+ @requiresSigner
225
+ public async setFileUrlAndHash(
226
+ url: string,
227
+ urlKey = 'url',
228
+ txOptions: TransactionOverrides = {}
229
+ ): Promise<void> {
230
+ if (!isValidUrl(url)) {
231
+ throw ErrorInvalidUrl;
232
+ }
233
+
234
+ const content = await fetch(url).then((res) => res.text());
235
+ const contentHash = ethers.keccak256(ethers.toUtf8Bytes(content));
236
+
237
+ const hashKey = urlKey + '_hash';
238
+
239
+ try {
240
+ await this.sendTxAndWait(
241
+ (overrides) =>
242
+ this.contract.setBulk(
243
+ [urlKey, hashKey],
244
+ [url, contentHash],
245
+ overrides
246
+ ),
247
+ txOptions
248
+ );
249
+ } catch (e) {
250
+ if (e instanceof Error) {
251
+ throw Error(`Failed to set URL and hash: ${e.message}`);
252
+ }
253
+ throw e;
254
+ }
255
+ }
256
+ /**
257
+ * Gets the value of a key-value pair in the contract.
258
+ *
259
+ * @param address - Address from which to get the key value.
260
+ * @param key - Key to obtain the value.
261
+ * @returns Value of the key.
262
+ * @throws ErrorKVStoreEmptyKey If the key is empty
263
+ * @throws ErrorInvalidAddress If the address is invalid
264
+ * @throws Error If the contract call fails
265
+ *
266
+ * @example
267
+ * ```ts
268
+ * const value = await kvstoreClient.get('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', 'Role');
269
+ * console.log('Value:', value);
270
+ * ```
271
+ */
272
+ public async get(address: string, key: string): Promise<string> {
273
+ if (key === '') {
274
+ throw ErrorKVStoreEmptyKey;
275
+ }
276
+
277
+ if (!ethers.isAddress(address)) {
278
+ throw ErrorInvalidAddress;
279
+ }
280
+
281
+ try {
282
+ const result = await this.contract?.get(address, key);
283
+ return result;
284
+ } catch (e) {
285
+ if (e instanceof Error) {
286
+ throw Error(`Failed to get value: ${e.message}`);
287
+ }
288
+ throw e;
289
+ }
290
+ }
291
+ }
@@ -0,0 +1,244 @@
1
+ import { ethers } from 'ethers';
2
+ import { KVStoreKeys, NETWORKS } from '../constants';
3
+ import { ChainId } from '../enums';
4
+ import {
5
+ ErrorInvalidAddress,
6
+ ErrorInvalidHash,
7
+ ErrorKVStoreEmptyKey,
8
+ ErrorUnsupportedChainID,
9
+ } from '../error';
10
+ import { KVStoreData } from '../graphql';
11
+ import {
12
+ GET_KVSTORE_BY_ADDRESS_AND_KEY_QUERY,
13
+ GET_KVSTORE_BY_ADDRESS_QUERY,
14
+ } from '../graphql/queries/kvstore';
15
+ import { IKVStore, SubgraphOptions } from '../interfaces';
16
+ import { customGqlFetch, getSubgraphUrl } from '../utils';
17
+ /**
18
+ * Utility helpers for KVStore-related queries.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { ChainId, KVStoreUtils } from '@human-protocol/sdk';
23
+ *
24
+ * const kvStoreData = await KVStoreUtils.getKVStoreData(
25
+ * ChainId.POLYGON_AMOY,
26
+ * "0x1234567890123456789012345678901234567890"
27
+ * );
28
+ * console.log('KVStore data:', kvStoreData);
29
+ * ```
30
+ */
31
+ export class KVStoreUtils {
32
+ /**
33
+ * This function returns the KVStore data for a given address.
34
+ *
35
+ * @param chainId - Network in which the KVStore is deployed
36
+ * @param address - Address of the KVStore
37
+ * @param options - Optional configuration for subgraph requests.
38
+ * @returns KVStore data
39
+ * @throws ErrorUnsupportedChainID If the network's chainId is not supported
40
+ * @throws ErrorInvalidAddress If the address is invalid
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const kvStoreData = await KVStoreUtils.getKVStoreData(
45
+ * ChainId.POLYGON_AMOY,
46
+ * "0x1234567890123456789012345678901234567890"
47
+ * );
48
+ * console.log('KVStore data:', kvStoreData);
49
+ * ```
50
+ */
51
+ public static async getKVStoreData(
52
+ chainId: ChainId,
53
+ address: string,
54
+ options?: SubgraphOptions
55
+ ): Promise<IKVStore[]> {
56
+ const networkData = NETWORKS[chainId];
57
+
58
+ if (!networkData) {
59
+ throw ErrorUnsupportedChainID;
60
+ }
61
+
62
+ if (address && !ethers.isAddress(address)) {
63
+ throw ErrorInvalidAddress;
64
+ }
65
+
66
+ const { kvstores } = await customGqlFetch<{ kvstores: KVStoreData[] }>(
67
+ getSubgraphUrl(networkData),
68
+ GET_KVSTORE_BY_ADDRESS_QUERY(),
69
+ { address: address.toLowerCase() },
70
+ options
71
+ );
72
+
73
+ const kvStoreData = kvstores.map((item) => ({
74
+ key: item.key,
75
+ value: item.value,
76
+ }));
77
+
78
+ return kvStoreData || [];
79
+ }
80
+
81
+ /**
82
+ * Gets the value of a key-value pair in the KVStore using the subgraph.
83
+ *
84
+ * @param chainId - Network in which the KVStore is deployed
85
+ * @param address - Address from which to get the key value.
86
+ * @param key - Key to obtain the value.
87
+ * @param options - Optional configuration for subgraph requests.
88
+ * @returns Value of the key.
89
+ * @throws ErrorUnsupportedChainID If the network's chainId is not supported
90
+ * @throws ErrorInvalidAddress If the address is invalid
91
+ * @throws ErrorKVStoreEmptyKey If the key is empty
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * const value = await KVStoreUtils.get(
96
+ * ChainId.POLYGON_AMOY,
97
+ * '0x1234567890123456789012345678901234567890',
98
+ * 'role'
99
+ * );
100
+ * console.log('Value:', value);
101
+ * ```
102
+ */
103
+ public static async get(
104
+ chainId: ChainId,
105
+ address: string,
106
+ key: string,
107
+ options?: SubgraphOptions
108
+ ): Promise<string> {
109
+ if (key === '') throw ErrorKVStoreEmptyKey;
110
+ if (!ethers.isAddress(address)) throw ErrorInvalidAddress;
111
+
112
+ const networkData = NETWORKS[chainId];
113
+
114
+ if (!networkData) {
115
+ throw ErrorUnsupportedChainID;
116
+ }
117
+
118
+ const { kvstores } = await customGqlFetch<{ kvstores: KVStoreData[] }>(
119
+ getSubgraphUrl(networkData),
120
+ GET_KVSTORE_BY_ADDRESS_AND_KEY_QUERY(),
121
+ { address: address.toLowerCase(), key },
122
+ options
123
+ );
124
+
125
+ if (!kvstores || kvstores.length === 0) {
126
+ return '';
127
+ }
128
+
129
+ return kvstores[0].value;
130
+ }
131
+
132
+ /**
133
+ * Gets the URL value of the given entity, and verifies its hash.
134
+ *
135
+ * @param chainId - Network in which the KVStore is deployed
136
+ * @param address - Address from which to get the URL value.
137
+ * @param urlKey - Configurable URL key. `url` by default.
138
+ * @param options - Optional configuration for subgraph requests.
139
+ * @returns URL value for the given address if it exists, and the content is valid
140
+ * @throws ErrorInvalidAddress If the address is invalid
141
+ * @throws ErrorInvalidHash If the hash verification fails
142
+ * @throws Error If fetching URL or hash fails
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * const url = await KVStoreUtils.getFileUrlAndVerifyHash(
147
+ * ChainId.POLYGON_AMOY,
148
+ * '0x1234567890123456789012345678901234567890'
149
+ * );
150
+ * console.log('Verified URL:', url);
151
+ * ```
152
+ */
153
+ public static async getFileUrlAndVerifyHash(
154
+ chainId: ChainId,
155
+ address: string,
156
+ urlKey = 'url',
157
+ options?: SubgraphOptions
158
+ ): Promise<string> {
159
+ if (!ethers.isAddress(address)) throw ErrorInvalidAddress;
160
+ const hashKey = urlKey + '_hash';
161
+
162
+ let url: string;
163
+
164
+ try {
165
+ url = await this.get(chainId, address, urlKey, options);
166
+ } catch (e) {
167
+ if (e instanceof Error) {
168
+ throw Error(`Failed to get URL: ${e.message}`);
169
+ }
170
+ throw e;
171
+ }
172
+
173
+ if (!url) {
174
+ throw new Error('No URL found for the given address and key');
175
+ }
176
+
177
+ let hash: string;
178
+ try {
179
+ hash = await this.get(chainId, address, hashKey);
180
+ } catch (e) {
181
+ if (e instanceof Error) {
182
+ throw Error(`Failed to get Hash: ${e.message}`);
183
+ }
184
+ throw e;
185
+ }
186
+
187
+ if (!hash) {
188
+ throw new Error('No hash found for the given address and url');
189
+ }
190
+
191
+ const content = await fetch(url).then((res) => res.text());
192
+ const contentHash = ethers.keccak256(ethers.toUtf8Bytes(content));
193
+
194
+ const formattedHash = hash?.replace(/^0x/, '');
195
+ const formattedContentHash = contentHash?.replace(/^0x/, '');
196
+
197
+ if (formattedHash !== formattedContentHash) {
198
+ throw ErrorInvalidHash;
199
+ }
200
+
201
+ return url;
202
+ }
203
+
204
+ /**
205
+ * Gets the public key of the given entity, and verifies its hash.
206
+ *
207
+ * @param chainId - Network in which the KVStore is deployed
208
+ * @param address - Address from which to get the public key.
209
+ * @param options - Optional configuration for subgraph requests.
210
+ * @returns Public key for the given address if it exists, and the content is valid
211
+ * @throws ErrorInvalidAddress If the address is invalid
212
+ * @throws ErrorInvalidHash If the hash verification fails
213
+ * @throws Error If fetching the public key fails
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * const publicKey = await KVStoreUtils.getPublicKey(
218
+ * ChainId.POLYGON_AMOY,
219
+ * '0x1234567890123456789012345678901234567890'
220
+ * );
221
+ * console.log('Public key:', publicKey);
222
+ * ```
223
+ */
224
+ public static async getPublicKey(
225
+ chainId: ChainId,
226
+ address: string,
227
+ options?: SubgraphOptions
228
+ ): Promise<string> {
229
+ const publicKeyUrl = await this.getFileUrlAndVerifyHash(
230
+ chainId,
231
+ address,
232
+ KVStoreKeys.publicKey,
233
+ options
234
+ );
235
+
236
+ if (publicKeyUrl === '') {
237
+ return '';
238
+ }
239
+
240
+ const publicKey = await fetch(publicKeyUrl).then((res) => res.text());
241
+
242
+ return publicKey;
243
+ }
244
+ }
@@ -0,0 +1 @@
1
+ export { OperatorUtils } from './operator_utils';
@@ -4,27 +4,27 @@ import {
4
4
  IOperatorsFilter,
5
5
  IReward,
6
6
  SubgraphOptions,
7
- } from './interfaces';
8
- import { GET_REWARD_ADDED_EVENTS_QUERY } from './graphql/queries/reward';
7
+ } from '../interfaces';
8
+ import { GET_REWARD_ADDED_EVENTS_QUERY } from '../graphql/queries/reward';
9
9
  import {
10
10
  IOperatorSubgraph,
11
11
  IReputationNetworkSubgraph,
12
12
  RewardAddedEventData,
13
- } from './graphql';
13
+ } from '../graphql';
14
14
  import {
15
15
  GET_LEADER_QUERY,
16
16
  GET_LEADERS_QUERY,
17
17
  GET_REPUTATION_NETWORK_QUERY,
18
- } from './graphql/queries/operator';
18
+ } from '../graphql/queries/operator';
19
19
  import { ethers } from 'ethers';
20
20
  import {
21
21
  ErrorInvalidSlasherAddressProvided,
22
22
  ErrorInvalidStakerAddressProvided,
23
23
  ErrorUnsupportedChainID,
24
- } from './error';
25
- import { getSubgraphUrl, customGqlFetch } from './utils';
26
- import { ChainId, OrderDirection } from './enums';
27
- import { NETWORKS } from './constants';
24
+ } from '../error';
25
+ import { getSubgraphUrl, customGqlFetch } from '../utils';
26
+ import { ChainId, OrderDirection } from '../enums';
27
+ import { NETWORKS } from '../constants';
28
28
 
29
29
  /**
30
30
  * Utility helpers for operator-related queries.
@@ -0,0 +1,2 @@
1
+ export { StakingClient } from './staking_client';
2
+ export { StakingUtils } from './staking_utils';