@api3/airnode-abi
Advanced tools
Comparing version 0.7.5 to 0.8.0
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -43,24 +7,23 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
exports.decode = void 0; | ||
var ethers_1 = require("ethers"); | ||
var chunk_1 = __importDefault(require("lodash/chunk")); | ||
var constants_1 = require("./constants"); | ||
const ethers_1 = require("ethers"); | ||
const chunk_1 = __importDefault(require("lodash/chunk")); | ||
const constants_1 = require("./constants"); | ||
// Certain types need to be parsed after ABI decoding happens | ||
var VALUE_TRANSFORMATIONS = { | ||
const VALUE_TRANSFORMATIONS = { | ||
string32: ethers_1.ethers.utils.parseBytes32String, | ||
int256: function (value) { return value.toString(); }, | ||
uint256: function (value) { return value.toString(); }, | ||
int256: (value) => value.toString(), | ||
uint256: (value) => value.toString(), | ||
}; | ||
function buildDecodedMap(types, nameValuePairs) { | ||
return nameValuePairs.reduce(function (acc, pair, index) { | ||
var _a, _b; | ||
var _c = __read(pair, 2), encodedName = _c[0], encodedValue = _c[1]; | ||
var name = ethers_1.ethers.utils.parseBytes32String(encodedName); | ||
var type = types[index]; | ||
var transform = VALUE_TRANSFORMATIONS[type]; | ||
return nameValuePairs.reduce((acc, pair, index) => { | ||
const [encodedName, encodedValue] = pair; | ||
const name = ethers_1.ethers.utils.parseBytes32String(encodedName); | ||
const type = types[index]; | ||
const transform = VALUE_TRANSFORMATIONS[type]; | ||
// If the type does not need to be transformed, return it as is | ||
if (!transform) { | ||
return __assign(__assign({}, acc), (_a = {}, _a[name] = encodedValue, _a)); | ||
return Object.assign(Object.assign({}, acc), { [name]: encodedValue }); | ||
} | ||
var parsedValue = transform(encodedValue); | ||
return __assign(__assign({}, acc), (_b = {}, _b[name] = parsedValue, _b)); | ||
const parsedValue = transform(encodedValue); | ||
return Object.assign(Object.assign({}, acc), { [name]: parsedValue }); | ||
}, {}); | ||
@@ -75,19 +38,19 @@ } | ||
// const header = encodedData.substring(0, 66); | ||
var header = ethers_1.ethers.utils.hexlify(ethers_1.ethers.utils.arrayify(encodedData).slice(0, 32)); | ||
var parsedHeader = ethers_1.ethers.utils.parseBytes32String(header); | ||
const header = ethers_1.ethers.utils.hexlify(ethers_1.ethers.utils.arrayify(encodedData).slice(0, 32)); | ||
const parsedHeader = ethers_1.ethers.utils.parseBytes32String(header); | ||
// Get and validate the first character of the header | ||
var encodedEncodingVersion = parsedHeader.substring(0, 1); | ||
const encodedEncodingVersion = parsedHeader.substring(0, 1); | ||
if (encodedEncodingVersion !== '1') { | ||
throw new Error("Unknown ABI schema version: ".concat(encodedEncodingVersion)); | ||
throw new Error(`Unknown ABI schema version: ${encodedEncodingVersion}`); | ||
} | ||
// The version is specified by the first byte and the parameters are specified by the rest | ||
var encodedParameterTypes = parsedHeader.substring(1); | ||
const encodedParameterTypes = parsedHeader.substring(1); | ||
// Replace encoded types with full type names | ||
var fullParameterTypes = Array.from(encodedParameterTypes).map(function (type) { return constants_1.PARAMETER_SHORT_TYPES[type]; }); | ||
const fullParameterTypes = Array.from(encodedParameterTypes).map((type) => constants_1.PARAMETER_SHORT_TYPES[type]); | ||
// The first `bytes32` is the type encoding | ||
var initialDecodedTypes = ['bytes32']; | ||
var decodingTypes = fullParameterTypes.reduce(function (acc, type) { | ||
const initialDecodedTypes = ['bytes32']; | ||
const decodingTypes = fullParameterTypes.reduce((acc, type) => { | ||
var _a; | ||
// Each parameter is expected to have a `bytes32` name | ||
return __spreadArray(__spreadArray([], __read(acc), false), ['bytes32', (_a = constants_1.TYPE_TRANSFORMATIONS[type]) !== null && _a !== void 0 ? _a : type], false); | ||
return [...acc, 'bytes32', (_a = constants_1.TYPE_TRANSFORMATIONS[type]) !== null && _a !== void 0 ? _a : type]; | ||
}, initialDecodedTypes); | ||
@@ -97,10 +60,10 @@ // It's important to leave the `encodedData` intact here and not try to trim off the first | ||
// exactly what you got from the contract, including the header. | ||
var decodedData = ethers_1.ethers.utils.defaultAbiCoder.decode(decodingTypes, encodedData); | ||
const decodedData = ethers_1.ethers.utils.defaultAbiCoder.decode(decodingTypes, encodedData); | ||
// Checks if the original encoded data matches the re-encoded data | ||
var reEncodedData = ethers_1.ethers.utils.defaultAbiCoder.encode(decodingTypes, decodedData); | ||
const reEncodedData = ethers_1.ethers.utils.defaultAbiCoder.encode(decodingTypes, decodedData); | ||
if (reEncodedData !== encodedData) { | ||
throw new Error('Re-encoding mismatch'); | ||
} | ||
var _a = __read(decodedData), _version = _a[0], decodedParameters = _a.slice(1); | ||
var nameValuePairs = (0, chunk_1.default)(decodedParameters, 2); | ||
const [_version, ...decodedParameters] = decodedData; | ||
const nameValuePairs = (0, chunk_1.default)(decodedParameters, 2); | ||
return buildDecodedMap(fullParameterTypes, nameValuePairs); | ||
@@ -107,0 +70,0 @@ } |
"use strict"; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -32,26 +7,26 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
exports.encode = void 0; | ||
var ethers_1 = require("ethers"); | ||
var flatMap_1 = __importDefault(require("lodash/flatMap")); | ||
var constants_1 = require("./constants"); | ||
var VERSION = '1'; | ||
const ethers_1 = require("ethers"); | ||
const flatMap_1 = __importDefault(require("lodash/flatMap")); | ||
const constants_1 = require("./constants"); | ||
const VERSION = '1'; | ||
// Certain types need to be encoded/transformed before ABI encoding happens | ||
var VALUE_TRANSFORMATIONS = { | ||
const VALUE_TRANSFORMATIONS = { | ||
string32: ethers_1.ethers.utils.formatBytes32String, | ||
}; | ||
function buildSchemaHeader(types) { | ||
var allShortTypes = Object.keys(constants_1.PARAMETER_SHORT_TYPES); | ||
const allShortTypes = Object.keys(constants_1.PARAMETER_SHORT_TYPES); | ||
// Shorten all selected types with the corresponding "short" type | ||
// i.e. 'address' types get set as simply 'a' and 'bytes32' becomes | ||
// simply 'b' etc | ||
var selectedShortTypes = types.reduce(function (acc, type) { | ||
var shortType = allShortTypes.find(function (st) { return constants_1.PARAMETER_SHORT_TYPES[st] === type; }); | ||
return __spreadArray(__spreadArray([], __read(acc), false), [shortType], false); | ||
const selectedShortTypes = types.reduce((acc, type) => { | ||
const shortType = allShortTypes.find((st) => constants_1.PARAMETER_SHORT_TYPES[st] === type); | ||
return [...acc, shortType]; | ||
}, []); | ||
return "".concat(VERSION).concat(selectedShortTypes.join('')); | ||
return `${VERSION}${selectedShortTypes.join('')}`; | ||
} | ||
function buildNameValuePairs(parameters) { | ||
return (0, flatMap_1.default)(parameters, function (parameter) { | ||
var name = parameter.name, value = parameter.value, type = parameter.type; | ||
var transform = VALUE_TRANSFORMATIONS[type]; | ||
var encodedName = ethers_1.ethers.utils.formatBytes32String(name); | ||
return (0, flatMap_1.default)(parameters, (parameter) => { | ||
const { name, value, type } = parameter; | ||
const transform = VALUE_TRANSFORMATIONS[type]; | ||
const encodedName = ethers_1.ethers.utils.formatBytes32String(name); | ||
// If the type does not need to be transformed, return it as is | ||
@@ -61,3 +36,3 @@ if (!transform) { | ||
} | ||
var encodedValue = transform(value); | ||
const encodedValue = transform(value); | ||
return [encodedName, encodedValue]; | ||
@@ -67,19 +42,19 @@ }); | ||
function encode(parameters) { | ||
var types = parameters.map(function (parameter) { return parameter.type; }); | ||
const types = parameters.map((parameter) => parameter.type); | ||
// Each parameter name is represented by a `bytes32` string. The value | ||
// types are what the user provides | ||
var nameTypePairs = (0, flatMap_1.default)(types, function (type) { | ||
var transformedType = constants_1.TYPE_TRANSFORMATIONS[type]; | ||
const nameTypePairs = (0, flatMap_1.default)(types, (type) => { | ||
const transformedType = constants_1.TYPE_TRANSFORMATIONS[type]; | ||
return ['bytes32', transformedType !== null && transformedType !== void 0 ? transformedType : type]; | ||
}); | ||
// The first type is always a bytes32 as it represents the schema header | ||
var allTypes = __spreadArray(['bytes32'], __read(nameTypePairs), false); | ||
const allTypes = ['bytes32', ...nameTypePairs]; | ||
// Build the schema which includes the version and the abbreviated list of parameters | ||
var schemaHeader = buildSchemaHeader(types); | ||
var encodedHeader = ethers_1.ethers.utils.formatBytes32String(schemaHeader); | ||
const schemaHeader = buildSchemaHeader(types); | ||
const encodedHeader = ethers_1.ethers.utils.formatBytes32String(schemaHeader); | ||
// Map and encode each name/value pair where necessary | ||
var flatNameValues = buildNameValuePairs(parameters); | ||
const flatNameValues = buildNameValuePairs(parameters); | ||
// The schema header is always the first value to be encoded | ||
var allValues = __spreadArray([encodedHeader], __read(flatNameValues), false); | ||
var encoder = new ethers_1.ethers.utils.AbiCoder(); | ||
const allValues = [encodedHeader, ...flatNameValues]; | ||
const encoder = new ethers_1.ethers.utils.AbiCoder(); | ||
return encoder.encode(allTypes, allValues); | ||
@@ -86,0 +61,0 @@ } |
{ | ||
"name": "@api3/airnode-abi", | ||
"license": "MIT", | ||
"version": "0.7.5", | ||
"version": "0.8.0", | ||
"private": false, | ||
@@ -13,3 +13,3 @@ "main": "dist/index", | ||
"build": "yarn run clean && yarn run compile", | ||
"clean": "rimraf -rf *.tsbuildinfo ./dist *.tgz", | ||
"clean": "rimraf -rf *.tsbuildinfo ./dist ./build *.tgz", | ||
"compile": "tsc --build tsconfig.json", | ||
@@ -21,11 +21,11 @@ "pack": "yarn pack", | ||
"dependencies": { | ||
"ethers": "^5.4.5", | ||
"ethers": "^5.7.0", | ||
"lodash": "^4.17.21" | ||
}, | ||
"devDependencies": { | ||
"@types/lodash": "^4.14.169", | ||
"jest": "^26.6.3", | ||
"@types/lodash": "^4.14.184", | ||
"jest": "^29.0.2", | ||
"rimraf": "^3.0.2", | ||
"typescript": "^4.2.4" | ||
"typescript": "^4.8.2" | ||
} | ||
} |
# `@api3/airnode-abi` | ||
> Encoding and decoding utilities for Airnode according to the | ||
> [Airnode ABI specifications](https://docs.api3.org/airnode/latest/reference/specifications/airnode-abi-specifications.html) | ||
## Documentation | ||
The Airnode-ABI package provides a unique way to encode and decode parameters. Parameters are provided with encoding | ||
@@ -4,0 +9,0 @@ types, names and values. The types are shortened and grouped with a version as the "header". The name/value pairs are |
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
16
19627
23
212
Updatedethers@^5.7.0