ic-mops 0.12.4 → 0.13.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/cli.js CHANGED
@@ -18,6 +18,7 @@ import {test} from './commands/test.js';
18
18
  import {template} from './commands/template.js';
19
19
  import {selfUpdate} from './commands/self-update.js';
20
20
  import {remove} from './commands/remove.js';
21
+ import {getUserProp, setUserProp} from './commands/user.js';
21
22
  // import {docs} from './commands/docs.js';
22
23
 
23
24
  program.name('mops');
@@ -79,6 +80,7 @@ program
79
80
  }
80
81
 
81
82
  if (pkg) {
83
+ // @deprecated
82
84
  console.log(chalk.yellow('Consider using the \'mops add\' command to install a specific package.'));
83
85
  await add(pkg, options);
84
86
  }
@@ -127,7 +129,7 @@ program
127
129
  .description('Import .pem file data to use as identity')
128
130
  .action(async (data) => {
129
131
  await importPem(data);
130
- whoami();
132
+ await whoami();
131
133
  });
132
134
 
133
135
  // sources
@@ -149,7 +151,7 @@ program
149
151
  .command('whoami')
150
152
  .description('Print your principal')
151
153
  .action(async () => {
152
- whoami();
154
+ await whoami();
153
155
  });
154
156
 
155
157
  // search
@@ -224,4 +226,24 @@ program
224
226
  }
225
227
  });
226
228
 
229
+ // user
230
+ program
231
+ .command('user set|get <prop> [value]')
232
+ .description('User settings')
233
+ .action(async (sub, prop, value) => {
234
+ if (sub == 'get') {
235
+ await getUserProp(prop);
236
+ }
237
+ else if (sub == 'set') {
238
+ if (!value) {
239
+ console.log('error: missing required argument "value"');
240
+ return;
241
+ }
242
+ await setUserProp(prop, value);
243
+ }
244
+ else {
245
+ console.log('Unknown sub command. Available sub commands: set, get');
246
+ }
247
+ });
248
+
227
249
  program.parse();
@@ -1,35 +1,53 @@
1
1
  import fs from 'fs';
2
2
  import chalk from 'chalk';
3
3
  import path from 'path';
4
+ import prompts from 'prompts';
5
+ import del from 'del';
4
6
  import {globalCacheDir} from '../mops.js';
7
+ import {encrypt} from '../pem.js';
5
8
 
6
9
  export async function importPem(data) {
7
10
  try {
8
11
  if (!fs.existsSync(globalCacheDir)) {
9
12
  fs.mkdirSync(globalCacheDir);
10
13
  }
14
+
15
+ let res = await prompts({
16
+ type: 'password',
17
+ name: 'password',
18
+ message: 'Enter password to encrypt identity.pem',
19
+ });
20
+ let password = res.password;
21
+
22
+ if (!password) {
23
+ let res = await prompts({
24
+ type: 'confirm',
25
+ name: 'ok',
26
+ message: 'Are you sure you don\'t want to protect your identity.pem with a password?',
27
+ });
28
+ if (!res.ok) {
29
+ console.log('aborted');
30
+ return;
31
+ }
32
+ }
33
+
11
34
  let identityPem = path.resolve(globalCacheDir, 'identity.pem');
12
- fs.writeFileSync(identityPem, data);
35
+ let identityPemEncrypted = path.resolve(globalCacheDir, 'identity.pem.encrypted');
36
+
37
+ del.sync([identityPem, identityPemEncrypted], {force: true});
38
+
39
+ // encrypted
40
+ if (password) {
41
+ data = await encrypt(Buffer.from(data), password);
42
+ fs.writeFileSync(identityPemEncrypted, data);
43
+ }
44
+ // unencrypted
45
+ else {
46
+ fs.writeFileSync(identityPem, data);
47
+ }
13
48
  console.log(chalk.green('Success'));
14
49
  }
15
50
  catch (err) {
16
51
  console.log(chalk.red('Error: ') + err);
17
52
  }
18
- }
19
-
20
- // export async function pemFile(file) {
21
- // try {
22
- // if (!file.endsWith('.pem')) {
23
- // throw 'Please specify .pem file';
24
- // }
25
- // if (!fs.existsSync(file)) {
26
- // throw 'File not found ' + file;
27
- // }
28
- // let url = new URL('./pem-file', import.meta.url);
29
- // fs.writeFileSync(url, file);
30
- // console.log(chalk.green('Success'));
31
- // }
32
- // catch (e) {
33
- // console.log(chalk.red('Error: ') + e);
34
- // }
35
- // }
53
+ }
@@ -2,11 +2,10 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import chalk from 'chalk';
4
4
  import logUpdate from 'log-update';
5
- import {Principal} from '@dfinity/principal';
6
5
  import {globbySync} from 'globby';
7
6
  import minimatch from 'minimatch';
8
7
  import prompts from 'prompts';
9
- import {checkConfigFile, getIdentity, getRootDir, mainActor, progressBar, readConfig} from '../mops.js';
8
+ import {checkConfigFile, getRootDir, mainActor, progressBar, readConfig} from '../mops.js';
10
9
  import {parallel} from '../parallel.js';
11
10
  import {docs} from './docs.js';
12
11
 
@@ -160,7 +159,6 @@ export async function publish({noDocs} = {}) {
160
159
  baseDir: 'src',
161
160
  readme: 'README.md',
162
161
  license: config.package.license || '',
163
- owner: getIdentity()?.getPrincipal() || Principal.anonymous(),
164
162
  dfx: config.package.dfx || '',
165
163
  moc: config.package.moc || '',
166
164
  donation: config.package.donation || '',
@@ -217,8 +215,9 @@ export async function publish({noDocs} = {}) {
217
215
  }
218
216
 
219
217
  // upload config
218
+ let actor = await mainActor(true);
219
+
220
220
  progress();
221
- let actor = await mainActor();
222
221
  let publishing = await actor.startPublish(backendPkgConfig);
223
222
  if (publishing.err) {
224
223
  console.log(chalk.red('Error: ') + publishing.err);
@@ -0,0 +1,20 @@
1
+ import chalk from 'chalk';
2
+ import {getIdentity, mainActor} from '../mops.js';
3
+
4
+ export async function getUserProp(prop) {
5
+ let actor = await mainActor();
6
+ let identity = await getIdentity();
7
+ let res = await actor.getUser(identity.getPrincipal());
8
+ console.log(res[0]?.[prop] || '');
9
+ }
10
+
11
+ export async function setUserProp(prop, value) {
12
+ let actor = await mainActor(true);
13
+ let res = await actor.setUserProp(prop, value);
14
+ if ('ok' in res) {
15
+ console.log(chalk.green('Success!'));
16
+ }
17
+ else {
18
+ console.log(chalk.red('Error: ') + res.err);
19
+ }
20
+ }
@@ -1,12 +1,9 @@
1
1
  import chalk from 'chalk';
2
- import fs from 'fs';
3
- import path from 'path';
4
- import {getIdentity, globalCacheDir} from '../mops.js';
2
+ import {getIdentity} from '../mops.js';
5
3
 
6
- export function whoami() {
7
- let identityPem = path.resolve(globalCacheDir, 'identity.pem');
8
- if (fs.existsSync(identityPem)) {
9
- let identity = getIdentity();
4
+ export async function whoami() {
5
+ let identity = await getIdentity();
6
+ if (identity) {
10
7
  console.log(identity.getPrincipal().toText());
11
8
  }
12
9
  else {
@@ -4,8 +4,14 @@ import { Actor, HttpAgent } from "@dfinity/agent";
4
4
  import { idlFactory } from "./main.did.js";
5
5
  export { idlFactory } from "./main.did.js";
6
6
 
7
- // CANISTER_ID is replaced by webpack based on node environment
8
- export const canisterId = process.env.MAIN_CANISTER_ID;
7
+ /* CANISTER_ID is replaced by webpack based on node environment
8
+ * Note: canister environment variable will be standardized as
9
+ * process.env.CANISTER_ID_<CANISTER_NAME_UPPERCASE>
10
+ * beginning in dfx 0.15.0
11
+ */
12
+ export const canisterId =
13
+ process.env.CANISTER_ID_MAIN ||
14
+ process.env.MAIN_CANISTER_ID;
9
15
 
10
16
  export const createActor = (canisterId, options = {}) => {
11
17
  const agent = options.agent || new HttpAgent({ ...options.agentOptions });
@@ -1,5 +1,31 @@
1
1
  type Version = text;
2
2
  type Ver = text;
3
+ type User__1 =
4
+ record {
5
+ displayName: text;
6
+ email: text;
7
+ emailVerified: bool;
8
+ github: text;
9
+ githubVerified: bool;
10
+ id: principal;
11
+ name: text;
12
+ site: text;
13
+ twitter: text;
14
+ twitterVerified: bool;
15
+ };
16
+ type User =
17
+ record {
18
+ displayName: text;
19
+ email: text;
20
+ emailVerified: bool;
21
+ github: text;
22
+ githubVerified: bool;
23
+ id: principal;
24
+ name: text;
25
+ site: text;
26
+ twitter: text;
27
+ twitterVerified: bool;
28
+ };
3
29
  type Time = int;
4
30
  type Text = text;
5
31
  type StorageStats =
@@ -14,21 +40,26 @@ type Script =
14
40
  name: text;
15
41
  value: text;
16
42
  };
17
- type Result_5 =
43
+ type Result_6 =
18
44
  variant {
19
45
  err: Err;
20
46
  ok: vec FileId;
21
47
  };
22
- type Result_4 =
48
+ type Result_5 =
23
49
  variant {
24
50
  err: Err;
25
51
  ok: Ver;
26
52
  };
27
- type Result_3 =
53
+ type Result_4 =
28
54
  variant {
29
55
  err: Err;
30
56
  ok: PackageDetails;
31
57
  };
58
+ type Result_3 =
59
+ variant {
60
+ err: text;
61
+ ok;
62
+ };
32
63
  type Result_2 =
33
64
  variant {
34
65
  err: Err;
@@ -53,6 +84,7 @@ type PackageSummary__1 =
53
84
  downloadsInLast7Days: nat;
54
85
  downloadsTotal: nat;
55
86
  owner: principal;
87
+ ownerInfo: User;
56
88
  publication: PackagePublication;
57
89
  };
58
90
  type PackageSummary =
@@ -62,6 +94,7 @@ type PackageSummary =
62
94
  downloadsInLast7Days: nat;
63
95
  downloadsTotal: nat;
64
96
  owner: principal;
97
+ ownerInfo: User;
65
98
  publication: PackagePublication;
66
99
  };
67
100
  type PackagePublication =
@@ -84,6 +117,7 @@ type PackageDetails =
84
117
  downloadsInLast7Days: nat;
85
118
  downloadsTotal: nat;
86
119
  owner: principal;
120
+ ownerInfo: User;
87
121
  publication: PackagePublication;
88
122
  versionHistory: vec PackageSummary__1;
89
123
  };
@@ -156,11 +190,11 @@ service : {
156
190
  (vec DownloadsSnapshot__1) query;
157
191
  getDownloadTrendByPackageName: (PackageName__1) ->
158
192
  (vec DownloadsSnapshot__1) query;
159
- getFileIds: (PackageName__1, Ver) -> (Result_5) query;
160
- getHighestVersion: (PackageName__1) -> (Result_4) query;
193
+ getFileIds: (PackageName__1, Ver) -> (Result_6) query;
194
+ getHighestVersion: (PackageName__1) -> (Result_5) query;
161
195
  getMostDownloadedPackages: () -> (vec PackageSummary) query;
162
196
  getMostDownloadedPackagesIn7Days: () -> (vec PackageSummary) query;
163
- getPackageDetails: (PackageName__1, Ver) -> (Result_3) query;
197
+ getPackageDetails: (PackageName__1, Ver) -> (Result_4) query;
164
198
  getRecentlyUpdatedPackages: () -> (vec PackageSummary) query;
165
199
  getStoragesStats: () -> (vec record {
166
200
  StorageId;
@@ -168,8 +202,10 @@ service : {
168
202
  }) query;
169
203
  getTotalDownloads: () -> (nat) query;
170
204
  getTotalPackages: () -> (nat) query;
205
+ getUser: (principal) -> (opt User__1) query;
171
206
  notifyInstall: (PackageName__1, Ver) -> () oneway;
172
207
  search: (Text) -> (vec PackageSummary) query;
208
+ setUserProp: (text, text) -> (Result_3);
173
209
  startFileUpload: (PublishingId, Text, nat, blob) -> (Result_2);
174
210
  startPublish: (PackageConfigV2) -> (Result_1);
175
211
  uploadFileChunk: (PublishingId, FileId, nat, blob) -> (Result);
@@ -55,6 +55,7 @@ export interface PackageConfigV2__1 {
55
55
  'readme' : string,
56
56
  }
57
57
  export interface PackageDetails {
58
+ 'ownerInfo' : User,
58
59
  'owner' : Principal,
59
60
  'deps' : Array<PackageSummary__1>,
60
61
  'downloadsTotal' : bigint,
@@ -76,6 +77,7 @@ export interface PackagePublication {
76
77
  'user' : Principal,
77
78
  }
78
79
  export interface PackageSummary {
80
+ 'ownerInfo' : User,
79
81
  'owner' : Principal,
80
82
  'downloadsTotal' : bigint,
81
83
  'downloadsInLast30Days' : bigint,
@@ -84,6 +86,7 @@ export interface PackageSummary {
84
86
  'publication' : PackagePublication,
85
87
  }
86
88
  export interface PackageSummary__1 {
89
+ 'ownerInfo' : User,
87
90
  'owner' : Principal,
88
91
  'downloadsTotal' : bigint,
89
92
  'downloadsInLast30Days' : bigint,
@@ -99,11 +102,13 @@ export type Result_1 = { 'ok' : PublishingId } |
99
102
  { 'err' : PublishingErr };
100
103
  export type Result_2 = { 'ok' : FileId } |
101
104
  { 'err' : Err };
102
- export type Result_3 = { 'ok' : PackageDetails } |
105
+ export type Result_3 = { 'ok' : null } |
106
+ { 'err' : string };
107
+ export type Result_4 = { 'ok' : PackageDetails } |
103
108
  { 'err' : Err };
104
- export type Result_4 = { 'ok' : Ver } |
109
+ export type Result_5 = { 'ok' : Ver } |
105
110
  { 'err' : Err };
106
- export type Result_5 = { 'ok' : Array<FileId> } |
111
+ export type Result_6 = { 'ok' : Array<FileId> } |
107
112
  { 'err' : Err };
108
113
  export interface Script { 'value' : string, 'name' : string }
109
114
  export type StorageId = Principal;
@@ -114,6 +119,30 @@ export interface StorageStats {
114
119
  }
115
120
  export type Text = string;
116
121
  export type Time = bigint;
122
+ export interface User {
123
+ 'id' : Principal,
124
+ 'emailVerified' : boolean,
125
+ 'twitter' : string,
126
+ 'displayName' : string,
127
+ 'name' : string,
128
+ 'site' : string,
129
+ 'email' : string,
130
+ 'twitterVerified' : boolean,
131
+ 'githubVerified' : boolean,
132
+ 'github' : string,
133
+ }
134
+ export interface User__1 {
135
+ 'id' : Principal,
136
+ 'emailVerified' : boolean,
137
+ 'twitter' : string,
138
+ 'displayName' : string,
139
+ 'name' : string,
140
+ 'site' : string,
141
+ 'email' : string,
142
+ 'twitterVerified' : boolean,
143
+ 'githubVerified' : boolean,
144
+ 'github' : string,
145
+ }
117
146
  export type Ver = string;
118
147
  export type Version = string;
119
148
  export interface _SERVICE {
@@ -131,17 +160,19 @@ export interface _SERVICE {
131
160
  [PackageName__1],
132
161
  Array<DownloadsSnapshot__1>
133
162
  >,
134
- 'getFileIds' : ActorMethod<[PackageName__1, Ver], Result_5>,
135
- 'getHighestVersion' : ActorMethod<[PackageName__1], Result_4>,
163
+ 'getFileIds' : ActorMethod<[PackageName__1, Ver], Result_6>,
164
+ 'getHighestVersion' : ActorMethod<[PackageName__1], Result_5>,
136
165
  'getMostDownloadedPackages' : ActorMethod<[], Array<PackageSummary>>,
137
166
  'getMostDownloadedPackagesIn7Days' : ActorMethod<[], Array<PackageSummary>>,
138
- 'getPackageDetails' : ActorMethod<[PackageName__1, Ver], Result_3>,
167
+ 'getPackageDetails' : ActorMethod<[PackageName__1, Ver], Result_4>,
139
168
  'getRecentlyUpdatedPackages' : ActorMethod<[], Array<PackageSummary>>,
140
169
  'getStoragesStats' : ActorMethod<[], Array<[StorageId, StorageStats]>>,
141
170
  'getTotalDownloads' : ActorMethod<[], bigint>,
142
171
  'getTotalPackages' : ActorMethod<[], bigint>,
172
+ 'getUser' : ActorMethod<[Principal], [] | [User__1]>,
143
173
  'notifyInstall' : ActorMethod<[PackageName__1, Ver], undefined>,
144
174
  'search' : ActorMethod<[Text], Array<PackageSummary>>,
175
+ 'setUserProp' : ActorMethod<[string, string], Result_3>,
145
176
  'startFileUpload' : ActorMethod<
146
177
  [PublishingId, Text, bigint, Uint8Array | number[]],
147
178
  Result_2
@@ -14,8 +14,20 @@ export const idlFactory = ({ IDL }) => {
14
14
  });
15
15
  const Ver = IDL.Text;
16
16
  const FileId = IDL.Text;
17
- const Result_5 = IDL.Variant({ 'ok' : IDL.Vec(FileId), 'err' : Err });
18
- const Result_4 = IDL.Variant({ 'ok' : Ver, 'err' : Err });
17
+ const Result_6 = IDL.Variant({ 'ok' : IDL.Vec(FileId), 'err' : Err });
18
+ const Result_5 = IDL.Variant({ 'ok' : Ver, 'err' : Err });
19
+ const User = IDL.Record({
20
+ 'id' : IDL.Principal,
21
+ 'emailVerified' : IDL.Bool,
22
+ 'twitter' : IDL.Text,
23
+ 'displayName' : IDL.Text,
24
+ 'name' : IDL.Text,
25
+ 'site' : IDL.Text,
26
+ 'email' : IDL.Text,
27
+ 'twitterVerified' : IDL.Bool,
28
+ 'githubVerified' : IDL.Bool,
29
+ 'github' : IDL.Text,
30
+ });
19
31
  const Script = IDL.Record({ 'value' : IDL.Text, 'name' : IDL.Text });
20
32
  const PackageName = IDL.Text;
21
33
  const DependencyV2 = IDL.Record({
@@ -47,6 +59,7 @@ export const idlFactory = ({ IDL }) => {
47
59
  'user' : IDL.Principal,
48
60
  });
49
61
  const PackageSummary = IDL.Record({
62
+ 'ownerInfo' : User,
50
63
  'owner' : IDL.Principal,
51
64
  'downloadsTotal' : IDL.Nat,
52
65
  'downloadsInLast30Days' : IDL.Nat,
@@ -55,6 +68,7 @@ export const idlFactory = ({ IDL }) => {
55
68
  'publication' : PackagePublication,
56
69
  });
57
70
  const PackageSummary__1 = IDL.Record({
71
+ 'ownerInfo' : User,
58
72
  'owner' : IDL.Principal,
59
73
  'downloadsTotal' : IDL.Nat,
60
74
  'downloadsInLast30Days' : IDL.Nat,
@@ -68,6 +82,7 @@ export const idlFactory = ({ IDL }) => {
68
82
  'downloads' : IDL.Nat,
69
83
  });
70
84
  const PackageDetails = IDL.Record({
85
+ 'ownerInfo' : User,
71
86
  'owner' : IDL.Principal,
72
87
  'deps' : IDL.Vec(PackageSummary__1),
73
88
  'downloadsTotal' : IDL.Nat,
@@ -80,13 +95,26 @@ export const idlFactory = ({ IDL }) => {
80
95
  'config' : PackageConfigV2__1,
81
96
  'publication' : PackagePublication,
82
97
  });
83
- const Result_3 = IDL.Variant({ 'ok' : PackageDetails, 'err' : Err });
98
+ const Result_4 = IDL.Variant({ 'ok' : PackageDetails, 'err' : Err });
84
99
  const StorageId = IDL.Principal;
85
100
  const StorageStats = IDL.Record({
86
101
  'fileCount' : IDL.Nat,
87
102
  'cyclesBalance' : IDL.Nat,
88
103
  'memorySize' : IDL.Nat,
89
104
  });
105
+ const User__1 = IDL.Record({
106
+ 'id' : IDL.Principal,
107
+ 'emailVerified' : IDL.Bool,
108
+ 'twitter' : IDL.Text,
109
+ 'displayName' : IDL.Text,
110
+ 'name' : IDL.Text,
111
+ 'site' : IDL.Text,
112
+ 'email' : IDL.Text,
113
+ 'twitterVerified' : IDL.Bool,
114
+ 'githubVerified' : IDL.Bool,
115
+ 'github' : IDL.Text,
116
+ });
117
+ const Result_3 = IDL.Variant({ 'ok' : IDL.Null, 'err' : IDL.Text });
90
118
  const Result_2 = IDL.Variant({ 'ok' : FileId, 'err' : Err });
91
119
  const PackageConfigV2 = IDL.Record({
92
120
  'dfx' : IDL.Text,
@@ -126,8 +154,8 @@ export const idlFactory = ({ IDL }) => {
126
154
  [IDL.Vec(DownloadsSnapshot__1)],
127
155
  ['query'],
128
156
  ),
129
- 'getFileIds' : IDL.Func([PackageName__1, Ver], [Result_5], ['query']),
130
- 'getHighestVersion' : IDL.Func([PackageName__1], [Result_4], ['query']),
157
+ 'getFileIds' : IDL.Func([PackageName__1, Ver], [Result_6], ['query']),
158
+ 'getHighestVersion' : IDL.Func([PackageName__1], [Result_5], ['query']),
131
159
  'getMostDownloadedPackages' : IDL.Func(
132
160
  [],
133
161
  [IDL.Vec(PackageSummary)],
@@ -140,7 +168,7 @@ export const idlFactory = ({ IDL }) => {
140
168
  ),
141
169
  'getPackageDetails' : IDL.Func(
142
170
  [PackageName__1, Ver],
143
- [Result_3],
171
+ [Result_4],
144
172
  ['query'],
145
173
  ),
146
174
  'getRecentlyUpdatedPackages' : IDL.Func(
@@ -155,8 +183,10 @@ export const idlFactory = ({ IDL }) => {
155
183
  ),
156
184
  'getTotalDownloads' : IDL.Func([], [IDL.Nat], ['query']),
157
185
  'getTotalPackages' : IDL.Func([], [IDL.Nat], ['query']),
186
+ 'getUser' : IDL.Func([IDL.Principal], [IDL.Opt(User__1)], ['query']),
158
187
  'notifyInstall' : IDL.Func([PackageName__1, Ver], [], ['oneway']),
159
188
  'search' : IDL.Func([Text], [IDL.Vec(PackageSummary)], ['query']),
189
+ 'setUserProp' : IDL.Func([IDL.Text, IDL.Text], [Result_3], []),
160
190
  'startFileUpload' : IDL.Func(
161
191
  [PublishingId, Text, IDL.Nat, IDL.Vec(IDL.Nat8)],
162
192
  [Result_2],
package/mops.js CHANGED
@@ -4,6 +4,7 @@ import chalk from 'chalk';
4
4
  import fetch from 'node-fetch';
5
5
  import path from 'path';
6
6
  import fs from 'fs';
7
+ import prompts from 'prompts';
7
8
 
8
9
  import {idlFactory} from './declarations/main/main.did.js';
9
10
  import {idlFactory as storageIdlFactory} from './declarations/storage/storage.did.js';
@@ -53,19 +54,28 @@ export function getNetwork() {
53
54
  }
54
55
  }
55
56
 
56
- export let getIdentity = () => {
57
+ export let getIdentity = async () => {
57
58
  let identityPem = path.resolve(globalCacheDir, 'identity.pem');
59
+ let identityPemEncrypted = path.resolve(globalCacheDir, 'identity.pem.encrypted');
60
+ if (fs.existsSync(identityPemEncrypted)) {
61
+ let res = await prompts({
62
+ type: 'password',
63
+ name: 'value',
64
+ message: 'Enter password:'
65
+ });
66
+ return await decodeFile(identityPemEncrypted, res.value);
67
+ }
58
68
  if (fs.existsSync(identityPem)) {
59
69
  return decodeFile(identityPem);
60
70
  }
61
71
  };
62
72
 
63
- export let mainActor = async () => {
73
+ export let mainActor = async (useIdentity = false) => {
64
74
  let network = getNetwork().network;
65
75
  let host = getNetwork().host;
66
76
  let canisterId = getNetwork().canisterId;
67
77
 
68
- let identity = getIdentity();
78
+ let identity = useIdentity && await getIdentity();
69
79
  let agent = new HttpAgent({host, identity});
70
80
 
71
81
  if (network === 'local') {
@@ -78,11 +88,11 @@ export let mainActor = async () => {
78
88
  });
79
89
  };
80
90
 
81
- export let storageActor = async (storageId) => {
91
+ export let storageActor = async (storageId, useIdentity = false) => {
82
92
  let network = getNetwork().network;
83
93
  let host = getNetwork().host;
84
94
 
85
- let identity = getIdentity();
95
+ let identity = useIdentity && await getIdentity();
86
96
  let agent = new HttpAgent({host, identity});
87
97
 
88
98
  if (network === 'local') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ic-mops",
3
- "version": "0.12.4",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mops": "cli.js"
package/pem.js CHANGED
@@ -1,13 +1,17 @@
1
1
  import fs from 'fs';
2
2
  import {Ed25519KeyIdentity, Secp256k1KeyIdentity} from '@dfinity/identity';
3
3
  import pemfile from 'pem-file';
4
+ import crypto from 'crypto';
4
5
 
5
- export function decodeFile(file) {
6
- const rawKey = fs.readFileSync(file).toString();
6
+ export function decodeFile(file, password) {
7
+ let rawKey = fs.readFileSync(file);
8
+ if (password) {
9
+ return decode(decrypt(rawKey, password));
10
+ }
7
11
  return decode(rawKey);
8
12
  }
9
13
 
10
- export function decode(rawKey) {
14
+ function decode(rawKey) {
11
15
  var buf = pemfile.decode(rawKey);
12
16
  if (rawKey.includes('EC PRIVATE KEY')) {
13
17
  if (buf.length != 118) {
@@ -20,4 +24,30 @@ export function decode(rawKey) {
20
24
  }
21
25
  let secretKey = Buffer.concat([buf.slice(16, 48), buf.slice(53, 85)]);
22
26
  return Ed25519KeyIdentity.fromSecretKey(secretKey);
27
+ }
28
+
29
+ let algorithm = 'aes-256-ctr';
30
+
31
+ export function encrypt(buffer, password) {
32
+ let key = crypto.createHash('sha256').update(password).digest('base64').slice(0, 32);
33
+ // Create an initialization vector
34
+ let iv = crypto.randomBytes(16);
35
+ // Create a new cipher using the algorithm, key, and iv
36
+ let cipher = crypto.createCipheriv(algorithm, key, iv);
37
+ // Create the new (encrypted) buffer
38
+ let result = Buffer.concat([iv, cipher.update(buffer), cipher.final()]);
39
+ return result;
40
+ }
41
+
42
+ function decrypt(encrypted, password) {
43
+ let key = crypto.createHash('sha256').update(password).digest('base64').slice(0, 32);
44
+ // Get the iv: the first 16 bytes
45
+ let iv = encrypted.slice(0, 16);
46
+ // Get the rest
47
+ encrypted = encrypted.slice(16);
48
+ // Create a decipher
49
+ let decipher = crypto.createDecipheriv(algorithm, key, iv);
50
+ // Actually decrypt it
51
+ let result = Buffer.concat([decipher.update(encrypted), decipher.final()]);
52
+ return result;
23
53
  }