@human-protocol/sdk 1.0.0 → 1.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.
- package/README.md +9 -0
- package/example/simple-existing-job.ts +86 -0
- package/example/simple-new-job-public.ts +74 -0
- package/example/simple-new-job.ts +72 -0
- package/package.json +9 -4
- package/src/error.ts +5 -0
- package/src/job.ts +215 -35
- package/src/storage.ts +5 -4
- package/src/types.ts +13 -0
- package/src/utils.ts +67 -1
- package/test/job.test.ts +716 -0
- package/test/utils/constants.ts +30 -0
- package/test/utils/manifest.ts +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { Job } from '../src';
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_GAS_PAYER_PRIVKEY,
|
|
5
|
+
DEFAULT_HMTOKEN_ADDR,
|
|
6
|
+
REPUTATION_ORACLE_PRIVKEY,
|
|
7
|
+
WORKER1_ADDR,
|
|
8
|
+
WORKER2_ADDR,
|
|
9
|
+
} from '../test/utils/constants';
|
|
10
|
+
import { manifest } from '../test/utils/manifest';
|
|
11
|
+
import * as dotenv from 'dotenv';
|
|
12
|
+
|
|
13
|
+
dotenv.config();
|
|
14
|
+
|
|
15
|
+
const main = async () => {
|
|
16
|
+
// Create job object
|
|
17
|
+
const newJob = new Job({
|
|
18
|
+
gasPayer: DEFAULT_GAS_PAYER_PRIVKEY,
|
|
19
|
+
reputationOracle: REPUTATION_ORACLE_PRIVKEY,
|
|
20
|
+
manifest: manifest,
|
|
21
|
+
hmTokenAddr: DEFAULT_HMTOKEN_ADDR,
|
|
22
|
+
logLevel: 'debug',
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Initialize new job object
|
|
26
|
+
await newJob.initialize();
|
|
27
|
+
|
|
28
|
+
// Launch the job
|
|
29
|
+
await newJob.launch();
|
|
30
|
+
|
|
31
|
+
// Access the existing job
|
|
32
|
+
const job = new Job({
|
|
33
|
+
gasPayer: DEFAULT_GAS_PAYER_PRIVKEY,
|
|
34
|
+
reputationOracle: REPUTATION_ORACLE_PRIVKEY,
|
|
35
|
+
manifest: manifest,
|
|
36
|
+
hmTokenAddr: DEFAULT_HMTOKEN_ADDR,
|
|
37
|
+
factoryAddr: newJob.contractData?.factoryAddr,
|
|
38
|
+
escrowAddr: newJob.contractData?.escrowAddr,
|
|
39
|
+
storageAccessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
40
|
+
storageSecretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
41
|
+
storageEndpoint: process.env.AWS_ENDPOINT,
|
|
42
|
+
storageBucket: process.env.AWS_BUCKET,
|
|
43
|
+
storagePublicBucket: process.env.AWS_PUBLIC_BUCKET,
|
|
44
|
+
logLevel: 'debug',
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Initialize the job object
|
|
48
|
+
await job.initialize();
|
|
49
|
+
|
|
50
|
+
// Setup the job
|
|
51
|
+
await job.setup();
|
|
52
|
+
|
|
53
|
+
console.log(
|
|
54
|
+
`Status: ${await job.status()}, Balance: ${(
|
|
55
|
+
await job.balance()
|
|
56
|
+
)?.toString()}`
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Bulk payout workers
|
|
60
|
+
await job.bulkPayout(
|
|
61
|
+
[
|
|
62
|
+
{
|
|
63
|
+
address: WORKER1_ADDR,
|
|
64
|
+
amount: 70,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
address: WORKER2_ADDR,
|
|
68
|
+
amount: 30,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
{
|
|
72
|
+
result: 'result',
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Complete the job
|
|
77
|
+
await job.complete();
|
|
78
|
+
|
|
79
|
+
console.log(
|
|
80
|
+
`Status: ${await job.status()}, Balance: ${(
|
|
81
|
+
await job.balance()
|
|
82
|
+
)?.toString()}`
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
main();
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { Job } from '../src';
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_GAS_PAYER_PRIVKEY,
|
|
5
|
+
DEFAULT_HMTOKEN_ADDR,
|
|
6
|
+
REPUTATION_ORACLE_PRIVKEY,
|
|
7
|
+
WORKER1_ADDR,
|
|
8
|
+
WORKER2_ADDR,
|
|
9
|
+
} from '../test/utils/constants';
|
|
10
|
+
import { manifest } from '../test/utils/manifest';
|
|
11
|
+
import * as dotenv from 'dotenv';
|
|
12
|
+
|
|
13
|
+
dotenv.config();
|
|
14
|
+
|
|
15
|
+
const main = async () => {
|
|
16
|
+
// Create job object
|
|
17
|
+
const job = new Job({
|
|
18
|
+
gasPayer: DEFAULT_GAS_PAYER_PRIVKEY,
|
|
19
|
+
reputationOracle: REPUTATION_ORACLE_PRIVKEY,
|
|
20
|
+
manifest: manifest,
|
|
21
|
+
hmTokenAddr: DEFAULT_HMTOKEN_ADDR,
|
|
22
|
+
storageAccessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
23
|
+
storageSecretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
24
|
+
storageEndpoint: process.env.AWS_ENDPOINT,
|
|
25
|
+
storageBucket: process.env.AWS_BUCKET,
|
|
26
|
+
storagePublicBucket: process.env.AWS_PUBLIC_BUCKET,
|
|
27
|
+
logLevel: 'debug',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Initialize new job
|
|
31
|
+
await job.initialize();
|
|
32
|
+
|
|
33
|
+
// Launch the job
|
|
34
|
+
await job.launch();
|
|
35
|
+
|
|
36
|
+
// Setup the job
|
|
37
|
+
await job.setup();
|
|
38
|
+
|
|
39
|
+
console.log(
|
|
40
|
+
`Status: ${await job.status()}, Balance: ${(
|
|
41
|
+
await job.balance()
|
|
42
|
+
)?.toString()}`
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Bulk payout workers
|
|
46
|
+
await job.bulkPayout(
|
|
47
|
+
[
|
|
48
|
+
{
|
|
49
|
+
address: WORKER1_ADDR,
|
|
50
|
+
amount: 70,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
address: WORKER2_ADDR,
|
|
54
|
+
amount: 30,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
{
|
|
58
|
+
result: 'result',
|
|
59
|
+
},
|
|
60
|
+
false,
|
|
61
|
+
true
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Complete the job
|
|
65
|
+
await job.complete();
|
|
66
|
+
|
|
67
|
+
console.log(
|
|
68
|
+
`Status: ${await job.status()}, Balance: ${(
|
|
69
|
+
await job.balance()
|
|
70
|
+
)?.toString()}`
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
main();
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { Job } from '../src';
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_GAS_PAYER_PRIVKEY,
|
|
5
|
+
DEFAULT_HMTOKEN_ADDR,
|
|
6
|
+
REPUTATION_ORACLE_PRIVKEY,
|
|
7
|
+
WORKER1_ADDR,
|
|
8
|
+
WORKER2_ADDR,
|
|
9
|
+
} from '../test/utils/constants';
|
|
10
|
+
import { manifest } from '../test/utils/manifest';
|
|
11
|
+
import * as dotenv from 'dotenv';
|
|
12
|
+
|
|
13
|
+
dotenv.config();
|
|
14
|
+
|
|
15
|
+
const main = async () => {
|
|
16
|
+
// Create job object
|
|
17
|
+
const job = new Job({
|
|
18
|
+
gasPayer: DEFAULT_GAS_PAYER_PRIVKEY,
|
|
19
|
+
reputationOracle: REPUTATION_ORACLE_PRIVKEY,
|
|
20
|
+
manifest: manifest,
|
|
21
|
+
hmTokenAddr: DEFAULT_HMTOKEN_ADDR,
|
|
22
|
+
storageAccessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
23
|
+
storageSecretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
24
|
+
storageEndpoint: process.env.AWS_ENDPOINT,
|
|
25
|
+
storageBucket: process.env.AWS_BUCKET,
|
|
26
|
+
storagePublicBucket: process.env.AWS_PUBLIC_BUCKET,
|
|
27
|
+
logLevel: 'debug',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Initialize new job
|
|
31
|
+
await job.initialize();
|
|
32
|
+
|
|
33
|
+
// Launch the job
|
|
34
|
+
await job.launch();
|
|
35
|
+
|
|
36
|
+
// Setup the job
|
|
37
|
+
await job.setup();
|
|
38
|
+
|
|
39
|
+
console.log(
|
|
40
|
+
`Status: ${await job.status()}, Balance: ${(
|
|
41
|
+
await job.balance()
|
|
42
|
+
)?.toString()}`
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Bulk payout workers
|
|
46
|
+
await job.bulkPayout(
|
|
47
|
+
[
|
|
48
|
+
{
|
|
49
|
+
address: WORKER1_ADDR,
|
|
50
|
+
amount: 70,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
address: WORKER2_ADDR,
|
|
54
|
+
amount: 30,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
{
|
|
58
|
+
result: 'result',
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Complete the job
|
|
63
|
+
await job.complete();
|
|
64
|
+
|
|
65
|
+
console.log(
|
|
66
|
+
`Status: ${await job.status()}, Balance: ${(
|
|
67
|
+
await job.balance()
|
|
68
|
+
)?.toString()}`
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@human-protocol/sdk",
|
|
3
3
|
"description": "Human Protocol SDK",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.2",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
7
|
-
"dist"
|
|
7
|
+
"dist",
|
|
8
|
+
"example",
|
|
9
|
+
"test"
|
|
8
10
|
],
|
|
9
11
|
"main": "dist/index.js",
|
|
10
12
|
"types": "dist/index.d.ts",
|
|
@@ -12,7 +14,7 @@
|
|
|
12
14
|
"clean": "rm -rf ./dist",
|
|
13
15
|
"build": "npm run clean && tsc",
|
|
14
16
|
"prepublish": "npm run build",
|
|
15
|
-
"test": "
|
|
17
|
+
"test": "concurrently -k -s first -g --hide 0 \"yarn workspace @human-protocol/core local\" \"sleep 5 && jest --runInBand\"",
|
|
16
18
|
"lint": "eslint .",
|
|
17
19
|
"lint:fix": "eslint . --fix",
|
|
18
20
|
"format": "prettier --write '**/*.{ts,json}'"
|
|
@@ -36,12 +38,15 @@
|
|
|
36
38
|
]
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@human-protocol/core": "
|
|
41
|
+
"@human-protocol/core": "^1.0.11",
|
|
40
42
|
"aws-sdk": "^2.1255.0",
|
|
41
43
|
"crypto": "^1.0.1",
|
|
42
44
|
"dotenv": "^16.0.3",
|
|
43
45
|
"ethers": "^5.7.2",
|
|
44
46
|
"secp256k1": "^4.0.3",
|
|
45
47
|
"winston": "^3.8.2"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@human-protocol/core": "^1.0.11"
|
|
46
51
|
}
|
|
47
52
|
}
|
package/src/error.ts
CHANGED
|
@@ -36,3 +36,8 @@ export const ErrorHMTokenMissing = new Error('HMToken is missing');
|
|
|
36
36
|
export const ErrorStorageAccessDataMissing = new Error(
|
|
37
37
|
'Storage access data is missing'
|
|
38
38
|
);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @constant {Error} - The Staking contract is missing.
|
|
42
|
+
*/
|
|
43
|
+
export const ErrorStakingMissing = new Error('Staking contract is missing');
|
package/src/job.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
getEscrow,
|
|
21
21
|
getEscrowFactory,
|
|
22
22
|
getHmToken,
|
|
23
|
+
getStaking,
|
|
23
24
|
toFullDigit,
|
|
24
25
|
} from './utils';
|
|
25
26
|
import {
|
|
@@ -29,6 +30,7 @@ import {
|
|
|
29
30
|
ErrorJobNotLaunched,
|
|
30
31
|
ErrorManifestMissing,
|
|
31
32
|
ErrorReputationOracleMissing,
|
|
33
|
+
ErrorStakingMissing,
|
|
32
34
|
ErrorStorageAccessDataMissing,
|
|
33
35
|
} from './error';
|
|
34
36
|
import { createLogger } from './logger';
|
|
@@ -94,6 +96,7 @@ export class Job {
|
|
|
94
96
|
storageEndpoint,
|
|
95
97
|
storagePublicBucket,
|
|
96
98
|
storageBucket,
|
|
99
|
+
stakingAddr,
|
|
97
100
|
logLevel = 'info',
|
|
98
101
|
}: JobArguments) {
|
|
99
102
|
const provider = network
|
|
@@ -134,6 +137,7 @@ export class Job {
|
|
|
134
137
|
hmTokenAddr,
|
|
135
138
|
escrowAddr,
|
|
136
139
|
factoryAddr,
|
|
140
|
+
stakingAddr,
|
|
137
141
|
};
|
|
138
142
|
|
|
139
143
|
this.manifestData = { manifest };
|
|
@@ -142,8 +146,8 @@ export class Job {
|
|
|
142
146
|
accessKeyId: storageAccessKeyId || '',
|
|
143
147
|
secretAccessKey: storageSecretAccessKey || '',
|
|
144
148
|
endpoint: storageEndpoint,
|
|
145
|
-
publicBucket: storagePublicBucket ||
|
|
146
|
-
bucket: storageBucket ||
|
|
149
|
+
publicBucket: storagePublicBucket || DEFAULT_PUBLIC_BUCKET,
|
|
150
|
+
bucket: storageBucket || DEFAULT_BUCKET,
|
|
147
151
|
};
|
|
148
152
|
|
|
149
153
|
this._logger = createLogger(logLevel);
|
|
@@ -174,9 +178,21 @@ export class Job {
|
|
|
174
178
|
return false;
|
|
175
179
|
}
|
|
176
180
|
|
|
181
|
+
if (!this.contractData.stakingAddr) {
|
|
182
|
+
this._logError(new Error('Staking contract is missing'));
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
this._logger.info('Getting staking...');
|
|
187
|
+
this.contractData.staking = await getStaking(
|
|
188
|
+
this.contractData.stakingAddr,
|
|
189
|
+
this.providerData?.gasPayer
|
|
190
|
+
);
|
|
191
|
+
|
|
177
192
|
this._logger.info('Deploying escrow factory...');
|
|
178
193
|
this.contractData.factory = await deployEscrowFactory(
|
|
179
194
|
this.contractData.hmTokenAddr,
|
|
195
|
+
this.contractData.stakingAddr,
|
|
180
196
|
this.providerData?.gasPayer
|
|
181
197
|
);
|
|
182
198
|
this.contractData.factoryAddr = this.contractData.factory.address;
|
|
@@ -197,6 +213,31 @@ export class Job {
|
|
|
197
213
|
this.providerData?.gasPayer
|
|
198
214
|
);
|
|
199
215
|
|
|
216
|
+
this._logger.info('Checking if staking is configured...');
|
|
217
|
+
const stakingAddr = await this.contractData.factory.staking();
|
|
218
|
+
if (!stakingAddr) {
|
|
219
|
+
this._logError(new Error('Factory is not configured with staking'));
|
|
220
|
+
this.contractData.factory = undefined;
|
|
221
|
+
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
this._logger.info('Getting staking...');
|
|
225
|
+
this.contractData.staking = await getStaking(
|
|
226
|
+
stakingAddr,
|
|
227
|
+
this.providerData?.gasPayer
|
|
228
|
+
);
|
|
229
|
+
this.contractData.stakingAddr = stakingAddr;
|
|
230
|
+
|
|
231
|
+
this._logger.info('Checking if reward pool is configured...');
|
|
232
|
+
const rewardPoolAddr = await this.contractData.staking.rewardPool();
|
|
233
|
+
if (!rewardPoolAddr) {
|
|
234
|
+
this._logError(new Error('Staking is not configured with reward pool'));
|
|
235
|
+
this.contractData.staking = undefined;
|
|
236
|
+
this.contractData.factory = undefined;
|
|
237
|
+
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
200
241
|
this._logger.info('Checking if escrow exists in the factory...');
|
|
201
242
|
const hasEscrow = await this.contractData?.factory.hasEscrow(
|
|
202
243
|
this.contractData?.escrowAddr
|
|
@@ -204,6 +245,8 @@ export class Job {
|
|
|
204
245
|
|
|
205
246
|
if (!hasEscrow) {
|
|
206
247
|
this._logError(new Error('Factory does not contain the escrow'));
|
|
248
|
+
this.contractData.factory = undefined;
|
|
249
|
+
|
|
207
250
|
return false;
|
|
208
251
|
}
|
|
209
252
|
|
|
@@ -214,17 +257,34 @@ export class Job {
|
|
|
214
257
|
);
|
|
215
258
|
this._logger.info('Accessed the escrow successfully.');
|
|
216
259
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
manifestlink: {
|
|
220
|
-
url: await this.contractData?.escrow.manifestUrl(),
|
|
221
|
-
hash: await this.contractData?.escrow.manifestHash(),
|
|
222
|
-
},
|
|
223
|
-
};
|
|
260
|
+
const manifestUrl = await this.contractData?.escrow.manifestUrl();
|
|
261
|
+
const manifestHash = await this.contractData?.escrow.manifestHash();
|
|
224
262
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
263
|
+
if (
|
|
264
|
+
(!manifestUrl.length || !manifestHash.length) &&
|
|
265
|
+
!this.manifestData?.manifest
|
|
266
|
+
) {
|
|
267
|
+
this._logError(ErrorManifestMissing);
|
|
268
|
+
|
|
269
|
+
this.contractData.factory = undefined;
|
|
270
|
+
this.contractData.escrow = undefined;
|
|
271
|
+
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (manifestUrl.length && manifestHash.length) {
|
|
276
|
+
this.manifestData = {
|
|
277
|
+
...this.manifestData,
|
|
278
|
+
manifestlink: {
|
|
279
|
+
url: manifestUrl,
|
|
280
|
+
hash: manifestHash,
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
this.manifestData.manifest = (await this._download(
|
|
285
|
+
manifestUrl
|
|
286
|
+
)) as Manifest;
|
|
287
|
+
}
|
|
228
288
|
}
|
|
229
289
|
|
|
230
290
|
return true;
|
|
@@ -238,18 +298,13 @@ export class Job {
|
|
|
238
298
|
* @returns {Promise<boolean>} - True if the escrow is launched successfully.
|
|
239
299
|
*/
|
|
240
300
|
async launch(): Promise<boolean> {
|
|
241
|
-
if (!this.contractData || this.contractData.escrow) {
|
|
242
|
-
this._logError(ErrorJobAlreadyLaunched);
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
301
|
if (!this.contractData || !this.contractData.factory) {
|
|
247
302
|
this._logError(ErrorJobNotInitialized);
|
|
248
303
|
return false;
|
|
249
304
|
}
|
|
250
305
|
|
|
251
|
-
if (!this.
|
|
252
|
-
this._logError(
|
|
306
|
+
if (!this.contractData || this.contractData.escrow) {
|
|
307
|
+
this._logError(ErrorJobAlreadyLaunched);
|
|
253
308
|
return false;
|
|
254
309
|
}
|
|
255
310
|
|
|
@@ -269,7 +324,8 @@ export class Job {
|
|
|
269
324
|
const txResponse = await txReceipt?.wait();
|
|
270
325
|
|
|
271
326
|
const event = txResponse?.events?.find(
|
|
272
|
-
|
|
327
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
328
|
+
(event: any) => event.event === 'Launched'
|
|
273
329
|
);
|
|
274
330
|
|
|
275
331
|
const escrowAddr = event?.args?.[1];
|
|
@@ -281,21 +337,6 @@ export class Job {
|
|
|
281
337
|
this.providerData?.gasPayer
|
|
282
338
|
);
|
|
283
339
|
|
|
284
|
-
this._logger.info('Uploading manifest...');
|
|
285
|
-
const uploadResult = await this._upload(this.manifestData.manifest);
|
|
286
|
-
if (!uploadResult) {
|
|
287
|
-
this._logError(new Error('Error uploading manifest'));
|
|
288
|
-
return false;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
this.manifestData.manifestlink = {
|
|
292
|
-
url: uploadResult.key,
|
|
293
|
-
hash: uploadResult.hash,
|
|
294
|
-
};
|
|
295
|
-
this._logger.info(
|
|
296
|
-
`Uploaded manifest.\n\tKey: ${uploadResult.key}\n\tHash: ${uploadResult.hash}`
|
|
297
|
-
);
|
|
298
|
-
|
|
299
340
|
return (
|
|
300
341
|
(await this.status()) == EscrowStatus.Launched &&
|
|
301
342
|
(await this.balance())?.toNumber() === 0
|
|
@@ -316,6 +357,16 @@ export class Job {
|
|
|
316
357
|
return false;
|
|
317
358
|
}
|
|
318
359
|
|
|
360
|
+
if (!this.manifestData || !this.manifestData.manifest) {
|
|
361
|
+
this._logError(ErrorManifestMissing);
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (this.manifestData.manifestlink) {
|
|
366
|
+
this._logError(new Error('Job is already setup'));
|
|
367
|
+
return false;
|
|
368
|
+
}
|
|
369
|
+
|
|
319
370
|
if (!this.contractData.hmToken) {
|
|
320
371
|
this._logError(ErrorHMTokenMissing);
|
|
321
372
|
return false;
|
|
@@ -358,6 +409,21 @@ export class Job {
|
|
|
358
409
|
}
|
|
359
410
|
this._logger.info('HMT transferred.');
|
|
360
411
|
|
|
412
|
+
this._logger.info('Uploading manifest...');
|
|
413
|
+
const uploadResult = await this._upload(this.manifestData.manifest);
|
|
414
|
+
if (!uploadResult) {
|
|
415
|
+
this._logError(new Error('Error uploading manifest'));
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
this.manifestData.manifestlink = {
|
|
420
|
+
url: uploadResult.key,
|
|
421
|
+
hash: uploadResult.hash,
|
|
422
|
+
};
|
|
423
|
+
this._logger.info(
|
|
424
|
+
`Uploaded manifest.\n\tKey: ${uploadResult.key}\n\tHash: ${uploadResult.hash}`
|
|
425
|
+
);
|
|
426
|
+
|
|
361
427
|
this._logger.info('Setting up the escrow...');
|
|
362
428
|
const contractSetup = await this._raffleExecute(
|
|
363
429
|
this.contractData.escrow,
|
|
@@ -609,6 +675,120 @@ export class Job {
|
|
|
609
675
|
return (await this.status()) === EscrowStatus.Complete;
|
|
610
676
|
}
|
|
611
677
|
|
|
678
|
+
/**
|
|
679
|
+
* **Stake HMTokens**
|
|
680
|
+
*
|
|
681
|
+
* @param {number} amount - Amount to stake
|
|
682
|
+
* @returns {Promise<boolean>} - True if the token is staked
|
|
683
|
+
*/
|
|
684
|
+
async stake(amount: number) {
|
|
685
|
+
if (!this.contractData?.staking) {
|
|
686
|
+
this._logError(ErrorStakingMissing);
|
|
687
|
+
return false;
|
|
688
|
+
}
|
|
689
|
+
if (!this.contractData.hmToken) {
|
|
690
|
+
this._logError(ErrorHMTokenMissing);
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
const approved = await this.contractData.hmToken.approve(
|
|
695
|
+
this.contractData.staking.address,
|
|
696
|
+
toFullDigit(amount)
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
if (!approved) {
|
|
700
|
+
this._logError(new Error('Error approving HMTokens for staking'));
|
|
701
|
+
return false;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
return await this._raffleExecute(
|
|
705
|
+
this.contractData.staking,
|
|
706
|
+
'stake',
|
|
707
|
+
toFullDigit(amount)
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* **Unstake HMTokens**
|
|
713
|
+
*
|
|
714
|
+
* @param {number} amount - Amount to unstake
|
|
715
|
+
* @returns {Promise<boolean>} - True if the token is unstaked
|
|
716
|
+
*/
|
|
717
|
+
async unstake(amount: number) {
|
|
718
|
+
if (!this.contractData?.staking) {
|
|
719
|
+
this._logError(ErrorStakingMissing);
|
|
720
|
+
return false;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
return await this._raffleExecute(
|
|
724
|
+
this.contractData.staking,
|
|
725
|
+
'unstake',
|
|
726
|
+
toFullDigit(amount)
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* **Withdraw unstaked HMTokens**
|
|
732
|
+
*
|
|
733
|
+
* @returns {Promise<boolean>} - True if the token is withdrawn
|
|
734
|
+
*/
|
|
735
|
+
async withdraw() {
|
|
736
|
+
if (!this.contractData?.staking) {
|
|
737
|
+
this._logError(ErrorStakingMissing);
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return await this._raffleExecute(this.contractData.staking, 'withdraw');
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* **Allocate HMTokens staked to the job**
|
|
746
|
+
*
|
|
747
|
+
* @param amount - Amount to allocate
|
|
748
|
+
* @returns {Promise<boolean>} - True if the token is allocated
|
|
749
|
+
*/
|
|
750
|
+
async allocate(amount: number) {
|
|
751
|
+
if (!this.contractData?.staking) {
|
|
752
|
+
this._logError(ErrorStakingMissing);
|
|
753
|
+
return false;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
if (!this.contractData.escrowAddr) {
|
|
757
|
+
this._logError(ErrorJobNotLaunched);
|
|
758
|
+
return false;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
return await this._raffleExecute(
|
|
762
|
+
this.contractData.staking,
|
|
763
|
+
'allocate',
|
|
764
|
+
this.contractData.escrowAddr,
|
|
765
|
+
toFullDigit(amount)
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* **Unallocate HMTokens from the job**
|
|
771
|
+
*
|
|
772
|
+
* @returns {Promise<boolean>} - True if the token is unallocated.
|
|
773
|
+
*/
|
|
774
|
+
async closeAllocation() {
|
|
775
|
+
if (!this.contractData?.staking) {
|
|
776
|
+
this._logError(ErrorStakingMissing);
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (!this.contractData.escrowAddr) {
|
|
781
|
+
this._logError(ErrorJobNotLaunched);
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
return await this._raffleExecute(
|
|
786
|
+
this.contractData.staking,
|
|
787
|
+
'closeAllocation',
|
|
788
|
+
this.contractData.escrowAddr
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
|
|
612
792
|
/**
|
|
613
793
|
* **Get current status of the escrow**
|
|
614
794
|
*
|
package/src/storage.ts
CHANGED
|
@@ -76,7 +76,7 @@ export const getKeyFromURL = (url: string): string => {
|
|
|
76
76
|
* @param {StorageAccessData} storageAccessData - Cloud storage access data
|
|
77
77
|
* @param {string} key - Key of result object
|
|
78
78
|
* @param {string} privateKey - Private key to decode encrypted content
|
|
79
|
-
* @param {
|
|
79
|
+
* @param {boolean} isPublic - Whether the objest is using public bucket, or private bucket
|
|
80
80
|
* @returns {Promise<Result>} - Downloaded result
|
|
81
81
|
*/
|
|
82
82
|
export const download = async (
|
|
@@ -104,14 +104,15 @@ export const download = async (
|
|
|
104
104
|
* @param {StorageAccessData} storageAccessData - Cloud storage access data
|
|
105
105
|
* @param {Result} result - Result to upload
|
|
106
106
|
* @param {string} publicKey - Public key to encrypt data if necessary
|
|
107
|
-
* @param {
|
|
108
|
-
* @param {
|
|
107
|
+
* @param {boolean} _encrypt - Whether to encrypt the result, or not
|
|
108
|
+
* @param {boolean} isPublic - Whether to use public bucket, or private bucket
|
|
109
109
|
* @returns {Promise<UploadResult>} - Uploaded result with key/hash
|
|
110
110
|
*/
|
|
111
111
|
export const upload = async (
|
|
112
112
|
storageAccessData: StorageAccessData,
|
|
113
113
|
result: Result,
|
|
114
114
|
publicKey: string,
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
115
116
|
encrypt = true,
|
|
116
117
|
isPublic = false
|
|
117
118
|
): Promise<UploadResult> => {
|
|
@@ -128,7 +129,7 @@ export const upload = async (
|
|
|
128
129
|
Body: content,
|
|
129
130
|
};
|
|
130
131
|
|
|
131
|
-
await s3.putObject(params);
|
|
132
|
+
await s3.putObject(params).promise();
|
|
132
133
|
|
|
133
134
|
return { key, hash };
|
|
134
135
|
};
|