@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.
Files changed (43) hide show
  1. package/README.md +134 -65
  2. package/bin/dev.js +1 -1
  3. package/dist/commands/account/get-sppi.d.ts +8 -0
  4. package/dist/commands/account/get-sppi.js +23 -0
  5. package/dist/commands/account/info.d.ts +1 -0
  6. package/dist/commands/account/info.js +5 -2
  7. package/dist/commands/auth/login.d.ts +4 -1
  8. package/dist/commands/auth/login.js +4 -2
  9. package/dist/commands/config/add.js +1 -16
  10. package/dist/commands/config/base.d.ts +1 -0
  11. package/dist/commands/config/base.js +22 -4
  12. package/dist/commands/config/create.js +1 -11
  13. package/dist/commands/config/list.js +20 -19
  14. package/dist/commands/files/download.js +8 -6
  15. package/dist/commands/files/upload.js +8 -6
  16. package/dist/commands/storage/base.js +3 -1
  17. package/dist/commands/storage/select.d.ts +4 -4
  18. package/dist/commands/storage/select.js +15 -21
  19. package/dist/commands/storage/show.d.ts +17 -0
  20. package/dist/commands/storage/show.js +36 -0
  21. package/dist/commands/workflows/extend-lease.d.ts +17 -0
  22. package/dist/commands/workflows/extend-lease.js +94 -0
  23. package/dist/config/config.schema.d.ts +9 -0
  24. package/dist/config/config.schema.js +5 -0
  25. package/dist/constants.d.ts +3 -0
  26. package/dist/constants.js +3 -0
  27. package/dist/hooks/finally/shutdown-blockchain.d.ts +3 -0
  28. package/dist/hooks/finally/shutdown-blockchain.js +8 -0
  29. package/dist/lib/container.d.ts +1 -0
  30. package/dist/lib/container.js +23 -1
  31. package/dist/managers/account-manager.d.ts +1 -0
  32. package/dist/managers/account-manager.js +17 -13
  33. package/dist/managers/config-file-manager.d.ts +1 -1
  34. package/dist/managers/config-file-manager.js +16 -4
  35. package/dist/services/storage.service.d.ts +3 -1
  36. package/dist/services/storage.service.js +87 -44
  37. package/dist/utils/helper.d.ts +1 -0
  38. package/dist/utils/helper.js +1 -0
  39. package/dist/utils/progress.js +10 -2
  40. package/oclif.manifest.json +190 -151
  41. package/package.json +10 -6
  42. package/dist/config/resource.schema.d.ts +0 -31
  43. 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 = 'describe the command here';
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 upload at once per transfer', max: 1000, min: 1,
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 storageSerivce = new StorageService(providerClient, this.logger);
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 storageSerivce.download({
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
- this.log('Download successful completed');
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 = 'describe the command here';
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 storageSerivce = new StorageService(providerClient, this.logger);
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 storageSerivce.upload({
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
- this.log('Upload successful completed');
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 = 'us-east-1';
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
- static flags: {
6
- id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
- };
8
- run(): Promise<void>;
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
- let storageId = flags.id;
21
- if (!storageId) {
22
- const storages = await this.storageService.requestStorages();
23
- storageId = this.ensurePromptValue(await select({
24
- message: 'Select storage',
25
- options: storages.map(storage => ({
26
- label: `${storage.id} (${storage.storageType}) ${storage.bucket}/${storage.prefix} `,
27
- value: storage.id,
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: ${storageId}`);
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' })),
@@ -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';
@@ -0,0 +1,3 @@
1
+ import { Hook } from '@oclif/core';
2
+ declare const hook: Hook<'finally'>;
3
+ export default hook;
@@ -0,0 +1,8 @@
1
+ import { BlockchainConnector } from '@super-protocol/sdk-js';
2
+ const hook = async function () {
3
+ const connector = BlockchainConnector.getInstance();
4
+ if (connector.isInitialized()) {
5
+ connector.shutdown();
6
+ }
7
+ };
8
+ export default hook;
@@ -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 }?: {
@@ -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
  }
@@ -13,5 +13,6 @@ export declare class AccountManager implements IAccountManager {
13
13
  createSign(nonce: string): Promise<string>;
14
14
  getAddress(): string;
15
15
  init(): Promise<void>;
16
+ interactWithUser(): Promise<void>;
16
17
  promptAccount(): Promise<Account>;
17
18
  }
@@ -65,23 +65,27 @@ export class AccountManager {
65
65
  }
66
66
  catch (error) {
67
67
  this.logger.warn({ err: error }, 'Incorrect config file');
68
- ux.warn('Config not found or have errors');
69
- const ask = await confirm({
70
- message: 'Do you want to create new one?',
71
- });
72
- if (isCancel(ask)) {
73
- ux.error('Operation cancelled.', { exit: 1 });
74
- }
75
- if (ask) {
76
- await this.promptAccount();
77
- }
78
- else {
79
- ux.error('Credentials not generated please check config file and rerun command again', { exit: 1 });
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 | undefined;
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
- return undefined;
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 {};