1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | const { Keygen } = require('eosjs-keygen');
|
7 | const ecc = require('eosjs-ecc');
|
8 | const { mockAction, mockOptions } = require('./helpers/eos');
|
9 | const { constructOrejs, mockGetAccount, mockGetAccountWithAlreadyExistingAccount, mockGetInfo, mockGetBlock,
|
10 | mockGetTransaction } = require('./helpers/orejs');
|
11 |
|
12 | describe('account', () => {
|
13 | let orejs;
|
14 | let transaction;
|
15 | let info;
|
16 | let block;
|
17 |
|
18 | beforeAll(() => {
|
19 | orejs = constructOrejs();
|
20 | });
|
21 |
|
22 |
|
23 |
|
24 | describe('addPermission', () => {
|
25 | let accountName = 'accountname';
|
26 | let keys;
|
27 | let parentPermission = 'active';
|
28 | let options = { authPermission: parentPermission };
|
29 |
|
30 | beforeEach(async () => {
|
31 | keys = await Keygen.generateMasterKeys();
|
32 | mockGetAccount(orejs, false);
|
33 | mockGetTransaction(orejs);
|
34 | });
|
35 |
|
36 | describe('when removing an existing permission', () => {
|
37 | let permissionName = 'newpermission';
|
38 | let spyTransaction;
|
39 | let spyAccount;
|
40 |
|
41 | beforeEach(() => {
|
42 | spyTransaction = jest.spyOn(orejs.eos, 'transact');
|
43 | spyAccount = jest.spyOn(orejs.eos.rpc, 'get_account');
|
44 | });
|
45 |
|
46 | it('returns the transaction', async () => {
|
47 | const permissionTransaction = await orejs.addPermission(accountName, [keys.publicKeys.active], permissionName, parentPermission, options);
|
48 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
49 | actions: [
|
50 | mockAction({
|
51 | account: 'eosio',
|
52 | name: 'updateauth',
|
53 | authorization: { actor: accountName, permission: parentPermission },
|
54 | data: {
|
55 | account: accountName,
|
56 | auth: {
|
57 | accounts: [],
|
58 | keys: [{
|
59 | key: expect.any(String),
|
60 | weight: 1,
|
61 | }],
|
62 | threshold: 1,
|
63 | waits: [],
|
64 | },
|
65 | parent: parentPermission,
|
66 | permission: permissionName,
|
67 | }
|
68 | })
|
69 | ],
|
70 | }, mockOptions());
|
71 | expect(spyAccount).toHaveBeenCalledWith(expect.any(String));
|
72 | });
|
73 | })
|
74 | });
|
75 |
|
76 | describe('createKeyPair', () => {
|
77 | let accountName = 'accountname';
|
78 | let parentPermission = 'active';
|
79 | let options = { parentPermission };
|
80 | let spyAccount;
|
81 | let spyTransaction;
|
82 | let spyInfo;
|
83 | let spyBlock;
|
84 |
|
85 | beforeEach(() => {
|
86 | mockGetAccount(orejs, false);
|
87 | mockGetTransaction(orejs);
|
88 |
|
89 | transaction = mockGetTransaction(orejs);
|
90 | info = mockGetInfo(orejs);
|
91 | block = mockGetBlock(orejs, { block_num: info.head_block_num, transactions: [{ trx: { id: transaction.transaction_id } }] });
|
92 |
|
93 | spyTransaction = jest.spyOn(orejs.eos, 'transact');
|
94 | spyAccount = jest.spyOn(orejs.eos.rpc, 'get_account');
|
95 | spyInfo = jest.spyOn(orejs.eos.rpc, 'get_info');
|
96 | spyBlock = jest.spyOn(orejs.eos.rpc, 'get_block');
|
97 | });
|
98 |
|
99 | describe('when generating a new permission', () => {
|
100 | let permissionName = 'newpermission';
|
101 |
|
102 | it('returns a new key pair', async () => {
|
103 | const keypair = await orejs.createKeyPair(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, accountName, permissionName, options);
|
104 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
105 | actions: [
|
106 | mockAction({
|
107 | account: 'eosio',
|
108 | name: 'updateauth',
|
109 | authorization: { actor: accountName, permission: parentPermission },
|
110 | data: {
|
111 | account: accountName,
|
112 | auth: {
|
113 | accounts: [],
|
114 | keys: [{
|
115 | key: expect.any(String),
|
116 | weight: 1,
|
117 | }],
|
118 | threshold: 1,
|
119 | waits: [],
|
120 | },
|
121 | parent: parentPermission,
|
122 | permission: permissionName,
|
123 | }
|
124 | })
|
125 | ],
|
126 | }, mockOptions());
|
127 |
|
128 | expect(spyInfo).toHaveBeenCalledWith({});
|
129 | expect(spyBlock).toHaveBeenCalledWith(block.block_num + 1);
|
130 | expect(ecc.privateToPublic(orejs.decrypt(keypair.privateKeys.owner, WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT))).toEqual(keypair.publicKeys.owner);
|
131 | });
|
132 |
|
133 | describe('when passing in links', () => {
|
134 | let code = 'contract';
|
135 | let type = 'action';
|
136 |
|
137 | beforeEach(() => {
|
138 | options.links = [{ code, type }];
|
139 | });
|
140 |
|
141 | it('returns a new key pair, with links', async () => {
|
142 | const keypair = await orejs.createKeyPair(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, accountName, permissionName, options);
|
143 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
144 | actions: [
|
145 | mockAction({
|
146 | account: 'eosio',
|
147 | name: 'updateauth',
|
148 | authorization: { actor: accountName, permission: parentPermission },
|
149 | data: {
|
150 | account: accountName,
|
151 | auth: {
|
152 | accounts: [],
|
153 | keys: [{
|
154 | key: expect.any(String),
|
155 | weight: 1,
|
156 | }],
|
157 | threshold: 1,
|
158 | waits: [],
|
159 | },
|
160 | parent: parentPermission,
|
161 | permission: permissionName,
|
162 | }
|
163 | }),
|
164 | mockAction({
|
165 | account: 'eosio',
|
166 | name: 'linkauth',
|
167 | authorization: { actor: accountName, permission: parentPermission },
|
168 | data: {
|
169 | account: accountName,
|
170 | code,
|
171 | type,
|
172 | requirement: permissionName,
|
173 | }
|
174 | })
|
175 | ],
|
176 | }, mockOptions());
|
177 | });
|
178 | });
|
179 | });
|
180 |
|
181 | describe('when appending keys to an pre-existing permission', () => {
|
182 | let permissionName = 'custom';
|
183 |
|
184 | beforeEach(() => {
|
185 | options.links = [];
|
186 | mockGetAccount(orejs, false);
|
187 | });
|
188 |
|
189 | it('returns the existing and new key pair', async () => {
|
190 | const keypair = await orejs.createKeyPair(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, accountName, permissionName, options);
|
191 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
192 | actions: [
|
193 | mockAction({
|
194 | account: 'eosio',
|
195 | name: 'updateauth',
|
196 | authorization: { actor: accountName, permission: parentPermission },
|
197 | data: {
|
198 | account: accountName,
|
199 | auth: {
|
200 | accounts: [],
|
201 | keys: [{
|
202 | key: expect.any(String),
|
203 | weight: 1,
|
204 | },{
|
205 | key: expect.any(String),
|
206 | weight: 1,
|
207 | }],
|
208 | threshold: 1,
|
209 | waits: [],
|
210 | },
|
211 | parent: parentPermission,
|
212 | permission: permissionName,
|
213 | }
|
214 | })
|
215 | ],
|
216 | }, mockOptions());
|
217 |
|
218 | expect(ecc.privateToPublic(orejs.decrypt(keypair.privateKeys.owner, WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT))).toEqual(keypair.publicKeys.owner);
|
219 | });
|
220 | });
|
221 |
|
222 | describe('when adding an pre-defined key pair', () => {
|
223 | let permissionName = 'custom';
|
224 | let keys = {
|
225 | privateKeys: {
|
226 | owner: '{"iv":"xr5XTgow76QCpEe8Tij7xw==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"gcm","adata":"","cipher":"aes","ct":"2YAap55e6O8gwZ6m33UjEjxqw1GU+cZbVrYP7TDRFiF0axe1XJ2W+uvhgG5ArEga8GO8cnNf+6KaFaQ="}',
|
227 | active: '{"iv":"whCS0NVLJv+5xFxm/udHaw==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"gcm","adata":"","cipher":"aes","ct":"G7So6hZeuqp3eZT4aj3w/C5lhXIJ8Z+9dTUCQNAhSWMVB9S+k+IHoUGQKgAi1cz3vnQ3VH4DdJobec4="}'
|
228 | },
|
229 | publicKeys: {
|
230 | owner: 'EOS8ekDXRqcWGYXHDZp246B8VF9DTwkuz13u5tpPnMdptE2SE9sVf',
|
231 | active: 'EOS6iGJBT4PPuhm5zKiKUiFNi7eYqLFofZqMYDyZyKHfNt5fuRLF2'
|
232 | }
|
233 | }
|
234 |
|
235 | beforeEach(() => {
|
236 | options.keys = keys;
|
237 | });
|
238 |
|
239 | it('returns the existing key pair', async () => {
|
240 | const keypair = await orejs.createKeyPair(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, accountName, permissionName, options);
|
241 | expect(ecc.privateToPublic(orejs.decrypt(keypair.privateKeys.owner, WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT))).toEqual(keypair.publicKeys.owner);
|
242 | expect(keypair.publicKeys.owner).toEqual(keys.publicKeys.owner);
|
243 | });
|
244 | })
|
245 | });
|
246 |
|
247 | describe('createOreAccount', () => {
|
248 | describe('when generating a new account name', () => {
|
249 | let spyTransaction;
|
250 | let spyAccount;
|
251 | let spyInfo;
|
252 | let spyBlock;
|
253 |
|
254 | beforeEach(() => {
|
255 | mockGetAccount(orejs);
|
256 | transaction = mockGetTransaction(orejs);
|
257 | info = mockGetInfo(orejs);
|
258 | block = mockGetBlock(orejs, { block_num: info.head_block_num, transactions: [{ trx: { id: transaction.transaction_id } }] });
|
259 | spyTransaction = jest.spyOn(orejs.eos, 'transact');
|
260 | spyAccount = jest.spyOn(orejs.eos.rpc, 'get_account');
|
261 | spyInfo = jest.spyOn(orejs.eos.rpc, 'get_info');
|
262 | spyBlock = jest.spyOn(orejs.eos.rpc, 'get_block');
|
263 | });
|
264 |
|
265 | it('returns a new account', async () => {
|
266 | const permission = 'custom';
|
267 | const options = { permission };
|
268 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME, options);
|
269 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
270 | actions: [
|
271 | mockAction({ account: 'eosio', name: 'newaccount', authorization: { permission }, data: {
|
272 | creator: ORE_PAYER_ACCOUNT_NAME,
|
273 | name: expect.any(String),
|
274 | newact: expect.any(String),
|
275 | owner: expect.any(Object),
|
276 | active: expect.any(Object),
|
277 | } }),
|
278 | mockAction({ account: 'eosio', name: 'buyrambytes', authorization: { permission } }),
|
279 | mockAction({ account: 'eosio', name: 'delegatebw', authorization: { permission }, data: {
|
280 | from: ORE_PAYER_ACCOUNT_NAME,
|
281 | receiver: expect.any(String),
|
282 | stake_net_quantity: '0.1000 SYS',
|
283 | stake_cpu_quantity: '0.1000 SYS',
|
284 | transfer: false,
|
285 | } }),
|
286 | ],
|
287 | }, mockOptions());
|
288 | expect(spyTransaction).toHaveBeenNthCalledWith(2, {
|
289 | actions: [
|
290 | mockAction({ account: 'eosio', name: 'updateauth' }),
|
291 | mockAction({ account: 'eosio', name: 'linkauth' }),
|
292 | ],
|
293 | }, mockOptions());
|
294 | expect(spyAccount).toHaveBeenCalledWith(expect.any(String));
|
295 | expect(spyInfo).toHaveBeenCalledWith({});
|
296 | expect(spyBlock).toHaveBeenCalledWith(block.block_num + 1);
|
297 | expect(account).toEqual({
|
298 | verifierAuthKey: expect.stringMatching(/^\w*$/),
|
299 | verifierAuthPublicKey: expect.stringMatching(/^EOS\w*$/),
|
300 | oreAccountName: expect.stringMatching(/[a-z1-5]{12}/),
|
301 | privateKey: expect.stringMatching(/^\{.*\}$/),
|
302 | publicKey: expect.stringMatching(/^EOS\w*$/),
|
303 | keys: expect.objectContaining({
|
304 | privateKeys: expect.objectContaining({
|
305 | active: expect.stringMatching(/^\{.*\}$/),
|
306 | owner: expect.stringMatching(/^\{.*\}$/)
|
307 | }),
|
308 | publicKeys: expect.objectContaining({
|
309 | active: expect.stringMatching(/^EOS\w*$/),
|
310 | owner: expect.stringMatching(/^EOS\w*$/)
|
311 | })
|
312 | }),
|
313 | transaction,
|
314 | });
|
315 | expect(ecc.privateToPublic(orejs.decrypt(account.privateKey, WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT))).toEqual(account.publicKey);
|
316 | expect(ecc.privateToPublic(account.verifierAuthKey)).toEqual(account.verifierAuthPublicKey);
|
317 | });
|
318 |
|
319 | describe('when the name already exists', () => {
|
320 | let spyAccount;
|
321 |
|
322 | beforeEach(() => {
|
323 | mockGetAccountWithAlreadyExistingAccount(orejs);
|
324 | spyAccount = jest.spyOn(orejs.eos.rpc, 'get_account');
|
325 | });
|
326 |
|
327 | it('still returns a new account', async () => {
|
328 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME);
|
329 | expect(spyAccount).toHaveBeenCalledWith(expect.stringMatching(/[a-z1-5]{12}/));
|
330 | expect(account).toEqual({
|
331 | verifierAuthKey: expect.stringMatching(/^\w*$/),
|
332 | verifierAuthPublicKey: expect.stringMatching(/^EOS\w*$/),
|
333 | oreAccountName: expect.stringMatching(/[a-z1-5]{12}/),
|
334 | privateKey: expect.stringMatching(/^\{.*\}$/),
|
335 | publicKey: expect.stringMatching(/^EOS\w*$/),
|
336 | keys: expect.objectContaining({
|
337 | privateKeys: expect.objectContaining({
|
338 | active: expect.stringMatching(/^\{.*\}$/),
|
339 | owner: expect.stringMatching(/^\{.*\}$/)
|
340 | }),
|
341 | publicKeys: expect.objectContaining({
|
342 | active: expect.stringMatching(/^EOS\w*$/),
|
343 | owner: expect.stringMatching(/^EOS\w*$/)
|
344 | })
|
345 | }),
|
346 | transaction,
|
347 | });
|
348 | });
|
349 | });
|
350 |
|
351 | describe('when defining an account name prefix', () => {
|
352 | const options = { accountNamePrefix: 'ore' };
|
353 |
|
354 | it('returns an account with the proper name', async () => {
|
355 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME, options);
|
356 | expect(account).toEqual(expect.objectContaining({
|
357 | oreAccountName: expect.stringMatching(/ore[a-z1-5]{9}/),
|
358 | }));
|
359 | });
|
360 | });
|
361 |
|
362 | describe('when pre-defining keys', () => {
|
363 | const key = 'EOS5vTStKDUDbLHu4hSi8iFrmaJET88HHcL5oVBYQ1wd2aeMHgHs2';
|
364 | const options = { keys: { publicKeys: { owner: key } } }
|
365 |
|
366 | it('returns an account with the specified key', async () => {
|
367 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME, options);
|
368 | expect(account).toEqual(expect.objectContaining({
|
369 | keys: expect.objectContaining({
|
370 | publicKeys: expect.objectContaining({ owner: key })
|
371 | }),
|
372 | }));
|
373 | });
|
374 | });
|
375 |
|
376 | describe('when defining an eos chain', () => {
|
377 | let spyTransaction;
|
378 | let transaction;
|
379 | let info;
|
380 | let block;
|
381 |
|
382 | beforeEach(() => {
|
383 | orejs = constructOrejs({ chainName: 'eos' });
|
384 | mockGetAccount(orejs);
|
385 | transaction = mockGetTransaction(orejs);
|
386 | info = mockGetInfo(orejs);
|
387 | block = mockGetBlock(orejs, { block_num: info.head_block_num, transactions: [{ trx: { id: transaction.transaction_id } }] });
|
388 | spyTransaction = jest.spyOn(orejs.eos, 'transact');
|
389 | });
|
390 |
|
391 | it('returns a new account with the expected tokenSymbol', async () => {
|
392 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME);
|
393 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
394 | actions: [
|
395 | mockAction({ account: 'eosio', name: 'newaccount' }),
|
396 | mockAction({ account: 'eosio', name: 'buyrambytes' }),
|
397 | mockAction({ account: 'eosio', name: 'delegatebw', data: {
|
398 | from: ORE_PAYER_ACCOUNT_NAME,
|
399 | receiver: expect.any(String),
|
400 | stake_net_quantity: '0.1000 EOS',
|
401 | stake_cpu_quantity: '0.1000 EOS',
|
402 | transfer: false,
|
403 | } }),
|
404 | ],
|
405 | }, mockOptions());
|
406 | });
|
407 |
|
408 | it('returns a new account without the verifier keys', async () => {
|
409 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME);
|
410 | expect(account).toEqual({
|
411 | oreAccountName: expect.stringMatching(/[a-z1-5]{12}/),
|
412 | privateKey: expect.stringMatching(/^\{.*\}$/),
|
413 | publicKey: expect.stringMatching(/^EOS\w*$/),
|
414 | keys: expect.objectContaining({
|
415 | privateKeys: expect.objectContaining({
|
416 | active: expect.stringMatching(/^\{.*\}$/),
|
417 | owner: expect.stringMatching(/^\{.*\}$/)
|
418 | }),
|
419 | publicKeys: expect.objectContaining({
|
420 | active: expect.stringMatching(/^EOS\w*$/),
|
421 | owner: expect.stringMatching(/^EOS\w*$/)
|
422 | })
|
423 | }),
|
424 | transaction,
|
425 | });
|
426 | });
|
427 | });
|
428 |
|
429 | describe('when the chain fails to create a new account', async () => {
|
430 | let options = { confirm: true };
|
431 |
|
432 | beforeEach(() => {
|
433 | transaction = mockGetTransaction(orejs, false);
|
434 | });
|
435 |
|
436 | it('returns a failure', async () => {
|
437 | try {
|
438 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME, options);
|
439 | } catch(error) {
|
440 | expect(error.message).toMatch(/^Await Transaction Failure: .*/);
|
441 | }
|
442 | });
|
443 | });
|
444 | });
|
445 |
|
446 | describe('when defining the accountName', () => {
|
447 | beforeEach(() => {
|
448 | let transaction = mockGetTransaction(orejs);
|
449 | let info = mockGetInfo(orejs);
|
450 | let block = mockGetBlock(orejs, { block_num: info.head_block_num, transactions: [{ trx: { id: transaction.transaction_id } }] });
|
451 | });
|
452 |
|
453 | it('returns a new account with the expected accountName', async () => {
|
454 | const oreAccountName = 'thenameiwant';
|
455 | const options = { oreAccountName };
|
456 | const account = await orejs.createOreAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, ORE_OWNER_ACCOUNT_KEY, ORE_PAYER_ACCOUNT_NAME, options);
|
457 | expect(account).toEqual({
|
458 | oreAccountName,
|
459 | privateKey: expect.stringMatching(/^\{.*\}$/),
|
460 | publicKey: expect.stringMatching(/^EOS\w*$/),
|
461 | keys: expect.objectContaining({
|
462 | privateKeys: expect.objectContaining({
|
463 | active: expect.stringMatching(/^\{.*\}$/),
|
464 | owner: expect.stringMatching(/^\{.*\}$/)
|
465 | }),
|
466 | publicKeys: expect.objectContaining({
|
467 | active: expect.stringMatching(/^EOS\w*$/),
|
468 | owner: expect.stringMatching(/^EOS\w*$/)
|
469 | })
|
470 | }),
|
471 | transaction,
|
472 | });
|
473 | });
|
474 | });
|
475 |
|
476 | });
|
477 |
|
478 | describe('createBridgeAccount', () => {
|
479 | let spyTransaction;
|
480 | let spyAccount;
|
481 | let spyInfo;
|
482 | let spyBlock;
|
483 |
|
484 | beforeEach(() => {
|
485 | mockGetAccount(orejs);
|
486 | transaction = mockGetTransaction(orejs);
|
487 | info = mockGetInfo(orejs);
|
488 | block = mockGetBlock(orejs, { block_num: info.head_block_num, transactions: [{ trx: { id: transaction.transaction_id } }] });
|
489 | spyTransaction = jest.spyOn(orejs.eos, 'transact');
|
490 | spyAccount = jest.spyOn(orejs.eos.rpc, 'get_account');
|
491 | spyInfo = jest.spyOn(orejs.eos.rpc, 'get_info');
|
492 | spyBlock = jest.spyOn(orejs.eos.rpc, 'get_block');
|
493 | });
|
494 |
|
495 | it('returns a new account', async () => {
|
496 | const permission = 'custom';
|
497 | const accountName = 'eptestoretyl';
|
498 | const dappName = 'ep.test.ore.tyl';
|
499 | const options = { permission, origin: dappName };
|
500 | const authorizingAccount = { accountName, permission };
|
501 | const account = await orejs.createBridgeAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, authorizingAccount, options);
|
502 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
503 | actions: [
|
504 | mockAction({ account: 'createbridge', name: 'create', authorization: { permission }, data: {
|
505 | memo: accountName,
|
506 | account: expect.stringMatching(/[a-z1-5]{12}/),
|
507 | ownerkey: expect.stringMatching(/^EOS\w*$/),
|
508 | activekey: expect.stringMatching(/^EOS\w*$/),
|
509 | origin: dappName
|
510 | } }),
|
511 | ],
|
512 | }, mockOptions());
|
513 | expect(spyAccount).toHaveBeenCalledWith(expect.any(String));
|
514 | expect(spyInfo).toHaveBeenCalledWith({});
|
515 | expect(spyBlock).toHaveBeenCalledWith(block.block_num + 1);
|
516 | expect(account).toEqual({
|
517 | oreAccountName: expect.stringMatching(/[a-z1-5]{12}/),
|
518 | privateKey: expect.stringMatching(/^\{.*\}$/),
|
519 | publicKey: expect.stringMatching(/^EOS\w*$/),
|
520 | keys: expect.objectContaining({
|
521 | privateKeys: expect.objectContaining({
|
522 | active: expect.stringMatching(/^\{.*\}$/),
|
523 | owner: expect.stringMatching(/^\{.*\}$/)
|
524 | }),
|
525 | publicKeys: expect.objectContaining({
|
526 | active: expect.stringMatching(/^EOS\w*$/),
|
527 | owner: expect.stringMatching(/^EOS\w*$/)
|
528 | })
|
529 | }),
|
530 | transaction,
|
531 | });
|
532 | expect(ecc.privateToPublic(orejs.decrypt(account.privateKey, WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT))).toEqual(account.publicKey);
|
533 | });
|
534 |
|
535 | it('returns a new account under a new contractName', async () => {
|
536 | const permission = 'custom';
|
537 | const accountName = 'eptestoretyl';
|
538 | const dappName = 'ep.test.ore.tyl';
|
539 | const contractName = 'orebridge';
|
540 | const options = { permission, origin: dappName, contractName };
|
541 | const authorizingAccount = { accountName, permission };
|
542 | const account = await orejs.createBridgeAccount(WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT, authorizingAccount, options);
|
543 | expect(spyTransaction).toHaveBeenNthCalledWith(1, {
|
544 | actions: [
|
545 | mockAction({ account: contractName, name: 'create', authorization: { permission }, data: {
|
546 | memo: accountName,
|
547 | account: expect.stringMatching(/[a-z1-5]{12}/),
|
548 | ownerkey: expect.stringMatching(/^EOS\w*$/),
|
549 | activekey: expect.stringMatching(/^EOS\w*$/),
|
550 | origin: dappName
|
551 | } }),
|
552 | ],
|
553 | }, mockOptions());
|
554 | expect(spyAccount).toHaveBeenCalledWith(expect.any(String));
|
555 | expect(spyInfo).toHaveBeenCalledWith({});
|
556 | expect(spyBlock).toHaveBeenCalledWith(block.block_num + 1);
|
557 | expect(account).toEqual({
|
558 | oreAccountName: expect.stringMatching(/[a-z1-5]{12}/),
|
559 | privateKey: expect.stringMatching(/^\{.*\}$/),
|
560 | publicKey: expect.stringMatching(/^EOS\w*$/),
|
561 | keys: expect.objectContaining({
|
562 | privateKeys: expect.objectContaining({
|
563 | active: expect.stringMatching(/^\{.*\}$/),
|
564 | owner: expect.stringMatching(/^\{.*\}$/)
|
565 | }),
|
566 | publicKeys: expect.objectContaining({
|
567 | active: expect.stringMatching(/^EOS\w*$/),
|
568 | owner: expect.stringMatching(/^EOS\w*$/)
|
569 | })
|
570 | }),
|
571 | transaction,
|
572 | });
|
573 | expect(ecc.privateToPublic(orejs.decrypt(account.privateKey, WALLET_PASSWORD, USER_ACCOUNT_ENCRYPTION_SALT))).toEqual(account.publicKey);
|
574 | });
|
575 | });
|
576 |
|
577 | describe('eosBase32', () => {
|
578 | it('encodes correctly', async () => {
|
579 | const accountName = await orejs.eosBase32('abcde.067899');
|
580 | expect(accountName).toEqual('abcde.vwxyzz');
|
581 | });
|
582 | });
|
583 |
|
584 | describe('generateAccountName', () => {
|
585 | let spyAccount;
|
586 | let accountMock;
|
587 |
|
588 | beforeEach(() => {
|
589 | accountMock = mockGetAccount(orejs);
|
590 | });
|
591 |
|
592 | it('returns a random string', async () => {
|
593 | const accountName = await orejs.generateAccountName();
|
594 | expect(accountMock).toHaveBeenCalled();
|
595 | expect(accountName).toEqual(expect.stringMatching(/[a-z1-5]{12}/))
|
596 | });
|
597 |
|
598 | it('lets us prefix account names', async () => {
|
599 | const accountName = await orejs.generateAccountName('ore');
|
600 | expect(accountName).toEqual(expect.stringMatching(/ore[a-z1-5]{9}/))
|
601 | });
|
602 |
|
603 | it('does not always have to check for pre-existing names', async () => {
|
604 | const accountName = await orejs.generateAccountName('ore', false);
|
605 | expect(accountMock).not.toHaveBeenCalled();
|
606 | expect(accountName).toEqual(expect.stringMatching(/ore[a-z1-5]{9}/))
|
607 | });
|
608 | });
|
609 |
|
610 | describe('generateEncryptedKeys', async () => {
|
611 | const password = 'password';
|
612 | const salt = 'salt';
|
613 |
|
614 | it('returns a full set of keys', async () => {
|
615 | const keys = await orejs.generateEncryptedKeys(password, salt);
|
616 | expect(keys).toEqual(expect.objectContaining({
|
617 | privateKeys: expect.objectContaining({
|
618 | active: expect.stringMatching(/^\{.*\}$/),
|
619 | owner: expect.stringMatching(/^\{.*\}$/)
|
620 | }),
|
621 | publicKeys: expect.objectContaining({
|
622 | active: expect.stringMatching(/^EOS\w*$/),
|
623 | owner: expect.stringMatching(/^EOS\w*$/)
|
624 | })
|
625 | }));
|
626 | });
|
627 |
|
628 | describe('when partially defining keys', () => {
|
629 | const publicKey = 'EOS8MoQ6DPdM9SWsaKbYTu1P54tLvdxrZY8DQ5uUrwQ9LMtoByCwm';
|
630 | const predefinedKeys = { publicKeys: { owner: publicKey } };
|
631 |
|
632 | it('returns the both the specified and non-specified keys', async () => {
|
633 | const keys = await orejs.generateEncryptedKeys(password, salt, predefinedKeys);
|
634 | expect(keys).toEqual(expect.objectContaining({
|
635 | publicKeys: expect.objectContaining({
|
636 | active: expect.stringMatching(/^EOS\w*$/),
|
637 | owner: expect.stringMatching(publicKey)
|
638 | })
|
639 | }));
|
640 | });
|
641 | });
|
642 |
|
643 | describe('when defining unencrypted keys', () => {
|
644 | const privateKey = '5KC9gtjqTQHLchEZAu4QUif8MNKoZPZENEJmsiapvxDAJCZpzGK';
|
645 | const predefinedKeys = { privateKeys: { owner: privateKey } };
|
646 |
|
647 | it('returns the key encrypted', async () => {
|
648 | const keys = await orejs.generateEncryptedKeys(password, salt, predefinedKeys);
|
649 | expect(keys).toEqual(expect.objectContaining({
|
650 | privateKeys: expect.objectContaining({
|
651 | active: expect.stringMatching(/^\{.*\}$/),
|
652 | owner: expect.stringMatching(/^\{.*\}$/)
|
653 | })
|
654 | }));
|
655 | });
|
656 | });
|
657 |
|
658 | describe('when defining encrypted keys', () => {
|
659 | const privateKey = '{"iv":"xr5XTgow76QCpEe8Tij7xw==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"gcm","adata":"","cipher":"aes","ct":"2YAap55e6O8gwZ6m33UjEjxqw1GU+cZbVrYP7TDRFiF0axe1XJ2W+uvhgG5ArEga8GO8cnNf+6KaFaQ="}';
|
660 | const predefinedKeys = { privateKeys: { owner: privateKey } };
|
661 |
|
662 | it('returns the key', async () => {
|
663 | const keys = await orejs.generateEncryptedKeys(password, salt, predefinedKeys);
|
664 | expect(keys).toEqual(expect.objectContaining({
|
665 | privateKeys: expect.objectContaining({
|
666 | active: expect.stringMatching(/^\{.*\}$/),
|
667 | owner: expect.stringContaining(privateKey)
|
668 | })
|
669 | }));
|
670 | });
|
671 | });
|
672 | });
|
673 |
|
674 | describe('getNameAlreadyExists', async () => {
|
675 | let accountName;
|
676 |
|
677 | beforeEach(() => {
|
678 | accountName = 'thenameiwant';
|
679 | });
|
680 |
|
681 | describe('when the name already exists', async () => {
|
682 |
|
683 | beforeEach(() => {
|
684 | mockGetAccountWithAlreadyExistingAccount(orejs);
|
685 | });
|
686 |
|
687 | it('return true', async () => {
|
688 | const nameAlreadyExists = await orejs.getNameAlreadyExists(accountName);
|
689 | expect(nameAlreadyExists).toEqual(true);
|
690 | });
|
691 | });
|
692 |
|
693 | describe('when the name does not yet exist', async () => {
|
694 |
|
695 | beforeEach(() => {
|
696 | mockGetAccount(orejs);
|
697 | });
|
698 |
|
699 | it('returns false', async () => {
|
700 | const nameAlreadyExists = await orejs.getNameAlreadyExists(accountName);
|
701 | expect(nameAlreadyExists).toEqual(false);
|
702 | });
|
703 | });
|
704 | });
|
705 | });
|