From 4bdd5bac01e965fdf05740f42e14678e17bf5303 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Thu, 23 Jan 2025 19:45:04 +0000 Subject: [PATCH 01/14] fix: fr9 recommendations --- packages/core/src/secp256k1/Secp256k1.ts | 38 ++- .../tests/secp256k1/Secp256k1.unit.test.ts | 216 ++++++++++-------- packages/core/tests/secp256k1/fixture.ts | 49 ---- 3 files changed, 146 insertions(+), 157 deletions(-) delete mode 100644 packages/core/tests/secp256k1/fixture.ts diff --git a/packages/core/src/secp256k1/Secp256k1.ts b/packages/core/src/secp256k1/Secp256k1.ts index 2d8416404..c083e8ad5 100644 --- a/packages/core/src/secp256k1/Secp256k1.ts +++ b/packages/core/src/secp256k1/Secp256k1.ts @@ -107,7 +107,7 @@ class Secp256k1 { * * {@link global.crypto.subtle.generateKey}; * * [nc_secp256k1.utils.randomPrivateKey](https://github.com/paulmillr/noble-secp256k1). */ - public static async generatePrivateKey(): Promise { + public static async _generatePrivateKey(): Promise { try { return nc_secp256k1.utils.randomPrivateKey(); } catch (e) { @@ -132,6 +132,32 @@ class Secp256k1 { } } + /** + * Generates a new Secp256k1 private key using a secure random number generator. + * + * @return {Promise} A promise that resolves to a Uint8Array representing the generated private key. + * This encoded private key is suitable for cryptographic operations. + * @throws {InvalidSecp256k1PrivateKey} Throws an error if private key generation fails if a secure random number + * generator is not provided by the hosting operating system. + * + * @remarks Security auditable method, depends on + * * [nc_secp256k1.utils.randomPrivateKey](https://github.com/paulmillr/noble-secp256k1). + */ + public static async generatePrivateKey(): Promise { + return await new Promise((resolve) => { + try { + resolve(nc_secp256k1.utils.randomPrivateKey()); + } catch (e) { + throw new InvalidSecp256k1PrivateKey( + 'Secp256k1.generatePrivateKey', + 'Private key generation failed: ensure you have a secure random number generator available at runtime.', + undefined, + e + ); + } + }); + } + /** * Inflate a compressed public key to its uncompressed form. * @@ -192,20 +218,18 @@ class Secp256k1 { * {@link {@link global.crypto} is used as fall back togenerate * the random sequence. * - * @param {number} [bytesLength=32] - Optional. The number of random bytes to generate. + * @param {number} [bytesLength=32] - Optional. The number of random bytes to generate, 32 by default. * @return {Uint8Array} - A Uint8Array containing the random bytes. * * @remarks Security auditable method, depends on - * * {@link global.crypto.getRandomValues}; + * * {@link global.crypto.getRandomValues}; * * [nh_randomBytes](https://github.com/paulmillr/noble-hashes). */ - public static randomBytes(bytesLength?: number): Uint8Array { + public static randomBytes(bytesLength: number = 32): Uint8Array { try { return nh_randomBytes(bytesLength); } catch (e) { - return global.crypto.getRandomValues( - new Uint8Array(bytesLength ?? 32) - ); + return global.crypto.getRandomValues(new Uint8Array(bytesLength)); } } diff --git a/packages/core/tests/secp256k1/Secp256k1.unit.test.ts b/packages/core/tests/secp256k1/Secp256k1.unit.test.ts index 9bd0b29f5..210b0dd14 100644 --- a/packages/core/tests/secp256k1/Secp256k1.unit.test.ts +++ b/packages/core/tests/secp256k1/Secp256k1.unit.test.ts @@ -4,177 +4,191 @@ import { InvalidSecp256k1PrivateKey, InvalidSecp256k1Signature } from '@vechain/sdk-errors'; -import { HexUInt, Secp256k1, ZERO_BYTES } from '../../src'; -import { - invalidMessageHashes, - messageHashBuffer, - privateKey, - publicKeyCompressed, - publicKeyUncompressed, - signature, - validMessageHashes, - validPrivateKeys -} from './fixture'; +import { Keccak256, Secp256k1, Txt, ZERO_BYTES } from '../../src'; +import * as n_utils from '@noble/curves/abstract/utils'; + +const HASHES = { + invalid: Txt.of('some_invalid_stuff').bytes, + valid: Keccak256.of(Txt.of('hello world').bytes).bytes +}; + +const KEYS = { + private: { + invalid: n_utils.hexToBytes( + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' + ), + valid: n_utils.hexToBytes( + '7582be841ca040aa940fff6c05773129e135623e41acce3e0b8ba520dc1ae26a' + ) + }, + public: { + compressed: n_utils.hexToBytes( + '03b90e9bb2617387eba4502c730de65a33878ef384a46f1096d86f2da19043304a' + ), + uncompressed: n_utils.hexToBytes( + '04b90e9bb2617387eba4502c730de65a33878ef384a46f1096d86f2da19043304afa67d0ad09cf2bea0c6f2d1767a9e62a7a7ecc41facf18f2fa505d92243a658f' + ) + } +}; + +const SIGNATURES = { + valid: n_utils.hexToBytes( + 'f8fe82c74f9e1f5bf443f8a7f8eb968140f554968fdcab0a6ffe904e451c8b9244be44bccb1feb34dd20d9d8943f8c131227e55861736907b02d32c06b934d7200' + ) +}; /** * Test Secp256k1 class. * @group unit/Secp256k1 */ describe('Secp256k1 class tests', () => { - const invalid = new TextEncoder().encode('some_invalid_stuff'); - describe('Secp256k1 - compressPublicKey', () => { - test('Secp256k1 - compressPublicKey - from compressed', () => { + describe('compressPublicKey', () => { + test('ok <- compressed', () => { expect( - Secp256k1.compressPublicKey(publicKeyCompressed) - ).toStrictEqual(publicKeyCompressed); + Secp256k1.compressPublicKey(KEYS.public.compressed) + ).toStrictEqual(KEYS.public.compressed); }); - test('Secp256k1 - compressPublicKey - from uncompressed', () => { + test('ok <- uncompressed', () => { expect( - Secp256k1.compressPublicKey(publicKeyUncompressed) - ).toStrictEqual(publicKeyCompressed); + Secp256k1.compressPublicKey(KEYS.public.uncompressed) + ).toStrictEqual(KEYS.public.compressed); }); }); - describe('Secp256k1 - derivePublicKey', () => { - test('Secp256k1 - derivePublicKey - compressed', () => { - expect(Secp256k1.derivePublicKey(privateKey)).toStrictEqual( - Secp256k1.compressPublicKey(publicKeyUncompressed) + describe('derivePublicKey', () => { + test('ok <- compressed', () => { + expect(Secp256k1.derivePublicKey(KEYS.private.valid)).toStrictEqual( + Secp256k1.compressPublicKey(KEYS.public.compressed) ); }); - test('Secp256k1 - derivePublicKey - uncompressed', () => { - expect(Secp256k1.derivePublicKey(privateKey, false)).toStrictEqual( - publicKeyUncompressed - ); + test('ok <- uncompressed', () => { + expect( + Secp256k1.derivePublicKey(KEYS.private.valid, false) + ).toStrictEqual(KEYS.public.uncompressed); }); - test('Secp256k1 - derivePublicKey - error', () => { + test('error <- invalid key', () => { expect(() => Secp256k1.derivePublicKey(ZERO_BYTES(32)) ).toThrowError(InvalidSecp256k1PrivateKey); }); }); - describe('Secp256k1 - generatePublicKey', () => { - test('Secp256k1 - generatePrivateKey', async () => { - const randomPrivateKey = await Secp256k1.generatePrivateKey(); + describe('generatePrivateKey', () => { + test('ok <- noble library', async () => { + const privateKey = await Secp256k1.generatePrivateKey(); // Length of private key should be 32 bytes - expect(randomPrivateKey.length).toBe(32); + expect(privateKey.length).toBe(32); // Private key should be valid - expect(Secp256k1.isValidPrivateKey(randomPrivateKey)).toBe(true); + expect(Secp256k1.isValidPrivateKey(privateKey)).toBe(true); + }); + + test('error <- mock no hw support for cryptography', async () => { + jest.spyOn(Secp256k1, 'generatePrivateKey').mockImplementation( + () => { + throw new InvalidSecp256k1PrivateKey( + 'Secp256k1.generatePrivateKey', + 'Private key generation failed: ensure you have a secure random number generator available at runtime.', + undefined + ); + } + ); + await expect( + async () => await Secp256k1.generatePrivateKey() + ).rejects.toThrowError(InvalidSecp256k1PrivateKey); }); }); - describe('Secp256k1 - inflatePublicKey', () => { - test('Secp256k1 - inflatePublicKey - compressed', () => { + describe('inflatePublicKey', () => { + test('ok <- compressed', () => { expect( - Secp256k1.inflatePublicKey(publicKeyCompressed) - ).toStrictEqual(publicKeyUncompressed); + Secp256k1.inflatePublicKey(KEYS.public.compressed) + ).toStrictEqual(KEYS.public.uncompressed); }); - test('Secp256k1 - inflatePublicKey - uncompressed', () => { + test('ok <- uncompressed', () => { expect( - Secp256k1.inflatePublicKey(publicKeyUncompressed) - ).toStrictEqual(publicKeyUncompressed); + Secp256k1.inflatePublicKey(KEYS.public.uncompressed) + ).toStrictEqual(KEYS.public.uncompressed); }); }); - describe('Secp256k1 - isValidMessageHash', () => { - test('Secp256k1 - isValidMessageHash - true', () => { - validMessageHashes.forEach((messageHash: Uint8Array) => { - expect(Secp256k1.isValidMessageHash(messageHash)).toBe(true); - }); + describe('isValidMessageHash', () => { + test('true <- valid', () => { + expect(Secp256k1.isValidMessageHash(HASHES.valid)).toBe(true); }); - test('Secp256k1 - isValidMessageHash - false', () => { - invalidMessageHashes.forEach((messageHash: Uint8Array) => { - expect(Secp256k1.isValidMessageHash(messageHash)).toBe(false); - }); + test('false <- invalid', () => { + expect(Secp256k1.isValidMessageHash(HASHES.invalid)).toBe(false); }); }); - describe('Secp256k1 - isValidPrivateKey', () => { - test('Secp256k1 - isValidPrivateKey - true', () => { - validPrivateKeys.forEach((privateKey: Uint8Array) => { - expect(Secp256k1.isValidPrivateKey(privateKey)).toBe(true); - }); + describe('isValidPrivateKey', () => { + test('true <- valid', () => { + expect(Secp256k1.isValidPrivateKey(KEYS.private.valid)).toBe(true); }); - test('Secp256k1 - isValidPrivateKey - false', () => { - validPrivateKeys.forEach((privateKey: Uint8Array) => { - expect(Secp256k1.isValidPrivateKey(privateKey)).toBe(true); - }); + test('false <- invalid', () => { + expect(Secp256k1.isValidPrivateKey(KEYS.private.invalid)).toBe( + false + ); }); }); - describe('Secp256k1 - sign', () => { - test('Secp256k1 - sign - success', () => { - expect(Secp256k1.sign(messageHashBuffer, privateKey)).toStrictEqual( - signature - ); + describe('sign', () => { + test('ok - valid hash', () => { + expect( + Secp256k1.sign(HASHES.valid, KEYS.private.valid) + ).toStrictEqual(SIGNATURES.valid); }); - test('Secp256k1 - sign - failure - invalid message hash', () => { - expect(() => Secp256k1.sign(invalid, privateKey)).toThrowError( - InvalidSecp256k1MessageHash - ); + test('error <- invalid hash', () => { + expect(() => + Secp256k1.sign(HASHES.invalid, KEYS.private.valid) + ).toThrowError(InvalidSecp256k1MessageHash); }); - test('Secp256k1 - sign - failure - invalid private key', () => { + test('error <- invalid private key', () => { expect(() => - Secp256k1.sign( - messageHashBuffer, - HexUInt.of( - 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff' - ).bytes - ) + Secp256k1.sign(HASHES.valid, KEYS.private.invalid) ).toThrowError(InvalidSecp256k1PrivateKey); }); }); - describe('Secp256k1 - randomBytes', () => { - test('Secp256k1 - randomBytes - without parameters', () => { + describe('randomBytes', () => { + test('ok <- default', () => { const result = Secp256k1.randomBytes(); - expect(result.length).toBeGreaterThan(0); + expect(result.length).toBe(32); }); - test('Secp256k1 - randomBytes - with param', () => { + test('ok <- set length', () => { const result = Secp256k1.randomBytes(16); expect(result.length).toBe(16); }); - - test('Secp256k1 - randomBytes - with param', () => { - expect(() => Secp256k1.randomBytes(28)).toBeDefined(); - }); }); - describe('Secp256k1 - recover', () => { - test('Secp256k1 - recover - success', () => { + describe('recover', () => { + test('ok < - valid', () => { expect( - Secp256k1.recover(messageHashBuffer, signature) - ).toStrictEqual(publicKeyUncompressed); + Secp256k1.recover(HASHES.valid, SIGNATURES.valid) + ).toStrictEqual(KEYS.public.uncompressed); }); - test('Secp256k1 - recover - invalid message hash', () => { - expect(() => Secp256k1.recover(invalid, signature)).toThrowError( - InvalidSecp256k1MessageHash - ); - }); - - test('Secp256k1 - recover - invalid signature', () => { - // Invalid signature + test('error <- invalid hash', () => { expect(() => - Secp256k1.recover(messageHashBuffer, invalid) - ).toThrowError(InvalidSecp256k1Signature); + Secp256k1.recover(HASHES.invalid, SIGNATURES.valid) + ).toThrowError(InvalidSecp256k1MessageHash); }); - test('Secp256k1 - recover - failure', () => { - // Invalid signature recovery - const invalidSignatureRecovery = new Uint8Array(signature); - invalidSignatureRecovery[64] = 8; + test('error <- invalid signature', () => { + // Forge an invalid signature... + const invalidSignature = new Uint8Array(SIGNATURES.valid); + // ... altering the last byte. + invalidSignature[64] = 8; expect(() => - Secp256k1.recover(messageHashBuffer, invalidSignatureRecovery) + Secp256k1.recover(HASHES.valid, invalidSignature) ).toThrowError(InvalidSecp256k1Signature); }); }); diff --git a/packages/core/tests/secp256k1/fixture.ts b/packages/core/tests/secp256k1/fixture.ts deleted file mode 100644 index e14fb1845..000000000 --- a/packages/core/tests/secp256k1/fixture.ts +++ /dev/null @@ -1,49 +0,0 @@ -import * as n_utils from '@noble/curves/abstract/utils'; -import { Keccak256, Txt } from '../../src'; - -/** - * Simple public key and private key pair with corresponding signature - */ -const privateKey = n_utils.hexToBytes( - '7582be841ca040aa940fff6c05773129e135623e41acce3e0b8ba520dc1ae26a' -); - -const publicKeyCompressed = n_utils.hexToBytes( - '03b90e9bb2617387eba4502c730de65a33878ef384a46f1096d86f2da19043304a' -); - -const publicKeyUncompressed = n_utils.hexToBytes( - '04b90e9bb2617387eba4502c730de65a33878ef384a46f1096d86f2da19043304afa67d0ad09cf2bea0c6f2d1767a9e62a7a7ecc41facf18f2fa505d92243a658f' -); - -const signature = n_utils.hexToBytes( - 'f8fe82c74f9e1f5bf443f8a7f8eb968140f554968fdcab0a6ffe904e451c8b9244be44bccb1feb34dd20d9d8943f8c131227e55861736907b02d32c06b934d7200' -); - -/** - * Simple message hashes - */ -const messageHashBuffer = Keccak256.of(Txt.of('hello world').bytes).bytes; -const validMessageHashes = [messageHashBuffer]; -const invalidMessageHashes = [Txt.of('some_invalid_stuff').bytes]; - -/** - * Valid and invalid private keys - */ -const validPrivateKeys = [ - // PLEASE: Don't use this private key for your wallet :D - n_utils.hexToBytes( - '7582be841ca040aa940fff6c05773129e135623e41acce3e0b8ba520dc1ae26a' - ) -]; - -export { - invalidMessageHashes, - messageHashBuffer, - privateKey, - publicKeyCompressed, - publicKeyUncompressed, - signature, - validMessageHashes, - validPrivateKeys -}; From c56175ce3e8907c81dd5c9a8d6460228680293dd Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 24 Jan 2025 18:24:25 +0000 Subject: [PATCH 02/14] fix: en_1 recommendations --- docs/accounts.md | 2 +- docs/certificates.md | 2 +- docs/cryptography.md | 2 +- docs/examples/accounts/keystore.ts | 2 +- docs/examples/certificates/sign_verify.ts | 2 +- docs/examples/cryptography/secp256k1.ts | 2 +- .../transactions/blockref-expiration.ts | 2 +- .../examples/transactions/multiple-clauses.ts | 2 +- docs/examples/transactions/sign-decode.ts | 2 +- docs/examples/transactions/tx-dependency.ts | 2 +- docs/transactions.md | 8 +-- packages/core/src/secp256k1/Secp256k1.ts | 63 ++++--------------- .../core/tests/keystore/keystore.unit.test.ts | 10 +-- .../tests/secp256k1/Secp256k1.unit.test.ts | 12 ++-- ...provider-internal-base-wallet.unit.test.ts | 5 +- 15 files changed, 38 insertions(+), 80 deletions(-) diff --git a/docs/accounts.md b/docs/accounts.md index 030eb7c66..7b8b55b49 100644 --- a/docs/accounts.md +++ b/docs/accounts.md @@ -130,7 +130,7 @@ Through the use of mnemonics and keystore, VeChainSDK ensures secure and user-fr ```typescript { name=keystore, category=example } // 1 - Create private key using Secp256k1 -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // @NOTE you can use BIP 39 too! // const words = Mnemonic.of() diff --git a/docs/certificates.md b/docs/certificates.md index 5ccdf6912..770f64bc1 100644 --- a/docs/certificates.md +++ b/docs/certificates.md @@ -47,7 +47,7 @@ It's important to note that certificates in the VeChainThor blockchain are self- ```typescript { name=sign_verify, category=example } // 1 - Generate a private key and address for the signer -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); const publicKey = Secp256k1.derivePublicKey(privateKey); const signerAddress = Address.ofPublicKey(publicKey).toString(); diff --git a/docs/cryptography.md b/docs/cryptography.md index 14d1d8dab..caa0e412e 100644 --- a/docs/cryptography.md +++ b/docs/cryptography.md @@ -51,7 +51,7 @@ Secp256k1 is mainly used for generating public and private key pairs in cryptogr ```typescript { name=secp256k1, category=example } // 1 - Generate a private key. -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); console.log('Private key:', Hex.of(privateKey).toString()); // Private key: ...SOME_PRIVATE_KEY... diff --git a/docs/examples/accounts/keystore.ts b/docs/examples/accounts/keystore.ts index de3d5e41d..b120514c9 100644 --- a/docs/examples/accounts/keystore.ts +++ b/docs/examples/accounts/keystore.ts @@ -5,7 +5,7 @@ import { expect } from 'expect'; // 1 - Create private key using Secp256k1 -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // @NOTE you can use BIP 39 too! // const words = Mnemonic.of() diff --git a/docs/examples/certificates/sign_verify.ts b/docs/examples/certificates/sign_verify.ts index 30843549d..aea3f4843 100644 --- a/docs/examples/certificates/sign_verify.ts +++ b/docs/examples/certificates/sign_verify.ts @@ -4,7 +4,7 @@ import { Address, Certificate, Secp256k1 } from '@vechain/sdk-core'; // 1 - Generate a private key and address for the signer -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); const publicKey = Secp256k1.derivePublicKey(privateKey); const signerAddress = Address.ofPublicKey(publicKey).toString(); diff --git a/docs/examples/cryptography/secp256k1.ts b/docs/examples/cryptography/secp256k1.ts index bfca9d93b..32fce2b51 100644 --- a/docs/examples/cryptography/secp256k1.ts +++ b/docs/examples/cryptography/secp256k1.ts @@ -5,7 +5,7 @@ import { expect } from 'expect'; // 1 - Generate a private key. -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); console.log('Private key:', Hex.of(privateKey).toString()); // Private key: ...SOME_PRIVATE_KEY... diff --git a/docs/examples/transactions/blockref-expiration.ts b/docs/examples/transactions/blockref-expiration.ts index 482b096c7..642592796 100644 --- a/docs/examples/transactions/blockref-expiration.ts +++ b/docs/examples/transactions/blockref-expiration.ts @@ -37,7 +37,7 @@ const body: TransactionBody = { // 3 - Create private key -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // 4 - Sign transaction diff --git a/docs/examples/transactions/multiple-clauses.ts b/docs/examples/transactions/multiple-clauses.ts index 38db1fd8f..3cfd258e6 100644 --- a/docs/examples/transactions/multiple-clauses.ts +++ b/docs/examples/transactions/multiple-clauses.ts @@ -46,7 +46,7 @@ const body: TransactionBody = { }; // Create private key -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // 4 - Sign transaction diff --git a/docs/examples/transactions/sign-decode.ts b/docs/examples/transactions/sign-decode.ts index 2ca476a2c..9fdc00c1c 100644 --- a/docs/examples/transactions/sign-decode.ts +++ b/docs/examples/transactions/sign-decode.ts @@ -40,7 +40,7 @@ const body: TransactionBody = { }; // Create private key -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // 4 - Sign transaction diff --git a/docs/examples/transactions/tx-dependency.ts b/docs/examples/transactions/tx-dependency.ts index 727c0a2eb..cd76ad71c 100644 --- a/docs/examples/transactions/tx-dependency.ts +++ b/docs/examples/transactions/tx-dependency.ts @@ -57,7 +57,7 @@ const txBBody: TransactionBody = { }; // Define the senders private key -const senderPrivateKey = await Secp256k1.generatePrivateKey(); +const senderPrivateKey = Secp256k1.generatePrivateKey(); // To define transaction B as dependent on transaction // it's necessary to sign transaction A, and then get its Id diff --git a/docs/transactions.md b/docs/transactions.md index a4360ecc9..26bbcfa32 100644 --- a/docs/transactions.md +++ b/docs/transactions.md @@ -47,7 +47,7 @@ const body: TransactionBody = { }; // Create private key -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // 4 - Sign transaction @@ -99,7 +99,7 @@ const body: TransactionBody = { }; // Create private key -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // 4 - Sign transaction @@ -214,7 +214,7 @@ const body: TransactionBody = { // 3 - Create private key -const privateKey = await Secp256k1.generatePrivateKey(); +const privateKey = Secp256k1.generatePrivateKey(); // 4 - Sign transaction @@ -277,7 +277,7 @@ const txBBody: TransactionBody = { }; // Define the senders private key -const senderPrivateKey = await Secp256k1.generatePrivateKey(); +const senderPrivateKey = Secp256k1.generatePrivateKey(); // To define transaction B as dependent on transaction // it's necessary to sign transaction A, and then get its Id diff --git a/packages/core/src/secp256k1/Secp256k1.ts b/packages/core/src/secp256k1/Secp256k1.ts index c083e8ad5..c5b421fac 100644 --- a/packages/core/src/secp256k1/Secp256k1.ts +++ b/packages/core/src/secp256k1/Secp256k1.ts @@ -94,70 +94,29 @@ class Secp256k1 { } /** - * Generates a new random private key. - * If an error occurs during generation using - * [nc_secp256k1](https://github.com/paulmillr/noble-secp256k1), - * an AES-GCM key is generated as a fallback in runtimes not supported - * by `nc_secp256k1`, if those support {@link {@link global.crypto}. + * Generates a new Secp256k1 private key using a secure random number generator. * - * @return {Promise} The generated private key as a Uint8Array. + * @return {Uint8Array} A Uint8Array representing the generated private key. + * This encoded private key is suitable for cryptographic operations. + * @throws {InvalidSecp256k1PrivateKey} Throws an error if private key generation fails if a secure random number + * generator is not provided by the hosting operating system. * * @remarks Security auditable method, depends on - * * {@link global.crypto.subtle.exportKey}; - * * {@link global.crypto.subtle.generateKey}; * * [nc_secp256k1.utils.randomPrivateKey](https://github.com/paulmillr/noble-secp256k1). */ - public static async _generatePrivateKey(): Promise { + public static generatePrivateKey(): Uint8Array { try { return nc_secp256k1.utils.randomPrivateKey(); } catch (e) { - // Generate an ECDSA key pair - const cryptoKey = await global.crypto.subtle.generateKey( - { - name: 'AES-GCM', - length: 256 - }, - true, - ['encrypt', 'decrypt'] - ); - - // Export the private key to raw format - const rawKey = await global.crypto.subtle.exportKey( - 'raw', - cryptoKey + throw new InvalidSecp256k1PrivateKey( + 'Secp256k1.generatePrivateKey', + 'Private key generation failed: ensure you have a secure random number generator available at runtime.', + undefined, + e ); - - // Convert the ArrayBuffer to Uint8Array - return new Uint8Array(rawKey); } } - /** - * Generates a new Secp256k1 private key using a secure random number generator. - * - * @return {Promise} A promise that resolves to a Uint8Array representing the generated private key. - * This encoded private key is suitable for cryptographic operations. - * @throws {InvalidSecp256k1PrivateKey} Throws an error if private key generation fails if a secure random number - * generator is not provided by the hosting operating system. - * - * @remarks Security auditable method, depends on - * * [nc_secp256k1.utils.randomPrivateKey](https://github.com/paulmillr/noble-secp256k1). - */ - public static async generatePrivateKey(): Promise { - return await new Promise((resolve) => { - try { - resolve(nc_secp256k1.utils.randomPrivateKey()); - } catch (e) { - throw new InvalidSecp256k1PrivateKey( - 'Secp256k1.generatePrivateKey', - 'Private key generation failed: ensure you have a secure random number generator available at runtime.', - undefined, - e - ); - } - }); - } - /** * Inflate a compressed public key to its uncompressed form. * diff --git a/packages/core/tests/keystore/keystore.unit.test.ts b/packages/core/tests/keystore/keystore.unit.test.ts index 10afec487..5bd8674d6 100644 --- a/packages/core/tests/keystore/keystore.unit.test.ts +++ b/packages/core/tests/keystore/keystore.unit.test.ts @@ -31,7 +31,7 @@ import { encryptionPassword } from './fixture'; */ test('encrypt', async () => { // Generate a random private key - const privateKey = await Secp256k1.generatePrivateKey(); + const privateKey = Secp256k1.generatePrivateKey(); const addressFromPrivateKey = Address.ofPrivateKey(privateKey).toString(); @@ -68,7 +68,7 @@ import { encryptionPassword } from './fixture'; */ test('decrypt', async () => { // Generate a random private key - const privateKey = await Secp256k1.generatePrivateKey(); + const privateKey = Secp256k1.generatePrivateKey(); const expected = HexUInt.of(privateKey).toString(); @@ -93,7 +93,7 @@ import { encryptionPassword } from './fixture'; */ test('decrypt with invalid password', async () => { // Generate a random private key - const privateKey = await Secp256k1.generatePrivateKey(); + const privateKey = Secp256k1.generatePrivateKey(); // Create keystore const myKeystore = await keystore.encrypt( @@ -116,7 +116,7 @@ import { encryptionPassword } from './fixture'; */ test('decrypt invalid keystore', async () => { // Generate a random private key - const privateKey = await Secp256k1.generatePrivateKey(); + const privateKey = Secp256k1.generatePrivateKey(); // Create keystore const myKeystore = await keystore.encrypt( @@ -149,7 +149,7 @@ import { encryptionPassword } from './fixture'; */ test('validation', async () => { // Generate a random private key - const privateKey = await Secp256k1.generatePrivateKey(); + const privateKey = Secp256k1.generatePrivateKey(); // Create keystore const myKeystore = await keystore.encrypt( diff --git a/packages/core/tests/secp256k1/Secp256k1.unit.test.ts b/packages/core/tests/secp256k1/Secp256k1.unit.test.ts index 210b0dd14..372a5a3a3 100644 --- a/packages/core/tests/secp256k1/Secp256k1.unit.test.ts +++ b/packages/core/tests/secp256k1/Secp256k1.unit.test.ts @@ -77,15 +77,15 @@ describe('Secp256k1 class tests', () => { }); describe('generatePrivateKey', () => { - test('ok <- noble library', async () => { - const privateKey = await Secp256k1.generatePrivateKey(); + test('ok <- noble library', () => { + const privateKey = Secp256k1.generatePrivateKey(); // Length of private key should be 32 bytes expect(privateKey.length).toBe(32); // Private key should be valid expect(Secp256k1.isValidPrivateKey(privateKey)).toBe(true); }); - test('error <- mock no hw support for cryptography', async () => { + test('error <- mock no hw support for cryptography', () => { jest.spyOn(Secp256k1, 'generatePrivateKey').mockImplementation( () => { throw new InvalidSecp256k1PrivateKey( @@ -95,9 +95,9 @@ describe('Secp256k1 class tests', () => { ); } ); - await expect( - async () => await Secp256k1.generatePrivateKey() - ).rejects.toThrowError(InvalidSecp256k1PrivateKey); + expect(() => Secp256k1.generatePrivateKey()).toThrowError( + InvalidSecp256k1PrivateKey + ); }); }); diff --git a/packages/network/tests/provider/helpers/provider-internal-wallets/base-wallet/provider-internal-base-wallet.unit.test.ts b/packages/network/tests/provider/helpers/provider-internal-wallets/base-wallet/provider-internal-base-wallet.unit.test.ts index 8d54c56fc..d97d786aa 100644 --- a/packages/network/tests/provider/helpers/provider-internal-wallets/base-wallet/provider-internal-base-wallet.unit.test.ts +++ b/packages/network/tests/provider/helpers/provider-internal-wallets/base-wallet/provider-internal-base-wallet.unit.test.ts @@ -169,9 +169,8 @@ describe('Base wallet tests', () => { // Initialize delegator const delegators: SignTransactionOptions[] = [ { - delegatorPrivateKey: Hex.of( - await Secp256k1.generatePrivateKey() - ).digits + delegatorPrivateKey: Hex.of(Secp256k1.generatePrivateKey()) + .digits }, { delegatorUrl: From e67a97675b2bc437fa63ead5c8f2ac2e77b3306d Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 24 Jan 2025 19:35:51 +0000 Subject: [PATCH 03/14] fix: en_1 recommendations --- packages/core/src/vcdm/hash/Keccak256.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/vcdm/hash/Keccak256.ts b/packages/core/src/vcdm/hash/Keccak256.ts index 83a75d5b4..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 [SHA-3](https://en.wikipedia.org/wiki/SHA-3) [KECCAK 256](https://keccak.team/keccak.html) 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. * From e103e738d5ded51015db747f5e70391e59b289e7 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 25 Jan 2025 12:58:08 +0000 Subject: [PATCH 04/14] fix: en_2 recommendations... --- packages/core/src/vcdm/Address.ts | 31 ++---- .../core/tests/keystore/keystore.unit.test.ts | 7 +- packages/core/tests/vcdm/Address.unit.test.ts | 105 +++++++----------- 3 files changed, 52 insertions(+), 91 deletions(-) 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/tests/keystore/keystore.unit.test.ts b/packages/core/tests/keystore/keystore.unit.test.ts index 10afec487..729157315 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 + ); }); }); }); From 0de0e922616e08a21da6fa1cbc2c02e6304e8348 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Sat, 25 Jan 2025 12:58:08 +0000 Subject: [PATCH 05/14] fix: en_2 recommendations... --- packages/core/src/vcdm/Address.ts | 31 ++---- .../core/tests/keystore/keystore.unit.test.ts | 7 +- packages/core/tests/vcdm/Address.unit.test.ts | 105 +++++++----------- 3 files changed, 52 insertions(+), 91 deletions(-) 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/tests/keystore/keystore.unit.test.ts b/packages/core/tests/keystore/keystore.unit.test.ts index 10afec487..729157315 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 + ); }); }); }); From 06a7788cd43527da145fba1f865035e487314088 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 27 Jan 2025 16:12:12 +0000 Subject: [PATCH 06/14] fix: en_7 recommendations... --- apps/sdk-vite-integration/tsconfig.json | 4 ++-- docs/tsconfig.json | 6 +++--- tsconfig.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/sdk-vite-integration/tsconfig.json b/apps/sdk-vite-integration/tsconfig.json index a1c490262..13b13fc84 100644 --- a/apps/sdk-vite-integration/tsconfig.json +++ b/apps/sdk-vite-integration/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ESNext", + "target": "ES2023", "lib": ["esnext", "dom"], "module": "ESNext", "moduleResolution": "Bundler", @@ -12,4 +12,4 @@ "esModuleInterop": true, "skipLibCheck": true } -} \ No newline at end of file +} diff --git a/docs/tsconfig.json b/docs/tsconfig.json index 1a83e52c0..a2bc768d2 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ESNext", + "target": "ES2023", "module": "ESNext", "moduleResolution": "Node", "allowSyntheticDefaultImports": true, @@ -9,9 +9,9 @@ "compilerOptions": { "esModuleInterop": true, "module": "ESNext", - "target": "ESNext", + "target": "ES2023", "moduleResolution": "Node", }, "esm": true } -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json index 0c3dd000b..4f44deff3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "declarationMap": true, "esModuleInterop": true, "module": "ESNext", - "target": "ESNext", + "target": "ES2023", "forceConsistentCasingInFileNames": true, "inlineSources": false, "isolatedModules": true, @@ -25,4 +25,4 @@ "module": "commonjs" } }, -} \ No newline at end of file +} From 1908cc86216776e82e274a255f66aa3550242ae7 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Mon, 27 Jan 2025 18:14:17 +0000 Subject: [PATCH 07/14] fix: en_7 recommendations... --- apps/sdk-cloudflare-integration/tsconfig.json | 8 ++++---- apps/sdk-nextjs-integration/tsconfig.json | 6 +++--- apps/sdk-vite-integration/src/App.tsx | 6 +++--- apps/sdk-vite-integration/src/components/GetLastBlock.tsx | 2 +- apps/sdk-vite-integration/src/components/Hash.tsx | 2 +- apps/sdk-vite-integration/src/components/TransferLogs.tsx | 4 ++-- apps/sdk-vite-integration/src/const/index.tsx | 2 +- apps/sdk-vite-integration/src/main.tsx | 2 +- apps/sdk-vite-integration/src/types/index.tsx | 2 +- apps/sdk-vite-integration/tests/Hash.spec.tsx | 4 ++-- apps/sdk-vite-integration/tsconfig.app.json | 4 ++-- apps/sdk-vite-integration/tsconfig.json | 4 ++-- apps/sdk-vite-integration/tsconfig.node.json | 4 ++-- docs/tsconfig.json | 8 ++++---- packages/rpc-proxy/tsconfig.json | 8 ++++---- tsconfig.json | 6 +++--- 16 files changed, 36 insertions(+), 36 deletions(-) diff --git a/apps/sdk-cloudflare-integration/tsconfig.json b/apps/sdk-cloudflare-integration/tsconfig.json index f6206be7a..9caec8099 100644 --- a/apps/sdk-cloudflare-integration/tsconfig.json +++ b/apps/sdk-cloudflare-integration/tsconfig.json @@ -1,12 +1,12 @@ { "compilerOptions": { "strict": true, - "module": "esnext", - "target": "esnext", + "module": "Node16", + "target": "ES2023", "lib": [ "esnext" ], - "moduleResolution": "bundler", + "moduleResolution": "Node16", "noEmit": true, "skipLibCheck": true, "allowSyntheticDefaultImports": true, @@ -18,4 +18,4 @@ "./**/*.ts" ] } -} \ No newline at end of file +} diff --git a/apps/sdk-nextjs-integration/tsconfig.json b/apps/sdk-nextjs-integration/tsconfig.json index 99281f9cd..8de2262a8 100644 --- a/apps/sdk-nextjs-integration/tsconfig.json +++ b/apps/sdk-nextjs-integration/tsconfig.json @@ -8,8 +8,8 @@ "forceConsistentCasingInFileNames": true, "noEmit": true, "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "bundler", + "module": "Node16", + "moduleResolution": "Node16", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", @@ -30,7 +30,7 @@ "**/*.ts", "**/*.tsx", "types.d.ts", - ".next/types/**/*.ts", + ".next/types/**/*.ts", "jest.config.js" ], "exclude": ["node_modules"] } diff --git a/apps/sdk-vite-integration/src/App.tsx b/apps/sdk-vite-integration/src/App.tsx index 9b11abeea..9ffdc283f 100644 --- a/apps/sdk-vite-integration/src/App.tsx +++ b/apps/sdk-vite-integration/src/App.tsx @@ -2,9 +2,9 @@ import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom'; import reactLogo from './assets/react.svg'; import viteLogo from '/vite.svg'; import './App.css'; -import Hash from './components/Hash'; -import TransferLogs from './components/TransferLogs'; -import GetLastBlock from './components/GetLastBlock'; +import Hash from './components/Hash.js'; +import TransferLogs from './components/TransferLogs.js'; +import GetLastBlock from './components/GetLastBlock.js'; function App() { return ( diff --git a/apps/sdk-vite-integration/src/components/GetLastBlock.tsx b/apps/sdk-vite-integration/src/components/GetLastBlock.tsx index 0f238d33d..dff854b67 100644 --- a/apps/sdk-vite-integration/src/components/GetLastBlock.tsx +++ b/apps/sdk-vite-integration/src/components/GetLastBlock.tsx @@ -1,6 +1,6 @@ import { type CompressedBlockDetail } from "@vechain/sdk-network"; import { useState } from "react"; -import { thorClient } from "../const"; +import { thorClient } from '../const/index.js'; const GetLastBlock = () => { const [block, setBlock] = useState(null); diff --git a/apps/sdk-vite-integration/src/components/Hash.tsx b/apps/sdk-vite-integration/src/components/Hash.tsx index cd216b37d..89c99833a 100644 --- a/apps/sdk-vite-integration/src/components/Hash.tsx +++ b/apps/sdk-vite-integration/src/components/Hash.tsx @@ -1,6 +1,6 @@ import { Blake2b256, Keccak256, Sha256, Txt } from '@vechain/sdk-core'; import { useEffect, useState } from 'react'; -import { HashedContent } from '../types'; +import { HashedContent } from '../types/index.js'; const Hash = () => { // State of content to hash diff --git a/apps/sdk-vite-integration/src/components/TransferLogs.tsx b/apps/sdk-vite-integration/src/components/TransferLogs.tsx index 89df83990..96827425c 100644 --- a/apps/sdk-vite-integration/src/components/TransferLogs.tsx +++ b/apps/sdk-vite-integration/src/components/TransferLogs.tsx @@ -4,8 +4,8 @@ import { FilterTransferLogsOptions } from '@vechain/sdk-network'; import { Link } from 'react-router-dom'; -import { Transfer } from "../types"; -import { explorerUrl, thorClient } from "../const"; +import { Transfer } from "../types/index.js"; +import { explorerUrl, thorClient } from "../const/index.js"; /** * Reduce the size of a hex string diff --git a/apps/sdk-vite-integration/src/const/index.tsx b/apps/sdk-vite-integration/src/const/index.tsx index f56fb0c46..cb9cb1ad9 100644 --- a/apps/sdk-vite-integration/src/const/index.tsx +++ b/apps/sdk-vite-integration/src/const/index.tsx @@ -1,2 +1,2 @@ // eslint-disable-next-line react-refresh/only-export-components -export * from './const'; +export * from '../const/const.js'; diff --git a/apps/sdk-vite-integration/src/main.tsx b/apps/sdk-vite-integration/src/main.tsx index db032b748..2b9db7ab6 100644 --- a/apps/sdk-vite-integration/src/main.tsx +++ b/apps/sdk-vite-integration/src/main.tsx @@ -1,7 +1,7 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' -import App from './App' +import App from './App.js' createRoot(document.getElementById('root')!).render( diff --git a/apps/sdk-vite-integration/src/types/index.tsx b/apps/sdk-vite-integration/src/types/index.tsx index 8b2ee98ba..85656badb 100644 --- a/apps/sdk-vite-integration/src/types/index.tsx +++ b/apps/sdk-vite-integration/src/types/index.tsx @@ -1 +1 @@ -export type * from './types.d'; +export type * from './types.d.tsx'; diff --git a/apps/sdk-vite-integration/tests/Hash.spec.tsx b/apps/sdk-vite-integration/tests/Hash.spec.tsx index 01b1f6864..809a4c9f4 100644 --- a/apps/sdk-vite-integration/tests/Hash.spec.tsx +++ b/apps/sdk-vite-integration/tests/Hash.spec.tsx @@ -1,9 +1,9 @@ import { expect, test } from 'vitest' import { render } from 'vitest-browser-react' -import Hash from '../src/components/Hash' +import Hash from '../src/components/Hash.js' test('renders name', async () => { const { getByText } = render() await expect.element(getByText('0xbf56c0728fd4e9cf64bfaf6dabab81554103298cdee5cc4d580433aa25e98b00')).toBeInTheDocument() -}) \ No newline at end of file +}) diff --git a/apps/sdk-vite-integration/tsconfig.app.json b/apps/sdk-vite-integration/tsconfig.app.json index 5a2def4b7..414016bec 100644 --- a/apps/sdk-vite-integration/tsconfig.app.json +++ b/apps/sdk-vite-integration/tsconfig.app.json @@ -3,11 +3,11 @@ "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", + "module": "Node16", "skipLibCheck": true, /* Bundler mode */ - "moduleResolution": "Bundler", + "moduleResolution": "Node16", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", diff --git a/apps/sdk-vite-integration/tsconfig.json b/apps/sdk-vite-integration/tsconfig.json index 13b13fc84..e6cb27392 100644 --- a/apps/sdk-vite-integration/tsconfig.json +++ b/apps/sdk-vite-integration/tsconfig.json @@ -2,8 +2,8 @@ "compilerOptions": { "target": "ES2023", "lib": ["esnext", "dom"], - "module": "ESNext", - "moduleResolution": "Bundler", + "module": "Node16", + "moduleResolution": "Node16", "jsx": "react-jsx", "types": ["@vitest/browser/providers/playwright"], "strict": true, diff --git a/apps/sdk-vite-integration/tsconfig.node.json b/apps/sdk-vite-integration/tsconfig.node.json index 9dad70185..d01017db5 100644 --- a/apps/sdk-vite-integration/tsconfig.node.json +++ b/apps/sdk-vite-integration/tsconfig.node.json @@ -2,11 +2,11 @@ "compilerOptions": { "target": "ES2022", "lib": ["ES2023"], - "module": "ESNext", + "module": "Node16", "skipLibCheck": true, /* Bundler mode */ - "moduleResolution": "Bundler", + "moduleResolution": "Node16", "allowImportingTsExtensions": true, "isolatedModules": true, "moduleDetection": "force", diff --git a/docs/tsconfig.json b/docs/tsconfig.json index a2bc768d2..de70fb4e2 100644 --- a/docs/tsconfig.json +++ b/docs/tsconfig.json @@ -1,16 +1,16 @@ { "compilerOptions": { "target": "ES2023", - "module": "ESNext", - "moduleResolution": "Node", + "module": "Node16", + "moduleResolution": "Node16", "allowSyntheticDefaultImports": true, }, "ts-node": { "compilerOptions": { "esModuleInterop": true, - "module": "ESNext", + "module": "Node16", "target": "ES2023", - "moduleResolution": "Node", + "moduleResolution": "Node16", }, "esm": true } diff --git a/packages/rpc-proxy/tsconfig.json b/packages/rpc-proxy/tsconfig.json index 98e4070be..9fccba33f 100644 --- a/packages/rpc-proxy/tsconfig.json +++ b/packages/rpc-proxy/tsconfig.json @@ -4,15 +4,15 @@ "rootDir": "./src", "outDir": "./dist", "strict": true, - "target": "es2020", - "module": "commonjs", + "target": "es2023", + "module": "Node16", "sourceMap": true, "esModuleInterop": true, "resolveJsonModule": true, - "moduleResolution": "node" + "moduleResolution": "Node16" }, "include": [ "./src/**/*.ts", "./tests/**/*.ts" ] -} \ No newline at end of file +} diff --git a/tsconfig.json b/tsconfig.json index 4f44deff3..e578283b2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,12 +5,12 @@ "declaration": true, "declarationMap": true, "esModuleInterop": true, - "module": "ESNext", + "module": "Node16", "target": "ES2023", "forceConsistentCasingInFileNames": true, "inlineSources": false, "isolatedModules": true, - "moduleResolution": "node", + "moduleResolution": "Node16", "noUnusedLocals": false, "noUnusedParameters": false, "preserveWatchOutput": true, @@ -22,7 +22,7 @@ "ts-node": { // these options are overrides used only by ts-node "compilerOptions": { - "module": "commonjs" + "module": "Node16" } }, } From da1bebec9f880f0697976ba546dfffac72a4e94a Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 28 Jan 2025 08:58:20 +0000 Subject: [PATCH 08/14] fix: n_7 recommandations --- .../vechain-private-key-signer.unit.test.ts | 15 ++++++++------- .../contracts/contract.event.solo.test.ts | 8 ++++---- .../thor-client/contracts/contract.solo.test.ts | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts b/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts index ca07ba381..65d23dc6f 100644 --- a/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts +++ b/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts @@ -12,6 +12,7 @@ import { Wallet } from 'ethers'; import { TESTNET_URL, ThorClient, + type TypedDataDomain, VeChainPrivateKeySigner, VeChainProvider, vnsUtils @@ -293,7 +294,7 @@ describe('VeChain base signer tests', () => { ); await expect( signer.signTypedData( - eip712TestCases.invalid.domain, + eip712TestCases.invalid.domain as TypedDataDomain, eip712TestCases.invalid.types, eip712TestCases.invalid.data, eip712TestCases.invalid.primaryType @@ -317,7 +318,7 @@ describe('VeChain base signer tests', () => { }); await expect( signer.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data, eip712TestCases.valid.primaryType @@ -326,7 +327,7 @@ describe('VeChain base signer tests', () => { await expect( signer.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data, eip712TestCases.valid.primaryType @@ -348,7 +349,7 @@ describe('VeChain base signer tests', () => { provider ); const actual = await privateKeySigner.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data, eip712TestCases.valid.primaryType @@ -356,7 +357,7 @@ describe('VeChain base signer tests', () => { expect(actual).toBe(expected); const actualWithoutPrimaryType = await privateKeySigner.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data ); @@ -378,7 +379,7 @@ describe('VeChain base signer tests', () => { const actualWithStringChainId = await privateKeySigner.signTypedData( { - ...eip712TestCases.valid.domain, + ...(eip712TestCases.valid.domain as TypedDataDomain), chainId: vechainChainId }, eip712TestCases.valid.types, @@ -389,7 +390,7 @@ describe('VeChain base signer tests', () => { const actualWithBigintChainId = await privateKeySigner.signTypedData( { - ...eip712TestCases.valid.domain, + ...(eip712TestCases.valid.domain as TypedDataDomain), chainId: BigInt(vechainChainId) }, eip712TestCases.valid.types, diff --git a/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts b/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts index c40f25a66..a7b26c9c7 100644 --- a/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts +++ b/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, test } from '@jest/globals'; -import { ERC20_ABI, HexUInt } from '@vechain/sdk-core'; +import { Address, ERC20_ABI, HexUInt } from '@vechain/sdk-core'; import { InvalidAbiItem } from '@vechain/sdk-errors'; import { THOR_SOLO_URL, @@ -101,7 +101,7 @@ describe('ThorClient - ERC20 Contracts', () => { const eventsWithAnArgsObject = await contract.filters .Transfer({ from: undefined, - to: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address + to: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address).digits}` }) .get(); @@ -476,7 +476,7 @@ describe('ThorClient - ERC20 Contracts', () => { await (await contractEventExample.transact.setValue(3000n)).wait(); const transferCriteria = contractERC20.criteria.Transfer({ - to: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address + to: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address).digits}` }); const valueCriteria = contractEventExample.criteria.ValueSet(); @@ -537,7 +537,7 @@ describe('ThorClient - ERC20 Contracts', () => { await (await contractEventExample.transact.setValue(3000n)).wait(); const transferCriteria = contractERC20.criteria.Transfer({ - to: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address + to: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address).digits}` }); const valueCriteria = contractEventExample.criteria.ValueSet(); diff --git a/packages/network/tests/thor-client/contracts/contract.solo.test.ts b/packages/network/tests/thor-client/contracts/contract.solo.test.ts index 7d419f91b..72005b26a 100644 --- a/packages/network/tests/thor-client/contracts/contract.solo.test.ts +++ b/packages/network/tests/thor-client/contracts/contract.solo.test.ts @@ -654,7 +654,7 @@ describe('ThorClient - Contracts', () => { .StateChanged({ newValue: undefined, oldValue: undefined, - sender: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_SENDER.address + sender: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_SENDER.address).digits}` }) .get(); From 893b4b70f20d711d34442ef466a4397eb2f22703 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 28 Jan 2025 08:58:20 +0000 Subject: [PATCH 09/14] fix: n_7 recommandations --- .../vechain-private-key-signer.unit.test.ts | 15 ++++++++------- .../contracts/contract.event.solo.test.ts | 8 ++++---- .../thor-client/contracts/contract.solo.test.ts | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts b/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts index ca07ba381..65d23dc6f 100644 --- a/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts +++ b/packages/network/tests/signer/signers/vechain-private-key-signer/vechain-private-key-signer.unit.test.ts @@ -12,6 +12,7 @@ import { Wallet } from 'ethers'; import { TESTNET_URL, ThorClient, + type TypedDataDomain, VeChainPrivateKeySigner, VeChainProvider, vnsUtils @@ -293,7 +294,7 @@ describe('VeChain base signer tests', () => { ); await expect( signer.signTypedData( - eip712TestCases.invalid.domain, + eip712TestCases.invalid.domain as TypedDataDomain, eip712TestCases.invalid.types, eip712TestCases.invalid.data, eip712TestCases.invalid.primaryType @@ -317,7 +318,7 @@ describe('VeChain base signer tests', () => { }); await expect( signer.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data, eip712TestCases.valid.primaryType @@ -326,7 +327,7 @@ describe('VeChain base signer tests', () => { await expect( signer.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data, eip712TestCases.valid.primaryType @@ -348,7 +349,7 @@ describe('VeChain base signer tests', () => { provider ); const actual = await privateKeySigner.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data, eip712TestCases.valid.primaryType @@ -356,7 +357,7 @@ describe('VeChain base signer tests', () => { expect(actual).toBe(expected); const actualWithoutPrimaryType = await privateKeySigner.signTypedData( - eip712TestCases.valid.domain, + eip712TestCases.valid.domain as TypedDataDomain, eip712TestCases.valid.types, eip712TestCases.valid.data ); @@ -378,7 +379,7 @@ describe('VeChain base signer tests', () => { const actualWithStringChainId = await privateKeySigner.signTypedData( { - ...eip712TestCases.valid.domain, + ...(eip712TestCases.valid.domain as TypedDataDomain), chainId: vechainChainId }, eip712TestCases.valid.types, @@ -389,7 +390,7 @@ describe('VeChain base signer tests', () => { const actualWithBigintChainId = await privateKeySigner.signTypedData( { - ...eip712TestCases.valid.domain, + ...(eip712TestCases.valid.domain as TypedDataDomain), chainId: BigInt(vechainChainId) }, eip712TestCases.valid.types, diff --git a/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts b/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts index c40f25a66..a7b26c9c7 100644 --- a/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts +++ b/packages/network/tests/thor-client/contracts/contract.event.solo.test.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, test } from '@jest/globals'; -import { ERC20_ABI, HexUInt } from '@vechain/sdk-core'; +import { Address, ERC20_ABI, HexUInt } from '@vechain/sdk-core'; import { InvalidAbiItem } from '@vechain/sdk-errors'; import { THOR_SOLO_URL, @@ -101,7 +101,7 @@ describe('ThorClient - ERC20 Contracts', () => { const eventsWithAnArgsObject = await contract.filters .Transfer({ from: undefined, - to: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address + to: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address).digits}` }) .get(); @@ -476,7 +476,7 @@ describe('ThorClient - ERC20 Contracts', () => { await (await contractEventExample.transact.setValue(3000n)).wait(); const transferCriteria = contractERC20.criteria.Transfer({ - to: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address + to: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address).digits}` }); const valueCriteria = contractEventExample.criteria.ValueSet(); @@ -537,7 +537,7 @@ describe('ThorClient - ERC20 Contracts', () => { await (await contractEventExample.transact.setValue(3000n)).wait(); const transferCriteria = contractERC20.criteria.Transfer({ - to: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address + to: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_RECEIVER.address).digits}` }); const valueCriteria = contractEventExample.criteria.ValueSet(); diff --git a/packages/network/tests/thor-client/contracts/contract.solo.test.ts b/packages/network/tests/thor-client/contracts/contract.solo.test.ts index 7d419f91b..72005b26a 100644 --- a/packages/network/tests/thor-client/contracts/contract.solo.test.ts +++ b/packages/network/tests/thor-client/contracts/contract.solo.test.ts @@ -654,7 +654,7 @@ describe('ThorClient - Contracts', () => { .StateChanged({ newValue: undefined, oldValue: undefined, - sender: TEST_ACCOUNTS.TRANSACTION.TRANSACTION_SENDER.address + sender: `0x${Address.of(TEST_ACCOUNTS.TRANSACTION.TRANSACTION_SENDER.address).digits}` }) .get(); From 6af3507cc06d64be558fcf9759a94755a802a37e Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 28 Jan 2025 12:39:59 +0000 Subject: [PATCH 10/14] Merge branch 'main' into 1656-fr9 --- apps/sdk-vite-integration/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 +} From 6f770b8ac4a46b891cdd8926d1cb671cdc5b230e Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Tue, 28 Jan 2025 18:47:17 +0000 Subject: [PATCH 11/14] Merge branch '1661-en_2' into 1662-en_7 --- .../tests/KMSVeChainSigner.solo.test.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/aws-kms-adapter/tests/KMSVeChainSigner.solo.test.ts b/packages/aws-kms-adapter/tests/KMSVeChainSigner.solo.test.ts index cd4f33379..b4d9552ef 100644 --- a/packages/aws-kms-adapter/tests/KMSVeChainSigner.solo.test.ts +++ b/packages/aws-kms-adapter/tests/KMSVeChainSigner.solo.test.ts @@ -6,7 +6,12 @@ import { Transaction, type TransactionClause } from '@vechain/sdk-core'; -import { signerUtils, THOR_SOLO_URL, ThorClient } from '@vechain/sdk-network'; +import { + signerUtils, + THOR_SOLO_URL, + ThorClient, + type TypedDataDomain +} from '@vechain/sdk-network'; import fs from 'fs'; import path from 'path'; import { @@ -297,7 +302,7 @@ describe('KMSVeChainSigner - Thor Solo', () => { } }; const signature = await signer.signTypedData( - typedData.domain, + typedData.domain as TypedDataDomain, typedData.types, typedData.data, typedData.primaryType @@ -307,7 +312,7 @@ describe('KMSVeChainSigner - Thor Solo', () => { expect(signature).toMatch(/^0x[A-Fa-f0-9]{130}$/); const signatureWithoutPrimaryType = await signer.signTypedData( - typedData.domain, + typedData.domain as TypedDataDomain, typedData.types, typedData.data ); From 6946e6efeb3eb0aec0225694793eea62c1497d67 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 31 Jan 2025 10:50:56 +0000 Subject: [PATCH 12/14] fix: EN_7 --- .../src/components/TransferLogs.tsx | 2 +- apps/sdk-vite-integration/src/main.tsx | 2 +- apps/sdk-vite-integration/tsconfig.json | 15 ++++++++------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/apps/sdk-vite-integration/src/components/TransferLogs.tsx b/apps/sdk-vite-integration/src/components/TransferLogs.tsx index 96827425c..fc24d4f43 100644 --- a/apps/sdk-vite-integration/src/components/TransferLogs.tsx +++ b/apps/sdk-vite-integration/src/components/TransferLogs.tsx @@ -5,7 +5,7 @@ import { } from '@vechain/sdk-network'; import { Link } from 'react-router-dom'; import { Transfer } from "../types/index.js"; -import { explorerUrl, thorClient } from "../const/index.js"; +import { explorerUrl, thorClient } from "../const/index.tsx"; /** * Reduce the size of a hex string diff --git a/apps/sdk-vite-integration/src/main.tsx b/apps/sdk-vite-integration/src/main.tsx index 2b9db7ab6..bef5202a3 100644 --- a/apps/sdk-vite-integration/src/main.tsx +++ b/apps/sdk-vite-integration/src/main.tsx @@ -1,7 +1,7 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' -import App from './App.js' +import App from './App.tsx' createRoot(document.getElementById('root')!).render( diff --git a/apps/sdk-vite-integration/tsconfig.json b/apps/sdk-vite-integration/tsconfig.json index e6cb27392..a80e93b92 100644 --- a/apps/sdk-vite-integration/tsconfig.json +++ b/apps/sdk-vite-integration/tsconfig.json @@ -1,15 +1,16 @@ { "compilerOptions": { - "target": "ES2023", + "allowImportingTsExtensions": true, + "declaration": true, + "esModuleInterop": true, + "jsx": "react-jsx", "lib": ["esnext", "dom"], "module": "Node16", "moduleResolution": "Node16", - "jsx": "react-jsx", - "types": ["@vitest/browser/providers/playwright"], - "strict": true, - "declaration": true, "noEmit": true, - "esModuleInterop": true, - "skipLibCheck": true + "skipLibCheck": true, + "strict": true, + "target": "ES2023", + "types": ["@vitest/browser/providers/playwright"] } } From cfb66975055f6727a48d6c01a55f9fc3a3e929b3 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 31 Jan 2025 10:59:54 +0000 Subject: [PATCH 13/14] fix: EN_7 --- apps/sdk-vite-integration/src/components/TransferLogs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/sdk-vite-integration/src/components/TransferLogs.tsx b/apps/sdk-vite-integration/src/components/TransferLogs.tsx index fc24d4f43..9e55d75f9 100644 --- a/apps/sdk-vite-integration/src/components/TransferLogs.tsx +++ b/apps/sdk-vite-integration/src/components/TransferLogs.tsx @@ -4,7 +4,7 @@ import { FilterTransferLogsOptions } from '@vechain/sdk-network'; import { Link } from 'react-router-dom'; -import { Transfer } from "../types/index.js"; +import { Transfer } from "../types/index.tsx"; import { explorerUrl, thorClient } from "../const/index.tsx"; /** From 5d30fb84f2d731d650358332e7e09c12cf4c5645 Mon Sep 17 00:00:00 2001 From: lucanicoladebiasi Date: Fri, 31 Jan 2025 15:03:09 +0000 Subject: [PATCH 14/14] fix: EN_7 --- apps/sdk-vite-integration/src/App.tsx | 6 +++--- apps/sdk-vite-integration/src/components/GetLastBlock.tsx | 2 +- apps/sdk-vite-integration/src/components/Hash.tsx | 2 +- apps/sdk-vite-integration/src/const/index.tsx | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/sdk-vite-integration/src/App.tsx b/apps/sdk-vite-integration/src/App.tsx index 9ffdc283f..eed507693 100644 --- a/apps/sdk-vite-integration/src/App.tsx +++ b/apps/sdk-vite-integration/src/App.tsx @@ -2,9 +2,9 @@ import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom'; import reactLogo from './assets/react.svg'; import viteLogo from '/vite.svg'; import './App.css'; -import Hash from './components/Hash.js'; -import TransferLogs from './components/TransferLogs.js'; -import GetLastBlock from './components/GetLastBlock.js'; +import Hash from './components/Hash.tsx'; +import TransferLogs from './components/TransferLogs.tsx'; +import GetLastBlock from './components/GetLastBlock.tsx'; function App() { return ( diff --git a/apps/sdk-vite-integration/src/components/GetLastBlock.tsx b/apps/sdk-vite-integration/src/components/GetLastBlock.tsx index dff854b67..8ad53c441 100644 --- a/apps/sdk-vite-integration/src/components/GetLastBlock.tsx +++ b/apps/sdk-vite-integration/src/components/GetLastBlock.tsx @@ -1,6 +1,6 @@ import { type CompressedBlockDetail } from "@vechain/sdk-network"; import { useState } from "react"; -import { thorClient } from '../const/index.js'; +import { thorClient } from '../const/index.tsx'; const GetLastBlock = () => { const [block, setBlock] = useState(null); diff --git a/apps/sdk-vite-integration/src/components/Hash.tsx b/apps/sdk-vite-integration/src/components/Hash.tsx index 89c99833a..d146be133 100644 --- a/apps/sdk-vite-integration/src/components/Hash.tsx +++ b/apps/sdk-vite-integration/src/components/Hash.tsx @@ -1,6 +1,6 @@ import { Blake2b256, Keccak256, Sha256, Txt } from '@vechain/sdk-core'; import { useEffect, useState } from 'react'; -import { HashedContent } from '../types/index.js'; +import { HashedContent } from '../types/index.tsx'; const Hash = () => { // State of content to hash diff --git a/apps/sdk-vite-integration/src/const/index.tsx b/apps/sdk-vite-integration/src/const/index.tsx index cb9cb1ad9..4f2f44285 100644 --- a/apps/sdk-vite-integration/src/const/index.tsx +++ b/apps/sdk-vite-integration/src/const/index.tsx @@ -1,2 +1,2 @@ // eslint-disable-next-line react-refresh/only-export-components -export * from '../const/const.js'; +export * from '../const/const.tsx';