@human-protocol/sdk 1.0.2 → 1.0.3
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 +1 -1
- package/dist/constants.d.ts +46 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +203 -0
- package/dist/decorators.d.ts +2 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +17 -0
- package/dist/enums.d.ts +17 -0
- package/dist/enums.d.ts.map +1 -0
- package/dist/enums.js +20 -0
- package/dist/error.d.ts +196 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +229 -0
- package/dist/escrow.d.ts +176 -0
- package/dist/escrow.d.ts.map +1 -0
- package/dist/escrow.js +590 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/init.d.ts +13 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +35 -0
- package/dist/interfaces.d.ts +44 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +2 -0
- package/dist/kvstore.d.ts +40 -0
- package/dist/kvstore.d.ts.map +1 -0
- package/dist/kvstore.js +106 -0
- package/dist/queries.d.ts +4 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.js +22 -0
- package/dist/staking.d.ts +121 -0
- package/dist/staking.d.ts.map +1 -0
- package/dist/staking.js +381 -0
- package/dist/storage.d.ts +48 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +164 -0
- package/dist/types.d.ts +123 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/utils.d.ts +32 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +99 -0
- package/package.json +4 -7
- package/src/constants.ts +221 -4
- package/src/decorators.ts +21 -0
- package/src/enums.ts +16 -0
- package/src/error.ts +295 -18
- package/src/escrow.ts +754 -0
- package/src/index.ts +14 -1
- package/src/init.ts +45 -0
- package/src/interfaces.ts +50 -0
- package/src/kvstore.ts +93 -0
- package/src/queries.ts +18 -0
- package/src/staking.ts +421 -0
- package/src/storage.ts +159 -131
- package/src/types.ts +36 -586
- package/src/utils.ts +80 -142
- package/test/escrow.test.ts +1339 -0
- package/test/init.test.ts +88 -0
- package/test/kvstore.test.ts +208 -0
- package/test/staking.test.ts +640 -0
- package/test/storage.test.ts +422 -0
- package/test/utils/constants.ts +38 -1
- package/example/simple-existing-job.ts +0 -86
- package/example/simple-new-job-public.ts +0 -74
- package/example/simple-new-job.ts +0 -72
- package/src/job.ts +0 -977
- package/src/logger.ts +0 -29
- package/test/job.test.ts +0 -716
- package/test/utils/manifest.ts +0 -33
package/src/storage.ts
CHANGED
|
@@ -1,135 +1,163 @@
|
|
|
1
|
-
import
|
|
1
|
+
import axios from 'axios';
|
|
2
2
|
import crypto from 'crypto';
|
|
3
|
+
import * as Minio from 'minio';
|
|
4
|
+
import {
|
|
5
|
+
ErrorInvalidUrl,
|
|
6
|
+
ErrorStorageBucketNotFound,
|
|
7
|
+
ErrorStorageClientNotInitialized,
|
|
8
|
+
ErrorStorageFileNotFound,
|
|
9
|
+
ErrorStorageFileNotUploaded,
|
|
10
|
+
} from './error';
|
|
11
|
+
import { UploadFile, StorageCredentials, StorageParams } from './types';
|
|
12
|
+
import { isValidUrl } from './utils';
|
|
13
|
+
import { HttpStatus } from './constants';
|
|
14
|
+
|
|
15
|
+
export default class StorageClient {
|
|
16
|
+
private client: Minio.Client;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* **Storage client constructor**
|
|
20
|
+
*
|
|
21
|
+
* @param {StorageCredentials} credentials - Cloud storage access data
|
|
22
|
+
* @param {StorageParams} params - Cloud storage params
|
|
23
|
+
*/
|
|
24
|
+
constructor(credentials: StorageCredentials, params: StorageParams) {
|
|
25
|
+
try {
|
|
26
|
+
this.client = new Minio.Client({
|
|
27
|
+
...params,
|
|
28
|
+
accessKey: credentials.accessKey,
|
|
29
|
+
secretKey: credentials.secretKey,
|
|
30
|
+
});
|
|
31
|
+
} catch (e) {
|
|
32
|
+
throw ErrorStorageClientNotInitialized;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* **Download files from cloud storage**
|
|
38
|
+
*
|
|
39
|
+
* @param {string} keys - Keys of files
|
|
40
|
+
* @returns {Promise<File>} - Downloaded file
|
|
41
|
+
*/
|
|
42
|
+
public async downloadFiles(keys: string[], bucket: string): Promise<any[]> {
|
|
43
|
+
const isBucketExists = await this.client.bucketExists(bucket);
|
|
44
|
+
if (!isBucketExists) {
|
|
45
|
+
throw ErrorStorageBucketNotFound;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return Promise.all(
|
|
49
|
+
keys.map(async (key) => {
|
|
50
|
+
try {
|
|
51
|
+
const response = await this.client.getObject(bucket, key);
|
|
52
|
+
const content = response?.read();
|
|
53
|
+
|
|
54
|
+
return { key, content: JSON.parse(content?.toString('utf-8') || '') };
|
|
55
|
+
} catch (e) {
|
|
56
|
+
throw ErrorStorageFileNotFound;
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* **Download files from cloud storage.*
|
|
64
|
+
*
|
|
65
|
+
* @param {string} url - URL to the file
|
|
66
|
+
* @returns {Promise<File>} - Downloaded file
|
|
67
|
+
*/
|
|
68
|
+
public static async downloadFileFromUrl(url: string): Promise<any> {
|
|
69
|
+
if (!isValidUrl(url)) {
|
|
70
|
+
throw ErrorInvalidUrl;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const { data, status } = await axios.get(url, {
|
|
75
|
+
headers: {
|
|
76
|
+
'Content-Type': 'application/json',
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (status !== HttpStatus.OK) {
|
|
81
|
+
throw ErrorStorageFileNotFound;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return data;
|
|
85
|
+
} catch (e) {
|
|
86
|
+
throw ErrorStorageFileNotFound;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* **Upload file to cloud storage**
|
|
92
|
+
*
|
|
93
|
+
* @param {File[]} files - Files to upload
|
|
94
|
+
* @param {string} bucket - Bucket name
|
|
95
|
+
* @returns {Promise<UploadFile>} - Uploaded file with key/hash
|
|
96
|
+
*/
|
|
97
|
+
public async uploadFiles(
|
|
98
|
+
files: any[],
|
|
99
|
+
bucket: string
|
|
100
|
+
): Promise<UploadFile[]> {
|
|
101
|
+
const isBucketExists = await this.client.bucketExists(bucket);
|
|
102
|
+
if (!isBucketExists) {
|
|
103
|
+
throw ErrorStorageBucketNotFound;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return Promise.all(
|
|
107
|
+
files.map(async (file) => {
|
|
108
|
+
const content = JSON.stringify(file);
|
|
109
|
+
|
|
110
|
+
const hash = crypto.createHash('sha1').update(content).digest('hex');
|
|
111
|
+
const key = hash;
|
|
112
|
+
|
|
113
|
+
try {
|
|
114
|
+
await this.client.putObject(bucket, key, content, {
|
|
115
|
+
'Content-Type': 'application/json',
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return { key, hash };
|
|
119
|
+
} catch (e) {
|
|
120
|
+
throw ErrorStorageFileNotUploaded;
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
);
|
|
124
|
+
}
|
|
3
125
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const getS3Instance = (storageAccessData: StorageAccessData): AWS.S3 => {
|
|
13
|
-
AWS.config.update({
|
|
14
|
-
accessKeyId: storageAccessData.accessKeyId,
|
|
15
|
-
secretAccessKey: storageAccessData.secretAccessKey,
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
const s3 = new AWS.S3({
|
|
19
|
-
endpoint: storageAccessData.endpoint,
|
|
20
|
-
region: storageAccessData.region,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
return s3;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* **Get bucket name**
|
|
28
|
-
*
|
|
29
|
-
* @param {StorageAccessData} storageAccessData - Cloud storage access data
|
|
30
|
-
* @param {boolean} isPublic - Whether to return public bucket, or private bucket.
|
|
31
|
-
* @returns {string} - Bucket name
|
|
32
|
-
*/
|
|
33
|
-
const getBucket = (
|
|
34
|
-
storageAccessData: StorageAccessData,
|
|
35
|
-
isPublic: boolean
|
|
36
|
-
): string => {
|
|
37
|
-
return isPublic ? storageAccessData.publicBucket : storageAccessData.bucket;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* **Get public URL of the object**
|
|
42
|
-
*
|
|
43
|
-
* @param {StorageAccessData} storageAccessData - Cloud storage access data
|
|
44
|
-
* @param {string} key - Key of the object
|
|
45
|
-
* @returns {string} - The public URL of the object
|
|
46
|
-
*/
|
|
47
|
-
export const getPublicURL = (
|
|
48
|
-
storageAccessData: StorageAccessData,
|
|
49
|
-
key: string
|
|
50
|
-
): string => {
|
|
51
|
-
return `https://${storageAccessData.publicBucket}.s3.amazonaws.com/${key}`;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* **Parse object key from URL**
|
|
56
|
-
*
|
|
57
|
-
* @param {string} url - URL to parse
|
|
58
|
-
* @returns {string} - The key of the object
|
|
59
|
-
*/
|
|
60
|
-
export const getKeyFromURL = (url: string): string => {
|
|
61
|
-
if (url.startsWith('https')) {
|
|
62
|
-
// URL is fully qualified URL. Let's split it and try to retrieve key from last part of it.
|
|
63
|
-
const keyParts = url.split('/');
|
|
64
|
-
const key = keyParts[keyParts.length - 1];
|
|
65
|
-
|
|
66
|
-
return key;
|
|
126
|
+
/**
|
|
127
|
+
* **Checks if a bucket exists**
|
|
128
|
+
*
|
|
129
|
+
* @param {string} bucket - Name of the bucket
|
|
130
|
+
* @returns {Promise<boolean>} - True if bucket exists, false otherwise
|
|
131
|
+
*/
|
|
132
|
+
public async bucketExists(bucket: string): Promise<boolean> {
|
|
133
|
+
return this.client.bucketExists(bucket);
|
|
67
134
|
}
|
|
68
135
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return data;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* **Upload result to cloud storage**
|
|
103
|
-
*
|
|
104
|
-
* @param {StorageAccessData} storageAccessData - Cloud storage access data
|
|
105
|
-
* @param {Result} result - Result to upload
|
|
106
|
-
* @param {string} publicKey - Public key to encrypt data if necessary
|
|
107
|
-
* @param {boolean} _encrypt - Whether to encrypt the result, or not
|
|
108
|
-
* @param {boolean} isPublic - Whether to use public bucket, or private bucket
|
|
109
|
-
* @returns {Promise<UploadResult>} - Uploaded result with key/hash
|
|
110
|
-
*/
|
|
111
|
-
export const upload = async (
|
|
112
|
-
storageAccessData: StorageAccessData,
|
|
113
|
-
result: Result,
|
|
114
|
-
publicKey: string,
|
|
115
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
116
|
-
encrypt = true,
|
|
117
|
-
isPublic = false
|
|
118
|
-
): Promise<UploadResult> => {
|
|
119
|
-
const s3 = getS3Instance(storageAccessData);
|
|
120
|
-
|
|
121
|
-
const content = JSON.stringify(result);
|
|
122
|
-
|
|
123
|
-
const hash = crypto.createHash('sha1').update(content).digest('hex');
|
|
124
|
-
const key = `s3${hash}`;
|
|
125
|
-
|
|
126
|
-
const params = {
|
|
127
|
-
Bucket: getBucket(storageAccessData, isPublic),
|
|
128
|
-
Key: key,
|
|
129
|
-
Body: content,
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
await s3.putObject(params).promise();
|
|
133
|
-
|
|
134
|
-
return { key, hash };
|
|
135
|
-
};
|
|
136
|
+
/**
|
|
137
|
+
* **Checks if a bucket exists**
|
|
138
|
+
*
|
|
139
|
+
* @param {string} bucket - Name of the bucket
|
|
140
|
+
* @returns {Promise<string[]>} - A list of filenames with their extensions in the bucket
|
|
141
|
+
*/
|
|
142
|
+
public async listObjects(bucket: string): Promise<string[]> {
|
|
143
|
+
const isBucketExists = await this.client.bucketExists(bucket);
|
|
144
|
+
if (!isBucketExists) {
|
|
145
|
+
throw ErrorStorageBucketNotFound;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
const keys: string[] = [];
|
|
151
|
+
const stream = this.client.listObjectsV2(bucket, '', true, '');
|
|
152
|
+
|
|
153
|
+
stream.on('data', (obj) => keys.push(obj.name));
|
|
154
|
+
stream.on('error', reject);
|
|
155
|
+
stream.on('end', () => {
|
|
156
|
+
resolve(keys);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
} catch (e) {
|
|
160
|
+
throw new Error(String(e));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|