Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update wallet.encrypt function signature 4.x #5581

Merged
merged 12 commits into from
Nov 9, 2022
Merged
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),
luu-alex marked this conversation as resolved.
Show resolved Hide resolved
};
};

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';
avkos marked this conversation as resolved.
Show resolved Hide resolved

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