Socket
Socket
Sign inDemoInstall

@ethersproject/bytes

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ethersproject/bytes - npm Package Compare versions

Comparing version 5.6.1 to 6.0.0-beta.1

lib/array.d.ts

2

lib/_version.d.ts

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

export declare const version = "bytes/5.6.1";
export declare const version = "@ethersproject/bytes@6.0.0-beta.1";
//# sourceMappingURL=_version.d.ts.map

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

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.version = void 0;
exports.version = "bytes/5.6.1";
export const version = "@ethersproject/bytes@6.0.0-beta.1";
//# sourceMappingURL=_version.js.map

@@ -1,42 +0,8 @@

export declare type Bytes = ArrayLike<number>;
export declare type BytesLike = Bytes | string;
export declare type DataOptions = {
allowMissingPrefix?: boolean;
hexPad?: "left" | "right" | null;
};
export interface Hexable {
toHexString(): string;
}
export declare type SignatureLike = {
r: string;
s?: string;
_vs?: string;
recoveryParam?: number;
v?: number;
} | BytesLike;
export interface Signature {
r: string;
s: string;
_vs: string;
recoveryParam: number;
v: number;
yParityAndS: string;
compact: string;
}
export declare function isBytesLike(value: any): value is BytesLike;
export declare function isBytes(value: any): value is Bytes;
export declare function arrayify(value: BytesLike | Hexable | number, options?: DataOptions): Uint8Array;
export declare function concat(items: ReadonlyArray<BytesLike>): Uint8Array;
export declare function stripZeros(value: BytesLike): Uint8Array;
export declare function zeroPad(value: BytesLike, length: number): Uint8Array;
export declare function isHexString(value: any, length?: number): boolean;
export declare function hexlify(value: BytesLike | Hexable | number | bigint, options?: DataOptions): string;
export declare function hexDataLength(data: BytesLike): number;
export declare function hexDataSlice(data: BytesLike, offset: number, endOffset?: number): string;
export declare function hexConcat(items: ReadonlyArray<BytesLike>): string;
export declare function hexValue(value: BytesLike | Hexable | number | bigint): string;
export declare function hexStripZeros(value: BytesLike): string;
export declare function hexZeroPad(value: BytesLike, length: number): string;
export declare function splitSignature(signature: SignatureLike): Signature;
export declare function joinSignature(signature: SignatureLike): string;
export { arrayify } from "./array.js";
export { decodeBase64, encodeBase64 } from "./base64.js";
export { isHexString, isBytesLike } from "./check.js";
export { concat, dataLength, dataSlice, stripZerosLeft } from "./data.js";
export { hexlify, quantity } from "./hex.js";
export { zeroPadLeft, zeroPadRight } from "./pad.js";
export type { BytesLike, Hexable } from "./types.js";
//# sourceMappingURL=index.d.ts.map

@@ -1,427 +0,7 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.joinSignature = exports.splitSignature = exports.hexZeroPad = exports.hexStripZeros = exports.hexValue = exports.hexConcat = exports.hexDataSlice = exports.hexDataLength = exports.hexlify = exports.isHexString = exports.zeroPad = exports.stripZeros = exports.concat = exports.arrayify = exports.isBytes = exports.isBytesLike = void 0;
var logger_1 = require("@ethersproject/logger");
var _version_1 = require("./_version");
var logger = new logger_1.Logger(_version_1.version);
///////////////////////////////
function isHexable(value) {
return !!(value.toHexString);
}
function addSlice(array) {
if (array.slice) {
return array;
}
array.slice = function () {
var args = Array.prototype.slice.call(arguments);
return addSlice(new Uint8Array(Array.prototype.slice.apply(array, args)));
};
return array;
}
function isBytesLike(value) {
return ((isHexString(value) && !(value.length % 2)) || isBytes(value));
}
exports.isBytesLike = isBytesLike;
function isInteger(value) {
return (typeof (value) === "number" && value == value && (value % 1) === 0);
}
function isBytes(value) {
if (value == null) {
return false;
}
if (value.constructor === Uint8Array) {
return true;
}
if (typeof (value) === "string") {
return false;
}
if (!isInteger(value.length) || value.length < 0) {
return false;
}
for (var i = 0; i < value.length; i++) {
var v = value[i];
if (!isInteger(v) || v < 0 || v >= 256) {
return false;
}
}
return true;
}
exports.isBytes = isBytes;
function arrayify(value, options) {
if (!options) {
options = {};
}
if (typeof (value) === "number") {
logger.checkSafeUint53(value, "invalid arrayify value");
var result = [];
while (value) {
result.unshift(value & 0xff);
value = parseInt(String(value / 256));
}
if (result.length === 0) {
result.push(0);
}
return addSlice(new Uint8Array(result));
}
if (options.allowMissingPrefix && typeof (value) === "string" && value.substring(0, 2) !== "0x") {
value = "0x" + value;
}
if (isHexable(value)) {
value = value.toHexString();
}
if (isHexString(value)) {
var hex = value.substring(2);
if (hex.length % 2) {
if (options.hexPad === "left") {
hex = "0" + hex;
}
else if (options.hexPad === "right") {
hex += "0";
}
else {
logger.throwArgumentError("hex data is odd-length", "value", value);
}
}
var result = [];
for (var i = 0; i < hex.length; i += 2) {
result.push(parseInt(hex.substring(i, i + 2), 16));
}
return addSlice(new Uint8Array(result));
}
if (isBytes(value)) {
return addSlice(new Uint8Array(value));
}
return logger.throwArgumentError("invalid arrayify value", "value", value);
}
exports.arrayify = arrayify;
function concat(items) {
var objects = items.map(function (item) { return arrayify(item); });
var length = objects.reduce(function (accum, item) { return (accum + item.length); }, 0);
var result = new Uint8Array(length);
objects.reduce(function (offset, object) {
result.set(object, offset);
return offset + object.length;
}, 0);
return addSlice(result);
}
exports.concat = concat;
function stripZeros(value) {
var result = arrayify(value);
if (result.length === 0) {
return result;
}
// Find the first non-zero entry
var start = 0;
while (start < result.length && result[start] === 0) {
start++;
}
// If we started with zeros, strip them
if (start) {
result = result.slice(start);
}
return result;
}
exports.stripZeros = stripZeros;
function zeroPad(value, length) {
value = arrayify(value);
if (value.length > length) {
logger.throwArgumentError("value out of range", "value", arguments[0]);
}
var result = new Uint8Array(length);
result.set(value, length - value.length);
return addSlice(result);
}
exports.zeroPad = zeroPad;
function isHexString(value, length) {
if (typeof (value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
return false;
}
if (length && value.length !== 2 + 2 * length) {
return false;
}
return true;
}
exports.isHexString = isHexString;
var HexCharacters = "0123456789abcdef";
function hexlify(value, options) {
if (!options) {
options = {};
}
if (typeof (value) === "number") {
logger.checkSafeUint53(value, "invalid hexlify value");
var hex = "";
while (value) {
hex = HexCharacters[value & 0xf] + hex;
value = Math.floor(value / 16);
}
if (hex.length) {
if (hex.length % 2) {
hex = "0" + hex;
}
return "0x" + hex;
}
return "0x00";
}
if (typeof (value) === "bigint") {
value = value.toString(16);
if (value.length % 2) {
return ("0x0" + value);
}
return "0x" + value;
}
if (options.allowMissingPrefix && typeof (value) === "string" && value.substring(0, 2) !== "0x") {
value = "0x" + value;
}
if (isHexable(value)) {
return value.toHexString();
}
if (isHexString(value)) {
if (value.length % 2) {
if (options.hexPad === "left") {
value = "0x0" + value.substring(2);
}
else if (options.hexPad === "right") {
value += "0";
}
else {
logger.throwArgumentError("hex data is odd-length", "value", value);
}
}
return value.toLowerCase();
}
if (isBytes(value)) {
var result = "0x";
for (var i = 0; i < value.length; i++) {
var v = value[i];
result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f];
}
return result;
}
return logger.throwArgumentError("invalid hexlify value", "value", value);
}
exports.hexlify = hexlify;
/*
function unoddify(value: BytesLike | Hexable | number): BytesLike | Hexable | number {
if (typeof(value) === "string" && value.length % 2 && value.substring(0, 2) === "0x") {
return "0x0" + value.substring(2);
}
return value;
}
*/
function hexDataLength(data) {
if (typeof (data) !== "string") {
data = hexlify(data);
}
else if (!isHexString(data) || (data.length % 2)) {
return null;
}
return (data.length - 2) / 2;
}
exports.hexDataLength = hexDataLength;
function hexDataSlice(data, offset, endOffset) {
if (typeof (data) !== "string") {
data = hexlify(data);
}
else if (!isHexString(data) || (data.length % 2)) {
logger.throwArgumentError("invalid hexData", "value", data);
}
offset = 2 + 2 * offset;
if (endOffset != null) {
return "0x" + data.substring(offset, 2 + 2 * endOffset);
}
return "0x" + data.substring(offset);
}
exports.hexDataSlice = hexDataSlice;
function hexConcat(items) {
var result = "0x";
items.forEach(function (item) {
result += hexlify(item).substring(2);
});
return result;
}
exports.hexConcat = hexConcat;
function hexValue(value) {
var trimmed = hexStripZeros(hexlify(value, { hexPad: "left" }));
if (trimmed === "0x") {
return "0x0";
}
return trimmed;
}
exports.hexValue = hexValue;
function hexStripZeros(value) {
if (typeof (value) !== "string") {
value = hexlify(value);
}
if (!isHexString(value)) {
logger.throwArgumentError("invalid hex string", "value", value);
}
value = value.substring(2);
var offset = 0;
while (offset < value.length && value[offset] === "0") {
offset++;
}
return "0x" + value.substring(offset);
}
exports.hexStripZeros = hexStripZeros;
function hexZeroPad(value, length) {
if (typeof (value) !== "string") {
value = hexlify(value);
}
else if (!isHexString(value)) {
logger.throwArgumentError("invalid hex string", "value", value);
}
if (value.length > 2 * length + 2) {
logger.throwArgumentError("value out of range", "value", arguments[1]);
}
while (value.length < 2 * length + 2) {
value = "0x0" + value.substring(2);
}
return value;
}
exports.hexZeroPad = hexZeroPad;
function splitSignature(signature) {
var result = {
r: "0x",
s: "0x",
_vs: "0x",
recoveryParam: 0,
v: 0,
yParityAndS: "0x",
compact: "0x"
};
if (isBytesLike(signature)) {
var bytes = arrayify(signature);
// Get the r, s and v
if (bytes.length === 64) {
// EIP-2098; pull the v from the top bit of s and clear it
result.v = 27 + (bytes[32] >> 7);
bytes[32] &= 0x7f;
result.r = hexlify(bytes.slice(0, 32));
result.s = hexlify(bytes.slice(32, 64));
}
else if (bytes.length === 65) {
result.r = hexlify(bytes.slice(0, 32));
result.s = hexlify(bytes.slice(32, 64));
result.v = bytes[64];
}
else {
logger.throwArgumentError("invalid signature string", "signature", signature);
}
// Allow a recid to be used as the v
if (result.v < 27) {
if (result.v === 0 || result.v === 1) {
result.v += 27;
}
else {
logger.throwArgumentError("signature invalid v byte", "signature", signature);
}
}
// Compute recoveryParam from v
result.recoveryParam = 1 - (result.v % 2);
// Compute _vs from recoveryParam and s
if (result.recoveryParam) {
bytes[32] |= 0x80;
}
result._vs = hexlify(bytes.slice(32, 64));
}
else {
result.r = signature.r;
result.s = signature.s;
result.v = signature.v;
result.recoveryParam = signature.recoveryParam;
result._vs = signature._vs;
// If the _vs is available, use it to populate missing s, v and recoveryParam
// and verify non-missing s, v and recoveryParam
if (result._vs != null) {
var vs_1 = zeroPad(arrayify(result._vs), 32);
result._vs = hexlify(vs_1);
// Set or check the recid
var recoveryParam = ((vs_1[0] >= 128) ? 1 : 0);
if (result.recoveryParam == null) {
result.recoveryParam = recoveryParam;
}
else if (result.recoveryParam !== recoveryParam) {
logger.throwArgumentError("signature recoveryParam mismatch _vs", "signature", signature);
}
// Set or check the s
vs_1[0] &= 0x7f;
var s = hexlify(vs_1);
if (result.s == null) {
result.s = s;
}
else if (result.s !== s) {
logger.throwArgumentError("signature v mismatch _vs", "signature", signature);
}
}
// Use recid and v to populate each other
if (result.recoveryParam == null) {
if (result.v == null) {
logger.throwArgumentError("signature missing v and recoveryParam", "signature", signature);
}
else if (result.v === 0 || result.v === 1) {
result.recoveryParam = result.v;
}
else {
result.recoveryParam = 1 - (result.v % 2);
}
}
else {
if (result.v == null) {
result.v = 27 + result.recoveryParam;
}
else {
var recId = (result.v === 0 || result.v === 1) ? result.v : (1 - (result.v % 2));
if (result.recoveryParam !== recId) {
logger.throwArgumentError("signature recoveryParam mismatch v", "signature", signature);
}
}
}
if (result.r == null || !isHexString(result.r)) {
logger.throwArgumentError("signature missing or invalid r", "signature", signature);
}
else {
result.r = hexZeroPad(result.r, 32);
}
if (result.s == null || !isHexString(result.s)) {
logger.throwArgumentError("signature missing or invalid s", "signature", signature);
}
else {
result.s = hexZeroPad(result.s, 32);
}
var vs = arrayify(result.s);
if (vs[0] >= 128) {
logger.throwArgumentError("signature s out of range", "signature", signature);
}
if (result.recoveryParam) {
vs[0] |= 0x80;
}
var _vs = hexlify(vs);
if (result._vs) {
if (!isHexString(result._vs)) {
logger.throwArgumentError("signature invalid _vs", "signature", signature);
}
result._vs = hexZeroPad(result._vs, 32);
}
// Set or check the _vs
if (result._vs == null) {
result._vs = _vs;
}
else if (result._vs !== _vs) {
logger.throwArgumentError("signature _vs mismatch v and s", "signature", signature);
}
}
result.yParityAndS = result._vs;
result.compact = result.r + result.yParityAndS.substring(2);
return result;
}
exports.splitSignature = splitSignature;
function joinSignature(signature) {
signature = splitSignature(signature);
return hexlify(concat([
signature.r,
signature.s,
(signature.recoveryParam ? "0x1c" : "0x1b")
]));
}
exports.joinSignature = joinSignature;
export { arrayify } from "./array.js";
export { decodeBase64, encodeBase64 } from "./base64.js"; /*-browser.js*/
export { isHexString, isBytesLike } from "./check.js";
export { concat, dataLength, dataSlice, stripZerosLeft } from "./data.js";
export { hexlify, quantity } from "./hex.js";
export { zeroPadLeft, zeroPadRight } from "./pad.js";
//# sourceMappingURL=index.js.map
MIT License
Copyright (c) 2019 Richard Moore
Copyright (c) 2022 Richard Moore

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

{
"author": "Richard Moore <me@ricmoo.com>",
"dependencies": {
"@ethersproject/logger": "^5.6.0"
"@ethersproject/logger": "^6.0.0-beta.1"
},
"description": "Bytes utility functions for ethers.",
"engines": {
"node": ">=12.17.0"
},
"ethereum": "donations.ethers.eth",
"funding": [
{
"type": "individual",
"url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
},
{
"type": "individual",
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
"gitHead": "ef1b28e958b50cea7ff44da43b3c5ff054e4b483",
"gitHead": "77f691b3bc3a6387a5184ec9b1779faab4bcb30d",
"keywords": [

@@ -25,6 +18,6 @@ "Ethereum",

"main": "./lib/index.js",
"module": "./lib.esm/index.js",
"name": "@ethersproject/bytes",
"publishConfig": {
"access": "public"
"access": "public",
"tag": "beta"
},

@@ -37,10 +30,9 @@ "repository": {

"scripts": {
"auto-build": "npm run build -- -w",
"build": "tsc -p ./tsconfig.json",
"test": "echo \"Error: no test specified\" && exit 1"
},
"sideEffects": false,
"tarballHash": "0xa59fd505043bda60a605ac83d7691a6b0f861cc8b16b0c56e6fb5ad0519aa475",
"tarballHash": "0xe518b1ceca91f872c4e77d7a4582d537014e542f246ed16268f5188425d3bd56",
"type": "module",
"types": "./lib/index.d.ts",
"version": "5.6.1"
"version": "6.0.0-beta.1"
}

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

export const version = "bytes/5.6.1";
export const version = "@ethersproject/bytes@6.0.0-beta.1";

@@ -1,483 +0,9 @@

"use strict";
import { Logger } from "@ethersproject/logger";
import { version } from "./_version";
const logger = new Logger(version);
export { arrayify } from "./array.js";
export { decodeBase64, encodeBase64 } from "./base64.js"; /*-browser.js*/
export { isHexString, isBytesLike } from "./check.js";
export { concat, dataLength, dataSlice, stripZerosLeft } from "./data.js";
export { hexlify, quantity } from "./hex.js";
export { zeroPadLeft, zeroPadRight } from "./pad.js";
///////////////////////////////
// Exported Types
export type Bytes = ArrayLike<number>;
export type BytesLike = Bytes | string;
export type DataOptions = {
allowMissingPrefix?: boolean;
hexPad?: "left" | "right" | null;
};
export interface Hexable {
toHexString(): string;
}
/*
export interface HexString {
length: number;
substring: (start: number, end?: number) => string;
[index: number]: string;
}
*/
export type SignatureLike = {
r: string;
s?: string;
_vs?: string,
recoveryParam?: number;
v?: number;
} | BytesLike;
export interface Signature {
r: string;
s: string;
_vs: string,
recoveryParam: number;
v: number;
yParityAndS: string
compact: string;
}
///////////////////////////////
function isHexable(value: any): value is Hexable {
return !!(value.toHexString);
}
function addSlice(array: Uint8Array): Uint8Array {
if (array.slice) { return array; }
array.slice = function() {
const args = Array.prototype.slice.call(arguments);
return addSlice(new Uint8Array(Array.prototype.slice.apply(array, args)));
}
return array;
}
export function isBytesLike(value: any): value is BytesLike {
return ((isHexString(value) && !(value.length % 2)) || isBytes(value));
}
function isInteger(value: number) {
return (typeof(value) === "number" && value == value && (value % 1) === 0);
}
export function isBytes(value: any): value is Bytes {
if (value == null) { return false; }
if (value.constructor === Uint8Array) { return true; }
if (typeof(value) === "string") { return false; }
if (!isInteger(value.length) || value.length < 0) { return false; }
for (let i = 0; i < value.length; i++) {
const v = value[i];
if (!isInteger(v) || v < 0 || v >= 256) { return false; }
}
return true;
}
export function arrayify(value: BytesLike | Hexable | number, options?: DataOptions): Uint8Array {
if (!options) { options = { }; }
if (typeof(value) === "number") {
logger.checkSafeUint53(value, "invalid arrayify value");
const result = [];
while (value) {
result.unshift(value & 0xff);
value = parseInt(String(value / 256));
}
if (result.length === 0) { result.push(0); }
return addSlice(new Uint8Array(result));
}
if (options.allowMissingPrefix && typeof(value) === "string" && value.substring(0, 2) !== "0x") {
value = "0x" + value;
}
if (isHexable(value)) { value = value.toHexString(); }
if (isHexString(value)) {
let hex = (<string>value).substring(2);
if (hex.length % 2) {
if (options.hexPad === "left") {
hex = "0" + hex;
} else if (options.hexPad === "right") {
hex += "0";
} else {
logger.throwArgumentError("hex data is odd-length", "value", value);
}
}
const result = [];
for (let i = 0; i < hex.length; i += 2) {
result.push(parseInt(hex.substring(i, i + 2), 16));
}
return addSlice(new Uint8Array(result));
}
if (isBytes(value)) {
return addSlice(new Uint8Array(value));
}
return logger.throwArgumentError("invalid arrayify value", "value", value);
}
export function concat(items: ReadonlyArray<BytesLike>): Uint8Array {
const objects = items.map(item => arrayify(item));
const length = objects.reduce((accum, item) => (accum + item.length), 0);
const result = new Uint8Array(length);
objects.reduce((offset, object) => {
result.set(object, offset);
return offset + object.length;
}, 0);
return addSlice(result);
}
export function stripZeros(value: BytesLike): Uint8Array {
let result: Uint8Array = arrayify(value);
if (result.length === 0) { return result; }
// Find the first non-zero entry
let start = 0;
while (start < result.length && result[start] === 0) { start++ }
// If we started with zeros, strip them
if (start) {
result = result.slice(start);
}
return result;
}
export function zeroPad(value: BytesLike, length: number): Uint8Array {
value = arrayify(value);
if (value.length > length) {
logger.throwArgumentError("value out of range", "value", arguments[0]);
}
const result = new Uint8Array(length);
result.set(value, length - value.length);
return addSlice(result);
}
export function isHexString(value: any, length?: number): boolean {
if (typeof(value) !== "string" || !value.match(/^0x[0-9A-Fa-f]*$/)) {
return false
}
if (length && value.length !== 2 + 2 * length) { return false; }
return true;
}
const HexCharacters: string = "0123456789abcdef";
export function hexlify(value: BytesLike | Hexable | number | bigint, options?: DataOptions): string {
if (!options) { options = { }; }
if (typeof(value) === "number") {
logger.checkSafeUint53(value, "invalid hexlify value");
let hex = "";
while (value) {
hex = HexCharacters[value & 0xf] + hex;
value = Math.floor(value / 16);
}
if (hex.length) {
if (hex.length % 2) { hex = "0" + hex; }
return "0x" + hex;
}
return "0x00";
}
if (typeof(value) === "bigint") {
value = value.toString(16);
if (value.length % 2) { return ("0x0" + value); }
return "0x" + value;
}
if (options.allowMissingPrefix && typeof(value) === "string" && value.substring(0, 2) !== "0x") {
value = "0x" + value;
}
if (isHexable(value)) { return value.toHexString(); }
if (isHexString(value)) {
if ((<string>value).length % 2) {
if (options.hexPad === "left") {
value = "0x0" + (<string>value).substring(2);
} else if (options.hexPad === "right") {
value += "0";
} else {
logger.throwArgumentError("hex data is odd-length", "value", value);
}
}
return (<string>value).toLowerCase();
}
if (isBytes(value)) {
let result = "0x";
for (let i = 0; i < value.length; i++) {
let v = value[i];
result += HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f];
}
return result;
}
return logger.throwArgumentError("invalid hexlify value", "value", value);
}
/*
function unoddify(value: BytesLike | Hexable | number): BytesLike | Hexable | number {
if (typeof(value) === "string" && value.length % 2 && value.substring(0, 2) === "0x") {
return "0x0" + value.substring(2);
}
return value;
}
*/
export function hexDataLength(data: BytesLike) {
if (typeof(data) !== "string") {
data = hexlify(data);
} else if (!isHexString(data) || (data.length % 2)) {
return null;
}
return (data.length - 2) / 2;
}
export function hexDataSlice(data: BytesLike, offset: number, endOffset?: number): string {
if (typeof(data) !== "string") {
data = hexlify(data);
} else if (!isHexString(data) || (data.length % 2)) {
logger.throwArgumentError("invalid hexData", "value", data );
}
offset = 2 + 2 * offset;
if (endOffset != null) {
return "0x" + data.substring(offset, 2 + 2 * endOffset);
}
return "0x" + data.substring(offset);
}
export function hexConcat(items: ReadonlyArray<BytesLike>): string {
let result = "0x";
items.forEach((item) => {
result += hexlify(item).substring(2);
});
return result;
}
export function hexValue(value: BytesLike | Hexable | number | bigint): string {
const trimmed = hexStripZeros(hexlify(value, { hexPad: "left" }));
if (trimmed === "0x") { return "0x0"; }
return trimmed;
}
export function hexStripZeros(value: BytesLike): string {
if (typeof(value) !== "string") { value = hexlify(value); }
if (!isHexString(value)) {
logger.throwArgumentError("invalid hex string", "value", value);
}
value = value.substring(2);
let offset = 0;
while (offset < value.length && value[offset] === "0") { offset++; }
return "0x" + value.substring(offset);
}
export function hexZeroPad(value: BytesLike, length: number): string {
if (typeof(value) !== "string") {
value = hexlify(value);
} else if (!isHexString(value)) {
logger.throwArgumentError("invalid hex string", "value", value);
}
if (value.length > 2 * length + 2) {
logger.throwArgumentError("value out of range", "value", arguments[1]);
}
while (value.length < 2 * length + 2) {
value = "0x0" + value.substring(2);
}
return value;
}
export function splitSignature(signature: SignatureLike): Signature {
const result = {
r: "0x",
s: "0x",
_vs: "0x",
recoveryParam: 0,
v: 0,
yParityAndS: "0x",
compact: "0x"
};
if (isBytesLike(signature)) {
let bytes: Uint8Array = arrayify(signature);
// Get the r, s and v
if (bytes.length === 64) {
// EIP-2098; pull the v from the top bit of s and clear it
result.v = 27 + (bytes[32] >> 7);
bytes[32] &= 0x7f;
result.r = hexlify(bytes.slice(0, 32));
result.s = hexlify(bytes.slice(32, 64));
} else if (bytes.length === 65) {
result.r = hexlify(bytes.slice(0, 32));
result.s = hexlify(bytes.slice(32, 64));
result.v = bytes[64];
} else {
logger.throwArgumentError("invalid signature string", "signature", signature);
}
// Allow a recid to be used as the v
if (result.v < 27) {
if (result.v === 0 || result.v === 1) {
result.v += 27;
} else {
logger.throwArgumentError("signature invalid v byte", "signature", signature);
}
}
// Compute recoveryParam from v
result.recoveryParam = 1 - (result.v % 2);
// Compute _vs from recoveryParam and s
if (result.recoveryParam) { bytes[32] |= 0x80; }
result._vs = hexlify(bytes.slice(32, 64))
} else {
result.r = signature.r;
result.s = signature.s;
result.v = signature.v;
result.recoveryParam = signature.recoveryParam;
result._vs = signature._vs;
// If the _vs is available, use it to populate missing s, v and recoveryParam
// and verify non-missing s, v and recoveryParam
if (result._vs != null) {
const vs = zeroPad(arrayify(result._vs), 32);
result._vs = hexlify(vs);
// Set or check the recid
const recoveryParam = ((vs[0] >= 128) ? 1: 0);
if (result.recoveryParam == null) {
result.recoveryParam = recoveryParam;
} else if (result.recoveryParam !== recoveryParam) {
logger.throwArgumentError("signature recoveryParam mismatch _vs", "signature", signature);
}
// Set or check the s
vs[0] &= 0x7f;
const s = hexlify(vs);
if (result.s == null) {
result.s = s;
} else if (result.s !== s) {
logger.throwArgumentError("signature v mismatch _vs", "signature", signature);
}
}
// Use recid and v to populate each other
if (result.recoveryParam == null) {
if (result.v == null) {
logger.throwArgumentError("signature missing v and recoveryParam", "signature", signature);
} else if (result.v === 0 || result.v === 1) {
result.recoveryParam = result.v;
} else {
result.recoveryParam = 1 - (result.v % 2);
}
} else {
if (result.v == null) {
result.v = 27 + result.recoveryParam;
} else {
const recId = (result.v === 0 || result.v === 1) ? result.v :(1 - (result.v % 2));
if (result.recoveryParam !== recId) {
logger.throwArgumentError("signature recoveryParam mismatch v", "signature", signature);
}
}
}
if (result.r == null || !isHexString(result.r)) {
logger.throwArgumentError("signature missing or invalid r", "signature", signature);
} else {
result.r = hexZeroPad(result.r, 32);
}
if (result.s == null || !isHexString(result.s)) {
logger.throwArgumentError("signature missing or invalid s", "signature", signature);
} else {
result.s = hexZeroPad(result.s, 32);
}
const vs = arrayify(result.s);
if (vs[0] >= 128) {
logger.throwArgumentError("signature s out of range", "signature", signature);
}
if (result.recoveryParam) { vs[0] |= 0x80; }
const _vs = hexlify(vs);
if (result._vs) {
if (!isHexString(result._vs)) {
logger.throwArgumentError("signature invalid _vs", "signature", signature);
}
result._vs = hexZeroPad(result._vs, 32);
}
// Set or check the _vs
if (result._vs == null) {
result._vs = _vs;
} else if (result._vs !== _vs) {
logger.throwArgumentError("signature _vs mismatch v and s", "signature", signature);
}
}
result.yParityAndS = result._vs;
result.compact = result.r + result.yParityAndS.substring(2);
return result;
}
export function joinSignature(signature: SignatureLike): string {
signature = splitSignature(signature);
return hexlify(concat([
signature.r,
signature.s,
(signature.recoveryParam ? "0x1c": "0x1b")
]));
}
export type { BytesLike, Hexable } from "./types.js";

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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