@aeternity/aepp-calldata
Advanced tools
Comparing version 1.1.1 to 1.2.0
{ | ||
"name": "@aeternity/aepp-calldata", | ||
"description": "Aeternity data serialization library", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"author": "aeternity", | ||
@@ -32,3 +32,3 @@ "license": "ISC", | ||
"dependencies": { | ||
"@aeternity/blakejs": "^1.1.2", | ||
"blakejs": "^1.2.1", | ||
"bs58": "^4.0.1", | ||
@@ -40,9 +40,10 @@ "rlp": "^3.0.0", | ||
"devDependencies": { | ||
"ava": "^4.0.1", | ||
"browserify": "^17.0.0", | ||
"eslint": "^8.8.0", | ||
"eslint-config-airbnb-base": "^15.0.0", | ||
"eslint-plugin-import": "^2.25.4", | ||
"nyc": "^15.1.0", | ||
"tape": "^5.5.0" | ||
"ava": "4.3.1", | ||
"benchmark": "2.1.4", | ||
"browserify": "17.0.0", | ||
"eslint": "8.20.0", | ||
"eslint-config-airbnb-base": "15.0.0", | ||
"eslint-plugin-import": "2.26.0", | ||
"nyc": "15.1.0", | ||
"tape": "5.5.3" | ||
}, | ||
@@ -53,2 +54,3 @@ "ava": { | ||
"!tests/test.js", | ||
"!tests/benchmark/*", | ||
"!tests/browser/test.js" | ||
@@ -55,0 +57,0 @@ ] |
@@ -114,2 +114,5 @@ # Aeternity data serialization | ||
| address | `ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt` | String | `ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt` | | ||
| Set.set | `Set.from_list([1, 2, 3])` | Set, Array | `new Set([1,2,3])`,`[1,2,3]` | | ||
| BLS12_381.fr| `BLS12_381.int_to_fr(3735928559)` | BigInt | `3735928559n` | | ||
| BLS12_381.fp| `BLS12_381.int_to_fp(3735928559)` | BigInt | `3735928559n` | | ||
@@ -137,3 +140,3 @@ - note the fixed structure of variant object with a single key - the variant constructor (i.e. `Some`) and array of variant arguments as it's value. | ||
where `Data: Boolean | BigInt | String | Array | Map | Object` | ||
where `Data: Boolean | BigInt | String | Array | Map | Set | Object` | ||
@@ -158,2 +161,4 @@ ### Errors | ||
Unit tests can be run with: | ||
```bash | ||
@@ -163,2 +168,14 @@ make tests | ||
Integration tests: | ||
```bash | ||
make integration-tests | ||
``` | ||
One can use the benchmarks to do relative comparison on performance for a given change: | ||
```bash | ||
make benchmark-tests | ||
``` | ||
Verify browser compatibility with: | ||
@@ -165,0 +182,0 @@ |
const assert = require('../utils/assert') | ||
const zip = require('../utils/zip') | ||
const PrimitiveDataFactory = require('./PrimitiveDataFactory') | ||
const ListDataFactory = require('./ListDataFactory') | ||
const SetDataFactory = require('./SetDataFactory') | ||
const MapDataFactory = require('./MapDataFactory') | ||
@@ -9,7 +11,4 @@ const TupleDataFactory = require('./TupleDataFactory') | ||
const EventDataFactory = require('./EventDataFactory') | ||
const Bls12381DataFactory = require('./Bls12381DataFactory') | ||
const zip = (arr, ...arrs) => { | ||
return arr.map((val, i) => arrs.reduce((a, curr) => [...a, curr[i]], [val])) | ||
} | ||
class CompositeDataFactory { | ||
@@ -21,2 +20,3 @@ constructor() { | ||
new ListDataFactory(this), | ||
new SetDataFactory(this), | ||
new MapDataFactory(this), | ||
@@ -27,2 +27,3 @@ new TupleDataFactory(this), | ||
variantFactory, | ||
new Bls12381DataFactory(this), | ||
] | ||
@@ -29,0 +30,0 @@ } |
@@ -0,3 +1,5 @@ | ||
const BaseDataFactory = require('./BaseDataFactory') | ||
const FateTuple = require('../types/FateTuple') | ||
const BaseDataFactory = require('./BaseDataFactory') | ||
const {FateTypeRecord} = require('../FateTypes') | ||
const FateTypeError = require('../Errors/FateTypeError') | ||
@@ -10,2 +12,17 @@ class RecordDataFactory extends BaseDataFactory { | ||
create(type, value) { | ||
if (typeof value !== 'object') { | ||
throw new FateTypeError( | ||
type.name, | ||
`Fate record must be an Object, got ${value} instead` | ||
) | ||
} | ||
const keyLen = Object.keys(value).length | ||
if (keyLen !== type.keys.length) { | ||
throw new FateTypeError( | ||
type.name, | ||
`Number of expected keys (${type.keys.length}) and actual keys (${keyLen}) should match` | ||
) | ||
} | ||
const resolvedValue = type.valueTypes.map((t, i) => { | ||
@@ -16,3 +33,13 @@ const key = type.keys[i] | ||
return new FateTuple(type.valueTypes, resolvedValue) | ||
// Unbox singleton tuples and records | ||
// https://github.com/aeternity/aesophia/pull/205 | ||
// https://github.com/aeternity/aesophia/commit/a403a9d227ac56266cf5bb8fbc916f17e6141d15 | ||
if (resolvedValue.length === 1) { | ||
return resolvedValue[0] | ||
} | ||
return new FateTuple( | ||
FateTypeRecord(type.keys, type.valueTypes), | ||
resolvedValue | ||
) | ||
} | ||
@@ -19,0 +46,0 @@ } |
@@ -22,2 +22,9 @@ const FateTuple = require('../types/FateTuple') | ||
// Unbox singleton tuples and records | ||
// https://github.com/aeternity/aesophia/pull/205 | ||
// https://github.com/aeternity/aesophia/commit/a403a9d227ac56266cf5bb8fbc916f17e6141d15 | ||
if (resolvedValue.length === 1) { | ||
return resolvedValue[0] | ||
} | ||
return new FateTuple(type.valueTypes, resolvedValue) | ||
@@ -24,0 +31,0 @@ } |
@@ -20,3 +20,3 @@ /* eslint-disable key-spacing, indent */ | ||
// 1111 Set below | ||
LONG_LIST : 0b00011111, // 0001 1111 | RLP encoded (length - 16) | [encoded lements] | ||
LONG_LIST : 0b00011111, // 0001 1111 | RLP encoded (length - 16) | [encoded elements] | ||
MAP : 0b00101111, // 0010 1111 | RLP encoded size | [encoded key, encoded value] | ||
@@ -23,0 +23,0 @@ EMPTY_TUPLE : 0b00111111, // 0011 1111 |
@@ -68,3 +68,3 @@ const FateTypeVoid = () => { | ||
const FateTypeTuple = (valueTypes) => { | ||
const FateTypeTuple = (valueTypes = []) => { | ||
return { | ||
@@ -84,2 +84,9 @@ name: 'tuple', | ||
const FateTypeSet = (valuesType) => { | ||
return { | ||
name: 'set', | ||
valuesType, | ||
} | ||
} | ||
const FateTypeMap = (keyType, valueType) => { | ||
@@ -196,2 +203,10 @@ return { | ||
const FateTypeBls12381Fr = () => { | ||
return {name: 'bls12_381.fr'} | ||
} | ||
const FateTypeBls12381Fp = () => { | ||
return {name: 'bls12_381.fp'} | ||
} | ||
module.exports = { | ||
@@ -214,2 +229,3 @@ FateTypeVoid, | ||
FateTypeRecord, | ||
FateTypeSet, | ||
FateTypeMap, | ||
@@ -225,2 +241,4 @@ FateTypeVariant, | ||
FateTypeEvent, | ||
FateTypeBls12381Fr, | ||
FateTypeBls12381Fp | ||
} |
const base58check = require('../utils/base58check') | ||
const {MontBytes2Int} = require('../utils/Bls12381') | ||
@@ -20,2 +21,6 @@ /** | ||
visitSet(acceptor) { | ||
return new Set(acceptor.items.map(e => e.accept(this))) | ||
} | ||
visitMap(acceptor) { | ||
@@ -49,4 +54,12 @@ const map = new Map() | ||
} | ||
visitBls12381Fr(acceptor) { | ||
return MontBytes2Int(acceptor.valueOf(), 'r') | ||
} | ||
visitBls12381Fp(acceptor) { | ||
return MontBytes2Int(acceptor.valueOf(), 'p') | ||
} | ||
} | ||
module.exports = CanonicalMapper |
const base58check = require('../utils/base58check') | ||
const {Int2MontBytes} = require('../utils/Bls12381') | ||
const FateTypeError = require('../Errors/FateTypeError') | ||
const zip = require('../utils/zip') | ||
@@ -28,2 +30,10 @@ const ADDRESS_PREFIX_MAP = { | ||
return this.toMap(type, value) | ||
case 'set': | ||
return this.toSet(type, value) | ||
case 'record': | ||
return this.toRecord(type, value) | ||
case 'bls12_381.fr': | ||
return this.toBls12381Fr(type, value) | ||
case 'bls12_381.fp': | ||
return this.toBls12381Fp(type, value) | ||
default: | ||
@@ -80,4 +90,47 @@ return value | ||
} | ||
toSet(type, value) { | ||
if (value instanceof Set) { | ||
return value | ||
} | ||
if (Array.isArray(value)) { | ||
return new Set(value) | ||
} | ||
throw new FateTypeError( | ||
'set', | ||
`Fate set must be a Set or Array, got "${value}" instead` | ||
) | ||
} | ||
toRecord(type, record) { | ||
return zip(type.keys, type.valueTypes).reduce( | ||
(v, [name, fieldType]) => ({ ...v, [name]: this.toInternal(fieldType, record[name]) }), | ||
record | ||
) | ||
} | ||
validateBls12381Field(type, value) { | ||
if (typeof value !== 'bigint' && !Number.isInteger(value)) { | ||
throw new FateTypeError( | ||
type.name, | ||
`Should be one of: BigInt or Number; got ${value} instead` | ||
) | ||
} | ||
} | ||
toBls12381Fr(type, value) { | ||
this.validateBls12381Field(type, value) | ||
return Int2MontBytes(value, 'r') | ||
} | ||
toBls12381Fp(type, value) { | ||
this.validateBls12381Field(type, value) | ||
return Int2MontBytes(value, 'p') | ||
} | ||
} | ||
module.exports = InternalMapper |
@@ -14,2 +14,3 @@ const TypeFactory = require('./TypeFactory') | ||
const ListSerializer = require('./Serializers/ListSerializer') | ||
const SetSerializer = require('./Serializers/SetSerializer') | ||
const MapSerializer = require('./Serializers/MapSerializer') | ||
@@ -21,2 +22,3 @@ const OracleQuerySerializer = require('./Serializers/OracleQuerySerializer') | ||
const VariantSerializer = require('./Serializers/VariantSerializer') | ||
const Bls12381FieldSerializer = require('./Serializers/Bls12381FieldSerializer') | ||
const SerializerError = require('./Errors/SerializerError') | ||
@@ -36,2 +38,3 @@ | ||
'list': new ListSerializer(this), | ||
'set': new SetSerializer(this), | ||
'map': new MapSerializer(this), | ||
@@ -50,2 +53,4 @@ 'byte_array': new ByteArraySerializer(), | ||
'channel_address': new ChannelSerializer(), | ||
'bls12_381.fr': new Bls12381FieldSerializer(), | ||
'bls12_381.fp': new Bls12381FieldSerializer(), | ||
} | ||
@@ -52,0 +57,0 @@ } |
@@ -1,2 +0,1 @@ | ||
const RLP = require('rlp') | ||
const FateTag = require('../FateTag') | ||
@@ -6,3 +5,2 @@ const RLPInt = require('../utils/RLPInt') | ||
const BaseSerializer = require('./BaseSerializer') | ||
const {ByteArray2Int} = require('../utils/Int2ByteArray') | ||
const abs = require('../utils/abs') | ||
@@ -16,3 +14,3 @@ | ||
prefix, | ||
...RLPInt(abs(data.value)) | ||
...RLPInt.encode(abs(data.value)) | ||
] | ||
@@ -24,8 +22,7 @@ } | ||
const sign = buffer[0] === FateTag.POS_BITS ? 1n : -1n | ||
const decoded = RLP.decode(buffer.slice(1), true) | ||
const i = ByteArray2Int(decoded.data) | ||
const [i, remainder] = RLPInt.decode(buffer.slice(1)) | ||
return [ | ||
new FateBits(i * sign), | ||
new Uint8Array(decoded.remainder) | ||
new Uint8Array(remainder) | ||
] | ||
@@ -32,0 +29,0 @@ } |
@@ -1,2 +0,1 @@ | ||
const RLP = require('rlp') | ||
const FateTag = require('../FateTag') | ||
@@ -6,3 +5,2 @@ const RLPInt = require('../utils/RLPInt') | ||
const BaseSerializer = require('./BaseSerializer') | ||
const {ByteArray2Int} = require('../utils/Int2ByteArray') | ||
const FatePrefixError = require('../Errors/FatePrefixError') | ||
@@ -33,3 +31,3 @@ const abs = require('../utils/abs') | ||
FateTag.NEG_BIG_INT, | ||
...RLPInt(absVal - 64n) | ||
...RLPInt.encode(absVal - 64n) | ||
] | ||
@@ -41,3 +39,3 @@ } | ||
FateTag.POS_BIG_INT, | ||
...RLPInt(absVal - 64n) | ||
...RLPInt.encode(absVal - 64n) | ||
] | ||
@@ -71,8 +69,7 @@ } | ||
const sign = prefix === FateTag.POS_BIG_INT ? 1n : -1n | ||
const decoded = RLP.decode(data.slice(1), true) | ||
const i = ByteArray2Int(decoded.data) | ||
const [i, remainder] = RLPInt.decode(data.slice(1)) | ||
return [ | ||
new FateInt((i + 64n) * sign), | ||
new Uint8Array(decoded.remainder) | ||
new Uint8Array(remainder) | ||
] | ||
@@ -79,0 +76,0 @@ } |
@@ -0,3 +1,3 @@ | ||
const RLPInt = require('../utils/RLPInt') | ||
const FateTag = require('../FateTag') | ||
const FateInt = require('../types/FateInt') | ||
const FateList = require('../types/FateList') | ||
@@ -25,3 +25,3 @@ const BaseSerializer = require('./BaseSerializer') | ||
FateTag.LONG_LIST, | ||
...this.globalSerializer.serialize(new FateInt(len - 16)), | ||
...RLPInt.encode(len - 16), | ||
...serializedElements | ||
@@ -38,3 +38,3 @@ ] | ||
if (prefix === FateTag.LONG_LIST) { | ||
[len, rest] = this.globalSerializer.deserializeStream(buffer.slice(1)) | ||
[len, rest] = RLPInt.decode(buffer.slice(1)) | ||
len += 16n | ||
@@ -41,0 +41,0 @@ } |
@@ -1,6 +0,4 @@ | ||
const RLP = require('rlp') | ||
const FateTag = require('../FateTag') | ||
const RLPInt = require('../utils/RLPInt') | ||
const BaseSerializer = require('./BaseSerializer') | ||
const {ByteArray2Int} = require('../utils/Int2ByteArray') | ||
const FateComparator = require('../FateComparator') | ||
@@ -27,3 +25,3 @@ const FateMap = require('../types/FateMap') | ||
FateTag.MAP, | ||
...RLPInt(len), | ||
...RLPInt.encode(len), | ||
...serializedItems.flat(Infinity) | ||
@@ -41,5 +39,4 @@ ] | ||
const decoded = RLP.decode(buffer.slice(1), true) | ||
const len = ByteArray2Int(decoded.data) | ||
let rest = decoded.remainder | ||
const [len, remainder] = RLPInt.decode(buffer.slice(1)) | ||
let rest = remainder | ||
@@ -46,0 +43,0 @@ if (len === 0n) { |
const FateTag = require('../FateTag') | ||
const FateInt = require('../types/FateInt') | ||
const FateTuple = require('../types/FateTuple') | ||
const BaseSerializer = require('./BaseSerializer') | ||
const RLPInt = require('../utils/RLPInt') | ||
@@ -28,3 +28,3 @@ class TupleSerializer extends BaseSerializer { | ||
FateTag.LONG_TUPLE, | ||
...this.globalSerializer.serialize(new FateInt(len - 16)), | ||
...RLPInt.encode(len - 16), | ||
...elements | ||
@@ -49,3 +49,3 @@ ] | ||
if (prefix === FateTag.LONG_TUPLE) { | ||
[len, rest] = this.globalSerializer.deserializeStream(buffer.slice(1)) | ||
[len, rest] = RLPInt.decode(buffer.slice(1)) | ||
len += 16n | ||
@@ -52,0 +52,0 @@ } |
@@ -19,2 +19,3 @@ const TypeResolveError = require('./Errors/TypeResolveError') | ||
FateTypeRecord, | ||
FateTypeSet, | ||
FateTypeVariant, | ||
@@ -29,2 +30,4 @@ FateTypeOption, | ||
FateTypeEvent, | ||
FateTypeBls12381Fr, | ||
FateTypeBls12381Fp | ||
} = require('./FateTypes') | ||
@@ -99,2 +102,6 @@ | ||
if (this.isStdType(type)) { | ||
return false | ||
} | ||
const [namespace, _localType] = type.split('.') | ||
@@ -106,2 +113,10 @@ const namespaceData = this.getNamespaceAci(namespace) | ||
isStdType(type) { | ||
if (type === 'Set.set') { | ||
return true | ||
} | ||
return false | ||
} | ||
getNamespaceAci(name) { | ||
@@ -134,4 +149,9 @@ for (const e of this.aci) { | ||
if (Array.isArray(valueTypes)) { | ||
if (key !== 'record' && key !== 'variant') { | ||
resolvedTypes = valueTypes.map(t => this.resolveType(t)) | ||
if (key !== 'variant') { | ||
resolvedTypes = valueTypes.map(v => { | ||
const tpl = v.hasOwnProperty('type') ? v.type : v | ||
const t = vars.hasOwnProperty(tpl) ? vars[tpl] : tpl | ||
return this.resolveType(t, vars) | ||
}) | ||
} | ||
@@ -144,2 +164,6 @@ } | ||
if (key === 'unit') { | ||
return FateTypeTuple([]) | ||
} | ||
if (key === 'int') { | ||
@@ -201,2 +225,14 @@ return FateTypeInt() | ||
if (key === 'Set.set') { | ||
return FateTypeSet(...resolvedTypes) | ||
} | ||
if (key === 'MCL_BLS12_381.fr') { | ||
return FateTypeBls12381Fr() | ||
} | ||
if (key === 'MCL_BLS12_381.fp') { | ||
return FateTypeBls12381Fp() | ||
} | ||
if (key === 'bytes') { | ||
@@ -210,2 +246,13 @@ return FateTypeBytes(valueTypes) | ||
if (key === 'map') { | ||
return FateTypeMap(...resolvedTypes) | ||
} | ||
// Unbox singleton tuples and records | ||
// https://github.com/aeternity/aesophia/pull/205 | ||
// https://github.com/aeternity/aesophia/commit/a403a9d227ac56266cf5bb8fbc916f17e6141d15 | ||
if ((key === 'tuple' || key === 'record') && resolvedTypes.length === 1) { | ||
return resolvedTypes[0] | ||
} | ||
if (key === 'tuple') { | ||
@@ -215,8 +262,6 @@ return FateTypeTuple(resolvedTypes) | ||
if (key === 'map') { | ||
return FateTypeMap(...resolvedTypes) | ||
} | ||
if (key === 'record') { | ||
const keys = valueTypes.map(e => e.name) | ||
if (key === 'record') { | ||
return this.resolveRecord(valueTypes) | ||
return FateTypeRecord(keys, resolvedTypes) | ||
} | ||
@@ -258,9 +303,2 @@ | ||
resolveRecord(valueTypes) { | ||
const keys = valueTypes.map(e => e.name) | ||
const resolvedTypes = valueTypes.map(e => this.resolveType(e.type)) | ||
return FateTypeRecord(keys, resolvedTypes) | ||
} | ||
resolveTypeDef(type, params = []) { | ||
@@ -267,0 +305,0 @@ const [namespace, localType] = type.split('.') |
@@ -43,2 +43,6 @@ const FateData = require('./FateData') | ||
get keys() { | ||
return this._value.keys() | ||
} | ||
valueOf() { | ||
@@ -45,0 +49,0 @@ const map = new Map() |
@@ -1,2 +0,2 @@ | ||
const blake = require('@aeternity/blakejs') | ||
const blake = require('blakejs') | ||
@@ -3,0 +3,0 @@ const HASH_BYTES = 32 |
@@ -14,3 +14,3 @@ const Int2ByteArray = (value) => { | ||
const ByteArray2Int = (data) => { | ||
const ByteArrayToHexArray = (data) => { | ||
const hex = [] | ||
@@ -28,8 +28,21 @@ | ||
return hex | ||
} | ||
const ByteArray2Int = (data) => { | ||
const hex = ByteArrayToHexArray(data) | ||
return BigInt('0x' + hex.join('')) | ||
} | ||
const ByteArray2IntBE = (data) => { | ||
const hex = ByteArrayToHexArray(data).reverse() | ||
return BigInt('0x' + hex.join('')) | ||
} | ||
module.exports = { | ||
Int2ByteArray, | ||
ByteArray2Int | ||
ByteArray2Int, | ||
ByteArray2IntBE | ||
} |
const RLP = require('rlp') | ||
const {Int2ByteArray} = require('./Int2ByteArray') | ||
const {Int2ByteArray, ByteArray2Int } = require('./Int2ByteArray') | ||
module.exports = function RLPInt(value) { | ||
return new Uint8Array(RLP.encode(Int2ByteArray(value))) | ||
module.exports = { | ||
encode(value) { | ||
return new Uint8Array(RLP.encode(Int2ByteArray(value))) | ||
}, | ||
decode(buffer) { | ||
const decoded = RLP.decode(buffer, true) | ||
return [ByteArray2Int(decoded.data), decoded.remainder] | ||
} | ||
} |
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
103246
86
2880
188
8
+ Addedblakejs@^1.2.1
+ Addedblakejs@1.2.1(transitive)
- Removed@aeternity/blakejs@^1.1.2
- Removed@aeternity/blakejs@1.1.2(transitive)