diff --git a/apps/sdk-nextjs-integration/src/app/hash/page.tsx b/apps/sdk-nextjs-integration/src/app/hash/page.tsx index fb2beca4a..3e82e6d35 100644 --- a/apps/sdk-nextjs-integration/src/app/hash/page.tsx +++ b/apps/sdk-nextjs-integration/src/app/hash/page.tsx @@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'; -import { blake2b256, keccak256, sha256 } from '@vechain/sdk-core'; +import { Blake2b256, Keccak256, Sha256, Txt } from '@vechain/sdk-core'; import { type HashedContent } from '@/types'; import { Header } from '@/components'; @@ -24,9 +24,9 @@ export default function HashPage(): JSX.Element { function hashContent(content: string): void { try { setHashedContent({ - blake2b256: blake2b256(content, 'hex'), - keccak256: keccak256(content, 'hex'), - sha256: sha256(content, 'hex') + blake2b256: Blake2b256.of(Txt.of(content).bytes).toString(), + keccak256: Keccak256.of(Txt.of(content).bytes).toString(), + sha256: Sha256.of(Txt.of(content).bytes).toString() }); } catch (error) { setHashedContent({ diff --git a/apps/sdk-nextjs-integration/src/app/transfer-logs/page.tsx b/apps/sdk-nextjs-integration/src/app/transfer-logs/page.tsx index f071b1be0..4a70d9557 100644 --- a/apps/sdk-nextjs-integration/src/app/transfer-logs/page.tsx +++ b/apps/sdk-nextjs-integration/src/app/transfer-logs/page.tsx @@ -4,7 +4,7 @@ import { Header } from '@/components'; import { explorerUrl, thorClient } from '@/const'; import { type Transfer } from '@/types'; import { reduceHexStringSize } from '@/utils'; -import { addressUtils, FixedPointNumber, Units } from '@vechain/sdk-core'; +import { Address, FixedPointNumber, Units } from '@vechain/sdk-core'; import { type CompressedBlockDetail, type FilterTransferLogsOptions @@ -66,8 +66,7 @@ export default function TransferLogs(): JSX.Element { // Update the history when the address changes useEffect(() => { - // Backwards compatibility, from now on use Address.isValid - if (addressUtils.isAddress(address)) { + if (Address.isValid(address)) { void getHistoryFor(address); } }, [address]); diff --git a/docs/accounts.md b/docs/accounts.md index 1da8fd55f..030eb7c66 100644 --- a/docs/accounts.md +++ b/docs/accounts.md @@ -31,7 +31,7 @@ console.log('Mnemonic words', randomMnemonic); // 2 - Derive private key from mnemonic words according to BIP32, using the path `m/44'/818'/0'/0`. // Defined for VET at https://github.com/satoshilabs/slips/blob/master/slip-0044.md -const privateKey = mnemonic.derivePrivateKey(randomMnemonic); +const privateKey = Mnemonic.toPrivateKey(randomMnemonic); console.log(Hex.of(privateKey).toString()); // ...SOME PRIVATE KEY... diff --git a/docs/diagrams/architecture/vcdm.md b/docs/diagrams/architecture/vcdm.md index 6e347a6ff..7bd345f06 100644 --- a/docs/diagrams/architecture/vcdm.md +++ b/docs/diagrams/architecture/vcdm.md @@ -9,7 +9,6 @@ classDiagram } class ABIContract { +ABIContract ofAbi(ViemABI abi)$ - +ABIContract ofStringAbi(string abi)$ +ABIFunction getFunction(string name) +ABIEvent getEvent(string name) +Hex encodeFunctionInput(string functionName, unknown[] functionData) diff --git a/docs/examples/accounts/bip39.ts b/docs/examples/accounts/bip39.ts index 1ec7b5c94..b00148c20 100644 --- a/docs/examples/accounts/bip39.ts +++ b/docs/examples/accounts/bip39.ts @@ -1,4 +1,4 @@ -import { Hex, Mnemonic, mnemonic } from '@vechain/sdk-core'; +import { Hex, Mnemonic } from '@vechain/sdk-core'; import { expect } from 'expect'; // START_SNIPPET: Bip39Snippet @@ -13,7 +13,7 @@ console.log('Mnemonic words', randomMnemonic); // 2 - Derive private key from mnemonic words according to BIP32, using the path `m/44'/818'/0'/0`. // Defined for VET at https://github.com/satoshilabs/slips/blob/master/slip-0044.md -const privateKey = mnemonic.derivePrivateKey(randomMnemonic); +const privateKey = Mnemonic.toPrivateKey(randomMnemonic); console.log(Hex.of(privateKey).toString()); // ...SOME PRIVATE KEY... diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js index 1af0f8357..f20d60d1d 100644 --- a/packages/core/jest.config.js +++ b/packages/core/jest.config.js @@ -8,10 +8,10 @@ module.exports = { workerThreads: true, coverageThreshold: { global: { - branches: 91, - functions: 92, - lines: 94, - statements: 94 + branches: 95, + functions: 97, + lines: 97, + statements: 97 } } }; diff --git a/packages/core/src/vcdm/Address.ts b/packages/core/src/vcdm/Address.ts index 9dc9d2ec8..86287c1ac 100644 --- a/packages/core/src/vcdm/Address.ts +++ b/packages/core/src/vcdm/Address.ts @@ -186,17 +186,4 @@ class Address extends HexUInt { } } -// Backwards compatibility, remove when it is matured enough #1184 - -const addressUtils = { - fromPrivateKey: (privateKey: Uint8Array): string => - Address.ofPrivateKey(privateKey).toString(), - fromPublicKey: (publicKey: Uint8Array): string => - Address.ofPublicKey(publicKey).toString(), - isAddress: (addressToVerify: string): boolean => - Address.isValid(addressToVerify), - toERC55Checksum: (address: string): string => - Address.checksum(HexUInt.of(address)).toString() -}; - -export { Address, addressUtils }; +export { Address }; diff --git a/packages/core/src/vcdm/Mnemonic.ts b/packages/core/src/vcdm/Mnemonic.ts index 7f3df90b7..d5932de44 100644 --- a/packages/core/src/vcdm/Mnemonic.ts +++ b/packages/core/src/vcdm/Mnemonic.ts @@ -11,7 +11,6 @@ import { InvalidOperation } from '@vechain/sdk-errors'; import { HDKey } from '../hdkey'; -import { Address } from './Address'; import { type VeChainDataModel } from './VeChainDataModel'; /** @@ -229,21 +228,5 @@ class Mnemonic implements VeChainDataModel { } } -// Backwards compatibility, remove in future versions #1184 - -const mnemonic = { - deriveAddress: (words: string[], path: string = 'm/0'): string => - Address.ofMnemonic(words, path).toString(), - derivePrivateKey: (words: string[], path: string = 'm/0'): Uint8Array => - Mnemonic.toPrivateKey(words, path), - generate: ( - wordlistSize?: WordlistSizeType, - randomGenerator?: ( - numberOfBytes: WordListRandomGeneratorSizeInBytes - ) => Uint8Array - ): string[] => Mnemonic.of(wordlistSize, randomGenerator), - isValid: (words: string[]): boolean => Mnemonic.isValid(words) -}; - -export { Mnemonic, mnemonic }; +export { Mnemonic }; export type { WordListRandomGeneratorSizeInBytes, WordlistSizeType }; diff --git a/packages/core/src/vcdm/Revision.ts b/packages/core/src/vcdm/Revision.ts index b0f7b4f02..067f2620a 100644 --- a/packages/core/src/vcdm/Revision.ts +++ b/packages/core/src/vcdm/Revision.ts @@ -82,13 +82,4 @@ class Revision extends Txt { } } -// Backwards compatibility, remove when it is matured enough #1184 - -const revisionUtils = { - isRevisionAccount: (revision: string | number): boolean => - Revision.isValid(revision), - isRevisionBlock: (revision: string | number): boolean => - Revision.isValid(revision) -}; - -export { Revision, revisionUtils }; +export { Revision }; diff --git a/packages/core/src/vcdm/abi/ABIContract.ts b/packages/core/src/vcdm/abi/ABIContract.ts index e5d7d8b88..a00082c2e 100644 --- a/packages/core/src/vcdm/abi/ABIContract.ts +++ b/packages/core/src/vcdm/abi/ABIContract.ts @@ -4,7 +4,6 @@ import { } from '@vechain/sdk-errors'; import { getAbiItem, - parseAbi, type AbiEvent, type AbiFunction, type DecodeEventLogReturnType, @@ -34,15 +33,6 @@ class ABIContract extends ABI { return new ABIContract(abi); } - /** - * Creates an ABIContract instance from an ABI string. - * @param {string} abi representation of the contract. - * @returns New instance of ABIContract. - */ - public static ofStringAbi(abi: string): ABIContract { - return new ABIContract(parseAbi([abi])); - } - /** * Returns the function with the given name. * @param {string} name The function's name. @@ -280,11 +270,9 @@ class ABIContract extends ABI { const eventLogDecoded = this.parseLog(data, topics); if (eventLogDecoded.args === undefined) { return []; - } else if (eventLogDecoded.args instanceof Object) { - return Object.values(eventLogDecoded.args); } - return eventLogDecoded.args; + return this.parseObjectValues(eventLogDecoded.args); } } diff --git a/packages/core/src/vcdm/abi/ABIEvent.ts b/packages/core/src/vcdm/abi/ABIEvent.ts index bfc0c6490..af221f80d 100644 --- a/packages/core/src/vcdm/abi/ABIEvent.ts +++ b/packages/core/src/vcdm/abi/ABIEvent.ts @@ -114,23 +114,13 @@ class ABIEvent extends ABIItem { * @returns {unknown[]} The decoded data as array of values. */ public decodeEventLogAsArray(event: ABIEventData): unknown[] { - try { - const rawDecodedData = this.decodeEventLog(event); + const rawDecodedData = this.decodeEventLog(event); - if (rawDecodedData.args === undefined) { - return []; - } else if (rawDecodedData.args instanceof Object) { - return Object.values(rawDecodedData.args); - } - return rawDecodedData.args as unknown[]; - } catch (error) { - throw new InvalidAbiDataToEncodeOrDecode( - 'ABIEvent.decodeEventLogAsArray', - 'Decoding failed: Data must be a valid hex string encoding a compliant ABI type.', - { data: event }, - error - ); + if (rawDecodedData.args === undefined) { + return []; } + + return this.parseObjectValues(rawDecodedData.args); } /** diff --git a/packages/core/src/vcdm/abi/ABIItem.ts b/packages/core/src/vcdm/abi/ABIItem.ts index db2404e49..dca655b4b 100644 --- a/packages/core/src/vcdm/abi/ABIItem.ts +++ b/packages/core/src/vcdm/abi/ABIItem.ts @@ -7,21 +7,19 @@ import { } from 'viem'; import { ABI } from './ABI'; -type ABIItemType = AbiFunction | AbiEvent; - /** * Represents an ABI (Application Binary Interface) item. * @extends ABI */ abstract class ABIItem extends ABI { - public readonly signature: ABIItemType; + public readonly signature: AbiFunction | AbiEvent; public readonly stringSignature: string; /** * ABIItem constructor from item (Event, Function...) signature. * - * @param {string | ViemABI} signature - The signature of the ABI item (Function, Event...). + * @param {string | AbiFunction | AbiEvent} signature - The signature of the ABI item (Function, Event...). **/ - public constructor(signature: string | ABIItemType) { + public constructor(signature: string | AbiFunction | AbiEvent) { super(); switch (typeof signature) { case 'string': @@ -45,19 +43,26 @@ abstract class ABIItem extends ABI { ): T; public static ofSignature( - ABIItemConstructor: new (signature: ABIItemType) => T, - signature: ABIItemType + ABIItemConstructor: new (signature: AbiFunction) => T, + signature: AbiFunction + ): T; + + public static ofSignature( + ABIItemConstructor: new (signature: AbiEvent) => T, + signature: AbiEvent ): T; /** * Returns and instance of an ABIItem from a signature. * @param ABIItemConstructor ABIItem constructor. - * @param {string | ABIItemType} signature Signature of the ABIIItem. + * @param {string | AbiFunction | AbiEvent} signature Signature of the ABIIItem. * @returns {T} An instance of the ABIItem. */ public static ofSignature( - ABIItemConstructor: new (signature: string | ABIItemType) => T, - signature: string | ABIItemType + ABIItemConstructor: new ( + signature: string | AbiFunction | AbiEvent + ) => T, + signature: string | AbiFunction | AbiEvent ): T { return new ABIItemConstructor(signature); } @@ -88,7 +93,7 @@ abstract class ABIItem extends ABI { * @returns {number} A non-zero number if the current ABIItem is different to the other ABI or zero if they are equal. * @override {@link VeChainDataModel#compareTo} **/ - public compareTo(that: ABIItem): number { + public override compareTo(that: ABIItem): number { if (super.compareTo(that) !== 0) { return -1; } @@ -96,4 +101,4 @@ abstract class ABIItem extends ABI { } } -export { ABIItem, type ABIItemType }; +export { ABIItem }; diff --git a/packages/core/src/vcdm/hash/Blake2b256.ts b/packages/core/src/vcdm/hash/Blake2b256.ts index e8fcc740a..1c6d19b07 100644 --- a/packages/core/src/vcdm/hash/Blake2b256.ts +++ b/packages/core/src/vcdm/hash/Blake2b256.ts @@ -2,7 +2,6 @@ import { blake2b as nh_blake2b } from '@noble/hashes/blake2b'; import { InvalidOperation } from '@vechain/sdk-errors'; import { Hex } from '../Hex'; import { HexUInt } from '../HexUInt'; -import { Txt } from '../Txt'; /** * Represents the result of an [BLAKE](https://en.wikipedia.org/wiki/BLAKE_(hash_function)) [BlAKE2B 256](https://www.blake2.net/) hash operation. @@ -40,23 +39,4 @@ class Blake2b256 extends HexUInt { } } -// Backwards compatibility, remove in future release #1184 - -function blake2b256( - data: string | Uint8Array, - returnType: 'buffer' -): Uint8Array; - -function blake2b256(data: string | Uint8Array, returnType: 'hex'): string; - -function blake2b256( - data: string | Uint8Array, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - returnType: 'buffer' | 'hex' = 'buffer' -): string | Uint8Array { - return returnType === 'buffer' - ? Blake2b256.of(Txt.of(data).bytes).bytes - : Blake2b256.of(Txt.of(data).bytes).toString(); -} - -export { Blake2b256, blake2b256 }; +export { Blake2b256 }; diff --git a/packages/core/src/vcdm/hash/Keccak256.ts b/packages/core/src/vcdm/hash/Keccak256.ts index 1c2fe2f3d..83a75d5b4 100644 --- a/packages/core/src/vcdm/hash/Keccak256.ts +++ b/packages/core/src/vcdm/hash/Keccak256.ts @@ -2,7 +2,6 @@ import { keccak_256 as nh_keccak_256 } from '@noble/hashes/sha3'; import { InvalidOperation } from '@vechain/sdk-errors'; import { Hex } from '../Hex'; import { HexUInt } from '../HexUInt'; -import { Txt } from '../Txt'; /** * Represents the result of an [SHA-3](https://en.wikipedia.org/wiki/SHA-3) [KECCAK 256](https://keccak.team/keccak.html) hash operation. @@ -37,20 +36,4 @@ class Keccak256 extends HexUInt { } } -// Backwards compatibility, remove in future release #1184 - -function keccak256(data: string | Uint8Array, returnType: 'buffer'): Uint8Array; - -function keccak256(data: string | Uint8Array, returnType: 'hex'): string; - -function keccak256( - data: string | Uint8Array, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - returnType: 'buffer' | 'hex' = 'buffer' -): string | Uint8Array { - return returnType === 'buffer' - ? Keccak256.of(Txt.of(data).bytes).bytes - : Keccak256.of(Txt.of(data).bytes).toString(); -} - -export { Keccak256, keccak256 }; +export { Keccak256 }; diff --git a/packages/core/src/vcdm/hash/Sha256.ts b/packages/core/src/vcdm/hash/Sha256.ts index 8bdc70c80..53b67a4b2 100644 --- a/packages/core/src/vcdm/hash/Sha256.ts +++ b/packages/core/src/vcdm/hash/Sha256.ts @@ -2,7 +2,6 @@ import * as nh_sha256 from '@noble/hashes/sha256'; import { InvalidOperation } from '@vechain/sdk-errors'; import { Hex } from '../Hex'; import { HexUInt } from '../HexUInt'; -import { Txt } from '../Txt'; /** * Represents the result of an [SHA256](https://en.wikipedia.org/wiki/SHA-2) hash operation. @@ -36,20 +35,4 @@ class Sha256 extends HexUInt { } } -// Backwards compatibility, remove in future release #1184 - -function sha256(data: string | Uint8Array, returnType: 'buffer'): Uint8Array; - -function sha256(data: string | Uint8Array, returnType: 'hex'): string; - -function sha256( - data: string | Uint8Array, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - returnType: 'buffer' | 'hex' = 'buffer' -): string | Uint8Array { - return returnType === 'buffer' - ? Sha256.of(Txt.of(data).bytes).bytes - : Sha256.of(Txt.of(data).bytes).toString(); -} - -export { Sha256, sha256 }; +export { Sha256 }; diff --git a/packages/core/tests/hdkey/HDKey.unit.test.ts b/packages/core/tests/hdkey/HDKey.unit.test.ts index 39385b1a1..92233b8e7 100644 --- a/packages/core/tests/hdkey/HDKey.unit.test.ts +++ b/packages/core/tests/hdkey/HDKey.unit.test.ts @@ -7,7 +7,7 @@ import { import { Address, HDKey, - mnemonic, + Mnemonic, Secp256k1, ZERO_BYTES, type WordlistSizeType @@ -166,7 +166,7 @@ describe('HDKey class tests', () => { test('fromMnemonic - valid - word list - multiple lengths', () => { new Array(12, 15, 18, 21, 24).forEach( (length: WordlistSizeType) => { - const hdKey = HDKey.fromMnemonic(mnemonic.generate(length)); + const hdKey = HDKey.fromMnemonic(Mnemonic.of(length)); expect(hdKey.privateKey).toBeDefined(); expect( Secp256k1.isValidPrivateKey( diff --git a/packages/core/tests/vcdm/Address.unit.test.ts b/packages/core/tests/vcdm/Address.unit.test.ts index 268b3e5b5..6fb1696c0 100644 --- a/packages/core/tests/vcdm/Address.unit.test.ts +++ b/packages/core/tests/vcdm/Address.unit.test.ts @@ -5,7 +5,7 @@ import { InvalidSecp256k1PrivateKey } from '@vechain/sdk-errors'; import { fail } from 'assert'; -import { Address, addressUtils } from '../../src'; +import { Address } from '../../src'; /** * Test Address class. @@ -118,29 +118,4 @@ describe('Address class tests', () => { } }); }); - describe('Backwards compatibility tests', () => { - test('Should get the address from a given private key', () => { - const privateKey = hexToBytes( - '5434c159b817c377a55f6be66369622976014e78bce2adfd3e44e5de88ce502f' - ); - const address = addressUtils.fromPrivateKey(privateKey); - expect(address).toBe('0x769E8AA372c8309c834EA6749B88861FF73581FF'); - }); - test('Should get the address from a given public key', () => { - const publicKey = hexToBytes( - '04a6711e14234b1d4e69aeed2acf18b9c3bd0e97db317b509516bd3a87e5b732685ccaf855d9f8a955bc1f420b4ebf8f682c2e480d98a360e7fd0c08e6eef65607' - ); - const address = addressUtils.fromPublicKey(publicKey); - expect(address).toBe('0x769E8AA372c8309c834EA6749B88861FF73581FF'); - }); - test('Should return true if the address is a valid address', () => { - const address = '0x769E8AA372c8309c834EA6749B88861FF73581FF'; - expect(addressUtils.isAddress(address)).toBeTruthy(); - }); - test('Should get the ERC55 checksum', () => { - const address = '0x769e8aa372c8309c834eA6749b88861ff73581ff'; - const checksum = addressUtils.toERC55Checksum(address); - expect(checksum).toBe('0x769E8AA372c8309c834EA6749B88861FF73581FF'); - }); - }); }); diff --git a/packages/core/tests/vcdm/Revision.unit.test.ts b/packages/core/tests/vcdm/Revision.unit.test.ts index f25b4ec55..ca2e0b7ce 100644 --- a/packages/core/tests/vcdm/Revision.unit.test.ts +++ b/packages/core/tests/vcdm/Revision.unit.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from '@jest/globals'; import { InvalidDataType } from '@vechain/sdk-errors'; -import { Hex, Revision, revisionUtils, Txt } from '../../src'; +import { Hex, Revision, Txt } from '../../src'; /** * Test Revision class. @@ -144,91 +144,4 @@ describe('Revision class tests', () => { }); }); }); - - describe('Back-compatibility tests', () => { - /** - * Test cases for the `isRevisionAccount` function. - */ - const accountRevisions = [ - { - revision: 'invalid-address', - expected: false - }, - { - revision: 'finalized', - expected: true - }, - { - revision: '0x34123', - expected: true - }, - { - revision: '100', - expected: true - }, - { - revision: 100, - expected: true - }, - { - revision: '0xG8656c6c6f', - expected: false - }, - { - revision: 'best', - expected: true - } - ]; - - /** - * Test cases for the `isRevisionBlock` function. - */ - const blockRevisions = [ - { - revision: 'invalid-address', - expected: false - }, - { - revision: '0x542fd', - expected: true - }, - { - revision: '100', - expected: true - }, - { - revision: 100, - expected: true - }, - { - revision: '0xG8656c6c6f', - expected: false - }, - { - revision: 'best', - expected: true - }, - { - revision: 'finalized', - expected: true - } - ]; - - test('isBlockRevision function test', () => { - blockRevisions.forEach(({ revision, expected }) => { - expect(revisionUtils.isRevisionBlock(revision)).toBe(expected); - }); - }); - - /** - * Test case for the `isRevisionAccount` function. - */ - test('isAccountRevision', () => { - accountRevisions.forEach(({ revision, expected }) => { - expect(revisionUtils.isRevisionAccount(revision)).toBe( - expected - ); - }); - }); - }); }); diff --git a/packages/core/tests/vcdm/abi/contract.unit.test.ts b/packages/core/tests/vcdm/abi/contract.unit.test.ts index ef3964687..8ac4d68c7 100644 --- a/packages/core/tests/vcdm/abi/contract.unit.test.ts +++ b/packages/core/tests/vcdm/abi/contract.unit.test.ts @@ -1,11 +1,12 @@ import { beforeAll, describe, expect, test } from '@jest/globals'; import { InvalidAbiDataToEncodeOrDecode, + InvalidAbiItem, InvalidDataType } from '@vechain/sdk-errors'; import { fail } from 'assert'; -import { encodeFunctionResult } from 'viem'; -import { ABIContract, ERC721_ABI, Hex } from '../../../src'; +import { type AbiEvent, encodeFunctionResult } from 'viem'; +import { ABIContract, ABIEvent, ABIItem, ERC721_ABI, Hex } from '../../../src'; import { contractABI, contractABIWithEvents, @@ -58,6 +59,15 @@ describe('Contract interface for ABI encoding/decoding', () => { ); }); + /** + * Test the error when getting a function ABI. + */ + test('get a function ABI and throw an error', () => { + expect(() => contractAbi.getFunction('undefined')).toThrowError( + InvalidAbiItem + ); + }); + /** * Test the failed encoding of a function input. */ @@ -103,10 +113,21 @@ describe('Contract interface for ABI encoding/decoding', () => { ValueChangedEventData.value ]) ).toEqual( - contractAbiWithEvents.encodeEventLog('ValueChanged', [ - ValueChangedEventData.sender, - ValueChangedEventData.value - ]) + contractAbiWithEvents + .getEvent('ValueChanged') + .encodeEventLog([ + ValueChangedEventData.sender, + ValueChangedEventData.value + ]) + ); + }); + + /** + * Test the error when getting an event ABI. + */ + test('get an event ABI and throw an error', () => { + expect(() => contractAbi.getEvent('undefined')).toThrowError( + InvalidAbiItem ); }); @@ -176,6 +197,61 @@ describe('Contract interface for ABI encoding/decoding', () => { expect(argsValues[2]).toEqual(1n); }); + /** + * Test the decoding of an encoded event log from a contract transaction returned as an array of values. + */ + test('parse an event log and return decoded data as array', () => { + const decodedEventLog = erc721Abi.parseLogAsArray(Hex.of('0x'), [ + Hex.of( + '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' + ), + Hex.of( + '0x0000000000000000000000000000000000000000000000000000000000000000' + ), + Hex.of( + '0x000000000000000000000000f02f557c753edf5fcdcbfe4c1c3a448b3cc84d54' + ), + Hex.of( + '0x0000000000000000000000000000000000000000000000000000000000000001' + ) + ]); + + expect(decodedEventLog).toBeDefined(); + expect(decodedEventLog.length).toEqual(3); + expect(decodedEventLog[0]).toEqual( + '0x0000000000000000000000000000000000000000' + ); + expect(decodedEventLog[1]).toEqual( + '0xF02f557c753edf5fcdCbfE4c1c3a448B3cC84D54' + ); + expect(decodedEventLog[2]).toEqual(1n); + }); + + /** + * Test the error flow when parsing an event log with null and array topics. + */ + test('throw an error when parsing an event log with null and array topics', () => { + expect(() => { + ABIEvent.parseLog(ERC721_ABI, { + data: Hex.of('0x0'), + topics: [ + null, + Hex.of( + '0x0000000000000000000000000000000000000000000000000000000000000000' + ), + [ + Hex.of( + '0x000000000000000000000000f02f557c753edf5fcdcbfe4c1c3a448b3cc84d54' + ) + ], + Hex.of( + '0x0000000000000000000000000000000000000000000000000000000000000001' + ) + ] + }); + }).toThrowError(InvalidAbiDataToEncodeOrDecode); + }); + /** * Test the failed decoding of an encoded event log from a contract transaction. */ @@ -222,6 +298,13 @@ describe('Contract interface for ABI encoding/decoding', () => { ); expect(decodedOutput).toBeDefined(); expect(decodedOutput).toEqual(mockReturnValue); + + const decodedOutputAsArray = contractStorageAbi + .getFunction(functionName) + .decodeOutputAsArray(Hex.of(encodedFunctionOutput)); + + expect(decodedOutputAsArray).toBeDefined(); + expect(decodedOutputAsArray).toEqual([mockReturnValue]); }); /** @@ -259,4 +342,15 @@ describe('Contract interface for ABI encoding/decoding', () => { ) ).toThrowError(InvalidDataType); }); + + /** + * Test ABIItem.ofSignature method. + */ + test('we get an ABI item from a signature', () => { + const expected = contractAbiWithEvents.getEvent('ValueChanged'); + const expectedSignature = expected.signature as AbiEvent; + const actual = ABIItem.ofSignature(ABIEvent, expectedSignature); + expect(expectedSignature).toEqual(actual.signature); + expect(actual.isEqual(expected)).toBeTruthy(); + }); }); diff --git a/packages/core/tests/vcdm/hash/Blake2b256.unit.test.ts b/packages/core/tests/vcdm/hash/Blake2b256.unit.test.ts index f86de49a1..07c4fe044 100644 --- a/packages/core/tests/vcdm/hash/Blake2b256.unit.test.ts +++ b/packages/core/tests/vcdm/hash/Blake2b256.unit.test.ts @@ -1,7 +1,6 @@ import { describe, expect, test } from '@jest/globals'; -import { bytesToHex } from '@noble/hashes/utils'; import { InvalidOperation } from '@vechain/sdk-errors'; -import { blake2b256, Blake2b256, Hex } from '../../../src'; +import { Blake2b256, Hex } from '../../../src'; import { CONTENT, NO_CONTENT } from './fixture'; // Hex on purpose because it must be equal to the returned HexUInt hash. @@ -46,19 +45,3 @@ describe('Blake2b256 class tests', () => { expect(() => Blake2b256.of('0xfoe')).toThrow(InvalidOperation); }); }); -describe('Backwards compatibility tests', () => { - test('Should return the hash as hex', () => { - const rawString = 'Hello, World!'; - const hash = blake2b256(rawString, 'hex'); - expect(hash).toBe( - '0x511bc81dde11180838c562c82bb35f3223f46061ebde4a955c27b3f489cf1e03' - ); - }); - test('Should return the hash as buffer', () => { - const rawString = 'Hello, World!'; - const hash = blake2b256(rawString, 'buffer'); - expect(bytesToHex(hash)).toBe( - '511bc81dde11180838c562c82bb35f3223f46061ebde4a955c27b3f489cf1e03' - ); - }); -}); diff --git a/packages/core/tests/vcdm/hash/Keccak256.unit.test.ts b/packages/core/tests/vcdm/hash/Keccak256.unit.test.ts index ca88a99cf..0c7f0774b 100644 --- a/packages/core/tests/vcdm/hash/Keccak256.unit.test.ts +++ b/packages/core/tests/vcdm/hash/Keccak256.unit.test.ts @@ -1,7 +1,6 @@ import { describe, expect, test } from '@jest/globals'; -import { bytesToHex } from '@noble/hashes/utils'; import { InvalidOperation } from '@vechain/sdk-errors'; -import { Hex, Keccak256, keccak256 } from '../../../src'; +import { Hex, Keccak256 } from '../../../src'; import { CONTENT, NO_CONTENT } from './fixture'; // Hex on purpose because it must be equal to the returned HexUInt hash. @@ -46,19 +45,3 @@ describe('Keccak256 class tests', () => { expect(() => Keccak256.of('0xfoe')).toThrow(InvalidOperation); }); }); -describe('Backwards compatibility tests', () => { - test('Should return the hash as hex', () => { - const rawString = 'Hello, World!'; - const hash = keccak256(rawString, 'hex'); - expect(hash).toBe( - '0xacaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f' - ); - }); - test('Should return the hash as buffer', () => { - const rawString = 'Hello, World!'; - const hash = keccak256(rawString, 'buffer'); - expect(bytesToHex(hash)).toBe( - 'acaf3289d7b601cbd114fb36c4d29c85bbfd5e133f14cb355c3fd8d99367964f' - ); - }); -}); diff --git a/packages/core/tests/vcdm/hash/Sha256.unit.test.ts b/packages/core/tests/vcdm/hash/Sha256.unit.test.ts index ee6f8db03..786b3bb31 100644 --- a/packages/core/tests/vcdm/hash/Sha256.unit.test.ts +++ b/packages/core/tests/vcdm/hash/Sha256.unit.test.ts @@ -1,7 +1,6 @@ import { describe, expect, test } from '@jest/globals'; -import { bytesToHex } from '@noble/hashes/utils'; import { InvalidOperation } from '@vechain/sdk-errors'; -import { Hex, sha256, Sha256 } from '../../../src'; +import { Hex, Sha256 } from '../../../src'; import { CONTENT, NO_CONTENT } from './fixture'; // Hex on purpose because it must be equal to the returned HexUInt hash. @@ -45,19 +44,3 @@ describe('Sha256 class tests', () => { expect(() => Sha256.of('0xfoe')).toThrow(InvalidOperation); }); }); -describe('Backwards compatibility tests', () => { - test('Should return the hash as hex', () => { - const rawString = 'Hello, World!'; - const hash = sha256(rawString, 'hex'); - expect(hash).toBe( - '0xdffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f' - ); - }); - test('Should return the hash as buffer', () => { - const rawString = 'Hello, World!'; - const hash = sha256(rawString, 'buffer'); - expect(bytesToHex(hash)).toBe( - 'dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f' - ); - }); -}); diff --git a/packages/core/tests/vcdm/mnemonic/Mnemonic.unit.test.ts b/packages/core/tests/vcdm/mnemonic/Mnemonic.unit.test.ts index 03b8129ec..9d6810d07 100644 --- a/packages/core/tests/vcdm/mnemonic/Mnemonic.unit.test.ts +++ b/packages/core/tests/vcdm/mnemonic/Mnemonic.unit.test.ts @@ -2,7 +2,6 @@ import { describe, expect, test } from '@jest/globals'; import { InvalidHDKey } from '@vechain/sdk-errors'; import { Address, - mnemonic, Mnemonic, Secp256k1, type WordlistSizeType @@ -49,7 +48,7 @@ describe('Mnemonic', () => { test(path.testName, () => { expect( Hex.of( - mnemonic.derivePrivateKey( + Mnemonic.toPrivateKey( words, path.derivationPath ) @@ -100,7 +99,7 @@ describe('Mnemonic', () => { // Derive address from mnemonic words expect(Address.ofMnemonic(words)).toBeDefined(); expect( - mnemonic.deriveAddress(words).toString().length + Address.ofMnemonic(words).toString().length ).toEqual(42); expect( Address.isValid( @@ -134,12 +133,10 @@ describe('Mnemonic', () => { describe('isValid', () => { test('isValid - false', () => { expect(Mnemonic.isValid('hello world')).toBeFalsy(); - expect(mnemonic.isValid(['hello world'])).toBeFalsy(); }); test('isValid - true', () => { expect(Mnemonic.isValid(Mnemonic.of())).toBeTruthy(); - expect(mnemonic.isValid(Mnemonic.of())).toBeTruthy(); }); }); diff --git a/packages/network/package.json b/packages/network/package.json index 8beecd8a7..a5271ed62 100644 --- a/packages/network/package.json +++ b/packages/network/package.json @@ -27,7 +27,7 @@ ], "scripts": { "build": "rm -rf ./dist && tsup-node src/index.ts --format cjs,esm --dts", - "check:circular-dependencies": "npx madge --exclude '^(provider/providers/vechain-provider/vechain-provider.ts|thor-client/contracts/model/contract.ts|thor-client/index.ts|provider/utils/formatter/blocks/index.ts|signer/signers/types.d.ts|provider/utils/helpers/transaction/transaction-helpers.ts|thor-client/contracts/model/contract-filter.ts)$' --circular --extensions ts src", + "check:circular-dependencies": "npx madge --json --circular --extensions ts src | jq '. | length' | awk '{if($1 > 11) exit 1}'", "lint": "eslint --ext .ts src --ext .ts tests", "format": "prettier --write src/**/*.ts tests/**/*.ts solo-seeding/**/*.ts", "test:unit": "rm -rf ./coverageUnit && UNIT=true jest --coverage --coverageDirectory=coverageUnit --group=unit", diff --git a/packages/network/src/provider/utils/rpc-mapper/methods/eth_accounts/eth_accounts.ts b/packages/network/src/provider/utils/rpc-mapper/methods/eth_accounts/eth_accounts.ts index b503b26f2..9cfea09a8 100644 --- a/packages/network/src/provider/utils/rpc-mapper/methods/eth_accounts/eth_accounts.ts +++ b/packages/network/src/provider/utils/rpc-mapper/methods/eth_accounts/eth_accounts.ts @@ -1,4 +1,4 @@ -import { type VeChainProvider } from '../../../../providers'; +import { type VeChainProvider } from '../../../../providers/vechain-provider'; /** * RPC Method eth_accounts implementation diff --git a/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTransaction/eth_signTransaction.ts b/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTransaction/eth_signTransaction.ts index 11dce9aa9..483f16cec 100644 --- a/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTransaction/eth_signTransaction.ts +++ b/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTransaction/eth_signTransaction.ts @@ -1,5 +1,5 @@ import type { ThorClient } from '../../../../../thor-client'; -import type { VeChainProvider } from '../../../../providers'; +import type { VeChainProvider } from '../../../../providers/vechain-provider'; import { JSONRPCInternalError, JSONRPCInvalidParams, diff --git a/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTypedData_v4/eth_signTypedData_v4.ts b/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTypedData_v4/eth_signTypedData_v4.ts index ccae8a92d..f203b845c 100644 --- a/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTypedData_v4/eth_signTypedData_v4.ts +++ b/packages/network/src/provider/utils/rpc-mapper/methods/eth_signTypedData_v4/eth_signTypedData_v4.ts @@ -1,11 +1,11 @@ import type { ThorClient } from '../../../../../thor-client'; -import type { VeChainProvider } from '../../../../providers'; +import type { VeChainProvider } from '../../../../providers/vechain-provider'; import { JSONRPCInternalError, JSONRPCInvalidParams, stringifyData } from '@vechain/sdk-errors'; -import type { VeChainSigner } from '../../../../../signer'; +import type { VeChainSigner } from '../../../../../signer/signers'; import { Address, type vechain_sdk_core_ethers } from '@vechain/sdk-core'; /** diff --git a/packages/network/src/provider/utils/rpc-mapper/methods/eth_subscribe/eth_subscribe.ts b/packages/network/src/provider/utils/rpc-mapper/methods/eth_subscribe/eth_subscribe.ts index b734f5493..885b815ef 100644 --- a/packages/network/src/provider/utils/rpc-mapper/methods/eth_subscribe/eth_subscribe.ts +++ b/packages/network/src/provider/utils/rpc-mapper/methods/eth_subscribe/eth_subscribe.ts @@ -9,7 +9,7 @@ import { type ThorClient } from '../../../../../thor-client'; import { type FilterOptions, type VeChainProvider -} from '../../../../providers'; +} from '../../../../providers/vechain-provider'; /** * Enumerates the types of subscriptions supported by the`eth_subscribe` RPC method. diff --git a/packages/network/src/provider/utils/rpc-mapper/methods/txpool_contentFrom/txpool_contentFrom.ts b/packages/network/src/provider/utils/rpc-mapper/methods/txpool_contentFrom/txpool_contentFrom.ts index 85da371a6..7f2dfd5dd 100644 --- a/packages/network/src/provider/utils/rpc-mapper/methods/txpool_contentFrom/txpool_contentFrom.ts +++ b/packages/network/src/provider/utils/rpc-mapper/methods/txpool_contentFrom/txpool_contentFrom.ts @@ -1,5 +1,5 @@ import { JSONRPCInvalidParams } from '@vechain/sdk-errors'; -import { addressUtils } from '@vechain/sdk-core'; +import { Address } from '@vechain/sdk-core'; /** * RPC Method txpool_contentFrom implementation @@ -18,7 +18,7 @@ const txPoolContentFrom = async (params: unknown[]): Promise => { if ( params.length !== 1 || typeof params[0] !== 'string' || - !addressUtils.isAddress(params[0]) + !Address.isValid(params[0]) ) throw new JSONRPCInvalidParams( 'txpool_contentFrom()', diff --git a/packages/network/tests/thor-client/contracts/contract.erc721.solo.test.ts b/packages/network/tests/thor-client/contracts/contract.erc721.solo.test.ts index 0ec289087..bafd58a43 100644 --- a/packages/network/tests/thor-client/contracts/contract.erc721.solo.test.ts +++ b/packages/network/tests/thor-client/contracts/contract.erc721.solo.test.ts @@ -128,7 +128,6 @@ describe('ThorClient - ERC721 Contracts', () => { function decodeResultOutput(result: TransactionReceipt): unknown[][] { return result?.outputs.map((output) => { return output.events.map((event) => { - // Modify when addressing #1184 return ABIContract.ofAbi(ERC721_ABI).parseLogAsArray( Hex.of(event.data), event.topics.map((topic) => Hex.of(topic)) diff --git a/packages/rpc-proxy/src/utils/validators/validators.ts b/packages/rpc-proxy/src/utils/validators/validators.ts index 959ed7ee3..2dfa90a36 100644 --- a/packages/rpc-proxy/src/utils/validators/validators.ts +++ b/packages/rpc-proxy/src/utils/validators/validators.ts @@ -1,4 +1,4 @@ -import { Hex, mnemonic, Secp256k1 } from '@vechain/sdk-core'; +import { Hex, Mnemonic, Secp256k1 } from '@vechain/sdk-core'; /** * Check if the url field is valid @@ -44,7 +44,7 @@ function isValidAccountsAsListOfPrivateKeys(accounts: string[]): boolean { * @returns True if the mnemonic is valid, false otherwise */ function isValidMnemonic(mnemonicWords: string): boolean { - return mnemonic.isValid(mnemonicWords.split(' ')); + return Mnemonic.isValid(mnemonicWords.split(' ')); } /**