diff --git a/apps/sdk-vite-integration/package.json b/apps/sdk-vite-integration/package.json index c576f8eee..adc37bcf7 100644 --- a/apps/sdk-vite-integration/package.json +++ b/apps/sdk-vite-integration/package.json @@ -34,4 +34,4 @@ "vitest": "^2.1.6", "vitest-browser-react": "^0.0.3" } -} \ No newline at end of file +} diff --git a/packages/core/src/vcdm/Address.ts b/packages/core/src/vcdm/Address.ts index 6ba492a41..aedc9829a 100644 --- a/packages/core/src/vcdm/Address.ts +++ b/packages/core/src/vcdm/Address.ts @@ -1,14 +1,10 @@ -import { Keccak256 } from './hash/Keccak256'; import { HDKey } from '../hdkey/HDKey'; import { Hex } from './Hex'; import { HexUInt } from './HexUInt'; +import { InvalidDataType, InvalidHDKey } from '@vechain/sdk-errors'; +import { Keccak256 } from './hash/Keccak256'; import { Secp256k1 } from '../secp256k1/Secp256k1'; import { Txt } from './Txt'; -import { - InvalidDataType, - InvalidHDKey, - InvalidSecp256k1PrivateKey -} from '@vechain/sdk-errors'; /** * Represents a VeChain Address as unsigned integer. @@ -89,29 +85,18 @@ class Address extends HexUInt { } /** - * Create an Address instance from the given private key. - * - * @param {Uint8Array} privateKey - The private key to convert. - * - * @param {boolean} [isCompressed=true] - The flag to indicate if the derived public key should be compressed. + * Generates an Address object from the given private key. * - * @returns {Address} The converted address. - * - * @remarks Security auditable method, depends on - * * {@link Secp256k1.derivePublicKey}. + * @param {Uint8Array} privateKey - The private key used to derive the corresponding address. + * @return {Address} The derived Address object. + * @throws {InvalidDataType} If the provided private key is invalid or cannot derive an address. */ - public static ofPrivateKey( - privateKey: Uint8Array, - isCompressed: boolean = true - ): Address { + public static ofPrivateKey(privateKey: Uint8Array): Address { try { return Address.ofPublicKey( - Secp256k1.derivePublicKey(privateKey, isCompressed) + Secp256k1.derivePublicKey(privateKey, true) ); } catch (error) { - if (error instanceof InvalidSecp256k1PrivateKey) { - throw error; - } throw new InvalidDataType( 'Address.ofPrivateKey', 'not a valid private key', diff --git a/packages/core/src/vcdm/hash/Keccak256.ts b/packages/core/src/vcdm/hash/Keccak256.ts index 62af9ecbf..7be2ab498 100644 --- a/packages/core/src/vcdm/hash/Keccak256.ts +++ b/packages/core/src/vcdm/hash/Keccak256.ts @@ -4,13 +4,13 @@ import { Hex } from '../Hex'; import { HexUInt } from '../HexUInt'; /** - * Represents the result of an [SHA-3](https://en.wikipedia.org/wiki/SHA-3) [KECCAK 256](https://keccak.team/keccak.html) hash operation. + * Represents the result of an [KECCAK 256](https://keccak.team/keccak.html) hash operation. * * @extends HexUInt */ class Keccak256 extends HexUInt { /** - * Generates the [KECCAK 256](https://eth-hash.readthedocs.io/en/stable/) hash of the given input. + * Generates the [KECCAK 256](https://keccak.team/keccak.html) hash of the given input. * * @param {bigint | number | string | Uint8Array | Hex} exp - The input value to hash. * diff --git a/packages/core/tests/keystore/keystore.unit.test.ts b/packages/core/tests/keystore/keystore.unit.test.ts index 5bd8674d6..1eac1d72f 100644 --- a/packages/core/tests/keystore/keystore.unit.test.ts +++ b/packages/core/tests/keystore/keystore.unit.test.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, test } from '@jest/globals'; import { + InvalidDataType, InvalidKeystore, InvalidKeystoreParams, InvalidSecp256k1PrivateKey, @@ -60,7 +61,11 @@ import { encryptionPassword } from './fixture'; new TextEncoder().encode('wrong private key'), encryptionPassword ) - ).rejects.toThrowError(InvalidSecp256k1PrivateKey); + ).rejects.toThrowError( + experimentalCryptography + ? InvalidDataType + : InvalidSecp256k1PrivateKey + ); }); /** diff --git a/packages/core/tests/vcdm/Address.unit.test.ts b/packages/core/tests/vcdm/Address.unit.test.ts index ed7f68f0f..efcb22c74 100644 --- a/packages/core/tests/vcdm/Address.unit.test.ts +++ b/packages/core/tests/vcdm/Address.unit.test.ts @@ -1,10 +1,6 @@ import { describe, expect, test } from '@jest/globals'; import { hexToBytes } from '@noble/ciphers/utils'; -import { - InvalidDataType, - InvalidSecp256k1PrivateKey -} from '@vechain/sdk-errors'; -import { fail } from 'assert'; +import { InvalidDataType } from '@vechain/sdk-errors'; import { Address } from '../../src'; /** @@ -13,47 +9,39 @@ import { Address } from '../../src'; */ describe('Address class tests', () => { describe('Construction tests', () => { - test('Return an Address instance if the passed argument is valid', () => { - let exp = '0xcfb79a9c950b78e14c43efa621ebcf9660dbe01f'; - let address = Address.of(exp); + test('ok <- valid lowercase', () => { + const exp = '0xcfb79a9c950b78e14c43efa621ebcf9660dbe01f'; + const address = Address.of(exp); expect(address).toBeInstanceOf(Address); - exp = '0xCfb79a9c950b78E14c43efa621ebcf9660dbe01F'; - address = Address.of(exp); + }); + + test('ok <- valid checksum format', () => { + const exp = '0xCfb79a9c950b78E14c43efa621ebcf9660dbe01F'; + const address = Address.of(exp); expect(address).toBeInstanceOf(Address); - exp = '0xCFB79A9C950B78E14C43EFA621EBCF9660DBE01F'; - address = Address.of(exp); + }); + + test('ok <- valid uppercase', () => { + const exp = '0xCFB79A9C950B78E14C43EFA621EBCF9660DBE01F'; + const address = Address.of(exp); expect(address).toBeInstanceOf(Address); - exp = '0xcaffee'; - address = Address.of(exp); + }); + + test('ok <- valid from shorter expression', () => { + const exp = '0xcaffee'; + const address = Address.of(exp); expect(address).toBeInstanceOf(Address); expect(address.toString().length).toBe(Address.DIGITS + 2); }); - test('Throw an error if the passed argument is an invalid address', () => { + + test('error <- invalid', () => { const exp = '-0xcaffee'; - try { - Address.of(exp); - fail('This should have thrown an error'); - } catch (e) { - expect(e).toBeInstanceOf(InvalidDataType); - if (e instanceof InvalidDataType) { - expect(e.message).toBe( - `Method 'Address.of' failed.` + - `\n-Reason: 'not a valid hexadecimal positive integer expression'` + - `\n-Parameters: \n\t{\n "exp": "-0xcaffee"\n}` + - `\n-Internal error: \n\tMethod 'HexUInt.of' failed.` + - `\n-Reason: 'not a hexadecimal positive integer expression'` + - `\n-Parameters: \n\t{\n "exp": "${exp}",\n "e": {\n "methodName": "HexUInt.of",\n "errorMessage": "not positive",\n "data": {\n "exp": "-0xcaffee"\n }\n }\n}` + - `\n-Internal error: ` + - `\n\tMethod 'HexUInt.of' failed.` + - `\n-Reason: 'not positive'` + - `\n-Parameters: \n\t{\n "exp": "${exp}"\n}` - ); - } - } + expect(() => Address.of(exp)).toThrow(InvalidDataType); }); }); - describe('Key tests', () => { - test('Should get the address from a given private key', () => { + + describe('ofPrivateKey', () => { + test('ok <- private key', () => { const privateKey = hexToBytes( '5434c159b817c377a55f6be66369622976014e78bce2adfd3e44e5de88ce502f' ); @@ -62,23 +50,16 @@ describe('Address class tests', () => { '0x769E8AA372c8309c834EA6749B88861FF73581FF' ); }); - test('Should throw an invalid data type error if the private key is invalid', () => { + + test('error <- invalid', () => { const privateKey = new Uint8Array([1, 2, 3, 4, 5]); - try { - Address.ofPrivateKey(privateKey); - fail('This should have thrown an error'); - } catch (e) { - expect(e).toBeInstanceOf(InvalidSecp256k1PrivateKey); - if (e instanceof InvalidSecp256k1PrivateKey) { - expect(e.message).toBe( - `Method 'Secp256k1.derivePublicKey' failed.` + - `\n-Reason: 'Invalid private key given as input. Ensure it is a valid 32-byte secp256k1 private key.'` + - `\n-Parameters: \n\tundefined` - ); - } - } + expect(() => Address.ofPrivateKey(privateKey)).toThrow( + InvalidDataType + ); }); - test('Should get the address from a given public key', () => { + }); + describe('ofPublicKey', () => { + test('ok <- valid', () => { const publicKey = hexToBytes( '04a6711e14234b1d4e69aeed2acf18b9c3bd0e97db317b509516bd3a87e5b732685ccaf855d9f8a955bc1f420b4ebf8f682c2e480d98a360e7fd0c08e6eef65607' ); @@ -87,22 +68,12 @@ describe('Address class tests', () => { '0x769E8AA372c8309c834EA6749B88861FF73581FF' ); }); - test('Should throw an invalid data type error if the public key is invalid', () => { + + test('error <- invalid', () => { const publicKey = new Uint8Array([1, 2, 3, 4, 5]); - try { - Address.ofPublicKey(publicKey); - fail('This should have thrown an error'); - } catch (e) { - expect(e).toBeInstanceOf(InvalidDataType); - if (e instanceof InvalidDataType) { - expect(e.message).toBe( - `Method 'Address.ofPublicKey' failed.` + - `\n-Reason: 'not a valid public key'` + - `\n-Parameters: \n\t{\n "publicKey": "${publicKey}"\n}` + - `\n-Internal error: \n\tinvalid Point, expected length of 33, or uncompressed 65, got 5` - ); - } - } + expect(() => Address.ofPublicKey(publicKey)).toThrow( + InvalidDataType + ); }); }); });