Skip to content
Merged
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
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

### Bug Fixes


- starknet types 0.7 ([#1087](https://github.com/starknet-io/starknet.js/issues/1087)) ([b038c76](https://github.com/starknet-io/starknet.js/commit/b038c76fe204746f1d1023c2ad3b46c022f6edbd))

- tslib ([#1068](https://github.com/starknet-io/starknet.js/issues/1068)) ([dd7dc10](https://github.com/starknet-io/starknet.js/commit/dd7dc10c57fc3cc35298c0d584a178666e9cfed1))
Expand Down
35 changes: 29 additions & 6 deletions src/utils/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import { assertInRange, toHex } from './num';
* Format a hex number to '0x' and 64 characters, adding leading zeros if necessary.
* @param {BigNumberish} address
* @returns {string} Hex string : 0x followed by 64 characters. No upper case characters in the response.
* @example
* ```typescript
* const address = "0x90591d9fa3efc87067d95a643f8455e0b8190eb8cb7bfd39e4fb7571fdf";
* const result = addAddressPadding(address);
* // result = "0x0000090591d9fa3efc87067d95a643f8455e0b8190eb8cb7bfd39e4fb7571fdf"
* ```
*/
export function addAddressPadding(address: BigNumberish): string {
return addHexPrefix(removeHexPrefix(toHex(address)).padStart(64, '0'));
Expand All @@ -20,6 +26,12 @@ export function addAddressPadding(address: BigNumberish): string {
* Check the validity of a Starknet address, and format it as a hex number : '0x' and 64 characters, adding leading zeros if necessary.
* @param {BigNumberish} address
* @returns {string} Hex string : 0x followed by 64 characters. No upper case characters in the response.
* @example
* ```typescript
* const address = "0x90591d9fa3efc87067d95a643f8455e0b8190eb8cb7bfd39e4fb7571fdf";
* const result = validateAndParseAddress(address);
* // result = "0x0000090591d9fa3efc87067d95a643f8455e0b8190eb8cb7bfd39e4fb7571fdf"
* ```
*/
export function validateAndParseAddress(address: BigNumberish): string {
assertInRange(address, ZERO, ADDR_BOUND - 1n, 'Starknet Address');
Expand All @@ -34,13 +46,18 @@ export function validateAndParseAddress(address: BigNumberish): string {
}

/**
* Computes the checksum address for the given Starknet address.
*
* From https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
* @param {BigNumberish} address - The address to compute the checksum for.
*
* @returns {string} The checksum address.
* Convert an address to her checksum representation which uses a specific pattern of uppercase and lowercase letters within
* a given address to reduce the risk of errors introduced from typing an address or cut and paste issues.
* @param {BigNumberish} address
* @returns {string} Hex string : 0x followed by 64 characters. Mix of uppercase and lowercase
* @example
* ```typescript
* const address = "0x90591d9fa3efc87067d95a643f8455e0b8190eb8cb7bfd39e4fb7571fdf";
* const result = getChecksumAddress(address);
* // result = "0x0000090591D9fA3EfC87067d95a643f8455E0b8190eb8Cb7bFd39e4fb7571fDF"
* ```
*/
// from https://github.com/ethers-io/ethers.js/blob/fc1e006575d59792fa97b4efb9ea2f8cca1944cf/packages/address/src.ts/index.ts#L12
export function getChecksumAddress(address: BigNumberish): string {
const chars = removeHexPrefix(validateAndParseAddress(address)).toLowerCase().split('');
const hex = removeHexPrefix(keccakBn(address));
Expand All @@ -65,6 +82,12 @@ export function getChecksumAddress(address: BigNumberish): string {
* @param address string
*
* @returns true if the ChecksumAddress is valid
* @example
* ```typescript
* const address = "0x0000090591D9fA3EfC87067d95a643f8455E0b8190eb8Cb7bFd39e4fb7571fDF";
* const result = validateChecksumAddress(address);
* // result = true
* ```
*/
export function validateChecksumAddress(address: string): boolean {
return getChecksumAddress(address) === address;
Expand Down
153 changes: 149 additions & 4 deletions src/utils/encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ const STRING_ZERO = '0';
* Convert array buffer to string
*
* *[internal usage]*
*
* @param {ArrayBuffer} array The ArrayBuffer to convert to string.
* @returns {string} The converted string.
*
* @example
* ```typescript
* const buffer = new ArrayBuffer(5);
* const view = new Uint8Array(buffer);
* [72, 101, 108, 108, 111].forEach((x, idx) => view[idx] = x);
* const result = encode.arrayBufferToString(buffer);
* // result = "Hello"
* ```
*/
export function arrayBufferToString(array: ArrayBuffer): string {
return new Uint8Array(array).reduce((data, byte) => data + String.fromCharCode(byte), '');
Expand All @@ -23,6 +35,16 @@ export function arrayBufferToString(array: ArrayBuffer): string {
* Convert utf8-string to Uint8Array
*
* *[internal usage]*
*
* @param {string} str The UTF-8 string to convert.
* @returns {Uint8Array} The encoded Uint8Array.
*
* @example
* ```typescript
* const myString = 'Hi';
* const result = encode.utf8ToArray(myString);
* // result = Uint8Array(2) [ 72, 105 ]
* ```
*/
export function utf8ToArray(str: string): Uint8Array {
return new TextEncoder().encode(str);
Expand All @@ -39,21 +61,50 @@ export function stringToArrayBuffer(str: string): Uint8Array {

/**
* Convert string to array buffer (browser and node compatible)
*
* @param {string} a The Base64 encoded string to convert.
* @returns {Uint8Array} The decoded Uint8Array.
*
* @example
* ```typescript
* const base64String = 'SGVsbG8='; // 'Hello' in Base64
* const result = encode.atobUniversal(base64String);
* // result = Uint8Array(5) [ 72, 101, 108, 108, 111 ]
* ```
*/
export function atobUniversal(a: string): Uint8Array {
return base64.decode(a);
}

/**
* Convert array buffer to string (browser and node compatible)
*
* @param {ArrayBuffer} b The Array buffer.
* @returns {string} The Base64 encoded string.
*
* @example
* ```typescript
* const buffer = new Uint8Array([72, 101, 108, 108, 111]); // Array with ASCII values for 'Hello'
* const result = encode.btoaUniversal(buffer);
* // result = "SGVsbG8="
* ```
*/
export function btoaUniversal(b: ArrayBuffer): string {
return base64.encode(new Uint8Array(b));
}

/**
* Convert array buffer to hex-string
* @returns format: hex-string
*
* @param {Uint8Array} buffer The encoded Uint8Array.
* @returns {string} The hex-string
*
* @example
* ```typescript
* const buffer = new Uint8Array([72, 101, 108, 108, 111]); // Array with ASCII values for 'Hello'
* const result = encode.buf2hex(buffer);
* // result = "48656c6c6f"
* ```
*/
export function buf2hex(buffer: Uint8Array) {
return buffer.reduce((r, x) => r + x.toString(16).padStart(2, '0'), '');
Expand All @@ -62,7 +113,14 @@ export function buf2hex(buffer: Uint8Array) {
/**
* Remove hex prefix '0x' from hex-string
* @param hex hex-string
* @returns format: base16-string
* @returns {string} The hex-string
*
* @example
* ```typescript
* const hexStringWithPrefix = '0x48656c6c6f';
* const result = encode.removeHexPrefix(hexStringWithPrefix);
* // result: "48656c6c6f"
* ```
*/
export function removeHexPrefix(hex: string): string {
return hex.replace(/^0x/i, '');
Expand All @@ -71,7 +129,14 @@ export function removeHexPrefix(hex: string): string {
/**
* Add hex prefix '0x' to base16-string
* @param hex base16-string
* @returns format: hex-string
* @returns {string} The hex-string
*
* @example
* ```typescript
* const plainHexString = '48656c6c6f';
* const result = encode.addHexPrefix(plainHexString);
* // result: "0x48656c6c6f"
* ```
*/
export function addHexPrefix(hex: string): string {
return `0x${removeHexPrefix(hex)}`;
Expand All @@ -81,6 +146,22 @@ export function addHexPrefix(hex: string): string {
* Prepend or append to string
*
* *[internal usage]*
*
* Pads a string to a certain length with a specific string.
* The padding can be applied either to the left or the right of the input string.
*
* @param {string} str The string to pad.
* @param {number} length The target length for the padded string.
* @param {boolean} left Set to true to add padding to the left, false to add it to the right.
* @param {string} [padding='0'] The string to use for padding. Defaults to '0'.
* @returns {string} The padded string.
*
* @example
* ```typescript
* const myString = 'hello';
* const result = padString(myString, 10, true);
* // result = '00000hello'
* ```
*/
function padString(str: string, length: number, left: boolean, padding = STRING_ZERO): string {
const diff = length - str.length;
Expand All @@ -94,6 +175,21 @@ function padString(str: string, length: number, left: boolean, padding = STRING_

/**
* Prepend string (default with '0')
*
* Pads a string to a certain length with a specific string.
* The padding can be applied only to the left of the input string.
*
* @param {string} str The string to pad.
* @param {number} length The target length for the padded string.
* @param {string} [padding='0'] The string to use for padding. Defaults to '0'.
* @returns {string} The padded string.
*
* @example
* ```typescript
* const myString = '1A3F';
* const result = encode.padLeft(myString, 10);
* // result: '0000001A3F'
* ```
*/
export function padLeft(str: string, length: number, padding = STRING_ZERO): string {
return padString(str, length, true, padding);
Expand All @@ -103,6 +199,21 @@ export function padLeft(str: string, length: number, padding = STRING_ZERO): str
* Calculate byte length of string
*
* *[no internal usage]*
*
* Calculates the byte length of a string based on a specified byte size.
* The function rounds up the byte count to the nearest multiple of the specified byte size.
*
* @param {string} str The string whose byte length is to be calculated.
* @param {number} [byteSize='8'] The size of the byte block to round up to. Defaults to 8.
* @returns {number} The calculated byte length, rounded to the nearest multiple of byteSize.
*
* @example
* ```typescript
* const myString = 'Hello';
* const result = encode.calcByteLength(myString, 4);
* // result = 8 (rounded up to the nearest multiple of 4)
*
* ```
*/
export function calcByteLength(str: string, byteSize = 8): number {
const { length } = str;
Expand All @@ -114,17 +225,41 @@ export function calcByteLength(str: string, byteSize = 8): number {
* Prepend '0' to string bytes
*
* *[no internal usage]*
*
*
* * Prepends padding to the left of a string to ensure it matches a specific byte length.
* The function uses a specified padding character and rounds up the string length to the nearest multiple of `byteSize`.
*
* @param {string} str The string to be padded.
* @param {number} [byteSize='8'] The byte block size to which the string length should be rounded up. Defaults to 8.
* @param {string} [padding='0'] The character to use for padding. Defaults to '0'.
* @returns {string} The padded string.
*
* @example
* ```typescript
* const myString = '123';
* const result = encode.sanitizeBytes(myString);
* // result: '00000123' (padded to 8 characters)
* ```
*/
export function sanitizeBytes(str: string, byteSize = 8, padding = STRING_ZERO): string {
return padLeft(str, calcByteLength(str, byteSize), padding);
}

/**
* Prepend '0' to hex-string bytes
* Sanitizes a hex-string by removing any existing '0x' prefix, padding the string with '0' to ensure it has even length,
* and then re-adding the '0x' prefix.
*
* *[no internal usage]*
* @param hex hex-string
* @returns format: hex-string
*
* @example
* ```typescript
* const unevenHex = '0x23abc';
* const result = encode.sanitizeHex(unevenHex);
* // result = '0x023abc' (padded to ensure even length)
* ```
*/
export function sanitizeHex(hex: string): string {
hex = removeHexPrefix(hex);
Expand All @@ -139,6 +274,16 @@ export function sanitizeHex(hex: string): string {
* String transformation util
*
* Pascal case to screaming snake case
*
* @param {string} text The PascalCase string to convert.
* @returns {string} The converted snake_case string in uppercase.
*
* @example
* ```typescript
* const pascalString = 'PascalCaseExample';
* const result = encode.pascalToSnake(pascalString);
* // result: 'PASCAL_CASE_EXAMPLE'
* ```
*/
export const pascalToSnake = (text: string) =>
/[a-z]/.test(text)
Expand Down