Skip to content

Commit

Permalink
Merge branch '1661-en_2' into 1662-en_7
Browse files Browse the repository at this point in the history
  • Loading branch information
lucanicoladebiasi committed Jan 28, 2025
1 parent 417f3e5 commit 0a30d35
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 94 deletions.
2 changes: 1 addition & 1 deletion apps/sdk-vite-integration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@
"vitest": "^2.1.4",
"vitest-browser-react": "^0.0.4"
}
}
}
31 changes: 8 additions & 23 deletions packages/core/src/vcdm/Address.ts
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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',
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/vcdm/hash/Keccak256.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
7 changes: 6 additions & 1 deletion packages/core/tests/keystore/keystore.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { beforeEach, describe, expect, test } from '@jest/globals';
import {
InvalidDataType,
InvalidKeystore,
InvalidKeystoreParams,
InvalidSecp256k1PrivateKey,
Expand Down Expand Up @@ -60,7 +61,11 @@ import { encryptionPassword } from './fixture';
new TextEncoder().encode('wrong private key'),
encryptionPassword
)
).rejects.toThrowError(InvalidSecp256k1PrivateKey);
).rejects.toThrowError(
experimentalCryptography
? InvalidDataType
: InvalidSecp256k1PrivateKey
);
});

/**
Expand Down
105 changes: 38 additions & 67 deletions packages/core/tests/vcdm/Address.unit.test.ts
Original file line number Diff line number Diff line change
@@ -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';

/**
Expand All @@ -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'
);
Expand All @@ -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'
);
Expand All @@ -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\tPoint of length 5 was invalid. Expected 33 compressed bytes or 65 uncompressed bytes`
);
}
}
expect(() => Address.ofPublicKey(publicKey)).toThrow(
InvalidDataType
);
});
});
});

1 comment on commit 0a30d35

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test Coverage

Summary

Lines Statements Branches Functions
Coverage: 98%
98.91% (4370/4418) 97.2% (1392/1432) 98.8% (906/917)
Title Tests Skipped Failures Errors Time
core 838 0 πŸ’€ 0 ❌ 0 πŸ”₯ 2m 25s ⏱️
network 731 0 πŸ’€ 0 ❌ 0 πŸ”₯ 4m 56s ⏱️
errors 40 0 πŸ’€ 0 ❌ 0 πŸ”₯ 17.5s ⏱️
logging 3 0 πŸ’€ 0 ❌ 0 πŸ”₯ 19.313s ⏱️
hardhat-plugin 19 0 πŸ’€ 0 ❌ 0 πŸ”₯ 1m 2s ⏱️
aws-kms-adapter 23 0 πŸ’€ 0 ❌ 0 πŸ”₯ 1m 27s ⏱️
ethers-adapter 5 0 πŸ’€ 0 ❌ 0 πŸ”₯ 1m 16s ⏱️
rpc-proxy 37 0 πŸ’€ 0 ❌ 0 πŸ”₯ 1m 8s ⏱️

Please sign in to comment.