From 5ddb12d43ce399e166e159be9faf364f9647c705 Mon Sep 17 00:00:00 2001 From: CJ42 Date: Fri, 3 May 2024 00:32:02 +0100 Subject: [PATCH] feat: allow to use `decodeData` to decode Array length only --- src/lib/decodeData.test.ts | 21 +++++++++++++++++++++ src/lib/decodeData.ts | 17 +++++++++++------ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/lib/decodeData.test.ts b/src/lib/decodeData.test.ts index f1e398ed..39545ebf 100644 --- a/src/lib/decodeData.test.ts +++ b/src/lib/decodeData.test.ts @@ -263,6 +263,27 @@ describe('decodeData', () => { ]); }); + it('parses type Array correctly but just the array length', () => { + const decodedData = decodeData( + { + keyName: 'LSP12IssuedAssets[]', + value: '0x00000000000000000000000000000003', + }, + [ + { + name: 'LSP12IssuedAssets[]', + key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd', + keyType: 'Array', + valueContent: 'Address', + valueType: 'address', + }, + ], + ); + + expect(decodedData.name).to.eql('LSP12IssuedAssets[]'); + expect(decodedData.value).to.eql(3); + }); + it('decodes dynamic keys', () => { const decodedData = decodeData( [ diff --git a/src/lib/decodeData.ts b/src/lib/decodeData.ts index cecb0bf8..05050361 100644 --- a/src/lib/decodeData.ts +++ b/src/lib/decodeData.ts @@ -31,7 +31,7 @@ import { import { isDynamicKeyName } from './encodeKeyName'; import { valueContentEncodingMap, decodeValueType } from './encoder'; import { getSchemaElement } from './getSchemaElement'; -import { decodeKeyValue, encodeArrayKey } from './utils'; +import { countNumberOfBytes, decodeKeyValue, encodeArrayKey } from './utils'; const tupleValueTypesRegex = /bytes(\d+)/; const valueContentsBytesRegex = /Bytes(\d+)/; @@ -195,23 +195,28 @@ export function decodeKey(schema: ERC725JSONSchema, value) { switch (lowerCaseKeyType) { case 'array': { - const results: any[] = []; - // If user has requested a key which does not exist in the contract, value will be: 0x and value.find() will fail. - if (!value || typeof value === 'string') { - return results; + if (!value) { + return []; + } + + // Decode as a Number when when the encoded value is to set the Array length only + if (typeof value === 'string' && countNumberOfBytes(value) === 16) { + return decodeKeyValue('Number', 'uint128', value, schema.name) || 0; } const valueElement = value.find((e) => e.key === schema.key); // Handle empty/non-existent array if (!valueElement) { - return results; + return []; } const arrayLength = decodeKeyValue('Number', 'uint128', valueElement.value, schema.name) || 0; + const results: any[] = []; + // This will not run if no match or arrayLength for (let index = 0; index < arrayLength; index++) { const dataElement = value.find(