@findeth/abi
Advanced tools
Comparing version 0.4.1 to 0.5.0
@@ -6,18 +6,7 @@ "use strict"; | ||
}); | ||
exports.decode = exports.encodeWithIdentifier = exports.encode = void 0; | ||
exports.decode = exports.encode = void 0; | ||
var _identifier = require("./identifier"); | ||
var _array = require("./parsers/array"); | ||
var _utils = require("./utils"); | ||
const encode = (input, values) => { | ||
const types = input.map(type => { | ||
if (typeof type === 'string') { | ||
return type; | ||
} | ||
return type.type; | ||
}); | ||
const encode = (types, values) => { | ||
return (0, _array.pack)(new Uint8Array(0), values, types); | ||
@@ -28,18 +17,3 @@ }; | ||
const encodeWithIdentifier = (contractFunction, values) => { | ||
const identifier = (0, _utils.fromHex)((0, _identifier.getIdentifier)(contractFunction)); | ||
const encoded = encode(contractFunction.inputs, values); | ||
return (0, _utils.concat)([identifier, encoded]); | ||
}; | ||
exports.encodeWithIdentifier = encodeWithIdentifier; | ||
const decode = (input, buffer) => { | ||
const types = input.map(type => { | ||
if (typeof type === 'string') { | ||
return type; | ||
} | ||
return type.type; | ||
}); | ||
const decode = (types, buffer) => { | ||
return (0, _array.unpack)(buffer, types); | ||
@@ -46,0 +20,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.parseType = void 0; | ||
const isTuple = input => { | ||
return input.type === 'tuple'; | ||
}; | ||
const parseType = input => { | ||
if (isTuple(input)) { | ||
return `(${input.components.map(parseType)})`; | ||
} | ||
return input.type; | ||
}; | ||
exports.parseType = parseType; | ||
//# sourceMappingURL=contract.js.map |
@@ -6,38 +6,25 @@ "use strict"; | ||
}); | ||
var _exportNames = { | ||
encode: true, | ||
encodeWithIdentifier: true, | ||
decode: true | ||
}; | ||
Object.defineProperty(exports, "encode", { | ||
enumerable: true, | ||
get: function () { | ||
return _abi.encode; | ||
} | ||
}); | ||
Object.defineProperty(exports, "encodeWithIdentifier", { | ||
enumerable: true, | ||
get: function () { | ||
return _abi.encodeWithIdentifier; | ||
} | ||
}); | ||
Object.defineProperty(exports, "decode", { | ||
enumerable: true, | ||
get: function () { | ||
return _abi.decode; | ||
} | ||
}); | ||
var _abi = require("./abi"); | ||
var _utils = require("./utils"); | ||
Object.keys(_abi).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _abi[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _abi[key]; | ||
} | ||
}); | ||
}); | ||
Object.keys(_utils).forEach(function (key) { | ||
var _types = require("./types"); | ||
Object.keys(_types).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; | ||
if (key in exports && exports[key] === _utils[key]) return; | ||
if (key in exports && exports[key] === _types[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _utils[key]; | ||
return _types[key]; | ||
} | ||
@@ -47,12 +34,11 @@ }); | ||
var _contract = require("./contract"); | ||
var _utils = require("./utils"); | ||
Object.keys(_contract).forEach(function (key) { | ||
Object.keys(_utils).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; | ||
if (key in exports && exports[key] === _contract[key]) return; | ||
if (key in exports && exports[key] === _utils[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _contract[key]; | ||
return _utils[key]; | ||
} | ||
@@ -59,0 +45,0 @@ }); |
@@ -20,4 +20,4 @@ "use strict"; | ||
const pointer = Number((0, _utils.toNumber)(value.subarray(0, 32))); | ||
const length = (0, _utils.toNumber)(value.subarray(pointer, pointer + 32)); | ||
return buffer.subarray(32, 32 + Number(length)); | ||
const length = Number((0, _utils.toNumber)(buffer.subarray(pointer, pointer + 32))); | ||
return buffer.subarray(pointer + 32, pointer + 32 + Number(length)); | ||
}; | ||
@@ -24,0 +24,0 @@ |
@@ -6,3 +6,3 @@ "use strict"; | ||
}); | ||
exports.toNumber = exports.addPadding = exports.concatAt = exports.concat = exports.toBuffer = exports.fromHex = exports.toHex = exports.fromUtf8 = exports.toUtf8 = exports.getTextDecoder = exports.getTextEncoder = exports.stripPrefix = void 0; | ||
exports.toNumber = exports.addPadding = exports.concat = exports.toBuffer = exports.fromHex = exports.toHex = exports.fromUtf8 = exports.toUtf8 = exports.getTextDecoder = exports.getTextEncoder = exports.stripPrefix = void 0; | ||
const BUFFER_WIDTH = 32; | ||
@@ -107,8 +107,2 @@ const HEX_REGEX = /^[a-f0-9]+$/i; | ||
const concatAt = (a, b, position) => { | ||
return concat([a.slice(0, position), b, a.slice(position)]); | ||
}; | ||
exports.concatAt = concatAt; | ||
const addPadding = (buffer, length = BUFFER_WIDTH) => { | ||
@@ -115,0 +109,0 @@ const padding = new Uint8Array(Math.max(length - buffer.length, 0)).fill(0x00); |
@@ -20,15 +20,2 @@ "use strict"; | ||
var _keccak = require("./keccak256"); | ||
Object.keys(_keccak).forEach(function (key) { | ||
if (key === "default" || key === "__esModule") return; | ||
if (key in exports && exports[key] === _keccak[key]) return; | ||
Object.defineProperty(exports, key, { | ||
enumerable: true, | ||
get: function () { | ||
return _keccak[key]; | ||
} | ||
}); | ||
}); | ||
var _twosComplement = require("./twos-complement"); | ||
@@ -35,0 +22,0 @@ |
@@ -1,29 +0,8 @@ | ||
import { getIdentifier } from './identifier'; | ||
import { pack, unpack } from './parsers/array'; | ||
import { concat, fromHex } from './utils'; | ||
export const encode = (input, values) => { | ||
const types = input.map(type => { | ||
if (typeof type === 'string') { | ||
return type; | ||
} | ||
return type.type; | ||
}); | ||
export const encode = (types, values) => { | ||
return pack(new Uint8Array(0), values, types); | ||
}; | ||
export const encodeWithIdentifier = (contractFunction, values) => { | ||
const identifier = fromHex(getIdentifier(contractFunction)); | ||
const encoded = encode(contractFunction.inputs, values); | ||
return concat([identifier, encoded]); | ||
}; | ||
export const decode = (input, buffer) => { | ||
const types = input.map(type => { | ||
if (typeof type === 'string') { | ||
return type; | ||
} | ||
return type.type; | ||
}); | ||
export const decode = (types, buffer) => { | ||
return unpack(buffer, types); | ||
}; | ||
//# sourceMappingURL=abi.js.map |
@@ -0,2 +1,12 @@ | ||
const isTuple = input => { | ||
return input.type === 'tuple'; | ||
}; | ||
export const parseType = input => { | ||
if (isTuple(input)) { | ||
return `(${input.components.map(parseType)})`; | ||
} | ||
return input.type; | ||
}; | ||
//# sourceMappingURL=contract.js.map |
@@ -1,4 +0,4 @@ | ||
export { encode, encodeWithIdentifier, decode } from './abi'; | ||
export * from './abi'; | ||
export * from './types'; | ||
export * from './utils'; | ||
export * from './contract'; | ||
//# sourceMappingURL=index.js.map |
@@ -9,5 +9,5 @@ import { addPadding, concat, toBuffer, toNumber } from '../utils'; | ||
const pointer = Number(toNumber(value.subarray(0, 32))); | ||
const length = toNumber(value.subarray(pointer, pointer + 32)); | ||
return buffer.subarray(32, 32 + Number(length)); | ||
const length = Number(toNumber(buffer.subarray(pointer, pointer + 32))); | ||
return buffer.subarray(pointer + 32, pointer + 32 + Number(length)); | ||
}; | ||
//# sourceMappingURL=bytes.js.map |
@@ -72,5 +72,2 @@ const BUFFER_WIDTH = 32; | ||
}; | ||
export const concatAt = (a, b, position) => { | ||
return concat([a.slice(0, position), b, a.slice(position)]); | ||
}; | ||
export const addPadding = (buffer, length = BUFFER_WIDTH) => { | ||
@@ -77,0 +74,0 @@ const padding = new Uint8Array(Math.max(length - buffer.length, 0)).fill(0x00); |
export * from './buffer'; | ||
export * from './keccak256'; | ||
export * from './twos-complement'; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@findeth/abi", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"description": "A tiny Solidity ABI encoder and decoder", | ||
@@ -54,5 +54,2 @@ "author": "Maarten Zuidhoorn <maarten@zuidhoorn.com>", | ||
}, | ||
"dependencies": { | ||
"keccak": "^3.0.1" | ||
}, | ||
"devDependencies": { | ||
@@ -87,3 +84,3 @@ "@babel/cli": "^7.10.1", | ||
"typedoc": "^0.20.17", | ||
"typescript": "^4.0.5" | ||
"typescript": "^4.2.3" | ||
}, | ||
@@ -90,0 +87,0 @@ "lint-staged": { |
@@ -6,3 +6,3 @@ # `@findeth/abi` | ||
`@findeth/abi` is a library used by FindETH, used to decode and encode Solidity contract ABI data. **This library is experimental**, and likely does not work with all contract interfaces. It is used in the desktop, web and CLI applications, that can be found here: | ||
`@findeth/abi` is a zero-dependencies ABI encoder and decoder library used by FindETH. **This library is experimental**, and likely does not work with all contract interfaces. It is used in the desktop, web and CLI applications, that can be found here: | ||
@@ -29,2 +29,4 @@ - [Desktop](https://github.com/FindETH/desktop) | ||
**Note**: If you are using TypeScript, `@findeth/abi` requires TypeScript 4.1 or newer. | ||
## Getting Started | ||
@@ -31,0 +33,0 @@ |
@@ -6,3 +6,3 @@ import { decode, encode } from './abi'; | ||
it('encodes simple values', () => { | ||
expect(toHex(encode(['uint256', 'uint256'], [12345, 12345]))).toBe( | ||
expect(toHex(encode(['uint256', 'uint256'] as const, [12345n, 12345n]))).toBe( | ||
'00000000000000000000000000000000000000000000000000000000000030390000000000000000000000000000000000000000000000000000000000003039' | ||
@@ -13,7 +13,7 @@ ); | ||
it('encodes array values', () => { | ||
expect(toHex(encode(['uint256', 'uint256[]', 'uint256'], [12345, [67890, 67890], 12345]))).toBe( | ||
expect(toHex(encode(['uint256', 'uint256[]', 'uint256'] as const, [12345n, [67890n, 67890n], 12345n]))).toBe( | ||
'000000000000000000000000000000000000000000000000000000000000303900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000003039000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000109320000000000000000000000000000000000000000000000000000000000010932' | ||
); | ||
expect(toHex(encode(['string[]'], ['foo', 'bar', 'baz']))).toBe( | ||
'00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016f00000000000000000000000000000000000000000000000000000000000000' | ||
expect(toHex(encode(['string', 'string', 'string'] as const, ['foo', 'bar', 'baz']))).toBe( | ||
'000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000003666f6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036261720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000362617a0000000000000000000000000000000000000000000000000000000000' | ||
); | ||
@@ -25,13 +25,10 @@ }); | ||
toHex( | ||
encode( | ||
['uint256', 'uint256[][]', 'uint256'], | ||
encode(['uint256', 'uint256[][]', 'uint256'] as const, [ | ||
12345n, | ||
[ | ||
12345, | ||
[ | ||
[54321, 12345], | ||
[67890, 98760] | ||
], | ||
12345 | ||
] | ||
) | ||
[54321n, 12345n], | ||
[67890n, 98760n] | ||
], | ||
12345n | ||
]) | ||
) | ||
@@ -44,4 +41,4 @@ ).toBe( | ||
it('encodes bytes values', () => { | ||
const bytes = '123456789abcdef123456789abcdef123456789abcde'; | ||
expect(toHex(encode(['bytes'], [bytes]))).toBe( | ||
const bytes = fromHex('123456789abcdef123456789abcdef123456789abcde'); | ||
expect(toHex(encode(['bytes'] as const, [bytes]))).toBe( | ||
'00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000016123456789abcdef123456789abcdef123456789abcde00000000000000000000' | ||
@@ -53,3 +50,3 @@ ); | ||
const string = 'foo bar baz qux quux corge'; | ||
expect(toHex(encode(['string'], [string]))).toBe( | ||
expect(toHex(encode(['string'] as const, [string]))).toBe( | ||
'0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a666f6f206261722062617a20717578207175757820636f726765000000000000' | ||
@@ -65,3 +62,3 @@ ); | ||
); | ||
expect(decode(['address', 'uint256'], buffer)).toStrictEqual([ | ||
expect(decode(['address', 'uint256'] as const, buffer)).toStrictEqual([ | ||
'0x6b175474e89094c44da98b954eedeac495271d0f', | ||
@@ -76,7 +73,23 @@ 12345n | ||
); | ||
expect(decode(['uint256', 'uint256[]', 'uint256'], buffer)).toStrictEqual([12345n, [67890n, 67890n], 12345n]); | ||
// TODO | ||
// expect(decode(['string[]'], Buffer.from('00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001660000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016f00000000000000000000000000000000000000000000000000000000000000', 'hex'))) | ||
// .toStrictEqual(['foo', 'bar', 'baz']); | ||
expect(decode(['uint256', 'uint256[]', 'uint256'] as const, buffer)).toStrictEqual([ | ||
12345n, | ||
[67890n, 67890n], | ||
12345n | ||
]); | ||
expect( | ||
decode( | ||
['string[]'], | ||
fromHex( | ||
'00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000003666f6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036261720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000362617a0000000000000000000000000000000000000000000000000000000000' | ||
) | ||
) | ||
).toStrictEqual([['foo', 'bar', 'baz']]); | ||
}); | ||
it('decodes bytes values', () => { | ||
const buffer = fromHex( | ||
'00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000016123456789abcdef123456789abcdef123456789abcde00000000000000000000' | ||
); | ||
expect(toHex(decode(['bytes'] as const, buffer)[0])).toBe('123456789abcdef123456789abcdef123456789abcde'); | ||
}); | ||
}); |
@@ -1,22 +0,8 @@ | ||
import { ContractFunction, ContractInput } from './contract'; | ||
import { getIdentifier } from './identifier'; | ||
import { pack, unpack } from './parsers/array'; | ||
import { concat, fromHex } from './utils'; | ||
import { Type, TypeMapper } from './types'; | ||
/** | ||
* Encode the input data with the provided types. | ||
* | ||
* @param {(ContractInput | string)[]} input | ||
* @param {unknown[]} values | ||
* @return {Uint8Array} | ||
* Encode the data with the provided types. | ||
*/ | ||
export const encode = (input: Array<ContractInput | string>, values: unknown[]): Uint8Array => { | ||
const types = input.map((type) => { | ||
if (typeof type === 'string') { | ||
return type; | ||
} | ||
return type.type; | ||
}); | ||
export const encode = <T extends Readonly<Array<Type | string>>>(types: T, values: TypeMapper<T>): Uint8Array => { | ||
return pack(new Uint8Array(0), values, types); | ||
@@ -26,25 +12,6 @@ }; | ||
/** | ||
* Encode the input data with the provided types, and prepend the function identifier. | ||
* | ||
* @param {ContractFunction} contractFunction | ||
* @param {unknown[]} values | ||
* @return {Uint8Array} | ||
* Decode the data with the provided types. | ||
*/ | ||
export const encodeWithIdentifier = (contractFunction: ContractFunction, values: unknown[]): Uint8Array => { | ||
const identifier = fromHex(getIdentifier(contractFunction)); | ||
const encoded = encode(contractFunction.inputs, values); | ||
return concat([identifier, encoded]); | ||
export const decode = <T extends Readonly<Array<Type | string>>>(types: T, buffer: Uint8Array): TypeMapper<T> => { | ||
return unpack(buffer, types) as TypeMapper<T>; | ||
}; | ||
export const decode = <T extends unknown[]>(input: Array<ContractInput | string>, buffer: Uint8Array): T => { | ||
const types = input.map((type) => { | ||
if (typeof type === 'string') { | ||
return type; | ||
} | ||
return type.type; | ||
}); | ||
return unpack(buffer, types) as T; | ||
}; |
@@ -1,107 +0,19 @@ | ||
/** | ||
* Most valid types for the Solidity JSON ABI specification, excluding dynamic types like `uint<N>`, `fixed<M>x<N>`, | ||
* `bytes<N>`, etc. | ||
*/ | ||
export type Type = | ||
| 'address' | ||
| 'array' | ||
| 'bool' | ||
| 'bytes' | ||
| 'fixed' | ||
| 'function' | ||
| 'int' | ||
| 'string' | ||
| 'tuple' | ||
| 'ufixed' | ||
| 'uint'; | ||
import { ContractInput, ContractInputTuple } from './types'; | ||
/** | ||
* Contract input that is not a `tuple` and thus does not contain extra `components`. | ||
*/ | ||
export interface ContractInputRegular { | ||
name: string; | ||
type: Type | string; | ||
} | ||
const isTuple = (input: ContractInput): input is ContractInputTuple => { | ||
return input.type === 'tuple'; | ||
}; | ||
/** | ||
* Contract input that is a `tuple` and thus contains extra `components`. | ||
* Parse the type of a contract input to a `string`. | ||
* | ||
* @param {ContractInput} input | ||
* @return {string} | ||
*/ | ||
export interface ContractInputTuple { | ||
name: string; | ||
type: 'tuple'; | ||
components: ContractInput[]; | ||
} | ||
export const parseType = (input: ContractInput): string => { | ||
if (isTuple(input)) { | ||
return `(${input.components.map(parseType)})`; | ||
} | ||
export type ContractInput = ContractInputRegular | ContractInputTuple; | ||
/** | ||
* Constant contract function, where `stateMutability` is either `pure` or `view`. | ||
*/ | ||
export interface ConstantContractFunction { | ||
stateMutability: 'pure' | 'view'; | ||
constant: true; | ||
/** | ||
* Defaults to `false`. | ||
*/ | ||
payable?: false; | ||
} | ||
/** | ||
* Payable contract function where `stateMutability` is `payable`. | ||
*/ | ||
export interface PayableContractFunction { | ||
stateMutability: 'payable'; | ||
/** | ||
* Defaults to `false`. | ||
*/ | ||
constant?: false; | ||
payable: true; | ||
} | ||
/** | ||
* Non-payable contract function where `stateMutability` is `nonpayable`. | ||
*/ | ||
export interface NonPayableContractFunction { | ||
stateMutability: 'nonpayable'; | ||
constant: false; | ||
/** | ||
* Defaults to `false`. | ||
*/ | ||
payable?: false; | ||
} | ||
export type NonConstantContractFunction = PayableContractFunction | NonPayableContractFunction; | ||
/** | ||
* Contract function. | ||
*/ | ||
export type ContractFunction = (ConstantContractFunction | NonConstantContractFunction) & { | ||
/** | ||
* Defaults to `function`. | ||
*/ | ||
type?: 'function' | 'constructor' | 'fallback'; | ||
name: string; | ||
inputs: ContractInput[]; | ||
/** | ||
* `undefined` if the function doesn't have any outputs. | ||
*/ | ||
outputs?: ContractInput[]; | ||
return input.type; | ||
}; | ||
export type ContractEventInput = ContractInput & { indexed: boolean }; | ||
/** | ||
* Contract event. | ||
*/ | ||
export interface ContractEvent { | ||
type: 'event'; | ||
name: string; | ||
inputs: ContractEventInput[]; | ||
anonymous: boolean; | ||
} | ||
export type ContractInterface = ContractFunction | ContractEvent; |
@@ -1,3 +0,3 @@ | ||
export { encode, encodeWithIdentifier, decode } from './abi'; | ||
export * from './abi'; | ||
export * from './types'; | ||
export * from './utils'; | ||
export * from './contract'; |
@@ -141,3 +141,3 @@ import { concat, toBuffer, toNumber } from '../utils'; | ||
*/ | ||
export const pack = (buffer: Uint8Array, values: unknown[], types: string[]): Uint8Array => { | ||
export const pack = (buffer: Uint8Array, values: unknown[], types: Readonly<string[]>): Uint8Array => { | ||
const { | ||
@@ -204,3 +204,3 @@ staticBuffer: packedStaticBuffer, | ||
export const unpack = (buffer: Uint8Array, types: string[]): unknown[] => { | ||
export const unpack = (buffer: Uint8Array, types: Readonly<string[]>): unknown[] => { | ||
const iterator = iterate(buffer, 32); | ||
@@ -207,0 +207,0 @@ |
@@ -1,3 +0,3 @@ | ||
import { fromUtf8, toHex } from '../utils'; | ||
import { encodeBytes } from './bytes'; | ||
import { fromHex, fromUtf8, toHex, toUtf8 } from '../utils'; | ||
import { decodeBytes, encodeBytes } from './bytes'; | ||
@@ -12,1 +12,10 @@ describe('encodeBytes', () => { | ||
}); | ||
describe('decodeBytes', () => { | ||
it('decodes a string from a buffer', () => { | ||
const value = fromHex( | ||
'000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000374c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c6974000000000000000000' | ||
); | ||
expect(toUtf8(decodeBytes(value, value, 'bytes'))).toBe('Lorem ipsum dolor sit amet, consectetur adipiscing elit'); | ||
}); | ||
}); |
@@ -14,5 +14,5 @@ import { addPadding, concat, toBuffer, toNumber } from '../utils'; | ||
const pointer = Number(toNumber(value.subarray(0, 32))); | ||
const length = toNumber(value.subarray(pointer, pointer + 32)); | ||
const length = Number(toNumber(buffer.subarray(pointer, pointer + 32))); | ||
return buffer.subarray(32, 32 + Number(length)); | ||
return buffer.subarray(pointer + 32, pointer + 32 + Number(length)); | ||
}; |
@@ -134,14 +134,2 @@ const BUFFER_WIDTH = 32; | ||
/** | ||
* Concatenate two buffers by placing one buffer at a specific position in another buffer. | ||
* | ||
* @param {Uint8Array} a | ||
* @param {Uint8Array} b | ||
* @param {number} position | ||
* @return {Uint8Array} | ||
*/ | ||
export const concatAt = (a: Uint8Array, b: Uint8Array, position: number): Uint8Array => { | ||
return concat([a.slice(0, position), b, a.slice(position)]); | ||
}; | ||
/** | ||
* Add padding to a buffer. If the buffer is larger than `length`, this function won't do anything. If it's smaller, the | ||
@@ -148,0 +136,0 @@ * buffer will be padded to the specified length, with extra zeroes at the end. |
export * from './buffer'; | ||
export * from './keccak256'; | ||
export * from './twos-complement'; |
@@ -1,18 +0,9 @@ | ||
import { ContractFunction, ContractInput } from './contract'; | ||
import { TypeMapper } from './types'; | ||
/** | ||
* Encode the input data with the provided types. | ||
* | ||
* @param {(ContractInput | string)[]} input | ||
* @param {unknown[]} values | ||
* @return {Uint8Array} | ||
* Encode the data with the provided types. | ||
*/ | ||
export declare const encode: (input: Array<ContractInput | string>, values: unknown[]) => Uint8Array; | ||
export declare const encode: <T extends readonly string[]>(types: T, values: { [K in keyof { -readonly [P in keyof T]: T[P]; }]: { -readonly [P in keyof T]: T[P]; }[K] extends { -readonly [P in keyof T]: T[P]; }[number] ? import("./types").TypeMap[{ -readonly [P in keyof T]: T[P]; }[K]] : unknown; }) => Uint8Array; | ||
/** | ||
* Encode the input data with the provided types, and prepend the function identifier. | ||
* | ||
* @param {ContractFunction} contractFunction | ||
* @param {unknown[]} values | ||
* @return {Uint8Array} | ||
* Decode the data with the provided types. | ||
*/ | ||
export declare const encodeWithIdentifier: (contractFunction: ContractFunction, values: unknown[]) => Uint8Array; | ||
export declare const decode: <T extends unknown[]>(input: Array<ContractInput | string>, buffer: Uint8Array) => T; | ||
export declare const decode: <T extends readonly string[]>(types: T, buffer: Uint8Array) => { [K in keyof { -readonly [P in keyof T]: T[P]; }]: { -readonly [P in keyof T]: T[P]; }[K] extends { -readonly [P in keyof T]: T[P]; }[number] ? import("./types").TypeMap[{ -readonly [P in keyof T]: T[P]; }[K]] : unknown; }; |
@@ -0,83 +1,8 @@ | ||
import { ContractInput } from './types'; | ||
/** | ||
* Most valid types for the Solidity JSON ABI specification, excluding dynamic types like `uint<N>`, `fixed<M>x<N>`, | ||
* `bytes<N>`, etc. | ||
* Parse the type of a contract input to a `string`. | ||
* | ||
* @param {ContractInput} input | ||
* @return {string} | ||
*/ | ||
export declare type Type = 'address' | 'array' | 'bool' | 'bytes' | 'fixed' | 'function' | 'int' | 'string' | 'tuple' | 'ufixed' | 'uint'; | ||
/** | ||
* Contract input that is not a `tuple` and thus does not contain extra `components`. | ||
*/ | ||
export interface ContractInputRegular { | ||
name: string; | ||
type: Type | string; | ||
} | ||
/** | ||
* Contract input that is a `tuple` and thus contains extra `components`. | ||
*/ | ||
export interface ContractInputTuple { | ||
name: string; | ||
type: 'tuple'; | ||
components: ContractInput[]; | ||
} | ||
export declare type ContractInput = ContractInputRegular | ContractInputTuple; | ||
/** | ||
* Constant contract function, where `stateMutability` is either `pure` or `view`. | ||
*/ | ||
export interface ConstantContractFunction { | ||
stateMutability: 'pure' | 'view'; | ||
constant: true; | ||
/** | ||
* Defaults to `false`. | ||
*/ | ||
payable?: false; | ||
} | ||
/** | ||
* Payable contract function where `stateMutability` is `payable`. | ||
*/ | ||
export interface PayableContractFunction { | ||
stateMutability: 'payable'; | ||
/** | ||
* Defaults to `false`. | ||
*/ | ||
constant?: false; | ||
payable: true; | ||
} | ||
/** | ||
* Non-payable contract function where `stateMutability` is `nonpayable`. | ||
*/ | ||
export interface NonPayableContractFunction { | ||
stateMutability: 'nonpayable'; | ||
constant: false; | ||
/** | ||
* Defaults to `false`. | ||
*/ | ||
payable?: false; | ||
} | ||
export declare type NonConstantContractFunction = PayableContractFunction | NonPayableContractFunction; | ||
/** | ||
* Contract function. | ||
*/ | ||
export declare type ContractFunction = (ConstantContractFunction | NonConstantContractFunction) & { | ||
/** | ||
* Defaults to `function`. | ||
*/ | ||
type?: 'function' | 'constructor' | 'fallback'; | ||
name: string; | ||
inputs: ContractInput[]; | ||
/** | ||
* `undefined` if the function doesn't have any outputs. | ||
*/ | ||
outputs?: ContractInput[]; | ||
}; | ||
export declare type ContractEventInput = ContractInput & { | ||
indexed: boolean; | ||
}; | ||
/** | ||
* Contract event. | ||
*/ | ||
export interface ContractEvent { | ||
type: 'event'; | ||
name: string; | ||
inputs: ContractEventInput[]; | ||
anonymous: boolean; | ||
} | ||
export declare type ContractInterface = ContractFunction | ContractEvent; | ||
export declare const parseType: (input: ContractInput) => string; |
@@ -1,3 +0,3 @@ | ||
export { encode, encodeWithIdentifier, decode } from './abi'; | ||
export * from './abi'; | ||
export * from './types'; | ||
export * from './utils'; | ||
export * from './contract'; |
@@ -38,3 +38,3 @@ import { DecodeFunction, EncodeFunction, Parser } from './parser'; | ||
*/ | ||
export declare const pack: (buffer: Uint8Array, values: unknown[], types: string[]) => Uint8Array; | ||
export declare const pack: (buffer: Uint8Array, values: unknown[], types: Readonly<string[]>) => Uint8Array; | ||
/** | ||
@@ -48,2 +48,2 @@ * Iterate over a `Buffer` with provided `chunkSize`. | ||
export declare function iterate(buffer: Uint8Array, chunkSize: number): Generator<Uint8Array, Uint8Array, void>; | ||
export declare const unpack: (buffer: Uint8Array, types: string[]) => unknown[]; | ||
export declare const unpack: (buffer: Uint8Array, types: Readonly<string[]>) => unknown[]; |
@@ -58,11 +58,2 @@ export declare type BinaryLike = string | number | bigint | ArrayBufferLike | number[]; | ||
/** | ||
* Concatenate two buffers by placing one buffer at a specific position in another buffer. | ||
* | ||
* @param {Uint8Array} a | ||
* @param {Uint8Array} b | ||
* @param {number} position | ||
* @return {Uint8Array} | ||
*/ | ||
export declare const concatAt: (a: Uint8Array, b: Uint8Array, position: number) => Uint8Array; | ||
/** | ||
* Add padding to a buffer. If the buffer is larger than `length`, this function won't do anything. If it's smaller, the | ||
@@ -69,0 +60,0 @@ * buffer will be padded to the specified length, with extra zeroes at the end. |
export * from './buffer'; | ||
export * from './keccak256'; | ||
export * from './twos-complement'; |
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
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
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
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
0
123
54
162960
2454
- Removedkeccak@^3.0.1
- Removedinherits@2.0.4(transitive)
- Removedkeccak@3.0.4(transitive)
- Removednode-addon-api@2.0.2(transitive)
- Removednode-gyp-build@4.8.2(transitive)
- Removedreadable-stream@3.6.2(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedstring_decoder@1.3.0(transitive)
- Removedutil-deprecate@1.0.2(transitive)