dkg.js 6.0.0 → 6.0.2

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.
@@ -1,15 +1,64 @@
1
+ const { OPERATIONS } = require('../constants');
2
+ const { deriveRepository } = require('../services/utilities.js');
3
+
1
4
  class GraphOperationsManager {
2
5
  constructor(config, services) {
3
6
  this.nodeApiService = services.nodeApiService;
7
+ this.validationService = services.validationService;
8
+ this.inputService = services.inputService;
4
9
  }
5
10
 
6
- async query(queryString, type, options = {}) {
7
- const operationId = await this.nodeApiService.query({ query: queryString, type }, options);
11
+ /**
12
+ * An asynchronous function that executes a SPARQL query using an API endpoint and returns the query result.
13
+ * @async
14
+ * @param {string} queryString - The string representation of the SPARQL query to be executed.
15
+ * @param {string} queryType - The type of the SPARQL query, "CONSTRUCT" or "SELECT".
16
+ * @param {Object} [options={}] - An object containing additional options for the query execution.
17
+ * @returns {Promise} A Promise that resolves to the query result.
18
+ */
19
+ async query(queryString, queryType, options = {}) {
20
+ const {
21
+ graphLocation,
22
+ graphState,
23
+ endpoint,
24
+ port,
25
+ maxNumberOfRetries,
26
+ frequency,
27
+ authToken,
28
+ } = this.inputService.getQueryArguments(options);
29
+
30
+ this.validationService.validateGraphQuery(
31
+ queryString,
32
+ queryType,
33
+ graphLocation,
34
+ graphState,
35
+ endpoint,
36
+ port,
37
+ maxNumberOfRetries,
38
+ frequency,
39
+ authToken,
40
+ );
41
+
42
+ const repository = deriveRepository(graphLocation, graphState);
43
+
44
+ const operationId = await this.nodeApiService.query(
45
+ endpoint,
46
+ port,
47
+ authToken,
48
+ queryString,
49
+ queryType,
50
+ repository,
51
+ );
8
52
 
9
- return this.nodeApiService.getOperationResult(operationId, {
10
- ...options,
11
- operation: 'query',
12
- });
53
+ return this.nodeApiService.getOperationResult(
54
+ endpoint,
55
+ port,
56
+ authToken,
57
+ OPERATIONS.QUERY,
58
+ maxNumberOfRetries,
59
+ frequency,
60
+ operationId,
61
+ );
13
62
  }
14
63
  }
15
64
  module.exports = GraphOperationsManager;
@@ -1,10 +1,24 @@
1
1
  class NodeOperationsManager {
2
2
  constructor(config, services) {
3
3
  this.nodeApiService = services.nodeApiService;
4
+ this.inputService = services.inputService;
4
5
  }
5
6
 
6
- async info() {
7
- const response = await this.nodeApiService.info();
7
+ /**
8
+ * Gets the node info from the specified endpoint using the provided options.
9
+ * @async
10
+ * @param {Object} [options={}] - The options for the request.
11
+ * @param {string} [options.endpoint] - The endpoint URL to send the request to.
12
+ * @param {number} [options.port] - The port number to use for the request.
13
+ * @param {string} [options.authToken] - The authentication token to include in the request headers.
14
+ * @returns {Promise} - A promise that resolves to the node info data returned from the API.
15
+ */
16
+ async info(options = {}) {
17
+ const endpoint = this.inputService.getEndpoint(options);
18
+ const port = this.inputService.getPort(options);
19
+ const authToken = this.inputService.getAuthToken(options);
20
+
21
+ const response = await this.nodeApiService.info(endpoint, port, authToken);
8
22
 
9
23
  return response.data;
10
24
  }
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "dkg.js",
3
- "version": "6.0.0",
3
+ "version": "6.0.2",
4
4
  "description": "Javascript library for interaction with the OriginTrail Decentralized Knowledge Graph",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "compile-contracts": "cd ./node_modules/dkg-evm-module && truffle compile",
8
- "test": "npm run test",
7
+ "compile-contracts": "cd ./node_modules/dkg-evm-module && npm run compile",
9
8
  "build": "npx webpack --config webpack.config.js",
10
9
  "watch": "npx webpack --config webpack.config.js --watch --progress",
11
10
  "lint": "eslint ."
@@ -32,23 +31,22 @@
32
31
  "dependencies": {
33
32
  "assertion-tools": "^2.0.2",
34
33
  "axios": "^0.27.2",
35
- "dkg-evm-module": "^3.2.1",
34
+ "dkg-evm-module": "^4.0.4",
35
+ "ethers": "^6.1.0",
36
36
  "jsonld": "^8.1.0",
37
37
  "web3": "^1.7.3"
38
38
  },
39
39
  "devDependencies": {
40
- "assert": "^2.0.0",
41
- "stream-browserify": "^3.0.0",
42
- "stream-http": "^3.2.0",
43
- "url": "^0.11.0",
44
40
  "crypto-browserify": "^3.12.0",
45
- "https-browserify": "^1.0.0",
46
- "terser-webpack-plugin": "^5.3.6",
47
- "webpack": "^5.69.0",
48
- "webpack-cli": "^4.9.2",
49
41
  "eslint": "^8.23.0",
50
42
  "eslint-config-airbnb": "^19.0.4",
51
43
  "eslint-config-prettier": "^8.5.0",
52
- "prettier": "^2.7.1"
44
+ "https-browserify": "^1.0.0",
45
+ "prettier": "^2.7.1",
46
+ "stream-browserify": "^3.0.0",
47
+ "stream-http": "^3.2.0",
48
+ "terser-webpack-plugin": "^5.3.6",
49
+ "webpack": "^5.75.0",
50
+ "webpack-cli": "^4.9.2"
53
51
  }
54
52
  }
@@ -4,6 +4,7 @@ const BlockchainInterface = require('./blockchain-service/blockchain-interface.j
4
4
  // services
5
5
  const ValidationService = require('./validation-service.js');
6
6
  const Utilities = require('./utilities.js');
7
+ const InputService = require('./input-service.js');
7
8
 
8
9
  class BaseServiceManager {
9
10
  constructor(config) {
@@ -13,6 +14,7 @@ class BaseServiceManager {
13
14
  initializeServices(config) {
14
15
  this.blockchainService = this.initializeBlockchainService(config);
15
16
  this.nodeApiService = this.initializeNodeApiService(config);
17
+ this.inputService = new InputService(config);
16
18
  this.validationService = new ValidationService();
17
19
  }
18
20
 
@@ -21,6 +23,7 @@ class BaseServiceManager {
21
23
  blockchainService: this.blockchainService,
22
24
  nodeApiService: this.nodeApiService,
23
25
  validationService: this.validationService,
26
+ inputService: this.inputService,
24
27
  };
25
28
  }
26
29
 
@@ -1,11 +1,13 @@
1
1
  const Web3 = require('web3');
2
- const HubAbi = require('dkg-evm-module/build/contracts/Hub.json').abi;
3
- const ServiceAgreementV1Abi = require('dkg-evm-module/build/contracts/ServiceAgreementV1.json').abi;
4
- const ContentAssetStorageAbi =
5
- require('dkg-evm-module/build/contracts/ContentAssetStorage.json').abi;
6
- const ContentAssetAbi = require('dkg-evm-module/build/contracts/ContentAsset.json').abi;
7
- const TokenAbi = require('dkg-evm-module/build/contracts/ERC20Token.json').abi;
8
- const { BLOCKCHAINS, OPERATIONS_STEP_STATUS } = require('../../constants');
2
+ const AssertionStorageAbi = require('dkg-evm-module/abi/AssertionStorage.json');
3
+ const HubAbi = require('dkg-evm-module/abi/Hub.json');
4
+ const ServiceAgreementV1Abi = require('dkg-evm-module/abi/ServiceAgreementV1.json');
5
+ const ServiceAgreementStorageProxyAbi = require('dkg-evm-module/abi/ServiceAgreementStorageProxy.json');
6
+ const ContentAssetStorageAbi = require('dkg-evm-module/abi/ContentAssetStorage.json');
7
+ const UnfinalizedStateStorageAbi = require('dkg-evm-module/abi/UnfinalizedStateStorage.json');
8
+ const ContentAssetAbi = require('dkg-evm-module/abi/ContentAsset.json');
9
+ const TokenAbi = require('dkg-evm-module/abi/Token.json');
10
+ const { OPERATIONS_STEP_STATUS } = require('../../constants');
9
11
  const emptyHooks = require('../../util/empty-hooks.js');
10
12
 
11
13
  const FIXED_GAS_LIMIT_METHODS = {
@@ -15,20 +17,14 @@ const FIXED_GAS_LIMIT_METHODS = {
15
17
  class BlockchainServiceBase {
16
18
  constructor() {
17
19
  this.abis = {};
20
+ this.abis.AssertionStorage = AssertionStorageAbi;
18
21
  this.abis.Hub = HubAbi;
19
22
  this.abis.ServiceAgreementV1 = ServiceAgreementV1Abi;
23
+ this.abis.ServiceAgreementStorageProxy = ServiceAgreementStorageProxyAbi;
20
24
  this.abis.ContentAssetStorage = ContentAssetStorageAbi;
25
+ this.abis.UnfinalizedStateStorage = UnfinalizedStateStorageAbi;
21
26
  this.abis.ContentAsset = ContentAssetAbi;
22
27
  this.abis.Token = TokenAbi;
23
-
24
- for (const blockchainName of Object.keys(BLOCKCHAINS)) {
25
- this[blockchainName] = {
26
- contracts: {},
27
- contractAddresses: {
28
- Hub: BLOCKCHAINS[blockchainName].hubContract,
29
- },
30
- };
31
- }
32
28
  }
33
29
 
34
30
  initializeWeb3() {
@@ -36,28 +32,18 @@ class BlockchainServiceBase {
36
32
  return {};
37
33
  }
38
34
 
39
- getBlockchain() {
40
- // overridden by subclasses
41
- return {};
42
- }
43
-
44
35
  async decodeEventLogs() {
45
36
  // overridden by subclasses
46
37
  return {};
47
38
  }
48
39
 
49
40
  async callContractFunction(contractName, functionName, args, blockchain) {
50
- const contractInstance = await this.getContractInstance(
51
- blockchain.name,
52
- contractName,
53
- blockchain.rpc,
54
- );
55
-
41
+ const contractInstance = await this.getContractInstance(contractName, blockchain);
56
42
  return contractInstance.methods[functionName](...args).call();
57
43
  }
58
44
 
59
45
  async prepareTransaction(contractInstance, functionName, args, blockchain) {
60
- const web3Instance = await this.getWeb3Instance(blockchain.name, blockchain.rpc);
46
+ const web3Instance = await this.getWeb3Instance(blockchain);
61
47
  let gasLimit;
62
48
  if (FIXED_GAS_LIMIT_METHODS[functionName]) {
63
49
  gasLimit = FIXED_GAS_LIMIT_METHODS[functionName];
@@ -82,70 +68,81 @@ class BlockchainServiceBase {
82
68
  to: contractInstance.options.address,
83
69
  data: encodedABI,
84
70
  gasPrice,
85
- gas: gasLimit ?? Web3.utils.toWei('900', 'Kwei'),
71
+ gas: gasLimit,
86
72
  };
87
73
  }
88
74
 
89
- async getWeb3Instance(blockchainName, blockchainRpc) {
90
- if (!this[blockchainName].web3) {
91
- this.initializeWeb3(blockchainName, blockchainRpc);
75
+ ensureBlockchainInfo(blockchain) {
76
+ if (!this[blockchain.name]) {
77
+ this[blockchain.name] = {
78
+ contracts: { [blockchain.hubContract]: {} },
79
+ contractAddresses: {
80
+ [blockchain.hubContract]: {
81
+ Hub: blockchain.hubContract,
82
+ },
83
+ },
84
+ };
92
85
  }
86
+ }
93
87
 
94
- return this[blockchainName].web3;
88
+ async getWeb3Instance(blockchain) {
89
+ this.ensureBlockchainInfo(blockchain);
90
+ if (!this[blockchain.name].web3) {
91
+ this.initializeWeb3(blockchain.name, blockchain.rpc);
92
+ }
93
+
94
+ return this[blockchain.name].web3;
95
95
  }
96
96
 
97
- async getContractAddress(blockchainName, contractName, blockchainRpc) {
98
- if (!this[blockchainName].contracts.Hub) {
99
- const web3Instance = await this.getWeb3Instance(blockchainName, blockchainRpc);
100
- this[blockchainName].contracts.Hub = new web3Instance.eth.Contract(
101
- this.abis.Hub,
102
- this[blockchainName].contractAddresses.Hub,
103
- );
97
+ async getContractAddress(contractName, blockchain) {
98
+ this.ensureBlockchainInfo(blockchain);
99
+ if (!this[blockchain.name].contracts[blockchain.hubContract]) {
100
+ this[blockchain.name].contracts[blockchain.hubContract] = {};
101
+ }
102
+ if (!this[blockchain.name].contracts[blockchain.hubContract].Hub) {
103
+ const web3Instance = await this.getWeb3Instance(blockchain);
104
+ this[blockchain.name].contracts[blockchain.hubContract].Hub =
105
+ new web3Instance.eth.Contract(this.abis.Hub, blockchain.hubContract);
104
106
  }
105
107
 
106
- if (!this[blockchainName].contractAddresses[contractName]) {
107
- this[blockchainName].contractAddresses[contractName] = await this.callContractFunction(
108
- 'Hub',
109
- contractName.includes('AssetStorage')
110
- ? 'getAssetStorageAddress'
111
- : 'getContractAddress',
112
- [contractName],
113
- {
114
- name: blockchainName,
115
- rpc: blockchainRpc,
116
- },
117
- );
108
+ if (!this[blockchain.name].contractAddresses[blockchain.hubContract][contractName]) {
109
+ this[blockchain.name].contractAddresses[blockchain.hubContract][contractName] =
110
+ await this.callContractFunction(
111
+ 'Hub',
112
+ contractName.includes('AssetStorage')
113
+ ? 'getAssetStorageAddress'
114
+ : 'getContractAddress',
115
+ [contractName],
116
+ blockchain,
117
+ );
118
118
  }
119
- return this[blockchainName].contractAddresses[contractName];
119
+ return this[blockchain.name].contractAddresses[blockchain.hubContract][contractName];
120
120
  }
121
121
 
122
- async getContractInstance(blockchainName, contractName, blockchainRpc) {
123
- if (!this[blockchainName].contractAddresses[contractName]) {
124
- this[blockchainName].contractAddresses[contractName] = await this.getContractAddress(
125
- blockchainName,
126
- contractName,
127
- blockchainRpc,
128
- );
122
+ async getContractInstance(contractName, blockchain) {
123
+ this.ensureBlockchainInfo(blockchain);
124
+ if (!this[blockchain.name].contractAddresses[blockchain.hubContract][contractName]) {
125
+ this[blockchain.name].contractAddresses[blockchain.hubContract][contractName] =
126
+ await this.getContractAddress(contractName, blockchain);
129
127
  }
130
- if (!this[blockchainName].contracts[contractName]) {
131
- const web3Instance = await this.getWeb3Instance(blockchainName, blockchainRpc);
132
- this[blockchainName].contracts[contractName] = new web3Instance.eth.Contract(
133
- this.abis[contractName],
134
- this[blockchainName].contractAddresses[contractName],
135
- );
128
+ if (!this[blockchain.name].contracts[blockchain.hubContract][contractName]) {
129
+ const web3Instance = await this.getWeb3Instance(blockchain);
130
+ this[blockchain.name].contracts[blockchain.hubContract][contractName] =
131
+ new web3Instance.eth.Contract(
132
+ this.abis[contractName],
133
+ this[blockchain.name].contractAddresses[blockchain.hubContract][contractName],
134
+ );
136
135
  }
137
136
 
138
- return this[blockchainName].contracts[contractName];
137
+ return this[blockchain.name].contracts[blockchain.hubContract][contractName];
139
138
  }
140
139
 
141
- async createAsset(requestData, options, stepHooks = emptyHooks) {
142
- const blockchain = this.getBlockchain(options);
143
-
140
+ async createAsset(requestData, blockchain, stepHooks = emptyHooks) {
144
141
  const serviceAgreementV1Address = await this.getContractAddress(
145
- blockchain.name,
146
142
  'ServiceAgreementV1',
147
- blockchain.rpc,
143
+ blockchain,
148
144
  );
145
+
149
146
  await this.executeContractFunction(
150
147
  'Token',
151
148
  'increaseAllowance',
@@ -165,7 +162,9 @@ class BlockchainServiceBase {
165
162
  blockchain,
166
163
  );
167
164
 
168
- const { tokenId } = await this.decodeEventLogs(receipt, 'AssetMinted', blockchain);
165
+ let { tokenId } = await this.decodeEventLogs(receipt, 'AssetMinted', blockchain);
166
+
167
+ tokenId = parseInt(tokenId, 10);
169
168
 
170
169
  stepHooks.afterHook({
171
170
  status: OPERATIONS_STEP_STATUS.CREATE_ASSET_COMPLETED,
@@ -184,54 +183,71 @@ class BlockchainServiceBase {
184
183
  }
185
184
  }
186
185
 
187
- async updateAsset(tokenId, requestData, options) {
188
- const blockchain = this.getBlockchain(options);
189
-
186
+ async updateAsset(
187
+ tokenId,
188
+ publicAssertionId,
189
+ assertionSize,
190
+ triplesNumber,
191
+ chunksNumber,
192
+ tokenAmount,
193
+ blockchain,
194
+ ) {
190
195
  const serviceAgreementV1Address = await this.getContractAddress(
191
- blockchain.name,
192
196
  'ServiceAgreementV1',
193
- blockchain.rpc,
197
+ blockchain,
194
198
  );
195
199
 
196
200
  await this.executeContractFunction(
197
201
  'Token',
198
202
  'increaseAllowance',
199
- [serviceAgreementV1Address, requestData.tokenAmount],
203
+ [serviceAgreementV1Address, tokenAmount],
200
204
  blockchain,
201
205
  );
202
206
 
203
207
  try {
204
208
  return this.executeContractFunction(
205
209
  'ContentAsset',
206
- 'updateAsset',
207
- [tokenId, Object.values(requestData)],
210
+ 'updateAssetState',
211
+ [
212
+ tokenId,
213
+ publicAssertionId,
214
+ assertionSize,
215
+ triplesNumber,
216
+ chunksNumber,
217
+ tokenAmount,
218
+ ],
208
219
  blockchain,
209
220
  );
210
221
  } catch (e) {
211
222
  await this.executeContractFunction(
212
223
  'Token',
213
224
  'decreaseAllowance',
214
- [serviceAgreementV1Address, requestData.tokenAmount],
225
+ [serviceAgreementV1Address, tokenAmount],
215
226
  blockchain,
216
227
  );
217
228
  throw e;
218
229
  }
219
230
  }
220
231
 
221
- async getAssertionIdsLength(tokenId, options = {}) {
222
- const blockchain = this.getBlockchain(options);
223
-
232
+ async hasPendingUpdate(tokenId, blockchain) {
224
233
  return this.callContractFunction(
225
- 'ContentAssetStorage',
226
- 'getAssertionIdsLength',
234
+ 'UnfinalizedStateStorage',
235
+ 'hasPendingUpdate',
227
236
  [tokenId],
228
237
  blockchain,
229
238
  );
230
239
  }
231
240
 
232
- async getLatestAssertionId(tokenId, options = {}) {
233
- const blockchain = this.getBlockchain(options);
241
+ async cancelAssetUpdate(tokenId, blockchain) {
242
+ return this.executeContractFunction(
243
+ 'ContentAsset',
244
+ 'cancelAssetStateUpdate',
245
+ [tokenId],
246
+ blockchain,
247
+ );
248
+ }
234
249
 
250
+ async getLatestAssertionId(tokenId, blockchain) {
235
251
  return this.callContractFunction(
236
252
  'ContentAssetStorage',
237
253
  'getLatestAssertionId',
@@ -240,12 +256,167 @@ class BlockchainServiceBase {
240
256
  );
241
257
  }
242
258
 
243
- async getAssetOwner(tokenId, options = {}) {
244
- const blockchain = this.getBlockchain(options);
259
+ async getUnfinalizedState(tokenId, blockchain) {
260
+ return this.callContractFunction(
261
+ 'UnfinalizedStateStorage',
262
+ 'getUnfinalizedState',
263
+ [tokenId],
264
+ blockchain,
265
+ );
266
+ }
245
267
 
268
+ async getAssetOwner(tokenId, blockchain) {
246
269
  return this.callContractFunction('ContentAssetStorage', 'ownerOf', [tokenId], blockchain);
247
270
  }
248
271
 
272
+ async burnAsset(tokenId, blockchain) {
273
+ return this.executeContractFunction('ContentAsset', 'burnAsset', [tokenId], blockchain);
274
+ }
275
+
276
+ async extendAssetStoringPeriod(tokenId, epochsNumber, tokenAmount, blockchain) {
277
+ const serviceAgreementV1Address = await this.getContractAddress(
278
+ 'ServiceAgreementV1',
279
+ blockchain,
280
+ );
281
+
282
+ await this.executeContractFunction(
283
+ 'Token',
284
+ 'increaseAllowance',
285
+ [serviceAgreementV1Address, tokenAmount],
286
+ blockchain,
287
+ );
288
+
289
+ try {
290
+ return this.executeContractFunction(
291
+ 'ContentAsset',
292
+ 'extendAssetStoringPeriod',
293
+ [tokenId, epochsNumber, tokenAmount],
294
+ blockchain,
295
+ );
296
+ } catch (e) {
297
+ await this.executeContractFunction(
298
+ 'Token',
299
+ 'decreaseAllowance',
300
+ [serviceAgreementV1Address, tokenAmount],
301
+ blockchain,
302
+ );
303
+ throw e;
304
+ }
305
+ }
306
+
307
+ async addTokens(tokenId, tokenAmount, blockchain) {
308
+ const serviceAgreementV1Address = await this.getContractAddress(
309
+ 'ServiceAgreementV1',
310
+ blockchain,
311
+ );
312
+
313
+ await this.executeContractFunction(
314
+ 'Token',
315
+ 'increaseAllowance',
316
+ [serviceAgreementV1Address, tokenAmount],
317
+ blockchain,
318
+ );
319
+
320
+ try {
321
+ return this.executeContractFunction(
322
+ 'ContentAsset',
323
+ 'increaseAssetTokenAmount',
324
+ [tokenId, tokenAmount],
325
+ blockchain,
326
+ );
327
+ } catch (e) {
328
+ await this.executeContractFunction(
329
+ 'Token',
330
+ 'decreaseAllowance',
331
+ [serviceAgreementV1Address, tokenAmount],
332
+ blockchain,
333
+ );
334
+ throw e;
335
+ }
336
+ }
337
+
338
+ async addUpdateTokens(tokenId, tokenAmount, blockchain) {
339
+ const serviceAgreementV1Address = await this.getContractAddress(
340
+ 'ServiceAgreementV1',
341
+ blockchain,
342
+ );
343
+
344
+ await this.executeContractFunction(
345
+ 'Token',
346
+ 'increaseAllowance',
347
+ [serviceAgreementV1Address, tokenAmount],
348
+ blockchain,
349
+ );
350
+
351
+ try {
352
+ return this.executeContractFunction(
353
+ 'ContentAsset',
354
+ 'increaseAssetUpdateTokenAmount',
355
+ [tokenId, tokenAmount],
356
+ blockchain,
357
+ );
358
+ } catch (e) {
359
+ await this.executeContractFunction(
360
+ 'Token',
361
+ 'decreaseAllowance',
362
+ [serviceAgreementV1Address, tokenAmount],
363
+ blockchain,
364
+ );
365
+ throw e;
366
+ }
367
+ }
368
+
369
+ async getAssertionIdByIndex(tokenId, index, blockchain) {
370
+ return this.callContractFunction(
371
+ 'ContentAssetStorage',
372
+ 'getAssertionIdByIndex',
373
+ [tokenId, index],
374
+ blockchain,
375
+ );
376
+ }
377
+
378
+ async getAgreementData(agreementId, blockchain) {
379
+ const result = await this.callContractFunction(
380
+ 'ServiceAgreementStorageProxy',
381
+ 'getAgreementData',
382
+ [agreementId],
383
+ blockchain,
384
+ );
385
+
386
+ return {
387
+ startTime: Number(result['0']),
388
+ epochsNumber: Number(result['1']),
389
+ epochLength: Number(result['2']),
390
+ tokenAmount: result['3'][0],
391
+ addedTokenAmount: result['3'][1],
392
+ scoreFunctionId: result['4'][0],
393
+ proofWindowOffsetPerc: result['4'][1],
394
+ };
395
+ }
396
+
397
+ async getAssertionSize(assertionId, blockchain) {
398
+ return this.callContractFunction(
399
+ 'AssertionStorage',
400
+ 'getAssertionSize',
401
+ [assertionId],
402
+ blockchain,
403
+ );
404
+ }
405
+
406
+ async getBlockchainTimestamp(blockchain) {
407
+ if (blockchain.name !== 'hardhat') return Math.floor(Date.now() / 1000);
408
+
409
+ const latestBlock = await this.getLatestBlock(blockchain);
410
+ return latestBlock.timestamp;
411
+ }
412
+
413
+ async getLatestBlock(blockchain) {
414
+ const web3 = await this.getWeb3Instance(blockchain);
415
+ const blockNumber = await web3.eth.getBlockNumber();
416
+
417
+ return web3.eth.getBlock(blockNumber);
418
+ }
419
+
249
420
  convertToWei(ether) {
250
421
  return Web3.utils.toWei(ether.toString(), 'ether');
251
422
  }