CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-web3-utils

Collection of utility functions used in web3.js for Ethereum dApp development

Pending
Overview
Eval results
Files

data-manipulation.mddocs/

String and Data Manipulation

String padding, two's complement conversion, object merging, and Uint8Array operations for data processing. These utilities provide essential data manipulation capabilities for blockchain development.

Capabilities

String Padding

Left Padding

/**
 * Adds padding to left of string/number
 * @param value - Value to pad (Numbers type)
 * @param characterAmount - Total character length after padding
 * @param sign - Padding character (default: "0")
 * @returns Left-padded string
 */
function padLeft(value: Numbers, characterAmount: number, sign?: string): string;

/**
 * Alias for padLeft
 */
const leftPad = padLeft;

Right Padding

/**
 * Adds padding to right of string/number
 * @param value - Value to pad (Numbers type)
 * @param characterAmount - Total character length after padding
 * @param sign - Padding character (default: "0")
 * @returns Right-padded string
 */
function padRight(value: Numbers, characterAmount: number, sign?: string): string;

/**
 * Alias for padRight
 */
const rightPad = padRight;

Two's Complement Operations

To Two's Complement

/**
 * Converts negative number to two's complement hex representation
 * @param value - Number to convert (Numbers type)
 * @param nibbleWidth - Width in nibbles (4-bit units), optional
 * @returns Two's complement hex string
 */
function toTwosComplement(value: Numbers, nibbleWidth?: number): string;

From Two's Complement

/**
 * Converts two's complement hex to decimal number
 * @param value - Two's complement hex value (Numbers type)
 * @param nibbleWidth - Width in nibbles (4-bit units), optional
 * @returns Decimal number or bigint
 */
function fromTwosComplement(value: Numbers, nibbleWidth?: number): number | bigint;

Object Operations

Deep Merge

/**
 * Deep merges multiple objects into destination object
 * @param destination - Target object to merge into
 * @param sources - Source objects to merge from
 * @returns Merged object with all properties
 */
function mergeDeep(
  destination: Record<string, unknown>, 
  ...sources: Record<string, unknown>[]
): Record<string, unknown>;

Uint8Array Operations

Type Guard

/**
 * Type guard for Uint8Array (including Node.js Buffer)
 * @param data - Data to check
 * @returns true if data is Uint8Array or Buffer
 */
function isUint8Array(data: unknown | Uint8Array): data is Uint8Array;

Array Concatenation

/**
 * Concatenates multiple Uint8Arrays into single array
 * @param parts - Uint8Array parts to concatenate
 * @returns New Uint8Array with concatenated data
 */
function uint8ArrayConcat(...parts: Uint8Array[]): Uint8Array;

Array Equality

/**
 * Checks if two Uint8Arrays have same content
 * @param a - First Uint8Array
 * @param b - Second Uint8Array
 * @returns true if arrays have identical content
 */
function uint8ArrayEquals(a: Uint8Array, b: Uint8Array): boolean;

Data Formatting and Parsing

Chunk Response Parser

/**
 * Parser for chunked JSON-RPC responses
 * Handles streaming response data and event emission
 */
class ChunkResponseParser {
  /**
   * Creates new chunk response parser
   * @param eventEmitter - EventEmitter for parsed responses
   * @param autoReconnect - Whether to auto-reconnect on errors
   */
  constructor(eventEmitter: EventEmitter, autoReconnect: boolean);

  /**
   * Handles parsing errors
   * @param clearQueues - Optional function to clear request queues
   */
  onError(clearQueues?: () => void): void;

  /**
   * Parses response data string into JSON-RPC responses
   * @param data - Raw response data string
   * @returns Array of parsed JSON-RPC responses
   */
  parseResponse(data: string): JsonRpcResponse[];
}

Usage Examples

String Padding

import { padLeft, padRight } from "web3-utils";

// Left padding with zeros (default)
const paddedHex = padLeft("0x1a", 8); // "0x00001a"
const paddedNumber = padLeft(26, 6); // "000026"

// Left padding with custom character
const paddedCustom = padLeft("abc", 10, " "); // "       abc"

// Right padding
const rightPaddedHex = padRight("0x1a", 8); // "0x1a0000"
const rightPaddedString = padRight("hello", 10, "."); // "hello....."

// Common use case: address padding
const address = "0x742E4C5b469F50A4a8b399D4915C1fc93d15651B";
const paddedAddress = padLeft(address, 66); // Pad to 32 bytes + "0x"

Two's Complement Operations

import { toTwosComplement, fromTwosComplement } from "web3-utils";

// Convert negative number to two's complement
const negative = -123;
const twosComp = toTwosComplement(negative); // Two's complement representation
const twosCompFixed = toTwosComplement(negative, 8); // Fixed 8-nibble width

// Convert back from two's complement
const original = fromTwosComplement(twosComp); // -123

// Working with different bit widths
const value8bit = toTwosComplement(-1, 2); // 8-bit: "0xff"
const value16bit = toTwosComplement(-1, 4); // 16-bit: "0xffff"
const value32bit = toTwosComplement(-1, 8); // 32-bit: "0xffffffff"

// Convert back with same width
const decoded8bit = fromTwosComplement(value8bit, 2); // -1
const decoded16bit = fromTwosComplement(value16bit, 4); // -1

Object Deep Merge

import { mergeDeep } from "web3-utils";

// Basic object merge
const target = { a: 1, b: { x: 10 } };
const source1 = { b: { y: 20 }, c: 3 };
const source2 = { b: { z: 30 }, d: 4 };

const merged = mergeDeep(target, source1, source2);
// Result: { a: 1, b: { x: 10, y: 20, z: 30 }, c: 3, d: 4 }

// Configuration merging example
const defaultConfig = {
  network: {
    chainId: 1,
    timeout: 5000,
    retries: 3
  },
  logging: {
    level: 'info',
    format: 'json'
  }
};

const userConfig = {
  network: {
    timeout: 10000,
    endpoint: 'https://custom-rpc.com'
  },
  logging: {
    level: 'debug'
  }
};

const finalConfig = mergeDeep({}, defaultConfig, userConfig);
// Result: Merged configuration with user overrides

Uint8Array Operations

import { isUint8Array, uint8ArrayConcat, uint8ArrayEquals } from "web3-utils";

// Type checking
const data1 = new Uint8Array([1, 2, 3]);
const data2 = Buffer.from([4, 5, 6]); // Node.js Buffer
const data3 = [7, 8, 9]; // Regular array

console.log(isUint8Array(data1)); // true
console.log(isUint8Array(data2)); // true (Buffer extends Uint8Array)
console.log(isUint8Array(data3)); // false

// Concatenation
const part1 = new Uint8Array([1, 2, 3]);
const part2 = new Uint8Array([4, 5, 6]);
const part3 = new Uint8Array([7, 8, 9]);

const combined = uint8ArrayConcat(part1, part2, part3);
// Result: Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9])

// Equality checking
const array1 = new Uint8Array([1, 2, 3, 4]);
const array2 = new Uint8Array([1, 2, 3, 4]);
const array3 = new Uint8Array([1, 2, 3, 5]);

console.log(uint8ArrayEquals(array1, array2)); // true
console.log(uint8ArrayEquals(array1, array3)); // false

// Common blockchain use case: signature concatenation
const r = new Uint8Array(32); // 32 bytes
const s = new Uint8Array(32); // 32 bytes
const v = new Uint8Array([27]); // 1 byte

const signature = uint8ArrayConcat(r, s, v); // 65-byte signature

Chunk Response Parser

import { ChunkResponseParser, EventEmitter } from "web3-utils";

// Set up parser for streaming responses
const emitter = new EventEmitter();
const parser = new ChunkResponseParser(emitter, true);

// Handle parsed responses
emitter.on('message', (response) => {
  console.log('Parsed response:', response);
});

emitter.on('error', (error) => {
  console.error('Parser error:', error);
});

// Parse chunked data (e.g., from WebSocket or HTTP streaming)
const chunkData = `{"jsonrpc":"2.0","id":1,"result":"0x1"}\n{"jsonrpc":"2.0","id":2,"result":"0x2"}`;
const responses = parser.parseResponse(chunkData);

// responses will contain parsed JSON-RPC objects
responses.forEach(response => {
  console.log('Individual response:', response);
});

Advanced Usage Patterns

import { 
  padLeft, padRight, mergeDeep, uint8ArrayConcat, 
  toTwosComplement, fromTwosComplement 
} from "web3-utils";

// Smart contract data encoding
function encodeContractCall(methodId: string, params: Uint8Array[]) {
  // Method ID is first 4 bytes (8 hex chars + 0x)
  const paddedMethodId = padRight(methodId, 10, "0");
  
  // Encode each parameter to 32 bytes
  const encodedParams = params.map(param => {
    const hex = Array.from(param, byte => byte.toString(16).padStart(2, '0')).join('');
    return padLeft(`0x${hex}`, 66, "0"); // 32 bytes = 64 hex chars + "0x"
  });
  
  return paddedMethodId + encodedParams.map(p => p.slice(2)).join('');
}

// Configuration system with deep merging
class ConfigManager {
  private config: Record<string, unknown> = {};

  loadDefaults(defaults: Record<string, unknown>) {
    this.config = mergeDeep({}, defaults);
  }

  loadUserConfig(userConfig: Record<string, unknown>) {
    this.config = mergeDeep(this.config, userConfig);
  }

  loadEnvironmentOverrides(envConfig: Record<string, unknown>) {
    this.config = mergeDeep(this.config, envConfig);
  }

  getConfig(): Record<string, unknown> {
    return this.config;
  }
}

// Binary data manipulation
function processSignature(r: Uint8Array, s: Uint8Array, recovery: number) {
  // Ensure r and s are 32 bytes
  const paddedR = r.length < 32 ? uint8ArrayConcat(new Uint8Array(32 - r.length), r) : r;
  const paddedS = s.length < 32 ? uint8ArrayConcat(new Uint8Array(32 - s.length), s) : s;
  
  // Recovery value (v) is typically 27 or 28
  const v = new Uint8Array([recovery + 27]);
  
  return uint8ArrayConcat(paddedR, paddedS, v);
}

Install with Tessl CLI

npx tessl i tessl/npm-web3-utils

docs

conversion.md

data-manipulation.md

events.md

hashing.md

index.md

json-rpc.md

promises.md

providers.md

random-validation.md

tile.json