diff --git a/src/lib/schemaParser.test.ts b/src/lib/schemaParser.test.ts index 21a1f370..3b90775b 100644 --- a/src/lib/schemaParser.test.ts +++ b/src/lib/schemaParser.test.ts @@ -13,7 +13,7 @@ */ import assert from 'assert'; -import { ERC725JSONSchema } from '../types/ERC725JSONSchema'; +import { DynamicNameSchema } from '../types/ERC725JSONSchema'; import { getSchema } from './schemaParser'; @@ -112,11 +112,13 @@ describe('schemaParser getSchema', () => { it('finds Known Mapping:
', () => { const address = 'af3bf2ffb025098b79caddfbdd113b3681817744'; - const name = `MyCoolAddress:${address}`; + const name = 'MyCoolAddress:
'; + const dynamicName = `MyCoolAddress:${address}`; const key = `0x22496f48a493035f00000000${address}`; - const extraSchema: ERC725JSONSchema = { + const extraSchema: DynamicNameSchema = { name, + dynamicName, key, keyType: 'Mapping', valueContent: 'Address', @@ -131,11 +133,13 @@ describe('schemaParser getSchema', () => { it('finds known SomeBytes32Mapping:', () => { const bytes32Value = '1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffff'; - const name = `SomeBytes32Mapping:${bytes32Value}`; + const name = `SomeBytes32Mapping:`; + const dynamicName = `SomeBytes32Mapping:${bytes32Value}`; const key = `0x0cfc51aec37c55a4d0b10000${bytes32Value.slice(0, 42)}`; - const extraSchema: ERC725JSONSchema = { + const extraSchema: DynamicNameSchema = { name, + dynamicName, key, keyType: 'Mapping', valueContent: 'Address', @@ -149,11 +153,13 @@ describe('schemaParser getSchema', () => { it('finds known SomeSelectorMap:', () => { const bytes4Value = 'beefbeef'; - const name = `SomeSelectorMap:${bytes4Value}`; + const name = `SomeSelectorMap:`; + const dynamicName = `SomeSelectorMap:${bytes4Value}`; const key = `0x0cfc51aec37c55a4d0b10000${bytes4Value}00000000000000000000000000000000`; - const extraSchema: ERC725JSONSchema = { + const extraSchema: DynamicNameSchema = { name, + dynamicName, key, keyType: 'Mapping', valueContent: '(Address,bool)', @@ -169,12 +175,14 @@ describe('schemaParser getSchema', () => { describe('MappingWithGrouping', () => { it('finds MappingWithGrouping', () => { const address = 'af3bf2ffb025098b79caddfbdd113b3681817744'; - const name = `AddressPermissions:Permissions:${address}`; + const name = `AddressPermissions:Permissions:
`; + const dynamicName = `AddressPermissions:Permissions:${address}`; const key = `0x4b80742de2bf82acb3630000${address}`; const schema = getSchema(key); assert.deepStrictEqual(schema, { name, + dynamicName, key, keyType: 'MappingWithGrouping', valueContent: 'BitArray', diff --git a/src/lib/schemaParser.ts b/src/lib/schemaParser.ts index d2e94c52..d321440e 100644 --- a/src/lib/schemaParser.ts +++ b/src/lib/schemaParser.ts @@ -21,6 +21,7 @@ import { keccak256 } from 'web3-utils'; import allSchemas from '../schemas'; import { + DynamicNameSchema, ERC725JSONSchema, ERC725JSONSchemaKeyType, } from '../types/ERC725JSONSchema'; @@ -87,10 +88,9 @@ const findArraySchemaForKey = ( const findMappingSchemaForKey = ( key: string, schemas: ERC725JSONSchema[], -): ERC725JSONSchema | null => { +): ERC725JSONSchema | DynamicNameSchema | null => { const firstWordHex = key.substring(0, 26); const secondWordHex = key.substring(26); - // Should detect: // 1. Known/defined mapping @@ -101,7 +101,7 @@ const findMappingSchemaForKey = ( } // 2. "Semi defined mappings" i.e. "SupportedStandards:??????" - let dynamicPart = '??????'; // default for "unknown" + let dynamicPartName = '??????'; // default for "unknown" keySchema = schemas.find( @@ -114,30 +114,32 @@ const findMappingSchemaForKey = ( const keyNameParts = keySchema.name.split(':'); + const result = { + ...keySchema, + name: `${keyNameParts[0]}:${dynamicPartName}`, + valueContent: '?', + key, + }; + // replace dynamic placeholder in the map part (e.g:
, ) with the hex value if (isDynamicKeyName(keySchema.name)) { - dynamicPart = secondWordHex; + dynamicPartName = secondWordHex; + result['dynamicName'] = `${keyNameParts[0]}:${dynamicPartName}`; } // if first 20 bytes of the hash of second word in schema match, // display the map part as plain word if (keccak256(keyNameParts[1]).substring(0, 26) === secondWordHex) { - [, dynamicPart] = keyNameParts; + [, dynamicPartName] = keyNameParts; } - // TODO: Handle the SupportedStandard Keys; we can get the valueContent from the Keys - return { - ...keySchema, - valueContent: '?', - name: `${keyNameParts[0]}:${dynamicPart}`, - key, - }; + return result; }; const findMappingWithGroupingSchemaForKey = ( key: string, schemas: ERC725JSONSchema[], -): ERC725JSONSchema | null => { +): ERC725JSONSchema | DynamicNameSchema | null => { const keySchema = schemas.find( (schema) => schema.key.substring(0, 26) === key.substring(0, 26), @@ -149,7 +151,7 @@ const findMappingWithGroupingSchemaForKey = ( return { ...keySchema, key, - name: `${keySchema.name.substring( + dynamicName: `${keySchema.name.substring( 0, keySchema.name.lastIndexOf(':'), )}:${address}`, diff --git a/src/types/ERC725JSONSchema.ts b/src/types/ERC725JSONSchema.ts index 5eb0eced..79a40cb6 100644 --- a/src/types/ERC725JSONSchema.ts +++ b/src/types/ERC725JSONSchema.ts @@ -163,3 +163,9 @@ export interface ERC725JSONSchema { valueContent: ERC725JSONSchemaValueContent | string; // string holds '0x1345ABCD...' If the value content are specific bytes, than the returned value is expected to equal those bytes. valueType: ERC725JSONSchemaValueType | string; // The type of the value. This is used to determine how the value should be encoded / decode (`string` for tuples and CompactBytesArray). } + +// The dynamic part placeholder in the `name` of ERC725JSONSchema is preserved to allow re-encoding after the schema +// of a hex data key got retrieved via `getSchema(...)`. +export interface DynamicNameSchema extends ERC725JSONSchema { + dynamicName: string; // Describes the name of the key where the dynamic part (
,