Socket
Socket
Sign inDemoInstall

@findeth/abi

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@findeth/abi - npm Package Compare versions

Comparing version 0.5.2 to 0.6.0

71

lib/cjs/parsers/array.js

@@ -6,4 +6,3 @@ "use strict";

});
exports.iterate = iterate;
exports.unpack = exports.pack = exports.getParser = exports.decodeArray = exports.encodeArray = exports.getType = exports.isArray = void 0;
exports.unpack = exports.pack = exports.getParser = exports.decodeArray = exports.encodeArray = exports.getType = exports.isTuple = exports.isArray = void 0;

@@ -25,2 +24,3 @@ var _utils = require("../utils");

const ARRAY_REGEX = /^(.*)\[]$/;
const TUPLE_REGEX = /^\((.*)\)$/;

@@ -33,4 +33,14 @@ const isArray = type => {

const isTuple = type => {
return TUPLE_REGEX.test(type);
};
exports.isTuple = isTuple;
const getType = type => {
return type.match(ARRAY_REGEX)[1];
if (!isArray(type) && isTuple(type)) {
return type.slice(1, -1).split(',').map(type => type.trim());
}
return [type.match(ARRAY_REGEX)[1]];
};

@@ -41,3 +51,3 @@

const encodeArray = (buffer, values, type) => {
if (!isArray(type)) {
if (!isArray(type) && !isTuple(type)) {
throw new Error('Invalid type: type is not array');

@@ -47,5 +57,10 @@ }

const actualType = getType(type);
if (isTuple(type)) {
return pack(buffer, values, actualType);
}
const length = (0, _utils.toBuffer)(values.length);
const arrayBuffer = (0, _utils.concat)([buffer, length]);
return pack(arrayBuffer, values, new Array(values.length).fill(actualType));
return pack(arrayBuffer, values, new Array(values.length).fill(actualType[0]));
};

@@ -56,3 +71,3 @@

const decodeArray = (value, buffer, type) => {
if (!isArray(type)) {
if (!isArray(type) && !isTuple(type)) {
throw new Error('Invalid type: type is not array');

@@ -63,6 +78,11 @@ }

const pointer = Number((0, _utils.toNumber)(value));
if (isTuple(type)) {
return unpack(value, actualType);
}
const length = Number((0, _utils.toNumber)(buffer.subarray(pointer, pointer + 32)));
const arrayPointer = pointer + 32;
const arrayBuffer = buffer.subarray(arrayPointer);
return unpack(arrayBuffer, new Array(length).fill(actualType));
return unpack(arrayBuffer, new Array(length).fill(actualType[0]));
};

@@ -82,2 +102,7 @@

},
tuple: {
dynamic: false,
encode: encodeArray,
decode: decodeArray
},
bool: {

@@ -127,2 +152,6 @@ dynamic: false,

if (isTuple(type)) {
return parsers.tuple;
}
throw new Error(`type "${type}" is not supported`);

@@ -180,19 +209,6 @@ };

function* iterate(buffer, chunkSize) {
for (let i = 0; i < buffer.length; i += chunkSize) {
yield buffer.slice(i, i + chunkSize);
}
return buffer;
}
const unpack = (buffer, types) => {
const iterator = iterate(buffer, 32);
let pointer = 0;
return types.map(type => {
const {
value,
done
} = iterator.next();
if (done) {
if (pointer >= buffer.length) {
throw new Error('input data has an invalid length');

@@ -202,2 +218,13 @@ }

const parser = getParser(type);
if (isTuple(type)) {
const types = getType(type);
const tupleLength = types.length * 32;
const value = buffer.subarray(pointer, pointer + tupleLength);
pointer += tupleLength;
return parser.decode(value, buffer, type);
}
const value = buffer.subarray(pointer, pointer + 32);
pointer += 32;
return parser.decode(value, buffer, type);

@@ -204,0 +231,0 @@ });

@@ -9,10 +9,18 @@ import { concat, toBuffer, toNumber } from '../utils';

const ARRAY_REGEX = /^(.*)\[]$/;
const TUPLE_REGEX = /^\((.*)\)$/;
export const isArray = type => {
return ARRAY_REGEX.test(type);
};
export const isTuple = type => {
return TUPLE_REGEX.test(type);
};
export const getType = type => {
return type.match(ARRAY_REGEX)[1];
if (!isArray(type) && isTuple(type)) {
return type.slice(1, -1).split(',').map(type => type.trim());
}
return [type.match(ARRAY_REGEX)[1]];
};
export const encodeArray = (buffer, values, type) => {
if (!isArray(type)) {
if (!isArray(type) && !isTuple(type)) {
throw new Error('Invalid type: type is not array');

@@ -22,8 +30,13 @@ }

const actualType = getType(type);
if (isTuple(type)) {
return pack(buffer, values, actualType);
}
const length = toBuffer(values.length);
const arrayBuffer = concat([buffer, length]);
return pack(arrayBuffer, values, new Array(values.length).fill(actualType));
return pack(arrayBuffer, values, new Array(values.length).fill(actualType[0]));
};
export const decodeArray = (value, buffer, type) => {
if (!isArray(type)) {
if (!isArray(type) && !isTuple(type)) {
throw new Error('Invalid type: type is not array');

@@ -34,6 +47,11 @@ }

const pointer = Number(toNumber(value));
if (isTuple(type)) {
return unpack(value, actualType);
}
const length = Number(toNumber(buffer.subarray(pointer, pointer + 32)));
const arrayPointer = pointer + 32;
const arrayBuffer = buffer.subarray(arrayPointer);
return unpack(arrayBuffer, new Array(length).fill(actualType));
return unpack(arrayBuffer, new Array(length).fill(actualType[0]));
};

@@ -51,2 +69,7 @@ const parsers = {

},
tuple: {
dynamic: false,
encode: encodeArray,
decode: decodeArray
},
bool: {

@@ -95,2 +118,6 @@ dynamic: false,

if (isTuple(type)) {
return parsers.tuple;
}
throw new Error(`type "${type}" is not supported`);

@@ -142,18 +169,6 @@ };

};
export function* iterate(buffer, chunkSize) {
for (let i = 0; i < buffer.length; i += chunkSize) {
yield buffer.slice(i, i + chunkSize);
}
return buffer;
}
export const unpack = (buffer, types) => {
const iterator = iterate(buffer, 32);
let pointer = 0;
return types.map(type => {
const {
value,
done
} = iterator.next();
if (done) {
if (pointer >= buffer.length) {
throw new Error('input data has an invalid length');

@@ -163,2 +178,13 @@ }

const parser = getParser(type);
if (isTuple(type)) {
const types = getType(type);
const tupleLength = types.length * 32;
const value = buffer.subarray(pointer, pointer + tupleLength);
pointer += tupleLength;
return parser.decode(value, buffer, type);
}
const value = buffer.subarray(pointer, pointer + 32);
pointer += 32;
return parser.decode(value, buffer, type);

@@ -165,0 +191,0 @@ });

{
"name": "@findeth/abi",
"version": "0.5.2",
"version": "0.6.0",
"description": "A tiny Solidity ABI encoder and decoder",

@@ -52,3 +52,4 @@ "author": "Maarten Zuidhoorn <maarten@zuidhoorn.com>",

"format": "prettier --write --ignore-path .gitignore '**/*.{ts,tsx,js,json,yml}'",
"prepare": "yarn run build"
"prepare": "husky install",
"prepack": "yarn run build"
},

@@ -76,3 +77,3 @@ "devDependencies": {

"eslint-plugin-jest": "^24.1.0",
"husky": "^4.2.5",
"husky": "^6.0.0",
"jest": "^26.0.1",

@@ -96,7 +97,2 @@ "lint-staged": "^10.2.9",

},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"publishConfig": {

@@ -103,0 +99,0 @@ "access": "public"

@@ -20,2 +20,8 @@ import { decode, encode } from './abi';

it('encodes tuple values', () => {
expect(toHex(encode(['uint256', '(uint256, uint256)', 'uint256'], [123n, [456n, 789n], 123n]))).toBe(
'000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c80000000000000000000000000000000000000000000000000000000000000315000000000000000000000000000000000000000000000000000000000000007b'
);
});
it('encodes nested values', () => {

@@ -82,2 +88,9 @@ expect(

it('decodes tuple values', () => {
const buffer = fromHex(
'000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000001c80000000000000000000000000000000000000000000000000000000000000315000000000000000000000000000000000000000000000000000000000000007b'
);
expect(decode(['uint256', '(uint256, uint256)', 'uint256'], buffer)).toStrictEqual([123n, [456n, 789n], 123n]);
});
it('decodes bytes values', () => {

@@ -84,0 +97,0 @@ const buffer = fromHex(

@@ -21,6 +21,12 @@ import { fromHex, toHex } from '../utils';

it('returns the type of an array', () => {
expect(getType('string[]')).toBe('string');
expect(getType('uint256[]')).toBe('uint256');
expect(getType('string[][]')).toBe('string[]');
expect(getType('string[]')).toStrictEqual(['string']);
expect(getType('uint256[]')).toStrictEqual(['uint256']);
expect(getType('string[][]')).toStrictEqual(['string[]']);
});
it('returns the type of a tuple', () => {
expect(getType('(foo, bar)')).toStrictEqual(['foo', 'bar']);
expect(getType('(foo,bar)')).toStrictEqual(['foo', 'bar']);
expect(getType('(foo,bar)[]')).toStrictEqual(['(foo,bar)']);
});
});

@@ -38,2 +44,8 @@

it('encodes a tuple', () => {
expect(toHex(encodeArray(new Uint8Array(0), ['foo', 'bar'], '(string, string)'))).toBe(
'000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003666f6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036261720000000000000000000000000000000000000000000000000000000000'
);
});
it('throws if a type is not an array type', () => {

@@ -54,2 +66,10 @@ expect(() => encodeArray(new Uint8Array(0), ['foo', 'bar', 'baz'], 'string')).toThrow();

it('decodes a tuple', () => {
const value = fromHex(
'000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003666f6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036261720000000000000000000000000000000000000000000000000000000000'
);
expect(decodeArray(value, value, '(string, string)')).toStrictEqual(['foo', 'bar']);
});
it('throws if a type is not an array type', () => {

@@ -56,0 +76,0 @@ const buffer = fromHex(

@@ -11,2 +11,3 @@ import { DecodeFunction, EncodeFunction } from '../types';

const ARRAY_REGEX = /^(.*)\[]$/;
const TUPLE_REGEX = /^\((.*)\)$/;

@@ -23,4 +24,8 @@ /**

export const isTuple = (type: string): boolean => {
return TUPLE_REGEX.test(type);
};
/**
* Get the "inner" type for an array type. E.g. `getType("uint256[]")` -> uint256.
* Get the "inner" type for an array or tuple type. E.g. `getType("uint256[]")` -> ["uint256"].
*

@@ -30,4 +35,11 @@ * @param {string} type

*/
export const getType = (type: string): string => {
return type.match(ARRAY_REGEX)![1];
export const getType = (type: string): string[] => {
if (!isArray(type) && isTuple(type)) {
return type
.slice(1, -1)
.split(',')
.map((type) => type.trim());
}
return [type.match(ARRAY_REGEX)![1]];
};

@@ -40,3 +52,3 @@

): Uint8Array => {
if (!isArray(type)) {
if (!isArray(type) && !isTuple(type)) {
throw new Error('Invalid type: type is not array');

@@ -46,7 +58,11 @@ }

const actualType = getType(type);
if (isTuple(type)) {
return pack(buffer, values, actualType);
}
const length = toBuffer(values.length);
const arrayBuffer = concat([buffer, length]);
return pack(arrayBuffer, values, new Array(values.length).fill(actualType));
return pack(arrayBuffer, values, new Array(values.length).fill(actualType[0]));
};

@@ -59,3 +75,3 @@

): unknown[] => {
if (!isArray(type)) {
if (!isArray(type) && !isTuple(type)) {
throw new Error('Invalid type: type is not array');

@@ -66,2 +82,7 @@ }

const pointer = Number(toNumber(value));
if (isTuple(type)) {
return unpack(value, actualType);
}
const length = Number(toNumber(buffer.subarray(pointer, pointer + 32)));

@@ -72,3 +93,3 @@

return unpack(arrayBuffer, new Array(length).fill(actualType));
return unpack(arrayBuffer, new Array(length).fill(actualType[0]));
};

@@ -90,2 +111,7 @@

},
tuple: {
dynamic: false,
encode: encodeArray,
decode: decodeArray
},
bool: {

@@ -148,2 +174,7 @@ dynamic: false,

// (type)
if (isTuple(type)) {
return parsers.tuple;
}
throw new Error(`type "${type}" is not supported`);

@@ -220,23 +251,6 @@ };

/**
* Iterate over a `Buffer` with provided `chunkSize`.
*
* @param {Buffer} buffer
* @param {number} chunkSize
* @return {Generator<Buffer, Buffer, void>}
*/
export function* iterate(buffer: Uint8Array, chunkSize: number): Generator<Uint8Array, Uint8Array, void> {
for (let i = 0; i < buffer.length; i += chunkSize) {
yield buffer.slice(i, i + chunkSize);
}
return buffer;
}
export const unpack = (buffer: Uint8Array, types: string[]): unknown[] => {
const iterator = iterate(buffer, 32);
let pointer = 0;
return types.map((type) => {
const { value, done } = iterator.next();
if (done) {
if (pointer >= buffer.length) {
throw new Error('input data has an invalid length');

@@ -246,4 +260,17 @@ }

const parser = getParser(type);
if (isTuple(type)) {
const types = getType(type);
const tupleLength = types.length * 32;
const value = buffer.subarray(pointer, pointer + tupleLength);
pointer += tupleLength;
return parser.decode(value, buffer, type);
}
const value = buffer.subarray(pointer, pointer + 32);
pointer += 32;
return parser.decode(value, buffer, type);
});
};

@@ -9,4 +9,5 @@ import { DecodeFunction, EncodeFunction } from '../types';

export declare const isArray: (type: string) => boolean;
export declare const isTuple: (type: string) => boolean;
/**
* Get the "inner" type for an array type. E.g. `getType("uint256[]")` -> uint256.
* Get the "inner" type for an array or tuple type. E.g. `getType("uint256[]")` -> ["uint256"].
*

@@ -16,3 +17,3 @@ * @param {string} type

*/
export declare const getType: (type: string) => string;
export declare const getType: (type: string) => string[];
export declare const encodeArray: EncodeFunction<unknown[]>;

@@ -34,2 +35,7 @@ export declare const decodeArray: DecodeFunction<unknown[]>;

};
tuple: {
dynamic: boolean;
encode: EncodeFunction<unknown[]>;
decode: DecodeFunction<unknown[]>;
};
bool: {

@@ -103,11 +109,3 @@ dynamic: boolean;

export declare const pack: (buffer: Uint8Array, values: unknown[], types: string[]) => Uint8Array;
/**
* Iterate over a `Buffer` with provided `chunkSize`.
*
* @param {Buffer} buffer
* @param {number} chunkSize
* @return {Generator<Buffer, Buffer, void>}
*/
export declare function iterate(buffer: Uint8Array, chunkSize: number): Generator<Uint8Array, Uint8Array, void>;
export declare const unpack: (buffer: Uint8Array, types: string[]) => unknown[];
export {};

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