dkg.js 6.0.0-beta.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +237 -0
- package/assets-demo.js +194 -0
- package/client/abstract-client.js +377 -0
- package/client/assets-client.js +141 -0
- package/client/native-client.js +34 -0
- package/dist/.gitkeep +0 -0
- package/dist/index.bundle.js +653 -0
- package/frontendMock.html +148 -0
- package/header.png +0 -0
- package/index.js +12 -0
- package/kg-example.json +29 -0
- package/native-demo.js +113 -0
- package/nft-example-updated.json +19 -0
- package/nft-example.json +19 -0
- package/package.json +44 -0
- package/utilities/assets-proxy-path.js +119 -0
- package/utilities/logger.js +23 -0
- package/webpack.config.js +12 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const FormData = require("form-data");
|
|
3
|
+
|
|
4
|
+
const Logger = require("../utilities/logger");
|
|
5
|
+
|
|
6
|
+
class AbstractClient {
|
|
7
|
+
defaultMaxNumberOfRetries = 50;
|
|
8
|
+
defaultTimeoutInSeconds = 10;
|
|
9
|
+
defaultNumberOfResults = 20;
|
|
10
|
+
STATUSES = {
|
|
11
|
+
pending: "PENDING",
|
|
12
|
+
completed: "COMPLETED",
|
|
13
|
+
failed: "FAILED",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Initialize client
|
|
17
|
+
* @constructor
|
|
18
|
+
* @param {object} options
|
|
19
|
+
* @param {string} options.endpoint
|
|
20
|
+
* @param {number} options.port
|
|
21
|
+
* @param {boolean} options.useSSL
|
|
22
|
+
* @param {string} options.loglevel (optional)
|
|
23
|
+
* @param {number} options.maxNumberOfRetries (optional)
|
|
24
|
+
*/
|
|
25
|
+
constructor(options) {
|
|
26
|
+
let loglevel = options.loglevel ? options.loglevel : "error";
|
|
27
|
+
this.maxNumberOfRetries =
|
|
28
|
+
options.maxNumberOfRetries && options.maxNumberOfRetries >= 0
|
|
29
|
+
? options.maxNumberOfRetries
|
|
30
|
+
: this.defaultMaxNumberOfRetries;
|
|
31
|
+
this.logger = new Logger(loglevel);
|
|
32
|
+
if (!options.endpoint || !options.port) {
|
|
33
|
+
throw Error("Endpoint and port are required parameters");
|
|
34
|
+
}
|
|
35
|
+
this.nodeBaseUrl = `${options.useSSL ? "https://" : "http://"}${
|
|
36
|
+
options.endpoint
|
|
37
|
+
}:${options.port}`;
|
|
38
|
+
this._sendNodeInfoRequest()
|
|
39
|
+
.then()
|
|
40
|
+
.catch((error) => {
|
|
41
|
+
throw new Error(`Endpoint not available: ${error}`);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get node information (version, is auto upgrade enabled, is telemetry enabled)
|
|
47
|
+
*/
|
|
48
|
+
nodeInfo() {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
this._sendNodeInfoRequest()
|
|
51
|
+
.then((response) => resolve(response.data))
|
|
52
|
+
.catch((error) => reject(error));
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_sendNodeInfoRequest() {
|
|
57
|
+
this.logger.debug("Sending node info request");
|
|
58
|
+
return axios.get(`${this.nodeBaseUrl}/info`, {
|
|
59
|
+
timeout: this.defaultTimeoutInSeconds * 1000,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
_publishRequest(options) {
|
|
64
|
+
this.logger.debug("Sending publish request.");
|
|
65
|
+
const form = new FormData();
|
|
66
|
+
form.append("data", JSON.stringify(options.content));
|
|
67
|
+
form.append("keywords", JSON.stringify(options.keywords));
|
|
68
|
+
if (options.ual) {
|
|
69
|
+
form.append("ual", options.ual);
|
|
70
|
+
}
|
|
71
|
+
form.append("visibility", options.visibility);
|
|
72
|
+
let axios_config = {
|
|
73
|
+
method: "post",
|
|
74
|
+
url: `${this.nodeBaseUrl}/${options.method}`,
|
|
75
|
+
data: form,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
return axios(axios_config);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {object} options
|
|
83
|
+
* @param {string[]} options.ids - assertion ids
|
|
84
|
+
*/
|
|
85
|
+
resolve(options) {
|
|
86
|
+
if (!options || !options.ids) {
|
|
87
|
+
throw Error("Please provide resolve options in order to resolve.");
|
|
88
|
+
}
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
this._resolveRequest(options)
|
|
91
|
+
.then((response) =>
|
|
92
|
+
this._getResult({
|
|
93
|
+
handler_id: response.data.handler_id,
|
|
94
|
+
operation: "resolve",
|
|
95
|
+
})
|
|
96
|
+
)
|
|
97
|
+
.then((response) => {
|
|
98
|
+
resolve(response);
|
|
99
|
+
})
|
|
100
|
+
.catch((error) => reject(error));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
_resolveRequest(options) {
|
|
105
|
+
this.logger.debug("Sending resolve request.");
|
|
106
|
+
const form = new FormData();
|
|
107
|
+
let ids = "";
|
|
108
|
+
|
|
109
|
+
let firstOne = true;
|
|
110
|
+
for (let id of options.ids) {
|
|
111
|
+
firstOne = false;
|
|
112
|
+
if (firstOne) {
|
|
113
|
+
ids += `ids=${id}`;
|
|
114
|
+
} else {
|
|
115
|
+
ids += `&ids=${id}`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let axios_config = {
|
|
120
|
+
method: "get",
|
|
121
|
+
url: `${this.nodeBaseUrl}/resolve?${ids}`,
|
|
122
|
+
data: form,
|
|
123
|
+
};
|
|
124
|
+
return axios(axios_config);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @param {object} options
|
|
129
|
+
* @param {string} options.query - search term
|
|
130
|
+
* @param {string} options.resultType - result type: assertions or entities
|
|
131
|
+
* @param {boolean} options.prefix (optional)
|
|
132
|
+
* @param {number} options.limit (optional)
|
|
133
|
+
* @param {string[]} options.issuers (optional)
|
|
134
|
+
* @param {string} options.schemaTypes (optional)
|
|
135
|
+
* @param {number} options.numberOfResults (optional)
|
|
136
|
+
* @param {number} options.timeout (optional)
|
|
137
|
+
*/
|
|
138
|
+
search(options) {
|
|
139
|
+
if (!options || !options.query || !options.resultType) {
|
|
140
|
+
throw Error("Please provide search options in order to search.");
|
|
141
|
+
}
|
|
142
|
+
return new Promise((resolve, reject) => {
|
|
143
|
+
this._searchRequest(options)
|
|
144
|
+
.then((response) =>
|
|
145
|
+
this._getSearchResult({
|
|
146
|
+
handler_id: response.data.handler_id,
|
|
147
|
+
resultType: options.resultType,
|
|
148
|
+
numberOfResults: options.numberOfResults,
|
|
149
|
+
timeout: options.timeout,
|
|
150
|
+
})
|
|
151
|
+
)
|
|
152
|
+
.then((response) => {
|
|
153
|
+
resolve(response);
|
|
154
|
+
})
|
|
155
|
+
.catch((error) => reject(error));
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
_searchRequest(options) {
|
|
160
|
+
this.logger.debug("Sending search request.");
|
|
161
|
+
const form = new FormData();
|
|
162
|
+
let prefix = options.prefix ? options.prefix : true;
|
|
163
|
+
let limit = options.limit ? options.limit : 20;
|
|
164
|
+
let query = options.query;
|
|
165
|
+
let resultType = options.resultType;
|
|
166
|
+
let url = `${this.nodeBaseUrl}/${resultType}:search?query=${query}`;
|
|
167
|
+
if (resultType === "entities") {
|
|
168
|
+
url = `${this.nodeBaseUrl}/${resultType}:search?query=${query}&limit=${limit}&prefix=${prefix}`;
|
|
169
|
+
}
|
|
170
|
+
let axios_config = {
|
|
171
|
+
method: "get",
|
|
172
|
+
url,
|
|
173
|
+
data: form,
|
|
174
|
+
};
|
|
175
|
+
return axios(axios_config);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async _getSearchResult(options) {
|
|
179
|
+
if (!options.handler_id) {
|
|
180
|
+
throw Error("Unable to get results, need handler id");
|
|
181
|
+
}
|
|
182
|
+
let searchResponse = {};
|
|
183
|
+
let retries = 0;
|
|
184
|
+
let timeout = options.timeout ? options.timeout : this.defaultTimeoutInSeconds;
|
|
185
|
+
let numberOfResults = options.numberOfResults
|
|
186
|
+
? options.numberOfResults
|
|
187
|
+
: this.defaultNumberOfResults;
|
|
188
|
+
|
|
189
|
+
const form = new FormData();
|
|
190
|
+
let axios_config = {
|
|
191
|
+
method: "get",
|
|
192
|
+
url: `${this.nodeBaseUrl}/${options.resultType}:search/result/${options.handler_id}`,
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
let timeoutFlag = false;
|
|
196
|
+
let currentNumberOfResults = numberOfResults;
|
|
197
|
+
setTimeout(() => {
|
|
198
|
+
timeoutFlag = true;
|
|
199
|
+
}, timeout * 1000);
|
|
200
|
+
|
|
201
|
+
do {
|
|
202
|
+
await this.sleepForMilliseconds(1 * 1000);
|
|
203
|
+
try {
|
|
204
|
+
searchResponse = await axios(axios_config);
|
|
205
|
+
currentNumberOfResults = searchResponse.data.itemListElement.length;
|
|
206
|
+
} catch (e) {
|
|
207
|
+
this.logger.error(e);
|
|
208
|
+
throw e;
|
|
209
|
+
}
|
|
210
|
+
} while (!timeoutFlag && numberOfResults > currentNumberOfResults);
|
|
211
|
+
return searchResponse.data;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param {object} options
|
|
216
|
+
* @param {string} options.query - sparql query
|
|
217
|
+
*/
|
|
218
|
+
query(options) {
|
|
219
|
+
if (!options || !options.query) {
|
|
220
|
+
throw Error("Please provide options in order to query.");
|
|
221
|
+
}
|
|
222
|
+
return new Promise((resolve, reject) => {
|
|
223
|
+
this._queryRequest(options)
|
|
224
|
+
.then((response) =>
|
|
225
|
+
this._getResult({
|
|
226
|
+
handler_id: response.data.handler_id,
|
|
227
|
+
operation: "query",
|
|
228
|
+
})
|
|
229
|
+
)
|
|
230
|
+
.then((response)=>{
|
|
231
|
+
resolve(response);
|
|
232
|
+
})
|
|
233
|
+
.catch((error) => reject(error));
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
_queryRequest(options) {
|
|
238
|
+
this.logger.debug("Sending query request.");
|
|
239
|
+
const form = new FormData();
|
|
240
|
+
let type = options.type ? options.type : "construct";
|
|
241
|
+
let sparqlQuery = options.query;
|
|
242
|
+
form.append("query", sparqlQuery);
|
|
243
|
+
let axios_config = {
|
|
244
|
+
method: "post",
|
|
245
|
+
url: `${this.nodeBaseUrl}/query?type=${type}`,
|
|
246
|
+
data: form,
|
|
247
|
+
};
|
|
248
|
+
return axios(axios_config);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @param {object} options
|
|
253
|
+
* @param {string[]} options.nquads
|
|
254
|
+
* @param {object} options.validationInstructions
|
|
255
|
+
*/
|
|
256
|
+
validate(options) {
|
|
257
|
+
if (!options || !options.nquads) {
|
|
258
|
+
throw Error(
|
|
259
|
+
"Please provide assertions and nquads in order to get proofs."
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
return new Promise((resolve, reject) => {
|
|
263
|
+
this._getProofsRequest(options)
|
|
264
|
+
.then((response) =>
|
|
265
|
+
this._getResult({
|
|
266
|
+
handler_id: response.data.handler_id,
|
|
267
|
+
operation: "proofs:get",
|
|
268
|
+
})
|
|
269
|
+
)
|
|
270
|
+
.then(async (response) => {
|
|
271
|
+
if (response.status === this.STATUSES.completed) {
|
|
272
|
+
response = await this._performValidation(response.data);
|
|
273
|
+
} else {
|
|
274
|
+
throw Error("Unable to get proofs for given nquads");
|
|
275
|
+
}
|
|
276
|
+
resolve(response);
|
|
277
|
+
})
|
|
278
|
+
.catch((error) => reject(error));
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
_getProofsRequest(options) {
|
|
283
|
+
this.logger.debug("Sending get proofs request.");
|
|
284
|
+
const form = new FormData();
|
|
285
|
+
let nquads = options.nquads;
|
|
286
|
+
form.append("nquads", JSON.stringify(nquads));
|
|
287
|
+
let axios_config = {
|
|
288
|
+
method: "post",
|
|
289
|
+
url: `${this.nodeBaseUrl}/proofs:get`,
|
|
290
|
+
data: form,
|
|
291
|
+
};
|
|
292
|
+
return axios(axios_config);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async _performValidation(assertions) {
|
|
296
|
+
let validationResult = [];
|
|
297
|
+
for (let assertion of assertions) {
|
|
298
|
+
let rootHash = await this._fetchRootHash(assertion.assertionId);
|
|
299
|
+
for (let obj of assertion.proofs) {
|
|
300
|
+
let validatedTriple = { triple: obj.triple, valid: false };
|
|
301
|
+
if (obj.proof === null) {
|
|
302
|
+
this.logger.debug(
|
|
303
|
+
`${obj.triple} has no proof in assertion ${assertion.assertionId}`
|
|
304
|
+
);
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
let verified = this._validateProof(obj, rootHash);
|
|
308
|
+
validatedTriple.valid = verified;
|
|
309
|
+
validationResult.push(validatedTriple);
|
|
310
|
+
if (verified) {
|
|
311
|
+
this.logger.debug(
|
|
312
|
+
`Validation successful for data: ${JSON.stringify(obj)}`
|
|
313
|
+
);
|
|
314
|
+
} else {
|
|
315
|
+
this.logger.debug(`Invalid data: ${JSON.stringify(obj)}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return validationResult;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
async _fetchRootHash(assertionId) {
|
|
323
|
+
let result = await this.resolve({ ids: [assertionId] });
|
|
324
|
+
return result.data[0][assertionId].rootHash;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
_validateProof(obj, rootHash) {
|
|
328
|
+
// const tree = new MerkleTools();
|
|
329
|
+
// const leaf = obj.tripleHash;
|
|
330
|
+
// const verified = tree.validateProof(obj.proof, leaf, rootHash);
|
|
331
|
+
// return verified;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async _getResult(options) {
|
|
335
|
+
await this.sleepForMilliseconds(500);
|
|
336
|
+
if (!options.handler_id || !options.operation) {
|
|
337
|
+
throw Error("Unable to get results, need handler id and operation");
|
|
338
|
+
}
|
|
339
|
+
let response = {
|
|
340
|
+
status: this.STATUSES.pending,
|
|
341
|
+
};
|
|
342
|
+
let retries = 0;
|
|
343
|
+
const form = new FormData();
|
|
344
|
+
let axios_config = {
|
|
345
|
+
method: "get",
|
|
346
|
+
url: `${this.nodeBaseUrl}/${options.operation}/result/${options.handler_id}`,
|
|
347
|
+
};
|
|
348
|
+
do {
|
|
349
|
+
if (retries > this.maxNumberOfRetries) {
|
|
350
|
+
throw Error("Unable to get results. Max number of retries reached.");
|
|
351
|
+
}
|
|
352
|
+
retries++;
|
|
353
|
+
await this.sleepForMilliseconds(1 * 1000);
|
|
354
|
+
try {
|
|
355
|
+
response = await axios(axios_config);
|
|
356
|
+
this.logger.debug(
|
|
357
|
+
`${options.operation} result status: ${response.data.status}`
|
|
358
|
+
);
|
|
359
|
+
} catch (e) {
|
|
360
|
+
this.logger.error(e);
|
|
361
|
+
throw e;
|
|
362
|
+
}
|
|
363
|
+
} while (response.data.status === this.STATUSES.pending);
|
|
364
|
+
if (response.data.status === this.STATUSES.failed) {
|
|
365
|
+
throw Error(
|
|
366
|
+
`Get ${options.operation} failed. Reason: ${response.data.message}.`
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
return response.data;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
async sleepForMilliseconds(milliseconds) {
|
|
373
|
+
await new Promise((r) => setTimeout(r, milliseconds));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
module.exports = AbstractClient;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
const AbstractClient = require("./abstract-client");
|
|
2
|
+
const AssetsProxyPath = require("../utilities/assets-proxy-path");
|
|
3
|
+
|
|
4
|
+
class AssetsClient extends AbstractClient {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
super(options);
|
|
7
|
+
this._assetsProxyPath = new AssetsProxyPath(options);
|
|
8
|
+
this.loadMetamask()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param content
|
|
13
|
+
* @param {object} options
|
|
14
|
+
* @param {string} options.filepath - path to the dataset
|
|
15
|
+
* @param {string[]} options.keywords (optional)
|
|
16
|
+
*/
|
|
17
|
+
async create(content, options) {
|
|
18
|
+
content['@context'] = "https://www.schema.org/";
|
|
19
|
+
content.proof = await this.signMessage(content.toString());
|
|
20
|
+
|
|
21
|
+
options.content = content;
|
|
22
|
+
options.method = 'provision';
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
this._publishRequest(options)
|
|
25
|
+
.then((response) =>
|
|
26
|
+
this._getResult({
|
|
27
|
+
handler_id: response.data.handler_id,
|
|
28
|
+
operation: options.method,
|
|
29
|
+
})
|
|
30
|
+
)
|
|
31
|
+
.then((response) => {
|
|
32
|
+
resolve(response);
|
|
33
|
+
})
|
|
34
|
+
.catch((error) => reject(error));
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {object} options
|
|
40
|
+
* @param {string} options.filepath - path to the dataset
|
|
41
|
+
* @param {string[]} options.keywords (optional)
|
|
42
|
+
*/
|
|
43
|
+
async update(content, ual, options) {
|
|
44
|
+
content['@context'] = "https://www.schema.org/";
|
|
45
|
+
content.proof = await this.signMessage(content.toString());
|
|
46
|
+
options.content = content;
|
|
47
|
+
options.ual = ual;
|
|
48
|
+
options.method = 'update';
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
this._publishRequest(options)
|
|
51
|
+
.then((response) =>
|
|
52
|
+
this._getResult({
|
|
53
|
+
handler_id: response.data.handler_id,
|
|
54
|
+
operation: options.method,
|
|
55
|
+
})
|
|
56
|
+
)
|
|
57
|
+
.then((response) => {
|
|
58
|
+
resolve(response);
|
|
59
|
+
})
|
|
60
|
+
.catch((error) => reject(error));
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async get(ual, commitHash) {
|
|
65
|
+
//TODO add cache
|
|
66
|
+
|
|
67
|
+
let result;
|
|
68
|
+
if (commitHash)
|
|
69
|
+
result = await this.resolve({ids: [commitHash]});
|
|
70
|
+
else
|
|
71
|
+
result = await this.resolve({ids: [ual]});
|
|
72
|
+
if (result.status === this.STATUSES.completed) {
|
|
73
|
+
const data = result.data[0].result;
|
|
74
|
+
|
|
75
|
+
return this._assetsProxyPath.createPath(
|
|
76
|
+
Object.assign(Object.create(null), undefined, undefined),
|
|
77
|
+
Object.assign(Object.create(null), undefined, data),
|
|
78
|
+
ual
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async getStateCommitHashes(ual) {
|
|
86
|
+
//TODO add cache
|
|
87
|
+
|
|
88
|
+
let result = await this.resolve({ids: [ual]});
|
|
89
|
+
if (result.status === this.STATUSES.completed) {
|
|
90
|
+
return result.data[0].result.assertions;
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
transfer(options) {
|
|
97
|
+
//TODO
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
approve(options) {
|
|
101
|
+
//TODO
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
loadMetamask(){
|
|
106
|
+
if (window.ethereum) {
|
|
107
|
+
window.web3 = new Web3(ethereum);
|
|
108
|
+
ethereum.enable()
|
|
109
|
+
.then(() => {
|
|
110
|
+
console.log("Ethereum enabled");
|
|
111
|
+
|
|
112
|
+
web3.eth.getAccounts(function (err, acc) {
|
|
113
|
+
if (err != null) {
|
|
114
|
+
self.setStatus("There was an error fetching your accounts");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (acc.length > 0) {
|
|
118
|
+
console.log(acc);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
})
|
|
122
|
+
.catch(() => {
|
|
123
|
+
console.warn('User didn\'t allow access to accounts.');
|
|
124
|
+
waitLogin();
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
console.log("Non-Ethereum browser detected. You should consider installing MetaMask.");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async signMessage(message) {
|
|
132
|
+
const web3 = new Web3(window.ethereum);
|
|
133
|
+
var hash = web3.utils.sha3(message)
|
|
134
|
+
var accounts = await web3.eth.getAccounts()
|
|
135
|
+
var signature = await web3.eth.personal.sign(hash, accounts[0])
|
|
136
|
+
return {hash, account: accounts[0], signature}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
module.exports = AssetsClient;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const AbstractClient = require("./abstract-client");
|
|
2
|
+
|
|
3
|
+
class NativeClient extends AbstractClient {
|
|
4
|
+
constructor(props) {
|
|
5
|
+
super(props);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param {object} options
|
|
10
|
+
* @param {string} options.filepath - path to the dataset
|
|
11
|
+
* @param {string[]} options.keywords (optional)
|
|
12
|
+
*/
|
|
13
|
+
publish(options) {
|
|
14
|
+
if (!options || !options.filepath) {
|
|
15
|
+
throw Error("Please provide publish options in order to publish.");
|
|
16
|
+
}
|
|
17
|
+
options.method = 'publish';
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
this._publishRequest(options)
|
|
20
|
+
.then((response) =>
|
|
21
|
+
this._getResult({
|
|
22
|
+
handler_id: response.data.handler_id,
|
|
23
|
+
operation: options.method,
|
|
24
|
+
})
|
|
25
|
+
)
|
|
26
|
+
.then((response) => {
|
|
27
|
+
resolve(response);
|
|
28
|
+
})
|
|
29
|
+
.catch((error) => reject(error));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = NativeClient;
|
package/dist/.gitkeep
ADDED
|
File without changes
|