Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 90d78c1

Browse files
author
Alex
authored
add privateKeyToPublicKey function to accounts (#6466)
1 parent bfcbea8 commit 90d78c1

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

packages/web3-eth-accounts/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ Documentation:
139139

140140
## [Unreleased]
141141

142+
### Added
143+
144+
- Added public function `privateKeyToPublicKey`
145+
142146
### Fixed
143147

144-
- Fixed `recover` function, `v` will be normalized to value 0,1 (#6344)
148+
- Fixed `recover` function, `v` will be normalized to value 0,1 (#6344)

packages/web3-eth-accounts/src/account.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,25 @@ export const privateKeyToAddress = (privateKey: Bytes): string => {
386386
return toChecksumAddress(`0x${address}`);
387387
};
388388

389+
/**
390+
* Get the public key from a private key
391+
*
392+
* @param privateKey - String or Uint8Array of 32 bytes
393+
* @param isCompressed - if true, will generate a 33 byte compressed public key instead of a 65 byte public key
394+
* @returns The public key
395+
* @example
396+
* ```ts
397+
* privateKeyToAddress("0x1e046a882bb38236b646c9f135cf90ad90a140810f439875f2a6dd8e50fa261f", true)
398+
* > "0x42beb65f179720abaa3ec9a70a539629cbbc5ec65bb57e7fc78977796837e537662dd17042e6449dc843c281067a4d6d8d1a1775a13c41901670d5de7ee6503a" // uncompressed public key
399+
* ```
400+
*/
401+
export const privateKeyToPublicKey = (privateKey: Bytes, isCompressed: boolean): string => {
402+
const privateKeyUint8Array = parseAndValidatePrivateKey(privateKey);
403+
404+
// Get public key from private key in compressed format
405+
return `0x${bytesToHex(secp256k1.getPublicKey(privateKeyUint8Array, isCompressed)).slice(4)}`; // 0x and removing compression byte
406+
};
407+
389408
/**
390409
* encrypt a private key with a password, returns a V3 JSON Keystore
391410
*

packages/web3-eth-accounts/test/fixtures/account.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
IVLengthError,
2525
PBKDF2IterationsError,
2626
} from 'web3-errors';
27-
import { CipherOptions, KeyStore } from 'web3-types';
27+
import { CipherOptions, KeyStore, Bytes } from 'web3-types';
2828
import { hexToBytes } from 'web3-utils';
2929
import { AccessListEIP2930TxData, FeeMarketEIP1559TxData, TxData } from '../../src/tx/types';
3030
import { sign, signTransaction, encrypt } from '../../src/account';
@@ -221,6 +221,31 @@ export const invalidPrivateKeytoAccountData: [
221221
[new Uint8Array([]), new PrivateKeyLengthError()],
222222
];
223223

224+
export const validPrivateKeyToPublicKeyData: [
225+
Bytes, boolean, string // private key, isCompressed, public key
226+
][] = [
227+
[
228+
"0x1e046a882bb38236b646c9f135cf90ad90a140810f439875f2a6dd8e50fa261f", // test string to uncompressed publickey
229+
false,
230+
"0x42beb65f179720abaa3ec9a70a539629cbbc5ec65bb57e7fc78977796837e537662dd17042e6449dc843c281067a4d6d8d1a1775a13c41901670d5de7ee6503a",
231+
],
232+
[
233+
"0x1e046a882bb38236b646c9f135cf90ad90a140810f439875f2a6dd8e50fa261f", // test string to compressed publickey
234+
true,
235+
"0x42beb65f179720abaa3ec9a70a539629cbbc5ec65bb57e7fc78977796837e537",
236+
],
237+
[
238+
hexToBytes("0xd933beabed94a9f23917576596b2bc64ffeacfe5ded09a99c0feee8369bd295d"), // test uint8array to uncompressed publickey
239+
false,
240+
"0x7891db4ed2d26584b0fa87329c40b398c940c08e7dbeb8e3dad83f34dba284c933fb14b1edd8893fa89af3823fd827ee59044033ca068803030afc294de5f390",
241+
],
242+
[
243+
hexToBytes("0xd933beabed94a9f23917576596b2bc64ffeacfe5ded09a99c0feee8369bd295d"), // test uint8array to compressed publickey
244+
true,
245+
"0x7891db4ed2d26584b0fa87329c40b398c940c08e7dbeb8e3dad83f34dba284c9",
246+
],
247+
];
248+
224249
export const validEncryptData: [[any, string | Uint8Array, CipherOptions], KeyStore][] = [
225250
[
226251
[

packages/web3-eth-accounts/test/unit/account.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
recoverTransaction,
2929
sign,
3030
signTransaction,
31+
privateKeyToPublicKey
3132
} from '../../src/account';
3233
import {
3334
invalidDecryptData,
@@ -42,6 +43,7 @@ import {
4243
validHashMessageData,
4344
validPrivateKeytoAccountData,
4445
validPrivateKeyToAddressData,
46+
validPrivateKeyToPublicKeyData,
4547
validRecover,
4648
} from '../fixtures/account';
4749
import { TransactionFactory } from '../../src/tx/transactionFactory';
@@ -91,6 +93,13 @@ describe('accounts', () => {
9193
});
9294
});
9395
});
96+
describe('privateKeyToPublicKey', () => {
97+
describe('valid cases', () => {
98+
it.each(validPrivateKeyToPublicKeyData)('%s', (privateKey, isCompressed, output) => {
99+
expect(privateKeyToPublicKey(privateKey, isCompressed)).toEqual(output);
100+
});
101+
})
102+
})
94103

95104
describe('Signing and Recovery of Transaction', () => {
96105
it.each(transactionsTestData)('sign transaction', async txData => {

0 commit comments

Comments
 (0)