Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1774 substitute thorid class with proper transaction id and block id classes #1786

Draft
wants to merge 6 commits into
base: feature-thorest
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 13 additions & 93 deletions packages/core/src/vcdm/BlockId.ts
Original file line number Diff line number Diff line change
@@ -1,79 +1,45 @@
import { Hex } from './Hex';
import { HexUInt } from './HexUInt';
import { type HexInt } from './HexInt';
import { HexUInt32 } from './HexUInt32';
import { InvalidDataType } from '@vechain/sdk-errors';

/**
* The BlockId class represents a Thor block ID value, which is a hexadecimal positive integer having 64 digits.
*
* @extends HexInt
* @extends HexUInt32
*/
class BlockId extends HexUInt {
/**
* Number of digits to represent a Thor block ID value.
*
* @remarks The `0x` prefix is excluded.
*
* @type {number}
*/
private static readonly DIGITS = 64;

class BlockId extends HexUInt32 {
/**
* Constructs a BlockId object with the provided hexadecimal value.
*
* @param {HexUInt} huint - The hexadecimal value representing the BlockId.
*/
protected constructor(huint: HexUInt) {
super(Hex.POSITIVE, huint.fit(BlockId.DIGITS).digits);
}

/**
* Check if the given expression is a valid BlockId.
*
* @param {string} exp - The expression to be validated.
*
* @return {boolean} Returns true if the expression is a valid BlockId, false otherwise.
* @param {HexUInt32} hexUInt32 - The hexadecimal value representing the BlockId.
*/
public static isValid(exp: string): boolean {
return Hex.isValid(exp) && HexUInt.REGEX_HEXUINT_PREFIX.test(exp)
? exp.length === BlockId.DIGITS + 2
: exp.length === BlockId.DIGITS;
protected constructor(hexUInt32: HexUInt32) {
super(Hex.POSITIVE, hexUInt32.digits);
}

/**
* Determines whether the given string is a valid hex number prefixed with '0x'.
*
* @param {string} exp - The hex number to be checked.
*
* @returns {boolean} - True if the hex number is valid, false otherwise.
*/
public static isValid0x(exp: string): boolean {
return HexUInt.REGEX_HEXUINT_PREFIX.test(exp) && BlockId.isValid(exp);
}

/**
* Creates a new BlockId object from the given expression.
*
* @param {bigint | number | string | Hex | Uint8Array} exp - The expression to create the BlockId from.
* @param {bigint | number | string | HexInt | Uint8Array} exp - The expression to create the BlockId from.
* It can be one of the following types:
* - bigint: A BigInteger value that represents the BlockId.
* - number: A number value that represents the BlockId.
* - string: A string value that represents the BlockId.
* - HexUInt: A HexUInt object that represents the BlockId.
* - HexInt: A HexInt object that represents the BlockId.
* - Uint8Array: A Uint8Array object that represents the BlockId.
*
* @returns {BlockId} - A new BlockId object created from the given expression.
*
* @throws {InvalidDataType} If the given expression is not a valid hexadecimal positive integer expression.
*/
public static of(
// eslint-disable-next-line sonarjs/use-type-alias
exp: bigint | number | string | Uint8Array | HexUInt
exp: bigint | number | string | Uint8Array | HexInt
): BlockId {
try {
if (exp instanceof HexUInt) {
if (exp instanceof HexUInt32) {
return new BlockId(exp);
}
return new BlockId(HexUInt.of(exp));
return new BlockId(HexUInt32.of(exp));
} catch (e) {
throw new InvalidDataType(
'BlockId.of',
Expand All @@ -85,50 +51,4 @@ class BlockId extends HexUInt {
}
}

/**
* This class is an alias of {@link BlockId} for back compatibility.
*/
class ThorId extends BlockId {
/**
* Constructs an instance of the class with the specified block ID.
*
* @param {BlockId} blockId - The unique identifier for the block.
*/
protected constructor(blockId: BlockId) {
super(blockId);
}

/**
* See {@link BlockId.of}.
*/
public static of(
exp: bigint | number | string | Uint8Array | HexUInt
): ThorId {
return new ThorId(BlockId.of(exp));
}
}

/**
* This class is an alias of {@link TxId} for back compatibility.
*/
class TxId extends BlockId {
/**
* Constructs an instance of the class with the specified transaction ID.
*
* @param {TxId} blockId - The unique identifier for the block.
*/
protected constructor(blockId: BlockId) {
super(blockId);
}

/**
* See {@link BlockId.of}.
*/
public static of(
exp: bigint | number | string | Uint8Array | HexUInt
): TxId {
return new TxId(BlockId.of(exp));
}
}

export { BlockId, ThorId, TxId };
export { BlockId };
54 changes: 54 additions & 0 deletions packages/core/src/vcdm/LogId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Hex } from './Hex';
import { type HexInt } from './HexInt';
import { HexUInt32 } from './HexUInt32';
import { InvalidDataType } from '@vechain/sdk-errors';

/**
* The LogId class represents a Thor event log ID, which is a hexadecimal positive integer having 64 digits.
*
* @extends HexUInt32
*/
class LogId extends HexUInt32 {
/**
* Constructs a LogId object with the provided hexadecimal value.
*
* @param {HexUInt32} hexUInt32 - The hexadecimal value representing the LogId.
*/
protected constructor(hexUInt32: HexUInt32) {
super(Hex.POSITIVE, hexUInt32.digits);
}
/**
* Creates a new LogId object from the given expression.
*
* @param {bigint | number | string | HexInt | Uint8Array} exp - The expression to create the LogId from.
* It can be one of the following types:
* - bigint: A BigInteger value that represents the LogId.
* - number: A number value that represents the LogId.
* - string: A string value that represents the LogId.
* - HexInt: A HexInt object that represents the LogId.
* - Uint8Array: A Uint8Array object that represents the LogId.
*
* @returns {LogId} - A new LogId object created from the given expression.
*
* @throws {InvalidDataType} If the given expression is not a valid hexadecimal positive integer expression.
*/
public static of(
exp: bigint | number | string | Uint8Array | HexInt
): LogId {
try {
if (exp instanceof HexUInt32) {
return new LogId(exp);
}
return new LogId(HexUInt32.of(exp));
} catch (e) {
throw new InvalidDataType(
'LogId.of',
'not a LogId expression',
{ exp: `${exp}` }, // Needed to serialize bigint values.
e
);
}
}
}

export { LogId };
54 changes: 54 additions & 0 deletions packages/core/src/vcdm/StorageKey.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Hex } from './Hex';
import { type HexInt } from './HexInt';
import { HexUInt32 } from './HexUInt32';
import { InvalidDataType } from '@vechain/sdk-errors';

/**
* The StorageKey class represents the location or key used to store data in the contract's persistent storage which is a hexadecimal positive integer having 64 digits.
*
* @extends HexUInt32
*/
class StorageKey extends HexUInt32 {
/**
* Constructs a StorageKey object with the provided hexadecimal value.
*
* @param {HexUInt32} hexUInt32 - The hexadecimal value representing the StorageKey.
*/
protected constructor(hexUInt32: HexUInt32) {
super(Hex.POSITIVE, hexUInt32.digits);
}
/**
* Creates a new StorageKey object from the given expression.
*
* @param {bigint | number | string | HexInt | Uint8Array} exp - The expression to create the StorageKey from.
* It can be one of the following types:
* - bigint: A BigInteger value that represents the StorageKey.
* - number: A number value that represents the StorageKey.
* - string: A string value that represents the StorageKey.
* - HexInt: A HexInt object that represents the StorageKey.
* - Uint8Array: A Uint8Array object that represents the StorageKey.
*
* @returns {StorageKey} - A new StorageKey object created from the given expression.
*
* @throws {InvalidDataType} If the given expression is not a valid hexadecimal positive integer expression.
*/
public static of(
exp: bigint | number | string | Uint8Array | HexInt
): StorageKey {
try {
if (exp instanceof HexUInt32) {
return new StorageKey(exp);
}
return new StorageKey(HexUInt32.of(exp));
} catch (e) {
throw new InvalidDataType(
'StorageKey.of',
'not a StorageKey expression',
{ exp: `${exp}` }, // Needed to serialize bigint values.
e
);
}
}
}

export { StorageKey };
54 changes: 54 additions & 0 deletions packages/core/src/vcdm/TxId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Hex } from './Hex';
import { type HexInt } from './HexInt';
import { HexUInt32 } from './HexUInt32';
import { InvalidDataType } from '@vechain/sdk-errors';

/**
* The TxId class represents a Thor transaction ID value, which is a hexadecimal positive integer having 64 digits.
*
* @extends HexUInt32
*/
class TxId extends HexUInt32 {
/**
* Constructs a TxId object with the provided hexadecimal value.
*
* @param {HexUInt32} hexUInt32 - The hexadecimal value representing the TxId.
*/
protected constructor(hexUInt32: HexUInt32) {
super(Hex.POSITIVE, hexUInt32.digits);
}
/**
* Creates a new TxId object from the given expression.
*
* @param {bigint | number | string | HexInt | Uint8Array} exp - The expression to create the TxId from.
* It can be one of the following types:
* - bigint: A BigInteger value that represents the TxId.
* - number: A number value that represents the TxId.
* - string: A string value that represents the TxId.
* - HexInt: A HexInt object that represents the TxId.
* - Uint8Array: A Uint8Array object that represents the TxId.
*
* @returns {TxId} - A new TxId object created from the given expression.
*
* @throws {InvalidDataType} If the given expression is not a valid hexadecimal positive integer expression.
*/
public static of(
exp: bigint | number | string | Uint8Array | HexInt
): TxId {
try {
if (exp instanceof HexUInt32) {
return new TxId(exp);
}
return new TxId(HexUInt32.of(exp));
} catch (e) {
throw new InvalidDataType(
'TxId.of',
'not a TxId expression',
{ exp: `${exp}` }, // Needed to serialize bigint values.
e
);
}
}
}

export { TxId };
6 changes: 5 additions & 1 deletion packages/core/src/vcdm/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './abi';
export * from './account';
export * from './Address';
export * from './BlockId';
export * from './BlockRef';
export * from './BloomFilter';
export * from './currency';
Expand All @@ -10,12 +11,15 @@ export * from './hash';
export * from './Hex';
export * from './HexInt';
export * from './HexUInt';
export * from './HexUInt32';
export * from './Int';
export * from './Mnemonic';
export * from './Nonce';
export * from './LogId';
export * from './Quantity';
export * from './Revision';
export * from './BlockId';
export * from './StorageKey';
export * from './TxId';
export * from './Txt';
export * from './UInt';
export type * from './VeChainDataModel';
47 changes: 47 additions & 0 deletions packages/core/tests/vcdm/BlockId.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { describe, expect, test } from '@jest/globals';
import { InvalidDataType } from '@vechain/sdk-errors';
import { BlockId } from '../../src/vcdm/BlockId';

/**
* Test BlockId class.
* @group unit/vcdm
*/
describe('BlockId class tests', () => {
describe('Construction tests', () => {
test('Return an BlockId instance of the provided expression', () => {
const expression = '0xcaffee';
const expectedBlockId =
'0x0000000000000000000000000000000000000000000000000000000000caffee';

const blockId = BlockId.of(expression);

expect(blockId).toBeInstanceOf(BlockId);
expect(blockId.toString()).toEqual(expectedBlockId);
});

test('Checks if the provided expression is a valid 32 bytes unsigned hexadecimal value', () => {
const expression =
'0x0000000000000000000000000000000000000000000000000000000000caffee';

expect(BlockId.isValid(expression)).toBeTruthy();
});

test('Throw an error if the provided argument is not an unsigned expression', () => {
const exp = '-0xnotUnsigned';
expect(() => BlockId.of(exp)).toThrow(InvalidDataType);
});
});

describe('Polymorphism equivalence', () => {
test('Equal for bigint, bytes, hex expression, number', () => {
const ofBigInt = BlockId.of(255n);
const ofBytes = BlockId.of(Uint8Array.of(255));
const ofHex = BlockId.of('0xff');
const ofNumber = BlockId.of(255);
expect(ofBigInt.toString()).toHaveLength(66);
expect(ofBigInt.isEqual(ofBytes)).toBeTruthy();
expect(ofBytes.isEqual(ofHex)).toBeTruthy();
expect(ofHex.isEqual(ofNumber)).toBeTruthy();
});
});
});
Loading
Loading