@findeth/abi
Advanced tools
Comparing version 0.6.0 to 0.6.1
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.unpack = exports.pack = exports.getParser = exports.decodeArray = exports.encodeArray = exports.getType = exports.isTuple = exports.isArray = void 0; | ||
exports.unpack = exports.pack = exports.getParser = exports.decodeArray = exports.encodeArray = exports.getType = exports.isArray = void 0; | ||
@@ -23,4 +23,5 @@ var _utils = require("../utils"); | ||
var _tuple = require("./tuple"); | ||
const ARRAY_REGEX = /^(.*)\[]$/; | ||
const TUPLE_REGEX = /^\((.*)\)$/; | ||
@@ -33,14 +34,4 @@ const isArray = type => { | ||
const isTuple = type => { | ||
return TUPLE_REGEX.test(type); | ||
}; | ||
exports.isTuple = isTuple; | ||
const getType = type => { | ||
if (!isArray(type) && isTuple(type)) { | ||
return type.slice(1, -1).split(',').map(type => type.trim()); | ||
} | ||
return [type.match(ARRAY_REGEX)[1]]; | ||
return type.match(ARRAY_REGEX)[1]; | ||
}; | ||
@@ -51,3 +42,3 @@ | ||
const encodeArray = (buffer, values, type) => { | ||
if (!isArray(type) && !isTuple(type)) { | ||
if (!isArray(type)) { | ||
throw new Error('Invalid type: type is not array'); | ||
@@ -57,10 +48,5 @@ } | ||
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[0])); | ||
return pack(arrayBuffer, values, new Array(values.length).fill(actualType)); | ||
}; | ||
@@ -71,3 +57,3 @@ | ||
const decodeArray = (value, buffer, type) => { | ||
if (!isArray(type) && !isTuple(type)) { | ||
if (!isArray(type)) { | ||
throw new Error('Invalid type: type is not array'); | ||
@@ -78,11 +64,6 @@ } | ||
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[0])); | ||
return unpack(arrayBuffer, new Array(length).fill(actualType)); | ||
}; | ||
@@ -102,7 +83,2 @@ | ||
}, | ||
tuple: { | ||
dynamic: false, | ||
encode: encodeArray, | ||
decode: decodeArray | ||
}, | ||
bool: { | ||
@@ -132,2 +108,7 @@ dynamic: false, | ||
decode: _string.decodeString | ||
}, | ||
tuple: { | ||
dynamic: false, | ||
encode: _tuple.encodeTuple, | ||
decode: _tuple.decodeTuple | ||
} | ||
@@ -153,3 +134,3 @@ }; | ||
if (isTuple(type)) { | ||
if ((0, _tuple.isTuple)(type)) { | ||
return parsers.tuple; | ||
@@ -219,4 +200,13 @@ } | ||
if (isTuple(type)) { | ||
const types = getType(type); | ||
if ((0, _tuple.isTuple)(type)) { | ||
const types = (0, _tuple.getTypes)(type); | ||
if ((0, _tuple.isDynamicTuple)(types)) { | ||
const value = buffer.subarray(pointer, pointer + 32); | ||
const valuePointer = Number((0, _utils.toNumber)(value)); | ||
const actualValue = buffer.subarray(valuePointer); | ||
pointer += 32; | ||
return parser.decode(actualValue, buffer, type); | ||
} | ||
const tupleLength = types.length * 32; | ||
@@ -223,0 +213,0 @@ const value = buffer.subarray(pointer, pointer + tupleLength); |
@@ -8,19 +8,12 @@ import { concat, toBuffer, toNumber } from '../utils'; | ||
import { decodeString, encodeString } from './string'; | ||
import { decodeTuple, encodeTuple, getTypes, isDynamicTuple, isTuple } from './tuple'; | ||
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 => { | ||
if (!isArray(type) && isTuple(type)) { | ||
return type.slice(1, -1).split(',').map(type => type.trim()); | ||
} | ||
return [type.match(ARRAY_REGEX)[1]]; | ||
return type.match(ARRAY_REGEX)[1]; | ||
}; | ||
export const encodeArray = (buffer, values, type) => { | ||
if (!isArray(type) && !isTuple(type)) { | ||
if (!isArray(type)) { | ||
throw new Error('Invalid type: type is not array'); | ||
@@ -30,13 +23,8 @@ } | ||
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[0])); | ||
return pack(arrayBuffer, values, new Array(values.length).fill(actualType)); | ||
}; | ||
export const decodeArray = (value, buffer, type) => { | ||
if (!isArray(type) && !isTuple(type)) { | ||
if (!isArray(type)) { | ||
throw new Error('Invalid type: type is not array'); | ||
@@ -47,11 +35,6 @@ } | ||
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[0])); | ||
return unpack(arrayBuffer, new Array(length).fill(actualType)); | ||
}; | ||
@@ -69,7 +52,2 @@ const parsers = { | ||
}, | ||
tuple: { | ||
dynamic: false, | ||
encode: encodeArray, | ||
decode: decodeArray | ||
}, | ||
bool: { | ||
@@ -99,2 +77,7 @@ dynamic: false, | ||
decode: decodeString | ||
}, | ||
tuple: { | ||
dynamic: false, | ||
encode: encodeTuple, | ||
decode: decodeTuple | ||
} | ||
@@ -179,3 +162,12 @@ }; | ||
if (isTuple(type)) { | ||
const types = getType(type); | ||
const types = getTypes(type); | ||
if (isDynamicTuple(types)) { | ||
const value = buffer.subarray(pointer, pointer + 32); | ||
const valuePointer = Number(toNumber(value)); | ||
const actualValue = buffer.subarray(valuePointer); | ||
pointer += 32; | ||
return parser.decode(actualValue, buffer, type); | ||
} | ||
const tupleLength = types.length * 32; | ||
@@ -182,0 +174,0 @@ const value = buffer.subarray(pointer, pointer + tupleLength); |
{ | ||
"name": "@findeth/abi", | ||
"version": "0.6.0", | ||
"version": "0.6.1", | ||
"description": "A tiny Solidity ABI encoder and decoder", | ||
@@ -5,0 +5,0 @@ "author": "Maarten Zuidhoorn <maarten@zuidhoorn.com>", |
@@ -26,2 +26,20 @@ import { decode, encode } from './abi'; | ||
it('encodes tuple array values', () => { | ||
expect( | ||
toHex( | ||
encode( | ||
['(uint256, uint256)[]'], | ||
[ | ||
[ | ||
[12n, 34n], | ||
[56n, 78n] | ||
] | ||
] | ||
) | ||
) | ||
).toBe( | ||
'00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000004e' | ||
); | ||
}); | ||
it('encodes nested values', () => { | ||
@@ -95,2 +113,15 @@ expect( | ||
it('decodes tuple array values', () => { | ||
const buffer = fromHex( | ||
'00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000004e' | ||
); | ||
expect(decode(['(uint256, uint256)[]'], buffer)).toStrictEqual([ | ||
[ | ||
[12n, 34n], | ||
[56n, 78n] | ||
] | ||
]); | ||
}); | ||
it('decodes bytes values', () => { | ||
@@ -97,0 +128,0 @@ const buffer = fromHex( |
@@ -21,12 +21,7 @@ import { fromHex, toHex } from '../utils'; | ||
it('returns the type of an array', () => { | ||
expect(getType('string[]')).toStrictEqual(['string']); | ||
expect(getType('uint256[]')).toStrictEqual(['uint256']); | ||
expect(getType('string[][]')).toStrictEqual(['string[]']); | ||
expect(getType('string[]')).toStrictEqual('string'); | ||
expect(getType('uint256[]')).toStrictEqual('uint256'); | ||
expect(getType('string[][]')).toStrictEqual('string[]'); | ||
expect(getType('(foo,bar)[]')).toStrictEqual('(foo,bar)'); | ||
}); | ||
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)']); | ||
}); | ||
}); | ||
@@ -44,8 +39,2 @@ | ||
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', () => { | ||
@@ -66,10 +55,2 @@ 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', () => { | ||
@@ -76,0 +57,0 @@ const buffer = fromHex( |
@@ -9,5 +9,5 @@ import { DecodeFunction, EncodeFunction } from '../types'; | ||
import { decodeString, encodeString } from './string'; | ||
import { decodeTuple, encodeTuple, getTypes, isDynamicTuple, isTuple } from './tuple'; | ||
const ARRAY_REGEX = /^(.*)\[]$/; | ||
const TUPLE_REGEX = /^\((.*)\)$/; | ||
@@ -24,8 +24,4 @@ /** | ||
export const isTuple = (type: string): boolean => { | ||
return TUPLE_REGEX.test(type); | ||
}; | ||
/** | ||
* Get the "inner" type for an array or tuple type. E.g. `getType("uint256[]")` -> ["uint256"]. | ||
* Get the "inner" type for an array type. E.g. `getType("uint256[]")` -> ["uint256"]. | ||
* | ||
@@ -35,11 +31,4 @@ * @param {string} type | ||
*/ | ||
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]]; | ||
export const getType = (type: string): string => { | ||
return type.match(ARRAY_REGEX)![1]; | ||
}; | ||
@@ -52,3 +41,3 @@ | ||
): Uint8Array => { | ||
if (!isArray(type) && !isTuple(type)) { | ||
if (!isArray(type)) { | ||
throw new Error('Invalid type: type is not array'); | ||
@@ -59,10 +48,6 @@ } | ||
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[0])); | ||
return pack(arrayBuffer, values, new Array(values.length).fill(actualType)); | ||
}; | ||
@@ -75,3 +60,3 @@ | ||
): unknown[] => { | ||
if (!isArray(type) && !isTuple(type)) { | ||
if (!isArray(type)) { | ||
throw new Error('Invalid type: type is not array'); | ||
@@ -82,7 +67,2 @@ } | ||
const pointer = Number(toNumber(value)); | ||
if (isTuple(type)) { | ||
return unpack(value, actualType); | ||
} | ||
const length = Number(toNumber(buffer.subarray(pointer, pointer + 32))); | ||
@@ -93,3 +73,3 @@ | ||
return unpack(arrayBuffer, new Array(length).fill(actualType[0])); | ||
return unpack(arrayBuffer, new Array(length).fill(actualType)); | ||
}; | ||
@@ -111,7 +91,2 @@ | ||
}, | ||
tuple: { | ||
dynamic: false, | ||
encode: encodeArray, | ||
decode: decodeArray | ||
}, | ||
bool: { | ||
@@ -141,2 +116,7 @@ dynamic: false, | ||
decode: decodeString | ||
}, | ||
tuple: { | ||
dynamic: false, | ||
encode: encodeTuple, | ||
decode: decodeTuple | ||
} | ||
@@ -260,3 +240,14 @@ }; | ||
if (isTuple(type)) { | ||
const types = getType(type); | ||
const types = getTypes(type); | ||
// TODO: Make this more generic | ||
if (isDynamicTuple(types)) { | ||
const value = buffer.subarray(pointer, pointer + 32); | ||
const valuePointer = Number(toNumber(value)); | ||
const actualValue = buffer.subarray(valuePointer); | ||
pointer += 32; | ||
return parser.decode(actualValue, buffer, type); | ||
} | ||
const tupleLength = types.length * 32; | ||
@@ -263,0 +254,0 @@ |
@@ -9,5 +9,4 @@ 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 or tuple type. E.g. `getType("uint256[]")` -> ["uint256"]. | ||
* Get the "inner" type for an array type. E.g. `getType("uint256[]")` -> ["uint256"]. | ||
* | ||
@@ -17,3 +16,3 @@ * @param {string} type | ||
*/ | ||
export declare const getType: (type: string) => string[]; | ||
export declare const getType: (type: string) => string; | ||
export declare const encodeArray: EncodeFunction<unknown[]>; | ||
@@ -35,7 +34,2 @@ export declare const decodeArray: DecodeFunction<unknown[]>; | ||
}; | ||
tuple: { | ||
dynamic: boolean; | ||
encode: EncodeFunction<unknown[]>; | ||
decode: DecodeFunction<unknown[]>; | ||
}; | ||
bool: { | ||
@@ -66,2 +60,7 @@ dynamic: boolean; | ||
}; | ||
tuple: { | ||
dynamic: boolean; | ||
encode: EncodeFunction<unknown[]>; | ||
decode: DecodeFunction<unknown[]>; | ||
}; | ||
}; | ||
@@ -68,0 +67,0 @@ export declare type ParserType = keyof typeof parsers; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
192209
130
2608