Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@vechain/sdk-core

Package Overview
Dependencies
Maintainers
6
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vechain/sdk-core - npm Package Compare versions

Comparing version 1.0.0-beta.1 to 1.0.0-beta.2

src/utils/hex/hex.ts

4

package.json
{
"name": "@vechain/sdk-core",
"version": "1.0.0-beta.1",
"version": "1.0.0-beta.2",
"description": "Includes modules for fundamental operations like hashing and cryptography",

@@ -35,3 +35,3 @@ "author": "vechain Foundation",

"@types/elliptic": "^6.4.18",
"@vechain/sdk-errors": "1.0.0-beta.1",
"@vechain/sdk-errors": "1.0.0-beta.2",
"blakejs": "^1.2.1",

@@ -38,0 +38,0 @@ "elliptic": "^6.5.5",

import { ethers, type Fragment } from 'ethers';
import {
type BytesLike,
type EventFragment,
type FormatType,

@@ -181,3 +182,3 @@ type FunctionFragment,

*/
public fragment: ethers.EventFragment;
public fragment: EventFragment;

@@ -184,0 +185,0 @@ /**

@@ -14,2 +14,7 @@ import { type ethers } from 'ethers';

/**
* Represents a wrapped Event Fragment for ethers.js types.
*/
type EventFragment = ethers.EventFragment;
/**
* Represents a wrapped Interface for ethers.js types.

@@ -50,2 +55,3 @@ */

FunctionFragment,
EventFragment,
Interface,

@@ -52,0 +58,0 @@ InterfaceAbi,

import { ethers } from 'ethers';
import { HEX_ADDRESS_REGEX } from '../utils';
import { Hex0x, HEX_ADDRESS_REGEX } from '../utils';
import { ADDRESS, assert } from '@vechain/sdk-errors';

@@ -17,3 +17,3 @@ import { secp256k1 } from '../secp256k1';

function fromPublicKey(publicKey: Buffer): string {
return ethers.computeAddress('0x' + publicKey.toString('hex'));
return ethers.computeAddress(Hex0x.of(publicKey));
}

@@ -20,0 +20,0 @@

import { assert, DATA, SECP256K1, TRANSACTION } from '@vechain/sdk-errors';
import { type Transaction } from '../../transaction';
import { dataUtils } from '../../utils';
import { Hex0x } from '../../utils';

@@ -17,3 +17,3 @@ /**

`assertValidTransactionID - ${methodName}`,
dataUtils.isThorId(transactionId, true),
Hex0x.isThorId(transactionId),
DATA.INVALID_DATA_TYPE,

@@ -34,3 +34,3 @@ 'Invalid transaction ID given as input. Input must be an hex string of length 64.',

`assertValidTransactionHead - ${methodName}`,
head === undefined || dataUtils.isThorId(head, true),
head === undefined || Hex0x.isThorId(head),
DATA.INVALID_DATA_TYPE,

@@ -37,0 +37,0 @@ 'Invalid head given as input. Input must be an hex string of length 64.',

@@ -6,3 +6,3 @@ import { addressUtils } from '../address';

import { Buffer } from 'buffer';
import { dataUtils } from '../utils';
import { Hex0x } from '../utils';
import { type Certificate } from './types';

@@ -43,4 +43,3 @@ import { assert, CERTIFICATE } from '@vechain/sdk-errors';

'verify',
dataUtils.isHexString(cert.signature as string) &&
(cert.signature as string).length % 2 === 0,
Hex0x.isValid(cert.signature as string, false, true),
CERTIFICATE.CERTIFICATE_INVALID_SIGNATURE_FORMAT,

@@ -47,0 +46,0 @@ 'Verification failed: Signature format is invalid.',

@@ -41,2 +41,3 @@ import { isAddress } from 'ethers';

*
* @param value - The amount of VET to send with the transaction.
* @returns A clause for interacting with a smart contract function.

@@ -49,7 +50,8 @@ *

functionFragment: FunctionFragment,
args: unknown[]
args: unknown[],
value = 0
): TransactionClause {
return {
to: contractAddress,
value: 0,
value,
data: new abi.Function(functionFragment).encodeInput(args)

@@ -56,0 +58,0 @@ };

import { assert, RLP } from '@vechain/sdk-errors';
import { Hex } from '../../../utils';
import { Hex0x } from '../../../utils';

@@ -62,3 +62,3 @@ /**

): string => {
return Hex.of0x(buffer, bytes);
return Hex0x.of(buffer, bytes);
};

@@ -65,0 +65,0 @@

@@ -1,2 +0,2 @@

import { dataUtils } from '../../../utils';
import { Hex0x } from '../../../utils';
import { type RLPInput } from '../types';

@@ -27,3 +27,3 @@ import { assert, RLP } from '@vechain/sdk-errors';

'assertValidHexBlobKindData',
dataUtils.isHexString(data as string, true),
Hex0x.isValid(data as string),
RLP.INVALID_RLP,

@@ -30,0 +30,0 @@ "Validation error: Input must be a valid hex string with a '0x' prefix.",

@@ -1,2 +0,2 @@

import { dataUtils, Hex } from '../../../utils';
import { dataUtils, Hex0x, Hex } from '../../../utils';
import { type RLPInput } from '../types';

@@ -71,3 +71,3 @@ import { assert, RLP } from '@vechain/sdk-errors';

const _validateNumericKindString = (str: string, context: string): void => {
const isHex = dataUtils.isHexString(str);
const isHex = Hex0x.isValid(str);
const isDecimal = dataUtils.isDecimalString(str);

@@ -165,3 +165,3 @@

const bi = BigInt('0x' + buffer.toString('hex'));
const bi = BigInt(Hex0x.of(buffer));
const num = Number(bi);

@@ -168,0 +168,0 @@

@@ -7,3 +7,3 @@ import {

import { FixedHexBlobKind } from './fixedhexblob';
import { Hex } from '../../../../utils';
import { Hex0x } from '../../../../utils';

@@ -42,3 +42,3 @@ /**

return {
decode: () => Hex.of0x(buffer, this.bytes) // Decode the buffer, returning a hex string with leading zeros.
decode: () => Hex0x.of(buffer, this.bytes) // Decode the buffer, returning a hex string with leading zeros.
};

@@ -45,0 +45,0 @@ }

@@ -7,3 +7,3 @@ import {

import { ScalarKind } from '../scalarkind.abstract';
import { Hex } from '../../../../utils';
import { Hex0x } from '../../../../utils';

@@ -44,3 +44,3 @@ /**

return {
decode: () => Hex.of0x(buffer)
decode: () => Hex0x.of(buffer)
};

@@ -47,0 +47,0 @@ }

import blake from 'blakejs';
import { type HashInput, type ReturnType } from './types';
import { assertIsValidReturnType } from '../assertions';
import { Hex } from '../utils';
import { Hex0x } from '../utils';

@@ -83,5 +83,5 @@ /**

return returnType === 'buffer' ? hash : Hex.of0x(hash);
return returnType === 'buffer' ? hash : Hex0x.of(hash);
}
export { blake2b256 };

@@ -7,3 +7,3 @@ /**

import { ethers } from 'ethers';
import { Hex, SCRYPT_PARAMS } from '../utils';
import { Hex0x, SCRYPT_PARAMS } from '../utils';
import { type Keystore, type KeystoreAccount } from './types';

@@ -30,3 +30,3 @@ import { assert, buildError, KEYSTORE } from '@vechain/sdk-errors';

address: deriveAddress,
privateKey: Hex.of0x(privateKey)
privateKey: Hex0x.of(privateKey)
};

@@ -33,0 +33,0 @@

import { ethers } from 'ethers';
import { randomBytes } from 'crypto';
import { HDNode } from '../hdnode';

@@ -10,2 +9,3 @@ import {

import { assert, HDNODE } from '@vechain/sdk-errors';
import { secp256k1 } from '../secp256k1';

@@ -69,3 +69,3 @@ /* --- Overloaded functions start --- */

// Default random generator
((numberOfBytes: number) => randomBytes(numberOfBytes));
((numberOfBytes: number) => secp256k1.randomBytes(numberOfBytes));

@@ -72,0 +72,0 @@ // Worldlist size

@@ -1,2 +0,1 @@

import { randomBytes } from 'crypto';
import { PRIVATE_KEY_MAX_VALUE, SIGNATURE_LENGTH, ZERO_BUFFER } from '../utils';

@@ -10,9 +9,13 @@ import { ec as EC } from 'elliptic';

// Curve algorithm
import { BN } from 'bn.js';
import { secp256k1 as _secp256k1 } from '@noble/curves/secp256k1';
import { randomBytes as _randomBytes } from '@noble/hashes/utils';
// Curve algorithm.
const curve = new EC('secp256k1');
/**
* Validate message hash
* @param hash of message
* @returns if message hash is valid or not
* Validate message hash.
* @param hash of message.
* @returns if message hash is valid or not.
*/

@@ -24,4 +27,4 @@ function isValidMessageHash(hash: Buffer): boolean {

/**
* Verify if private key is valid
* @returns If private key is valid or not
* Verify if private key is valid.
* @returns If private key is valid or not.
*/

@@ -38,51 +41,40 @@ function isValidPrivateKey(key: Buffer): boolean {

/**
* Generate private key using elliptic curve algorithm on the curve secp256k1
* @param entropy - entropy function
* @returns Private key generated
* Generate private key using elliptic curve algorithm on the curve secp256k1.
* @returns Private key generated.
*/
function generatePrivateKey(entropy?: () => Buffer): Buffer {
entropy = entropy ?? ((): Buffer => randomBytes(32));
let privateKey: Buffer;
do {
privateKey = entropy();
} while (!isValidPrivateKey(privateKey));
return privateKey;
function generatePrivateKey(): Buffer {
return Buffer.from(_secp256k1.utils.randomPrivateKey());
}
/**
* Derive public key from private key using elliptic curve algorithm on the curve secp256k1
* Derive public key from private key using elliptic curve algorithm secp256k1.
*
* @throws{InvalidSecp256k1PrivateKeyError}
* @param privateKey - private key to derive public key from
* @returns Public key derived from private key
* @param privateKey - private key to derive public key from.
* @returns Public key derived from private key.
*/
function derivePublicKey(privateKey: Buffer): Buffer {
assertIsValidPrivateKey('derivePublicKey', privateKey, isValidPrivateKey);
const keyPair = curve.keyFromPrivate(privateKey);
return Buffer.from(keyPair.getPublic().encode('array', false));
const publicKey = _secp256k1.getPublicKey(privateKey, false);
return Buffer.from(publicKey);
}
/**
* sign a message using elliptic curve algorithm on the curve secp256k1
* Sign a message using elliptic curve algorithm secp256k1.
*
* @throws{InvalidSecp256k1PrivateKeyError, InvalidSecp256k1MessageHashError}
* @param messageHash hash of message
* @param privateKey serialized private key
* @param messageHash hash of message.
* @param privateKey serialized private key.
*/
function sign(messageHash: Buffer, privateKey: Buffer): Buffer {
assertIsValidSecp256k1MessageHash('sign', messageHash, isValidMessageHash);
assertIsValidPrivateKey('sign', privateKey, isValidPrivateKey);
const keyPair = curve.keyFromPrivate(privateKey);
const sig = keyPair.sign(messageHash, { canonical: true });
const r = Buffer.from(sig.r.toArray('be', 32));
const s = Buffer.from(sig.s.toArray('be', 32));
return Buffer.concat([r, s, Buffer.from([sig.recoveryParam as number])]);
const sig = _secp256k1.sign(messageHash, privateKey);
const r = Buffer.from(new BN(sig.r.toString()).toArray('be', 32));
const s = Buffer.from(new BN(sig.s.toString()).toArray('be', 32));
return Buffer.concat([r, s, Buffer.from([sig.recovery])]);
}
/**
* Recovery signature to public key
* Recover the public key from its signature and messahe hash.
*

@@ -117,14 +109,7 @@ * @throws{InvalidSecp256k1MessageHashError, InvalidSecp256k1SignatureError, InvalidSecp256k1SignatureRecoveryError}

const rCopy = Uint8Array.from(sig);
const r = rCopy.slice(0, 32);
const sCopy = Uint8Array.from(sig);
const s = sCopy.slice(32, 64);
return Buffer.from(
(
curve.recoverPubKey(messageHash, { r, s }, recovery) as {
encode: (enc: string, flag: boolean) => ArrayBuffer;
}
).encode('array', false)
_secp256k1.Signature.fromCompact(Uint8Array.from(sig).slice(0, 64))
.addRecoveryBit(recovery)
.recoverPublicKey(messageHash)
.toRawBytes(false)
);

@@ -136,5 +121,5 @@ }

*
* @param extendedPublicKey extended public key
* @param compact if public key should be compressed or not
* @returns array public key
* @param extendedPublicKey extended public key.
* @param compact if public key should be compressed or not.
* @returns array public key.
*/

@@ -148,2 +133,18 @@ function extendedPublicKeyToArray(

/**
* Generates random bytes of specified length.
*
* The function relays on [noble-hashes](https://github.com/paulmillr/noble-hashes/blob/main/src/utils.ts)
* functionality to delegate the OS to generate the random sequence according the host hardware.
*
* @param {number} bytesLength - The length of the random bytes to generate.
* @return {Buffer} - The generated random bytes as a Buffer object.
* @throws Error with `crypto.getRandomValues must be defined`
* message if no hardware for random generation is
* available at runtime.
*/
function randomBytes(bytesLength?: number | undefined): Buffer {
return Buffer.from(_randomBytes(bytesLength));
}
export const secp256k1 = {

@@ -156,3 +157,4 @@ isValidMessageHash,

recover,
extendedPublicKeyToArray
extendedPublicKeyToArray,
randomBytes
};

@@ -7,3 +7,3 @@ import { addressUtils } from '../address';

BLOCK_REF_LENGTH,
dataUtils,
Hex0x,
SIGNATURE_LENGTH,

@@ -412,3 +412,3 @@ SIGNED_TRANSACTION_RLP,

body.blockRef !== undefined &&
dataUtils.isHexString(body.blockRef) &&
Hex0x.isValid(body.blockRef) &&
Buffer.from(body.blockRef.slice(2), 'hex').length ===

@@ -415,0 +415,0 @@ BLOCK_REF_LENGTH &&

import { bloom as bloomInstance } from '../../bloom';
import { dataUtils } from '../data';
import { addressUtils } from '../../address';
import { BLOOM_REGEX_LOWERCASE, BLOOM_REGEX_UPPERCASE } from '../const';
import { ADDRESS, assert, BLOOM, DATA } from '@vechain/sdk-errors';
import { Hex0x, Hex } from '../hex';

@@ -55,3 +55,3 @@ /**

'isInBloom',
dataUtils.isHexString(data, false),
Hex0x.isValid(data, true),
DATA.INVALID_DATA_TYPE,

@@ -79,5 +79,5 @@ 'Invalid data type. Data should be an hexadecimal string',

// Ensure data is a Buffer
const dataBuffer = Buffer.from(dataUtils.removePrefix(data), 'hex');
const dataBuffer = Buffer.from(Hex.canon(data), 'hex');
const bloomBuffer = Buffer.from(dataUtils.removePrefix(bloom), 'hex');
const bloomBuffer = Buffer.from(Hex.canon(bloom), 'hex');
const bloomFilter = new bloomInstance.Filter(bloomBuffer, k);

@@ -84,0 +84,0 @@

@@ -10,13 +10,2 @@ /**

/**
* Regular expression for validating hexadecimal strings.
* Allows optional "0x" prefix and validates both lower and uppercase hex characters.
*/
const HEX_REGEX_OPTIONAL_PREFIX = /^(0x)?[0-9a-fA-F]*$/;
/**
* Regular expression for validating hexadecimal strings. Must have "0x" prefix.
*/
const HEX_REGEX = /^0x[0-9a-f]*$/i;
/**
* Regular expression for validating hexadecimal addresses. Must have "0x" prefix. Must be 40 characters long.

@@ -38,17 +27,2 @@ */

/**
* Default length of thor id hex string.
* Thor id is a 64 characters long hexadecimal string.
* This is used to validate thor id strings (block ids, transaction ids, ...).
*/
const THOR_ID_LENGTH = 64;
export {
ZERO_BUFFER,
HEX_REGEX,
HEX_ADDRESS_REGEX,
HEX_REGEX_OPTIONAL_PREFIX,
DECIMAL_INTEGER_REGEX,
NUMERIC_REGEX,
THOR_ID_LENGTH
};
export { ZERO_BUFFER, HEX_ADDRESS_REGEX, DECIMAL_INTEGER_REGEX, NUMERIC_REGEX };
import { ethers } from 'ethers';
import {
DECIMAL_INTEGER_REGEX,
HEX_REGEX,
HEX_REGEX_OPTIONAL_PREFIX,
NUMERIC_REGEX,
THOR_ID_LENGTH
} from '../const';
import { type HexConfig } from './types';
import { DECIMAL_INTEGER_REGEX, NUMERIC_REGEX } from '../const';
import { assert, buildError, DATA } from '@vechain/sdk-errors';
import * as crypto from 'crypto';
import { Hex } from '../hex';
import { Hex0x, Hex } from '../hex';
/**
* Convert data to a hexadecimal string representation.
*
* @remarks
* This function takes a `string` or `Uint8Array` and converts it into a hexadecimal string.
* The resulting string can optionally be prefixed with '0x' based on the configuration provided.
*
* @param data - The input data to be converted, either a string or a Uint8Array.
* @param config - An optional configuration object that may include a `withPrefix` boolean, which, if true, prefixes the resulting string with '0x'.
* @returns The hexadecimal string representation of the input data.
*/
const toHexString = (data: string | Uint8Array, config?: HexConfig): string => {
return config?.withPrefix === true ? Hex.of0x(data) : Hex.of(data);
};
/**
* Checks whether the provided data is a valid hexadecimal string.
*
* @remarks
* The check can optionally validate the presence of a '0x' prefix.
*
* @param data - The string data to check.
* @param checkPrefix - A boolean determining whether to validate the '0x' prefix (default: false).
* @returns A boolean indicating whether the input is a valid hexadecimal string.
*/
const isHexString = (data: string, checkPrefix: boolean = true): boolean => {
return checkPrefix
? HEX_REGEX.test(data)
: HEX_REGEX_OPTIONAL_PREFIX.test(data);
};
/**
* Pads a hexadecimal string to a fixed length by adding zeros to the left.
*
* @param {string} hexString - The original hexadecimal string to pad. It can optionally start with '0x'.
* @param {number} [hexTargetLength=64] - The desired length in characters for the output string. Defaults to vechain data length of 64 characters if not specified. If the value is less than or equal to str.length, then str is returned as-is.
* @returns {string} - The padded hexadecimal string, starting with '0x' and with length matching the specified number of characters.
*
* @example
* // returns '0x000000000000000000000000000000000000000000000000000000000000001a'
* padHexString('1a', 64);
*/
function padHexString(hexString: string, hexTargetLength: number = 64): string {
// Check if the input length is an integer, if not throw an error
if (!Number.isInteger(hexTargetLength)) {
throw buildError(
'padHexString',
DATA.INVALID_DATA_TYPE,
`The target length '${hexTargetLength}' must be an integer.`,
{ hexTargetLength }
);
}
if (hexString.replace(/^0x/, '').length > hexTargetLength) {
throw buildError(
'padHexString',
DATA.INVALID_DATA_TYPE,
`The input string '${hexString}' is longer than the target length '${hexTargetLength}'.`,
{ hexString, hexTargetLength }
);
}
// Remove the '0x' prefix if present
if (hexString.startsWith('0x')) {
hexString = hexString.slice(2);
}
// Pad the string with zeros on the left and add the '0x' prefix back
return '0x' + hexString.padStart(hexTargetLength, '0');
}
/**
* Checks whether the provided data is a valid decimal string.

@@ -99,18 +20,2 @@ *

/**
* Remove the '0x' prefix from a hexadecimal string.
*
* @remarks
* If the input hexadecimal string starts with '0x', it is removed. If the input string does not start with '0x', it is returned unmodified.
*
* @param hex - The input hexadecimal string.
* @returns The hexadecimal string without the '0x' prefix.
*/
const removePrefix = (hex: string): string => {
if (hex.startsWith('0x')) {
return hex.slice(2);
}
return hex;
};
/**
* Checks whether the provided string is a valid decimal numeric string.

@@ -125,23 +30,2 @@ * @param value - The string to check.

/**
* Checks whether the provided data is a valid transaction thor id.
* Thor id is a 64 characters long hexadecimal string.
* It is used to identify a transaction id, a block id, ....
*
* @remarks
* The check can optionally validate the presence of a '0x' prefix.
*
* @param data - The string data to check.
* @param checkPrefix - A boolean determining whether to validate the '0x' prefix (default: false).
* @returns A boolean indicating whether the input is a valid hexadecimal string.
*/
const isThorId = (data: string, checkPrefix: boolean = false): boolean => {
return (
isHexString(data, checkPrefix) &&
(checkPrefix
? data.length === THOR_ID_LENGTH + 2 // +2 for '0x'
: data.length === THOR_ID_LENGTH)
);
};
/**
* Encode a string to bytes32 string.

@@ -189,3 +73,3 @@ * An example of usage is to encode a string to bytes32 string to be used as a parameter for a smart contract function.

'decodeBytes32String',
isHexString(value) && removePrefix(value).length === 64,
Hex0x.isValid(value) && Hex.canon(value).length === 64,
DATA.INVALID_DATA_TYPE,

@@ -196,3 +80,3 @@ `Failed to decode value ${value} to string. Value is not a valid hex string or it is not 64 characters long`,

const valueInBytes = Buffer.from(removePrefix(value), 'hex');
const valueInBytes = Buffer.from(Hex.canon(value), 'hex');

@@ -218,26 +102,7 @@ // find the first zero byte

/**
* Generates a random hexadecimal string of a specified length.
*
* @param stringLength - The length of the hexadecimal string to generate. This is twice the number of bytes that will be generated, since each byte is represented by two hexadecimal characters.
* @returns A random hexadecimal string of the specified length.
*/
const generateRandomHexOfLength = (stringLength: number): string => {
// Ensure the number of bytes generated is half the size of the desired hex string length
// since each byte will be converted to two hex characters.
const bytes = Math.ceil(stringLength / 2);
return Hex.of(crypto.randomBytes(bytes)).substring(0, stringLength);
};
export const dataUtils = {
toHexString,
isHexString,
padHexString,
removePrefix,
isDecimalString,
isNumeric,
isThorId,
encodeBytes32String,
decodeBytes32String,
generateRandomHexOfLength
decodeBytes32String
};

@@ -1,1 +0,1 @@

export * from './Hex';
export * from './hex';
import { dataUtils } from '../data';
import { Hex0x } from '../hex';

@@ -31,3 +32,3 @@ /**

revision === 'best' ||
(typeof revision === 'string' && dataUtils.isHexString(revision)) ||
(typeof revision === 'string' && Hex0x.isValid(revision)) ||
(typeof revision === 'string' && dataUtils.isDecimalString(revision)) ||

@@ -34,0 +35,0 @@ (typeof revision === 'number' && revision >= 0)

import { addressUtils } from '../../address';
import { type TransactionClause } from '../../transaction';
import { TRANSACTIONS_GAS_CONSTANTS } from '../const';
import { dataUtils } from '../data';
import { assert, DATA } from '@vechain/sdk-errors';
import { Hex0x } from '../hex';

@@ -57,3 +57,3 @@ /**

'_calculateDataUsedGas',
data === '' || dataUtils.isHexString(data),
data === '' || Hex0x.isValid(data),
DATA.INVALID_DATA_TYPE,

@@ -60,0 +60,0 @@ 'Invalid data type for gas calculation. Data should be a hexadecimal string.',

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc