or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

conversion.mddata-manipulation.mdevents.mdhashing.mdindex.mdjson-rpc.mdpromises.mdproviders.mdrandom-validation.md

data-manipulation.mddocs/

0

# String and Data Manipulation

1

2

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

3

4

## Capabilities

5

6

### String Padding

7

8

#### Left Padding

9

10

```typescript { .api }

11

/**

12

* Adds padding to left of string/number

13

* @param value - Value to pad (Numbers type)

14

* @param characterAmount - Total character length after padding

15

* @param sign - Padding character (default: "0")

16

* @returns Left-padded string

17

*/

18

function padLeft(value: Numbers, characterAmount: number, sign?: string): string;

19

20

/**

21

* Alias for padLeft

22

*/

23

const leftPad = padLeft;

24

```

25

26

#### Right Padding

27

28

```typescript { .api }

29

/**

30

* Adds padding to right of string/number

31

* @param value - Value to pad (Numbers type)

32

* @param characterAmount - Total character length after padding

33

* @param sign - Padding character (default: "0")

34

* @returns Right-padded string

35

*/

36

function padRight(value: Numbers, characterAmount: number, sign?: string): string;

37

38

/**

39

* Alias for padRight

40

*/

41

const rightPad = padRight;

42

```

43

44

### Two's Complement Operations

45

46

#### To Two's Complement

47

48

```typescript { .api }

49

/**

50

* Converts negative number to two's complement hex representation

51

* @param value - Number to convert (Numbers type)

52

* @param nibbleWidth - Width in nibbles (4-bit units), optional

53

* @returns Two's complement hex string

54

*/

55

function toTwosComplement(value: Numbers, nibbleWidth?: number): string;

56

```

57

58

#### From Two's Complement

59

60

```typescript { .api }

61

/**

62

* Converts two's complement hex to decimal number

63

* @param value - Two's complement hex value (Numbers type)

64

* @param nibbleWidth - Width in nibbles (4-bit units), optional

65

* @returns Decimal number or bigint

66

*/

67

function fromTwosComplement(value: Numbers, nibbleWidth?: number): number | bigint;

68

```

69

70

### Object Operations

71

72

#### Deep Merge

73

74

```typescript { .api }

75

/**

76

* Deep merges multiple objects into destination object

77

* @param destination - Target object to merge into

78

* @param sources - Source objects to merge from

79

* @returns Merged object with all properties

80

*/

81

function mergeDeep(

82

destination: Record<string, unknown>,

83

...sources: Record<string, unknown>[]

84

): Record<string, unknown>;

85

```

86

87

### Uint8Array Operations

88

89

#### Type Guard

90

91

```typescript { .api }

92

/**

93

* Type guard for Uint8Array (including Node.js Buffer)

94

* @param data - Data to check

95

* @returns true if data is Uint8Array or Buffer

96

*/

97

function isUint8Array(data: unknown | Uint8Array): data is Uint8Array;

98

```

99

100

#### Array Concatenation

101

102

```typescript { .api }

103

/**

104

* Concatenates multiple Uint8Arrays into single array

105

* @param parts - Uint8Array parts to concatenate

106

* @returns New Uint8Array with concatenated data

107

*/

108

function uint8ArrayConcat(...parts: Uint8Array[]): Uint8Array;

109

```

110

111

#### Array Equality

112

113

```typescript { .api }

114

/**

115

* Checks if two Uint8Arrays have same content

116

* @param a - First Uint8Array

117

* @param b - Second Uint8Array

118

* @returns true if arrays have identical content

119

*/

120

function uint8ArrayEquals(a: Uint8Array, b: Uint8Array): boolean;

121

```

122

123

### Data Formatting and Parsing

124

125

#### Chunk Response Parser

126

127

```typescript { .api }

128

/**

129

* Parser for chunked JSON-RPC responses

130

* Handles streaming response data and event emission

131

*/

132

class ChunkResponseParser {

133

/**

134

* Creates new chunk response parser

135

* @param eventEmitter - EventEmitter for parsed responses

136

* @param autoReconnect - Whether to auto-reconnect on errors

137

*/

138

constructor(eventEmitter: EventEmitter, autoReconnect: boolean);

139

140

/**

141

* Handles parsing errors

142

* @param clearQueues - Optional function to clear request queues

143

*/

144

onError(clearQueues?: () => void): void;

145

146

/**

147

* Parses response data string into JSON-RPC responses

148

* @param data - Raw response data string

149

* @returns Array of parsed JSON-RPC responses

150

*/

151

parseResponse(data: string): JsonRpcResponse[];

152

}

153

```

154

155

## Usage Examples

156

157

### String Padding

158

159

```typescript

160

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

161

162

// Left padding with zeros (default)

163

const paddedHex = padLeft("0x1a", 8); // "0x00001a"

164

const paddedNumber = padLeft(26, 6); // "000026"

165

166

// Left padding with custom character

167

const paddedCustom = padLeft("abc", 10, " "); // " abc"

168

169

// Right padding

170

const rightPaddedHex = padRight("0x1a", 8); // "0x1a0000"

171

const rightPaddedString = padRight("hello", 10, "."); // "hello....."

172

173

// Common use case: address padding

174

const address = "0x742E4C5b469F50A4a8b399D4915C1fc93d15651B";

175

const paddedAddress = padLeft(address, 66); // Pad to 32 bytes + "0x"

176

```

177

178

### Two's Complement Operations

179

180

```typescript

181

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

182

183

// Convert negative number to two's complement

184

const negative = -123;

185

const twosComp = toTwosComplement(negative); // Two's complement representation

186

const twosCompFixed = toTwosComplement(negative, 8); // Fixed 8-nibble width

187

188

// Convert back from two's complement

189

const original = fromTwosComplement(twosComp); // -123

190

191

// Working with different bit widths

192

const value8bit = toTwosComplement(-1, 2); // 8-bit: "0xff"

193

const value16bit = toTwosComplement(-1, 4); // 16-bit: "0xffff"

194

const value32bit = toTwosComplement(-1, 8); // 32-bit: "0xffffffff"

195

196

// Convert back with same width

197

const decoded8bit = fromTwosComplement(value8bit, 2); // -1

198

const decoded16bit = fromTwosComplement(value16bit, 4); // -1

199

```

200

201

### Object Deep Merge

202

203

```typescript

204

import { mergeDeep } from "web3-utils";

205

206

// Basic object merge

207

const target = { a: 1, b: { x: 10 } };

208

const source1 = { b: { y: 20 }, c: 3 };

209

const source2 = { b: { z: 30 }, d: 4 };

210

211

const merged = mergeDeep(target, source1, source2);

212

// Result: { a: 1, b: { x: 10, y: 20, z: 30 }, c: 3, d: 4 }

213

214

// Configuration merging example

215

const defaultConfig = {

216

network: {

217

chainId: 1,

218

timeout: 5000,

219

retries: 3

220

},

221

logging: {

222

level: 'info',

223

format: 'json'

224

}

225

};

226

227

const userConfig = {

228

network: {

229

timeout: 10000,

230

endpoint: 'https://custom-rpc.com'

231

},

232

logging: {

233

level: 'debug'

234

}

235

};

236

237

const finalConfig = mergeDeep({}, defaultConfig, userConfig);

238

// Result: Merged configuration with user overrides

239

```

240

241

### Uint8Array Operations

242

243

```typescript

244

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

245

246

// Type checking

247

const data1 = new Uint8Array([1, 2, 3]);

248

const data2 = Buffer.from([4, 5, 6]); // Node.js Buffer

249

const data3 = [7, 8, 9]; // Regular array

250

251

console.log(isUint8Array(data1)); // true

252

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

253

console.log(isUint8Array(data3)); // false

254

255

// Concatenation

256

const part1 = new Uint8Array([1, 2, 3]);

257

const part2 = new Uint8Array([4, 5, 6]);

258

const part3 = new Uint8Array([7, 8, 9]);

259

260

const combined = uint8ArrayConcat(part1, part2, part3);

261

// Result: Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9])

262

263

// Equality checking

264

const array1 = new Uint8Array([1, 2, 3, 4]);

265

const array2 = new Uint8Array([1, 2, 3, 4]);

266

const array3 = new Uint8Array([1, 2, 3, 5]);

267

268

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

269

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

270

271

// Common blockchain use case: signature concatenation

272

const r = new Uint8Array(32); // 32 bytes

273

const s = new Uint8Array(32); // 32 bytes

274

const v = new Uint8Array([27]); // 1 byte

275

276

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

277

```

278

279

### Chunk Response Parser

280

281

```typescript

282

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

283

284

// Set up parser for streaming responses

285

const emitter = new EventEmitter();

286

const parser = new ChunkResponseParser(emitter, true);

287

288

// Handle parsed responses

289

emitter.on('message', (response) => {

290

console.log('Parsed response:', response);

291

});

292

293

emitter.on('error', (error) => {

294

console.error('Parser error:', error);

295

});

296

297

// Parse chunked data (e.g., from WebSocket or HTTP streaming)

298

const chunkData = `{"jsonrpc":"2.0","id":1,"result":"0x1"}\n{"jsonrpc":"2.0","id":2,"result":"0x2"}`;

299

const responses = parser.parseResponse(chunkData);

300

301

// responses will contain parsed JSON-RPC objects

302

responses.forEach(response => {

303

console.log('Individual response:', response);

304

});

305

```

306

307

### Advanced Usage Patterns

308

309

```typescript

310

import {

311

padLeft, padRight, mergeDeep, uint8ArrayConcat,

312

toTwosComplement, fromTwosComplement

313

} from "web3-utils";

314

315

// Smart contract data encoding

316

function encodeContractCall(methodId: string, params: Uint8Array[]) {

317

// Method ID is first 4 bytes (8 hex chars + 0x)

318

const paddedMethodId = padRight(methodId, 10, "0");

319

320

// Encode each parameter to 32 bytes

321

const encodedParams = params.map(param => {

322

const hex = Array.from(param, byte => byte.toString(16).padStart(2, '0')).join('');

323

return padLeft(`0x${hex}`, 66, "0"); // 32 bytes = 64 hex chars + "0x"

324

});

325

326

return paddedMethodId + encodedParams.map(p => p.slice(2)).join('');

327

}

328

329

// Configuration system with deep merging

330

class ConfigManager {

331

private config: Record<string, unknown> = {};

332

333

loadDefaults(defaults: Record<string, unknown>) {

334

this.config = mergeDeep({}, defaults);

335

}

336

337

loadUserConfig(userConfig: Record<string, unknown>) {

338

this.config = mergeDeep(this.config, userConfig);

339

}

340

341

loadEnvironmentOverrides(envConfig: Record<string, unknown>) {

342

this.config = mergeDeep(this.config, envConfig);

343

}

344

345

getConfig(): Record<string, unknown> {

346

return this.config;

347

}

348

}

349

350

// Binary data manipulation

351

function processSignature(r: Uint8Array, s: Uint8Array, recovery: number) {

352

// Ensure r and s are 32 bytes

353

const paddedR = r.length < 32 ? uint8ArrayConcat(new Uint8Array(32 - r.length), r) : r;

354

const paddedS = s.length < 32 ? uint8ArrayConcat(new Uint8Array(32 - s.length), s) : s;

355

356

// Recovery value (v) is typically 27 or 28

357

const v = new Uint8Array([recovery + 27]);

358

359

return uint8ArrayConcat(paddedR, paddedS, v);

360

}

361

```