diff --git a/docs/classes/ERC725.md b/docs/classes/ERC725.md index d50f7c76..29b467ce 100644 --- a/docs/classes/ERC725.md +++ b/docs/classes/ERC725.md @@ -615,6 +615,30 @@ myErc725.encodeData([ +
+ Encode array length + +If the key is of type Array and you pass an integer as a value (for instance, the array length), it will be encoded accordingly. + +```javascript title="Encode the length of an array" +myErc725.encodeData([ + { + keyName: 'LSP3IssuedAssets[]', + value: 5, + }, +]); +/** +{ + keys: [ + '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0', + ], + values: ['0x00000000000000000000000000000005'], +} +*/ +``` + +
+ --- ## encodeKeyName diff --git a/src/index.ts b/src/index.ts index 6cf27f14..5ae7ce3d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -124,7 +124,7 @@ export class ERC725 { } /** - * To prevent weird behovior from the lib, we must make sure all the schemas are correct before loading them. + * To prevent weird behavior from the lib, we must make sure all the schemas are correct before loading them. * * @param schemas * @returns diff --git a/src/lib/encoder.ts b/src/lib/encoder.ts index 6ff989b3..d4db5dad 100644 --- a/src/lib/encoder.ts +++ b/src/lib/encoder.ts @@ -332,30 +332,6 @@ const returnTypesOfUintNCompactBytesArray = () => { return types; }; -/** - * Encodes any set of strings to string[CompactBytesArray] - * - * @param values An array of non restricted strings - * @returns string[CompactBytesArray] - */ -const encodeStringCompactBytesArray = (values: string[]): string => { - const hexValues: string[] = values.map((element) => utf8ToHex(element)); - - return encodeCompactBytesArray(hexValues); -}; - -/** - * Decode a string[CompactBytesArray] to an array of strings - * @param compactBytesArray A string[CompactBytesArray] - * @returns An array of strings - */ -const decodeStringCompactBytesArray = (compactBytesArray: string): string[] => { - const hexValues: string[] = decodeCompactBytesArray(compactBytesArray); - const stringValues: string[] = hexValues.map((element) => hexToUtf8(element)); - - return stringValues; -}; - const valueTypeEncodingMap = { bool: { encode: (value: boolean) => (value ? '0x01' : '0x00'), @@ -494,8 +470,17 @@ const valueTypeEncodingMap = { decode: (value: string) => decodeCompactBytesArray(value), }, 'string[CompactBytesArray]': { - encode: (value: string[]) => encodeStringCompactBytesArray(value), - decode: (value: string) => decodeStringCompactBytesArray(value), + encode: (values: string[]) => { + const hexValues: string[] = values.map((element) => utf8ToHex(element)); + return encodeCompactBytesArray(hexValues); + }, + decode: (value: string) => { + const hexValues: string[] = decodeCompactBytesArray(value); + const stringValues: string[] = hexValues.map((element) => + hexToUtf8(element), + ); + return stringValues; + }, }, ...returnTypesOfBytesNCompactBytesArray(), ...returnTypesOfUintNCompactBytesArray(), diff --git a/src/lib/utils.test.ts b/src/lib/utils.test.ts index 0ae455ad..57a5add0 100644 --- a/src/lib/utils.test.ts +++ b/src/lib/utils.test.ts @@ -29,7 +29,6 @@ import { SUPPORTED_VERIFICATION_METHOD_STRINGS } from '../constants/constants'; import { guessKeyTypeFromKeyName, isDataAuthentic, - encodeArrayKey, encodeKeyValue, decodeKeyValue, encodeKey, @@ -44,6 +43,7 @@ import { decodeKey } from './decodeData'; describe('utils', () => { describe('encodeKey/decodeKey', () => { const testCases = [ + // test encoding an array of address { schema: { name: 'LSP3IssuedAssets[]', @@ -226,12 +226,28 @@ describe('utils', () => { encodeKey(testCase.schema as ERC725JSONSchema, testCase.decodedValue), testCase.encodedValue, ); + assert.deepStrictEqual( decodeKey(testCase.schema as ERC725JSONSchema, testCase.encodedValue), testCase.decodedValue, ); }); }); + + it('should encode the array length only if passing a number', async () => { + const schema: ERC725JSONSchema = { + name: 'LSP3IssuedAssets[]', + key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0', + keyType: 'Array', + valueContent: 'Address', + valueType: 'address', + }; + + const decodedValue = 3; + const encodedValue = '0x00000000000000000000000000000003'; + + assert.equal(encodeKey(schema, decodedValue), encodedValue); + }); }); describe('encodeKeyValue/decodeKeyValue', () => { @@ -391,19 +407,19 @@ describe('utils', () => { }); describe('encodeArrayKey', () => { - it('encodes array key correctly', () => { - const key = - '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0'; - - const expectedValues = [ - '0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000000', - '0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000001', - '0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000002', - ]; + it('should encode the array length only if passing a number', async () => { + const schema: ERC725JSONSchema = { + name: 'LSP3IssuedAssets[]', + key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0', + keyType: 'Array', + valueContent: 'Address', + valueType: 'address', + }; - expectedValues.forEach((expectedValue, index) => { - assert.strictEqual(encodeArrayKey(key, index), expectedValue); - }); + const decodedValue = 3; + const encodedValue = '0x00000000000000000000000000000003'; + + assert.equal(encodeKey(schema, decodedValue), encodedValue); }); }); @@ -567,6 +583,27 @@ describe('utils', () => { }); }); + it('encodes array length only if giving a number', () => { + const length = 5; + + const encodedArrayLengthKey = encodeData( + [ + { + keyName: 'LSP3IssuedAssets[]', + value: length, + }, + ], + schemas, + ); + + assert.deepStrictEqual(encodedArrayLengthKey, { + keys: [ + '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0', + ], + values: ['0x00000000000000000000000000000005'], + }); + }); + it('encodes multiple keys', () => { const encodedMultipleKeys = encodeData( [ diff --git a/src/lib/utils.ts b/src/lib/utils.ts index a29a9a72..0e5555c9 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -249,6 +249,11 @@ export function encodeKey( switch (lowerCaseKeyType) { case 'array': { + // if we are encoding only the Array length + if (typeof value === 'number') { + return encodeValueType('uint128', value); + } + if (!Array.isArray(value)) { console.error("Can't encode a non array for key of type array"); return null; diff --git a/src/types/encodeData/JSONURL.ts b/src/types/encodeData/JSONURL.ts index 1c00ac90..4948cdc9 100644 --- a/src/types/encodeData/JSONURL.ts +++ b/src/types/encodeData/JSONURL.ts @@ -27,7 +27,12 @@ export interface URLDataWithJson extends URLData { export type JSONURLDataToEncode = URLDataWithHash | URLDataWithJson; -export type EncodeDataType = string | string[] | JSONURLDataToEncode | boolean; +export type EncodeDataType = + | string + | string[] + | JSONURLDataToEncode + | boolean + | number; export interface EncodeDataReturn { keys: string[];