@super-protocol/sp-cli 0.0.2-beta.9 → 0.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 +134 -65
- package/bin/dev.js +1 -1
- package/dist/commands/account/get-sppi.d.ts +8 -0
- package/dist/commands/account/get-sppi.js +23 -0
- package/dist/commands/account/info.d.ts +1 -0
- package/dist/commands/account/info.js +5 -2
- package/dist/commands/auth/login.d.ts +4 -1
- package/dist/commands/auth/login.js +4 -2
- package/dist/commands/config/add.js +1 -16
- package/dist/commands/config/base.d.ts +1 -0
- package/dist/commands/config/base.js +22 -4
- package/dist/commands/config/create.js +1 -11
- package/dist/commands/config/list.js +20 -19
- package/dist/commands/files/download.js +8 -6
- package/dist/commands/files/upload.js +8 -6
- package/dist/commands/storage/base.js +3 -1
- package/dist/commands/storage/select.d.ts +4 -4
- package/dist/commands/storage/select.js +15 -21
- package/dist/commands/storage/show.d.ts +17 -0
- package/dist/commands/storage/show.js +36 -0
- package/dist/commands/workflows/extend-lease.d.ts +17 -0
- package/dist/commands/workflows/extend-lease.js +94 -0
- package/dist/config/config.schema.d.ts +9 -0
- package/dist/config/config.schema.js +5 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +3 -0
- package/dist/hooks/finally/shutdown-blockchain.d.ts +3 -0
- package/dist/hooks/finally/shutdown-blockchain.js +8 -0
- package/dist/lib/container.d.ts +1 -0
- package/dist/lib/container.js +23 -1
- package/dist/managers/account-manager.d.ts +1 -0
- package/dist/managers/account-manager.js +17 -13
- package/dist/managers/config-file-manager.d.ts +1 -1
- package/dist/managers/config-file-manager.js +16 -4
- package/dist/services/storage.service.d.ts +3 -1
- package/dist/services/storage.service.js +87 -44
- package/dist/utils/helper.d.ts +1 -0
- package/dist/utils/helper.js +1 -0
- package/dist/utils/progress.js +10 -2
- package/oclif.manifest.json +190 -151
- package/package.json +10 -6
- package/dist/config/resource.schema.d.ts +0 -31
- package/dist/config/resource.schema.js +0 -14
|
@@ -8,13 +8,13 @@ export default class FilesDownload extends BaseCommand {
|
|
|
8
8
|
// eslint-disable-next-line perfectionist/sort-objects
|
|
9
9
|
localDirectory: Args.string({ description: 'Path to save downloaded file', required: true }),
|
|
10
10
|
};
|
|
11
|
-
static description = '
|
|
11
|
+
static description = 'Download file or directory described in resource file';
|
|
12
12
|
static examples = [
|
|
13
13
|
'<%= config.bin %> <%= command.id %> ./resource.json ./pathToDownload ',
|
|
14
14
|
];
|
|
15
15
|
static flags = {
|
|
16
16
|
'maximum-concurrent': Flags.integer({
|
|
17
|
-
default: 1, description: 'Maximum concurrent pieces to
|
|
17
|
+
default: 1, description: 'Maximum concurrent pieces to download at once per transfer', max: 1000, min: 1,
|
|
18
18
|
}),
|
|
19
19
|
};
|
|
20
20
|
static help = 'Download and decrypt a file from the remote storage to <localPath> using resource file <resourcePath>';
|
|
@@ -25,20 +25,19 @@ export default class FilesDownload extends BaseCommand {
|
|
|
25
25
|
async run() {
|
|
26
26
|
const { args, flags } = await this.parse(FilesDownload);
|
|
27
27
|
const { providerClient } = this.container;
|
|
28
|
-
const
|
|
28
|
+
const storageService = new StorageService(providerClient, this.logger);
|
|
29
29
|
const progress = createProgressPrinter({
|
|
30
30
|
action: 'Download',
|
|
31
31
|
start: 'Downloading: ',
|
|
32
32
|
});
|
|
33
33
|
try {
|
|
34
|
-
await
|
|
34
|
+
await storageService.download({
|
|
35
35
|
downloadPath: args.localDirectory,
|
|
36
36
|
maximumConcurrent: flags['maximum-concurrent'],
|
|
37
37
|
resourcePath: args.resourceFile,
|
|
38
38
|
}, ({ current, key, total }) => {
|
|
39
39
|
progress.advance(key, current / total * 100, `Downloading: ${key} [${current}/${total}]`);
|
|
40
40
|
});
|
|
41
|
-
progress.finish();
|
|
42
41
|
}
|
|
43
42
|
catch (error) {
|
|
44
43
|
let reason = '';
|
|
@@ -48,6 +47,9 @@ export default class FilesDownload extends BaseCommand {
|
|
|
48
47
|
}
|
|
49
48
|
this.error(`Download aborted. Reason: ${reason}`);
|
|
50
49
|
}
|
|
51
|
-
|
|
50
|
+
finally {
|
|
51
|
+
progress.finish();
|
|
52
|
+
}
|
|
53
|
+
this.log('Download successfully completed');
|
|
52
54
|
}
|
|
53
55
|
}
|
|
@@ -6,7 +6,7 @@ export default class FilesUpload extends BaseCommand {
|
|
|
6
6
|
static args = {
|
|
7
7
|
path: Args.string({ description: 'file or directory to upload', required: true }),
|
|
8
8
|
};
|
|
9
|
-
static description = '
|
|
9
|
+
static description = 'Upload file or directory to remote storage';
|
|
10
10
|
static examples = [
|
|
11
11
|
'<%= config.bin %> <%= command.id %> ./file.txt',
|
|
12
12
|
];
|
|
@@ -45,24 +45,23 @@ export default class FilesUpload extends BaseCommand {
|
|
|
45
45
|
async run() {
|
|
46
46
|
const { args, flags } = await this.parse(FilesUpload);
|
|
47
47
|
const { providerClient } = this.container;
|
|
48
|
-
const
|
|
48
|
+
const storageService = new StorageService(providerClient, this.logger);
|
|
49
49
|
const progress = createProgressPrinter({
|
|
50
50
|
action: 'Upload',
|
|
51
51
|
start: 'Uploading: ',
|
|
52
52
|
});
|
|
53
53
|
try {
|
|
54
|
-
await
|
|
54
|
+
await storageService.upload({
|
|
55
55
|
localPath: args.path,
|
|
56
56
|
maximumConcurrent: flags['maximum-concurrent'],
|
|
57
57
|
metadataPath: flags.metadata,
|
|
58
58
|
outputPath: flags.output,
|
|
59
59
|
remotePath: flags.filename,
|
|
60
60
|
sync: flags.sync,
|
|
61
|
-
withEncryption: flags['skip-encryption'],
|
|
61
|
+
withEncryption: !flags['skip-encryption'],
|
|
62
62
|
}, ({ current, key, total }) => {
|
|
63
63
|
progress.advance(key, current / total * 100, `Uploading: ${key} [${current}/${total}]`);
|
|
64
64
|
});
|
|
65
|
-
progress.finish();
|
|
66
65
|
}
|
|
67
66
|
catch (error) {
|
|
68
67
|
let reason = '';
|
|
@@ -72,6 +71,9 @@ export default class FilesUpload extends BaseCommand {
|
|
|
72
71
|
}
|
|
73
72
|
this.error(`Upload aborted. Reason: ${reason}`);
|
|
74
73
|
}
|
|
75
|
-
|
|
74
|
+
finally {
|
|
75
|
+
progress.finish();
|
|
76
|
+
}
|
|
77
|
+
this.log('Upload successfully completed');
|
|
76
78
|
}
|
|
77
79
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { password, select, text } from '@clack/prompts';
|
|
2
2
|
import { StorageType } from '@super-protocol/provider-client';
|
|
3
3
|
import { BaseCommand } from '../../commands/base.js';
|
|
4
|
+
import { S3_REGION } from '../../constants.js';
|
|
4
5
|
import { StorageService } from '../../services/storage.service.js';
|
|
5
6
|
export class BaseStorageCommand extends BaseCommand {
|
|
6
7
|
currentDir = process.cwd();
|
|
@@ -12,7 +13,7 @@ export class BaseStorageCommand extends BaseCommand {
|
|
|
12
13
|
this.storageService = new StorageService(providerClient, this.logger);
|
|
13
14
|
}
|
|
14
15
|
async promptS3Credentials() {
|
|
15
|
-
const region =
|
|
16
|
+
const region = S3_REGION;
|
|
16
17
|
const readAccessKeyId = this.ensurePromptValue(await text({
|
|
17
18
|
message: 'Read access key ID',
|
|
18
19
|
validate(value) {
|
|
@@ -61,6 +62,7 @@ export class BaseStorageCommand extends BaseCommand {
|
|
|
61
62
|
})).trim();
|
|
62
63
|
const prefix = this.ensurePromptValue(await text({
|
|
63
64
|
defaultValue: '/',
|
|
65
|
+
initialValue: '/',
|
|
64
66
|
message: 'Prefix',
|
|
65
67
|
validate(value) {
|
|
66
68
|
return value ? undefined : 'Prefix is required';
|
|
@@ -2,8 +2,8 @@ import { BaseStorageCommand } from './base.js';
|
|
|
2
2
|
export default class StorageSelect extends BaseStorageCommand<typeof StorageSelect> {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
run(): Promise<{
|
|
6
|
+
label: string;
|
|
7
|
+
selectedStorageId: string;
|
|
8
|
+
}>;
|
|
9
9
|
}
|
|
@@ -1,38 +1,32 @@
|
|
|
1
1
|
import { select } from '@clack/prompts';
|
|
2
|
-
import { Flags } from '@oclif/core';
|
|
3
2
|
import { StoragesUndefinedError } from '../../services/storage.service.js';
|
|
4
3
|
import { BaseStorageCommand } from './base.js';
|
|
5
4
|
export default class StorageSelect extends BaseStorageCommand {
|
|
6
5
|
static description = 'Select a storage that will be used by subsequent commands.';
|
|
7
6
|
static examples = [
|
|
8
7
|
'<%= config.bin %> storage select',
|
|
9
|
-
'<%= config.bin %> storage select --id=2de3e3a4-0000-1111-2222-333344445555',
|
|
10
8
|
];
|
|
11
|
-
static flags = {
|
|
12
|
-
id: Flags.string({
|
|
13
|
-
char: 'i',
|
|
14
|
-
description: 'Storage ID to select',
|
|
15
|
-
}),
|
|
16
|
-
};
|
|
17
9
|
async run() {
|
|
18
|
-
const { flags } = await this.parse(StorageSelect);
|
|
19
10
|
try {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
})),
|
|
29
|
-
}));
|
|
30
|
-
}
|
|
11
|
+
const storages = await this.storageService.requestStorages();
|
|
12
|
+
const storageId = this.ensurePromptValue(await select({
|
|
13
|
+
message: 'Select storage',
|
|
14
|
+
options: storages.map(storage => ({
|
|
15
|
+
label: this.storageService.getLabel(storage),
|
|
16
|
+
value: storage.id,
|
|
17
|
+
})),
|
|
18
|
+
}));
|
|
31
19
|
if (!storageId) {
|
|
32
20
|
this.error('Storage ID is required');
|
|
33
21
|
}
|
|
22
|
+
const storage = storages.find(storage => storage.id === storageId);
|
|
23
|
+
if (!storage) {
|
|
24
|
+
this.error(`Storage with ID: ${storageId} not found `);
|
|
25
|
+
}
|
|
26
|
+
const label = this.storageService.getLabel(storage);
|
|
34
27
|
await this.storageService.saveStorage(storageId);
|
|
35
|
-
this.log(`Selected storage: ${
|
|
28
|
+
this.log(`Selected storage: ${label}`);
|
|
29
|
+
return { label, selectedStorageId: storageId };
|
|
36
30
|
}
|
|
37
31
|
catch (error) {
|
|
38
32
|
if (error instanceof StoragesUndefinedError) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseStorageCommand } from './base.js';
|
|
2
|
+
export default class StorageShow extends BaseStorageCommand<typeof StorageShow> {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
run(): Promise<{
|
|
6
|
+
bucket: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
id: string;
|
|
9
|
+
isCentralized: boolean;
|
|
10
|
+
prefix: string;
|
|
11
|
+
s3Credentials?: import("@super-protocol/provider-client").components["schemas"]["S3CredentialsResponseDto"];
|
|
12
|
+
storageType: import("@super-protocol/provider-client").components["schemas"]["StorageType"];
|
|
13
|
+
storjCredentials?: import("@super-protocol/provider-client").components["schemas"]["StorJCredentialsResponseDto"];
|
|
14
|
+
updatedAt: string;
|
|
15
|
+
userId: string;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { StorageType } from '@super-protocol/provider-client';
|
|
2
|
+
import { BaseStorageCommand } from './base.js';
|
|
3
|
+
const stripString = (str, chars) => {
|
|
4
|
+
if (str.length <= 2 * chars) {
|
|
5
|
+
return '*'.repeat(str.length);
|
|
6
|
+
}
|
|
7
|
+
return `${str.slice(0, chars)}...${str.slice(-1 * chars)}`;
|
|
8
|
+
};
|
|
9
|
+
export default class StorageShow extends BaseStorageCommand {
|
|
10
|
+
static description = 'Show current selected storage';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> <%= command.id %>',
|
|
13
|
+
];
|
|
14
|
+
async run() {
|
|
15
|
+
const storage = await this.storageService.getCurrentStorage();
|
|
16
|
+
this.log(`Current storage: ${storage.isCentralized ? 'Super Cloud' : 'Custom storage'}`);
|
|
17
|
+
this.log(`- ID: ${storage.id}`);
|
|
18
|
+
this.log(`- Storage type: ${storage.storageType}`);
|
|
19
|
+
this.log(`- Bucket: ${storage.bucket}`);
|
|
20
|
+
this.log(`- Prefix: ${storage.prefix}`);
|
|
21
|
+
this.log(' -- Credentials --');
|
|
22
|
+
if (storage.storageType === StorageType.S3) {
|
|
23
|
+
const { readAccessKeyId, readSecretAccessKey = '', writeAccessKeyId, writeSecretAccessKey = '' } = storage.s3Credentials || {};
|
|
24
|
+
this.log(` readAccessKeyId: ${readAccessKeyId}`);
|
|
25
|
+
this.log(` readSecretAccessKey: ${stripString(readSecretAccessKey, 5)}`);
|
|
26
|
+
this.log(` writeAccessKeyId: ${writeAccessKeyId}`);
|
|
27
|
+
this.log(` writeSecretAccessKey: ${stripString(writeSecretAccessKey, 5)}`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const { readAccessToken = '', writeAccessToken = '' } = storage.storjCredentials || {};
|
|
31
|
+
this.log(` readAccessToken: ${stripString(readAccessToken, 5)}`);
|
|
32
|
+
this.log(` writeAccessToken: ${stripString(writeAccessToken, 5)}`);
|
|
33
|
+
}
|
|
34
|
+
return storage;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SelectOptions } from '@clack/prompts';
|
|
2
|
+
import { BaseCommand } from '../base.js';
|
|
3
|
+
export default class WorkflowsExtendLease extends BaseCommand<typeof WorkflowsExtendLease> {
|
|
4
|
+
static args: {
|
|
5
|
+
orderId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
minutes: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
sppi: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
};
|
|
14
|
+
init(): Promise<void>;
|
|
15
|
+
run(): Promise<void>;
|
|
16
|
+
protected selectPrompt<Value>(options: SelectOptions<Value>): Promise<Value>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { select } from '@clack/prompts';
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { Orders } from '@super-protocol/sdk-js';
|
|
4
|
+
import { formatEther, parseEther } from 'viem/utils';
|
|
5
|
+
import { BaseCommand } from '../base.js';
|
|
6
|
+
export default class WorkflowsExtendLease extends BaseCommand {
|
|
7
|
+
static args = {
|
|
8
|
+
orderId: Args.string({ description: 'Order ID', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'Replenish deposit for a workflow to extend its lease time';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> <%= command.id %> <orderId> --sppi 1.5',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> <orderId> --minutes 120',
|
|
14
|
+
'<%= config.bin %> <%= command.id %> <orderId> --sppi 2 --yes',
|
|
15
|
+
];
|
|
16
|
+
static flags = {
|
|
17
|
+
minutes: Flags.integer({ description: 'Time to extend order in minutes (automatically calculates tokens)' }),
|
|
18
|
+
sppi: Flags.string({ description: 'SPPI token amount to add to the order' }),
|
|
19
|
+
yes: Flags.boolean({ char: 'y', default: false, description: 'Skip confirmation prompt' }),
|
|
20
|
+
};
|
|
21
|
+
async init() {
|
|
22
|
+
await super.init();
|
|
23
|
+
await this.container
|
|
24
|
+
.initConfigManager()
|
|
25
|
+
.initAccountManager()
|
|
26
|
+
.initBlockchainConnector()
|
|
27
|
+
.initProviderClient({ enableAuth: true })
|
|
28
|
+
.build();
|
|
29
|
+
}
|
|
30
|
+
async run() {
|
|
31
|
+
const { args, flags } = await this.parse(WorkflowsExtendLease);
|
|
32
|
+
const { providerClient } = this.container;
|
|
33
|
+
try {
|
|
34
|
+
this.logger.info(`Checking order ${args.orderId}`);
|
|
35
|
+
// Get actual per-hour price from blockchain
|
|
36
|
+
const amountPerHour = await Orders.calculateWorkflowPerHourPrice(args.orderId);
|
|
37
|
+
let tokenAmount;
|
|
38
|
+
let minutes;
|
|
39
|
+
if (flags.minutes) {
|
|
40
|
+
// Calculate token amount from minutes
|
|
41
|
+
tokenAmount = (BigInt(amountPerHour) * BigInt(flags.minutes)) / 60n;
|
|
42
|
+
minutes = flags.minutes;
|
|
43
|
+
}
|
|
44
|
+
else if (flags.sppi) {
|
|
45
|
+
// Use provided SPPI amount
|
|
46
|
+
tokenAmount = parseEther(flags.sppi);
|
|
47
|
+
minutes = Number((tokenAmount * 60n) / BigInt(amountPerHour));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.error('Please provide either --sppi or --minutes flag to specify the replenishment amount');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Confirmation prompt
|
|
54
|
+
const confirmed = this.flags.yes || await this.selectPrompt({
|
|
55
|
+
message: `Deposit will be replenished by ${formatEther(tokenAmount)} SPPI. Order time is extended by ${minutes} minutes. Confirm?`,
|
|
56
|
+
options: [
|
|
57
|
+
{ label: 'Yes', value: true },
|
|
58
|
+
{ label: 'No', value: false },
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
if (!confirmed) {
|
|
62
|
+
this.logger.info('Operation cancelled by user');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Call API to replenish deposit
|
|
66
|
+
const { data, error } = await providerClient.POST('/api/workflows/{orderId}/replenish', {
|
|
67
|
+
body: {
|
|
68
|
+
amount: tokenAmount.toString(),
|
|
69
|
+
},
|
|
70
|
+
params: {
|
|
71
|
+
path: {
|
|
72
|
+
orderId: args.orderId,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
if (error) {
|
|
77
|
+
this.logger.error({ error }, `Order ${args.orderId} was not replenished`);
|
|
78
|
+
this.error(`Failed to replenish deposit: ${error.message || 'Unknown error'}`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.logger.info({ data }, 'Deposit replenished successfully');
|
|
82
|
+
this.log('Deposit replenished successfully');
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
86
|
+
this.logger.error({ error }, `Order ${args.orderId} was not replenished`);
|
|
87
|
+
this.error(`Order ${args.orderId} was not replenished: ${errorMessage}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async selectPrompt(options) {
|
|
91
|
+
const result = await select(options);
|
|
92
|
+
return this.ensurePromptValue(result);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -6,6 +6,10 @@ export declare const accountSchema: Type.TObject<{
|
|
|
6
6
|
export declare const authSchema: Type.TObject<{
|
|
7
7
|
accessKey: Type.TString;
|
|
8
8
|
}>;
|
|
9
|
+
export declare const blockchainSchema: Type.TObject<{
|
|
10
|
+
blockchainUrl: Type.TOptional<Type.TString>;
|
|
11
|
+
contractAddress: Type.TString;
|
|
12
|
+
}>;
|
|
9
13
|
export declare const cliConfigSchema: Type.TObject<{
|
|
10
14
|
account: Type.TOptional<Type.TObject<{
|
|
11
15
|
address: Type.TString;
|
|
@@ -14,6 +18,10 @@ export declare const cliConfigSchema: Type.TObject<{
|
|
|
14
18
|
auth: Type.TOptional<Type.TObject<{
|
|
15
19
|
accessKey: Type.TString;
|
|
16
20
|
}>>;
|
|
21
|
+
blockchain: Type.TOptional<Type.TObject<{
|
|
22
|
+
blockchainUrl: Type.TOptional<Type.TString>;
|
|
23
|
+
contractAddress: Type.TString;
|
|
24
|
+
}>>;
|
|
17
25
|
cookies: Type.TOptional<Type.TUnknown>;
|
|
18
26
|
name: Type.TOptional<Type.TString>;
|
|
19
27
|
providerUrl: Type.TOptional<Type.TString>;
|
|
@@ -22,3 +30,4 @@ export declare const cliConfigSchema: Type.TObject<{
|
|
|
22
30
|
export type CliConfig = Static<typeof cliConfigSchema>;
|
|
23
31
|
export type Account = Static<typeof accountSchema>;
|
|
24
32
|
export type Auth = Static<typeof authSchema>;
|
|
33
|
+
export type Blockchain = Static<typeof blockchainSchema>;
|
|
@@ -6,9 +6,14 @@ export const accountSchema = Type.Object({
|
|
|
6
6
|
export const authSchema = Type.Object({
|
|
7
7
|
accessKey: Type.String(),
|
|
8
8
|
});
|
|
9
|
+
export const blockchainSchema = Type.Object({
|
|
10
|
+
blockchainUrl: Type.Optional(Type.String({ format: 'url' })),
|
|
11
|
+
contractAddress: Type.String({ pattern: '^0x[a-fA-F0-9]{40}$' }),
|
|
12
|
+
});
|
|
9
13
|
export const cliConfigSchema = Type.Object({
|
|
10
14
|
account: Type.Optional(accountSchema),
|
|
11
15
|
auth: Type.Optional(authSchema),
|
|
16
|
+
blockchain: Type.Optional(blockchainSchema),
|
|
12
17
|
cookies: Type.Optional(Type.Unknown()),
|
|
13
18
|
name: Type.Optional(Type.String()),
|
|
14
19
|
providerUrl: Type.Optional(Type.String({ format: 'url' })),
|
package/dist/constants.d.ts
CHANGED
|
@@ -3,3 +3,6 @@ export declare const DIR_ACCESS_PERMS = 448;
|
|
|
3
3
|
export declare const PROVIDER_URL = "https://api.dp.superprotocol.com";
|
|
4
4
|
export declare const REFRESH_TOKEN_URI = "/api/auth/refresh-access";
|
|
5
5
|
export declare const S3_ENDPOINT = "https://gateway.storjshare.io";
|
|
6
|
+
export declare const S3_REGION = "us-east-1";
|
|
7
|
+
export declare const DEFAULT_USER_CONFIG_FILE = "default.config.json";
|
|
8
|
+
export declare const DEFAULT_USER_CONFIG_NAME = "Default";
|
package/dist/constants.js
CHANGED
|
@@ -5,3 +5,6 @@ export const DIR_ACCESS_PERMS = 0o700;
|
|
|
5
5
|
export const PROVIDER_URL = 'https://api.dp.superprotocol.com';
|
|
6
6
|
export const REFRESH_TOKEN_URI = '/api/auth/refresh-access';
|
|
7
7
|
export const S3_ENDPOINT = 'https://gateway.storjshare.io';
|
|
8
|
+
export const S3_REGION = 'us-east-1';
|
|
9
|
+
export const DEFAULT_USER_CONFIG_FILE = 'default.config.json';
|
|
10
|
+
export const DEFAULT_USER_CONFIG_NAME = 'Default';
|
package/dist/lib/container.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export declare class AppContainer {
|
|
|
25
25
|
get providerClient(): ProviderClient;
|
|
26
26
|
build(): Promise<this>;
|
|
27
27
|
initAccountManager(rebuild?: boolean): this;
|
|
28
|
+
initBlockchainConnector(): this;
|
|
28
29
|
initConfigFileManager(rebuild?: boolean): this;
|
|
29
30
|
initConfigManager(rebuild?: boolean): this;
|
|
30
31
|
initProviderClient({ enableAuth, enableCookies, rebuild }?: {
|
package/dist/lib/container.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createProviderClient, loggerMiddleware, requestIdMiddleware, } from '@super-protocol/provider-client';
|
|
2
|
+
import { BlockchainConnector } from '@super-protocol/sdk-js';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { PROVIDER_URL } from '../constants.js';
|
|
4
5
|
import logger from '../logger.js';
|
|
@@ -75,6 +76,27 @@ export class AppContainer {
|
|
|
75
76
|
this._accountManager = accountManager;
|
|
76
77
|
}, rebuild);
|
|
77
78
|
}
|
|
79
|
+
initBlockchainConnector() {
|
|
80
|
+
this.initConfigManager();
|
|
81
|
+
return this.queueInit('blockchainConnector', async () => {
|
|
82
|
+
await this.waitFor('configManager');
|
|
83
|
+
let blockchainConfig = await this.configManager.get('blockchain');
|
|
84
|
+
if (!blockchainConfig) {
|
|
85
|
+
await this.waitFor('providerClient');
|
|
86
|
+
const { data, error } = await this.providerClient.GET('/api/config');
|
|
87
|
+
if (error || !data) {
|
|
88
|
+
throw new Error('Could not get configuration from provider');
|
|
89
|
+
}
|
|
90
|
+
blockchainConfig = {
|
|
91
|
+
blockchainUrl: data.blockchainUrl,
|
|
92
|
+
contractAddress: data.contractAddress,
|
|
93
|
+
};
|
|
94
|
+
await this.configManager.set('blockchain', blockchainConfig);
|
|
95
|
+
}
|
|
96
|
+
this.logger.info('Initializing blockchain connector');
|
|
97
|
+
await BlockchainConnector.getInstance().initialize(blockchainConfig);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
78
100
|
initConfigFileManager(rebuild = false) {
|
|
79
101
|
return this.queueInit('configFileManager', async () => {
|
|
80
102
|
if (this._configFileManager) {
|
|
@@ -94,7 +116,7 @@ export class AppContainer {
|
|
|
94
116
|
if (this._configManager) {
|
|
95
117
|
return;
|
|
96
118
|
}
|
|
97
|
-
const configFilePath = this.configFileManager.getCurrentConfigPath();
|
|
119
|
+
const configFilePath = await this.configFileManager.getCurrentConfigPath();
|
|
98
120
|
if (!configFilePath) {
|
|
99
121
|
throw new Error('Config file not found');
|
|
100
122
|
}
|
|
@@ -65,23 +65,27 @@ export class AccountManager {
|
|
|
65
65
|
}
|
|
66
66
|
catch (error) {
|
|
67
67
|
this.logger.warn({ err: error }, 'Incorrect config file');
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
68
|
+
await this.interactWithUser();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async interactWithUser() {
|
|
72
|
+
ux.warn("Account doesn't exist in current configuration");
|
|
73
|
+
const ask = await confirm({
|
|
74
|
+
message: 'Do you want to create a new account?',
|
|
75
|
+
});
|
|
76
|
+
if (isCancel(ask)) {
|
|
77
|
+
ux.error('Operation cancelled.', { exit: 1 });
|
|
78
|
+
}
|
|
79
|
+
if (ask) {
|
|
80
|
+
await this.promptAccount();
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
ux.error('Credentials not generated please check config file and rerun command again', { exit: 1 });
|
|
81
84
|
}
|
|
82
85
|
}
|
|
83
86
|
async promptAccount() {
|
|
84
87
|
const askPrivateKey = await confirm({
|
|
88
|
+
initialValue: false,
|
|
85
89
|
message: 'Do you want to input privateKey?',
|
|
86
90
|
});
|
|
87
91
|
if (isCancel(askPrivateKey)) {
|
|
@@ -37,7 +37,7 @@ export declare class ConfigFileManager implements IManager {
|
|
|
37
37
|
name: string;
|
|
38
38
|
}>;
|
|
39
39
|
getCurrentConfigFile(): string | undefined;
|
|
40
|
-
getCurrentConfigPath(): string
|
|
40
|
+
getCurrentConfigPath(): Promise<string>;
|
|
41
41
|
importConfig(sourcePath: string, targetName?: string): Promise<string>;
|
|
42
42
|
init(): Promise<void>;
|
|
43
43
|
removeConfig(configName: string): Promise<void>;
|
|
@@ -4,7 +4,7 @@ import * as fs from 'node:fs';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { Value } from 'typebox/value';
|
|
6
6
|
import { cliConfigSchema } from '../config/config.schema.js';
|
|
7
|
-
import { DIR_ACCESS_PERMS, FILE_ACCESS_PERMS } from '../constants.js';
|
|
7
|
+
import { DEFAULT_USER_CONFIG_FILE, DEFAULT_USER_CONFIG_NAME, DIR_ACCESS_PERMS, FILE_ACCESS_PERMS, } from '../constants.js';
|
|
8
8
|
import { getConfigName } from '../utils/helper.js';
|
|
9
9
|
export class ConfigFileManager {
|
|
10
10
|
logger;
|
|
@@ -165,14 +165,26 @@ export class ConfigFileManager {
|
|
|
165
165
|
}
|
|
166
166
|
return this.configs.currentConfig;
|
|
167
167
|
}
|
|
168
|
-
getCurrentConfigPath() {
|
|
168
|
+
async getCurrentConfigPath() {
|
|
169
169
|
if (this.runtimeConfigFile) {
|
|
170
170
|
return this.runtimeConfigFile;
|
|
171
171
|
}
|
|
172
172
|
if (!this.configs.currentConfig) {
|
|
173
|
-
|
|
173
|
+
try {
|
|
174
|
+
await this.createConfig(DEFAULT_USER_CONFIG_FILE, DEFAULT_USER_CONFIG_NAME);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
//
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
await this.setCurrentConfig(DEFAULT_USER_CONFIG_FILE);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
this.logger.error({ err: error }, 'Failed to set default config');
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
174
186
|
}
|
|
175
|
-
return path.join(this.configsDir, this.configs.currentConfig);
|
|
187
|
+
return path.join(this.configsDir, this.configs.currentConfig || DEFAULT_USER_CONFIG_FILE);
|
|
176
188
|
}
|
|
177
189
|
async importConfig(sourcePath, targetName) {
|
|
178
190
|
if (!fs.existsSync(sourcePath)) {
|
|
@@ -43,6 +43,7 @@ export declare class StorageService {
|
|
|
43
43
|
download(params: IDownloadParams, progressCb: ProgressCb): Promise<void>;
|
|
44
44
|
getCentralizedStorage(): Promise<StorageResponseDto>;
|
|
45
45
|
getCurrentStorage(): Promise<StorageResponseDto>;
|
|
46
|
+
getLabel(storage: StorageResponseDto): string;
|
|
46
47
|
hasStorage(): Promise<boolean>;
|
|
47
48
|
initCentralizedStorage(): Promise<{
|
|
48
49
|
bucket: string;
|
|
@@ -64,8 +65,9 @@ export declare class StorageService {
|
|
|
64
65
|
id: string;
|
|
65
66
|
updatedAt: string;
|
|
66
67
|
userId: string;
|
|
67
|
-
}>;
|
|
68
|
+
} | undefined>;
|
|
68
69
|
updateStorage(id: string, storage: UpdateStorageDto): Promise<StorageResponseDto>;
|
|
69
70
|
upload(params: IUploadParams, progressCb: ProgressCb): Promise<void>;
|
|
71
|
+
private getStorageCredentials;
|
|
70
72
|
}
|
|
71
73
|
export {};
|