Skip to content

Commit

Permalink
Update wallet.encrypt function signature 4.x (#5581)
Browse files Browse the repository at this point in the history
* fix

* fix unit tests

* lint fix

* fix build

* fix lint

* fix test utils

* add change logs

* Update packages/web3-eth-accounts/CHANGELOG.md

Co-authored-by: Junaid <[email protected]>

* Update packages/web3-eth-accounts/CHANGELOG.md

Co-authored-by: Junaid <[email protected]>

* Update CHANGELOG.md

Co-authored-by: Junaid <[email protected]>

* fix change logs

Co-authored-by: Junaid <[email protected]>
  • Loading branch information
avkos and jdevcs authored Nov 9, 2022
1 parent 9b15fb1 commit b967954
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 98 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ should use 4.0.1-alpha.0 for testing.
#### web3-eth-contract

- According to the latest change in `web3-eth-abi`, the decoded values of the large numbers, returned from function calls or events, are now available as `BigInt`. (#5435)
- Emit past contract events based on `fromBlock` when passed to `contract.events.someEventName` (#5201)
- Emit past contract events based on `fromBlock` when passed to `contract.events.someEventName` (#5201)

#### web3-eth-abi

Expand Down Expand Up @@ -893,3 +893,15 @@ should use 4.0.1-alpha.0 for testing.
- Removed direct function `toJSON()` in `Web3ValidatorError` class as its available via base class (#5435)

## [Unreleased]

### Added

#### web3-types

- These types were moved from `web3-eth-accounts` to `web3-types` package: Cipher, CipherOptions, ScryptParams, PBKDF2SHA256Params, KeyStore (#5581 )

### Removed

#### web3-eth-accounts

- These types were moved from `web3-eth-accounts` to `web3-types` package: Cipher, CipherOptions, ScryptParams, PBKDF2SHA256Params, KeyStore (#5581 )
4 changes: 4 additions & 0 deletions packages/web3-eth-accounts/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `signTransaction` and `privateKeyToAccount` will throw `TransactionSigningError` instead of `SignerError` now (#5462)

## [Unreleased]

### Removed

- These types were moved to `web3-types` package: Cipher, CipherOptions, ScryptParams, PBKDF2SHA256Params, KeyStore (#5581)
29 changes: 12 additions & 17 deletions packages/web3-eth-accounts/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ import {
TransactionSigningError,
UndefinedRawTransactionError,
} from 'web3-errors';
import { Address, Bytes, HexString } from 'web3-types';
import {
Address,
Bytes,
HexString,
CipherOptions,
PBKDF2SHA256Params,
ScryptParams,
KeyStore,
} from 'web3-types';
import {
bytesToBuffer,
bytesToHex,
Expand All @@ -47,16 +55,7 @@ import {
} from 'web3-utils';
import { isBuffer, isNullish, isString, validator } from 'web3-validator';
import { keyStoreSchema } from './schemas';
import {
CipherOptions,
KeyStore,
PBKDF2SHA256Params,
ScryptParams,
SignatureObject,
SignResult,
SignTransactionResult,
Web3Account,
} from './types';
import { SignatureObject, SignResult, SignTransactionResult, Web3Account } from './types';

/**
* Get the private key buffer after the validation
Expand Down Expand Up @@ -574,7 +573,6 @@ export const encrypt = async (
const ciphertext = bytesToHex(cipher).slice(2);

const mac = sha3Raw(Buffer.from([...derivedKey.slice(16, 32), ...cipher])).replace('0x', '');

return {
version: 3,
id: uuidV4(),
Expand Down Expand Up @@ -625,11 +623,8 @@ export const privateKeyToAccount = (privateKey: Bytes, ignoreLength?: boolean):
},
sign: (data: Record<string, unknown> | string) =>
sign(typeof data === 'string' ? data : JSON.stringify(data), privateKeyBuffer),
encrypt: async (password: string, options?: Record<string, unknown>) => {
const data = await encrypt(privateKeyBuffer, password, options);

return JSON.stringify(data);
},
encrypt: async (password: string, options?: Record<string, unknown>) =>
encrypt(privateKeyBuffer, password, options),
};
};

Expand Down
43 changes: 0 additions & 43 deletions packages/web3-eth-accounts/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,49 +47,6 @@ export type SignFunction = (data: string, privateKey: string) => SignResult;

// https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition

export type Cipher = 'aes-128-ctr' | 'aes-128-cbc' | 'aes-256-cbc';

export type CipherOptions = {
salt?: Buffer | string;
iv?: Buffer | string;
kdf?: 'scrypt' | 'pbkdf2';
dklen?: number;
c?: number; // iterrations
n?: number; // cpu/memory cost
r?: number; // block size
p?: number; // parallelization cost
};

export type ScryptParams = {
dklen: number;
n: number;
p: number;
r: number;
salt: Buffer | string;
};
export type PBKDF2SHA256Params = {
c: number; // iterations
dklen: number;
prf: 'hmac-sha256';
salt: Buffer | string;
};

export type KeyStore = {
crypto: {
cipher: Cipher;
ciphertext: string;
cipherparams: {
iv: string;
};
kdf: 'pbkdf2' | 'scrypt';
kdfparams: ScryptParams | PBKDF2SHA256Params;
mac: HexString;
};
id: string;
version: 3;
address: string;
};

export interface Web3Account extends Web3BaseWalletAccount {
address: HexString;
privateKey: HexString;
Expand Down
20 changes: 11 additions & 9 deletions packages/web3-eth-accounts/src/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ You should have received a copy of the GNU Lesser General Public License
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

import { Web3BaseWallet, Web3BaseWalletAccount, Web3EncryptedWallet } from 'web3-types';
import { Web3BaseWallet, Web3BaseWalletAccount, KeyStore } from 'web3-types';
import { isNullish } from 'web3-validator';
import { WebStorage } from './types';

Expand Down Expand Up @@ -172,7 +172,7 @@ export class Wallet<
* Get the account of the wallet with either the index or public address.
*
* @param addressOrIndex - A string of the address or number index within the wallet.
* @returns The account object or undefined if the account doesnt exist
* @returns The account object or undefined if the account doesn't exist
*/

public get(addressOrIndex: string | number): T | undefined {
Expand All @@ -193,7 +193,7 @@ export class Wallet<
* Removes an account from the wallet.
*
* @param addressOrIndex - The account address, or index in the wallet.
* @returns true if the wallet was removed. false if it couldnt be found.
* @returns true if the wallet was removed. false if it couldn't be found.
* ```ts
* web3.eth.accounts.wallet.add('0xbce9b59981303e76c4878b1a6d7b088ec6b9dd5c966b7d5f54d7a749ff683387');
*
Expand Down Expand Up @@ -279,8 +279,11 @@ export class Wallet<
* ]
* ```
*/
public async encrypt(password: string, options?: Record<string, unknown> | undefined) {
return Promise.all(this.map(async account => account.encrypt(password, options)));
public async encrypt(
password: string,
options?: Record<string, unknown> | undefined,
): Promise<KeyStore[]> {
return Promise.all(this.map(async (account: T) => account.encrypt(password, options)));
}

/**
Expand Down Expand Up @@ -358,16 +361,15 @@ export class Wallet<
* ```
*/
public async decrypt(
encryptedWallets: string[],
encryptedWallets: KeyStore[],
password: string,
options?: Record<string, unknown> | undefined,
) {
const results = await Promise.all(
encryptedWallets.map(async wallet =>
encryptedWallets.map(async (wallet: KeyStore) =>
this._accountProvider.decrypt(wallet, password, options),
),
);

for (const res of results) {
this.add(res);
}
Expand Down Expand Up @@ -430,7 +432,7 @@ export class Wallet<
const keystore = storage.getItem(keyName ?? this._defaultKeyName);

if (keystore) {
await this.decrypt((JSON.parse(keystore) as Web3EncryptedWallet[]) || [], password);
await this.decrypt((JSON.parse(keystore) as KeyStore[]) || [], password);
}

return this;
Expand Down
2 changes: 1 addition & 1 deletion packages/web3-eth-accounts/test/fixtures/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import {
IVLengthError,
PBKDF2IterationsError,
} from 'web3-errors';
import { CipherOptions, KeyStore } from 'web3-types';
import { sign, signTransaction, encrypt } from '../../src/account';
import { CipherOptions, KeyStore } from '../../src/types';

export const validPrivateKeyToAddressData: [string, string][] = [
[
Expand Down
13 changes: 4 additions & 9 deletions packages/web3-eth-accounts/test/integration/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.

/* eslint-disable @typescript-eslint/no-magic-numbers */

import { Web3AccountProvider } from 'web3-types';
import { Web3AccountProvider, KeyStore } from 'web3-types';
import { isBrowser, isElectron, itIf } from '../fixtures/system_test_utils';
import { Wallet } from '../../src';
import * as accountProvider from '../../src/account';
import { Web3Account } from '../../dist';

describe('Wallet', () => {
let wallet: Wallet;
Expand Down Expand Up @@ -222,14 +221,10 @@ describe('Wallet', () => {
wallet.add(account1);
wallet.add(account2);

const result: string[] = await wallet.encrypt('password', options);
const result: KeyStore[] = await wallet.encrypt('password', options);
expect(result).toHaveLength(2);
expect(`0x${(JSON.parse(result[0]) as Web3Account)?.address.toLowerCase()}`).toBe(
account1.address.toLowerCase(),
);
expect(`0x${(JSON.parse(result[1]) as Web3Account)?.address.toLowerCase()}`).toBe(
account2.address.toLowerCase(),
);
expect(`0x${result[0]?.address.toLowerCase()}`).toBe(account1.address.toLowerCase());
expect(`0x${result[1]?.address.toLowerCase()}`).toBe(account2.address.toLowerCase());
});
});

Expand Down
10 changes: 5 additions & 5 deletions packages/web3-eth-accounts/test/unit/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
/* eslint-disable @typescript-eslint/no-magic-numbers */

import { when } from 'jest-when';
import { Web3AccountProvider, Web3BaseWalletAccount } from 'web3-types';
import { Web3AccountProvider, Web3BaseWalletAccount, KeyStore } from 'web3-types';
import { Wallet } from '../../src/wallet';

describe('Wallet', () => {
Expand Down Expand Up @@ -264,8 +264,8 @@ describe('Wallet', () => {

describe('decrypt', () => {
it('should decrypt all accounts and add to wallet', async () => {
const encryptedAccount1 = 'encrypted_account1';
const encryptedAccount2 = 'encrypted_account2';
const encryptedAccount1 = { address: 'encrypted_account1' } as KeyStore;
const encryptedAccount2 = { address: 'encrypted_account2' } as KeyStore;
const account1 = { address: 'my_address1' } as any;
const account2 = { address: 'my_address2' } as any;
const options = { myOptions: 'myOptions' };
Expand Down Expand Up @@ -304,7 +304,7 @@ describe('Wallet', () => {
});

it('should encrypt wallet and store with local storage for given key', async () => {
const encryptedWallet = ['encryptedWallet'];
const encryptedWallet = [{ address: 'encryptedWallet' }] as KeyStore[];
jest.spyOn(wallet, 'encrypt').mockResolvedValue(encryptedWallet);

await wallet.save('password', 'myKey');
Expand All @@ -319,7 +319,7 @@ describe('Wallet', () => {
});

it('should encrypt wallet and store with local storage with default key', async () => {
const encryptedWallet = ['encryptedWallet'];
const encryptedWallet = [{ address: 'encryptedWallet' }] as KeyStore[];
jest.spyOn(wallet, 'encrypt').mockResolvedValue(encryptedWallet);

await wallet.save('password');
Expand Down
2 changes: 1 addition & 1 deletion packages/web3-eth-contract/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,6 @@ const transactionHash = receipt.transactionHash;
### Fixed

- According to the latest change in `web3-eth-abi`, the decoded values of the large numbers, returned from function calls or events, are now available as `BigInt`. (#5435)
- Emit past contract events based on `fromBlock` when passed to `contract.events.someEventName` (#5201)
- Emit past contract events based on `fromBlock` when passed to `contract.events.someEventName` (#5201)

## [Unreleased]
4 changes: 4 additions & 0 deletions packages/web3-types/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Web3APISpec`, `Web3APIMethod`, and `Web3APIParams` now supports `unknown` APIs (#5393)

## [Unreleased]

### Added

- These types were moved from `web3-eth-accounts` to `web3-types` package: Cipher, CipherOptions, ScryptParams, PBKDF2SHA256Params, KeyStore (#5581 )
58 changes: 50 additions & 8 deletions packages/web3-types/src/web3_base_wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,48 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
import { HexString } from './primitives_types';

export type Web3EncryptedWallet = string;
export type Cipher = 'aes-128-ctr' | 'aes-128-cbc' | 'aes-256-cbc';

export type CipherOptions = {
salt?: Buffer | string;
iv?: Buffer | string;
kdf?: 'scrypt' | 'pbkdf2';
dklen?: number;
c?: number; // iterrations
n?: number; // cpu/memory cost
r?: number; // block size
p?: number; // parallelization cost
};

export type ScryptParams = {
dklen: number;
n: number;
p: number;
r: number;
salt: Buffer | string;
};
export type PBKDF2SHA256Params = {
c: number; // iterations
dklen: number;
prf: 'hmac-sha256';
salt: Buffer | string;
};

export type KeyStore = {
crypto: {
cipher: Cipher;
ciphertext: string;
cipherparams: {
iv: string;
};
kdf: 'pbkdf2' | 'scrypt';
kdfparams: ScryptParams | PBKDF2SHA256Params;
mac: HexString;
};
id: string;
version: 3;
address: string;
};

export interface Web3BaseWalletAccount {
[key: string]: unknown;
Expand All @@ -38,16 +79,17 @@ export interface Web3BaseWalletAccount {
readonly message?: string;
readonly signature: HexString;
};
readonly encrypt: (
password: string,
options?: Record<string, unknown>,
) => Promise<Web3EncryptedWallet>;
readonly encrypt: (password: string, options?: Record<string, unknown>) => Promise<KeyStore>;
}

export interface Web3AccountProvider<T> {
privateKeyToAccount: (privateKey: string) => T;
create: () => T;
decrypt: (keystore: string, password: string, options?: Record<string, unknown>) => Promise<T>;
decrypt: (
keystore: KeyStore | string,
password: string,
options?: Record<string, unknown>,
) => Promise<T>;
}

export abstract class Web3BaseWallet<T extends Web3BaseWalletAccount> extends Array<T> {
Expand All @@ -66,9 +108,9 @@ export abstract class Web3BaseWallet<T extends Web3BaseWalletAccount> extends Ar
public abstract encrypt(
password: string,
options?: Record<string, unknown>,
): Promise<Web3EncryptedWallet[]>;
): Promise<KeyStore[]>;
public abstract decrypt(
encryptedWallet: Web3EncryptedWallet[],
encryptedWallet: KeyStore[],
password: string,
options?: Record<string, unknown>,
): Promise<this>;
Expand Down
Loading

0 comments on commit b967954

Please sign in to comment.