thor-devkit
Version:
Typescript library to aid DApp development on VeChain Thor
223 lines • 16.7 kB
JavaScript
import { AbiCoder, Fragment, ParamType } from 'ethers';
import { keccak256 } from './keccak';
import { Buffer } from 'buffer';
const _coder = new AbiCoder();
function processDecoded(type, value) {
if (type.baseType === 'address')
return value.toLowerCase();
if (type.baseType.startsWith('uint') || type.baseType.startsWith('int'))
return value.toString();
if (type.baseType === 'array')
return value.map((v) => processDecoded(type.arrayChildren, v));
if (type.baseType === 'tuple') {
const processed = value.map((v, i) => processDecoded(type.components[i], v));
type.components.forEach((comp, i) => {
if (comp.name) {
processed[comp.name] = processed[i];
}
});
return processed;
}
return value;
}
function toParamType(t) {
return typeof t === 'string'
? ParamType.from(t)
: ParamType.from({ name: t.name, type: t.type, components: t.components });
}
function encodeValues(types, values) {
var _a;
try {
return _coder.encode(types.map(toParamType), values);
}
catch (err) {
throw new Error((_a = err.message) !== null && _a !== void 0 ? _a : String(err));
}
}
function decodeValues(types, data) {
var _a;
if (types.length === 0)
return [];
try {
const pts = types.map(toParamType);
const raw = _coder.decode(pts, data);
return pts.map((pt, i) => processDecoded(pt, raw[i]));
}
catch (err) {
throw new Error((_a = err.message) !== null && _a !== void 0 ? _a : String(err));
}
}
function formatSignature(fragment) {
var _a;
try {
return Fragment.from(fragment).format('sighash');
}
catch (err) {
throw new Error((_a = err.message) !== null && _a !== void 0 ? _a : String(err));
}
}
/** encode/decode parameters of contract function call, event log, according to ABI JSON */
export var abi;
(function (abi) {
/**
* encode single parameter
* @param type type of the parameter
* @param value value of the parameter
* @returns encoded value in hex string
*/
function encodeParameter(type, value) {
return encodeValues([type], [value]);
}
abi.encodeParameter = encodeParameter;
/**
* decode single parameter
* @param type type of the parameter
* @param data encoded parameter in hex string
* @returns decoded value
*/
function decodeParameter(type, data) {
return decodeValues([type], data)[0];
}
abi.decodeParameter = decodeParameter;
/**
* encode a group of parameters
* @param types type array
* @param values value array
* @returns encoded values in hex string
*/
function encodeParameters(types, values) {
return encodeValues(types, values);
}
abi.encodeParameters = encodeParameters;
/**
* decode a group of parameters
* @param types type array
* @param data encoded values in hex string
* @returns decoded object
*/
function decodeParameters(types, data) {
const result = decodeValues(types, data);
const decoded = {};
types.forEach((t, i) => {
decoded[i] = result[i];
if (t.name) {
decoded[t.name] = result[i];
}
});
return decoded;
}
abi.decodeParameters = decodeParameters;
/** for contract function */
class Function {
/**
* create a function object
* @param definition abi definition of the function
*/
constructor(definition) {
this.definition = definition;
this.canonicalName = formatSignature(definition);
this.signature = '0x' + keccak256(this.canonicalName).slice(0, 4).toString('hex');
}
/**
* encode input parameters into call data
* @param args arguments for the function
*/
encode(...args) {
return this.signature + encodeParameters(this.definition.inputs, args).slice(2);
}
/**
* decode output data
* @param outputData output data to decode
*/
decode(outputData) {
return decodeParameters(this.definition.outputs, outputData);
}
}
abi.Function = Function;
/** for contract event */
class Event {
/** for contract event */
constructor(definition) {
this.definition = definition;
this.canonicalName = formatSignature(definition);
this.signature = '0x' + keccak256(this.canonicalName).toString('hex');
}
/**
* encode an object of indexed keys into topics.
* @param indexed an object contains indexed keys
*/
encode(indexed) {
const topics = [];
if (!this.definition.anonymous) {
topics.push(this.signature);
}
for (const input of this.definition.inputs) {
if (!input.indexed) {
continue;
}
const value = indexed[input.name];
if (value === undefined || value === null) {
topics.push(null);
}
else {
let topic;
// https://docs.soliditylang.org/en/v0.8.11/abi-spec.html#encoding-of-indexed-event-parameters
if (isValueType(input.type)) {
topic = encodeParameter(input.type, value);
}
else {
if (input.type === 'string') {
topic = '0x' + keccak256(value).toString('hex');
}
else if (typeof value === 'string' &&
/^0x[0-9a-f]+$/i.test(value) && value.length % 2 === 0) {
// value is encoded
topic = '0x' + keccak256(Buffer.from(value.slice(2), 'hex')).toString('hex');
}
else {
throw new Error(`event.encode: invalid ${input.type} value`);
}
}
topics.push(topic);
}
}
return topics;
}
/**
* decode event log
* @param data data in event output
* @param topics topics in event
*/
decode(data, topics) {
if (!this.definition.anonymous) {
topics = topics.slice(1);
}
if (this.definition.inputs.filter(t => t.indexed).length !== topics.length) {
throw new Error('invalid topics count');
}
const decodedNonIndexed = decodeValues(this.definition.inputs.filter(t => !t.indexed), data);
const decoded = {};
this.definition.inputs.forEach((t, i) => {
if (t.indexed) {
const topic = topics.shift();
decoded[i] = isValueType(t.type) ? decodeParameter(t.type, topic) : topic;
}
else {
decoded[i] = decodedNonIndexed.shift();
}
if (t.name) {
decoded[t.name] = decoded[i];
}
});
return decoded;
}
}
abi.Event = Event;
function isValueType(type) {
return (type === 'address' ||
type === 'bool' ||
/^(u?int)(\d*)$/.test(type) ||
/^bytes(\d+)$/.test(type));
}
})(abi || (abi = {}));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FiaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDdEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUNwQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBRS9CLE1BQU0sTUFBTSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUE7QUFFN0IsU0FBUyxjQUFjLENBQUMsSUFBZSxFQUFFLEtBQVU7SUFDL0MsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVM7UUFDM0IsT0FBUSxLQUFnQixDQUFDLFdBQVcsRUFBRSxDQUFBO0lBQzFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBQ25FLE9BQVEsS0FBZ0IsQ0FBQyxRQUFRLEVBQUUsQ0FBQTtJQUN2QyxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssT0FBTztRQUN6QixPQUFRLEtBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsYUFBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDbkYsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQzVCLE1BQU0sU0FBUyxHQUFJLEtBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsQ0FBUyxFQUFFLEVBQUUsQ0FDekQsY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUMzQyxJQUFJLENBQUMsVUFBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFB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