Skip to content

Commit

Permalink
Merge pull request #449 from ERC725Alliance/feat/array-index-encoding
Browse files Browse the repository at this point in the history
feat: allow to encode array index using `dynamicKeyPart` in `encodeData` + return `dynamicName` with `getSchema` for Arrays
  • Loading branch information
CJ42 authored May 21, 2024
2 parents 91363c4 + 5445222 commit 622675d
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 46 deletions.
11 changes: 11 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1908,6 +1908,17 @@ describe('encodeKeyName', () => {
'0x31145577efe228036af40000a4fbbfe353124e6fa6bb7f8e088a9269df552ea2',
);
});

it('works for Array keys with index as `dynamicKeyParts', () => {
assert.deepStrictEqual(
encodeKeyName('MusicPlaylist[]', 2),
'0x03573598507fc76d82171baa336b7fd700000000000000000000000000000002',
);
assert.deepStrictEqual(
erc725Instance.encodeKeyName('MusicPlaylist[]', 2),
'0x03573598507fc76d82171baa336b7fd700000000000000000000000000000002',
);
});
});

describe('supportsInterface', () => {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/encodeKeyName.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ describe('encodeKeyName', () => {
expectedKey: keccak256('MyKeyName'),
},
{
keyName: 'LSP3IssuedAssets[]',
keyName: 'LSP12IssuedAssets[]',
expectedKey:
'0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
'0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
},
{
keyName: 'SupportedStandards:LSP3Profile',
Expand Down
16 changes: 13 additions & 3 deletions src/lib/encodeKeyName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
padLeft,
} from 'web3-utils';

import { guessKeyTypeFromKeyName } from './utils';
import { encodeArrayKey, guessKeyTypeFromKeyName } from './utils';
import { DynamicKeyParts } from '../types/dynamicKeys';

// https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md#mapping
Expand Down Expand Up @@ -248,9 +248,12 @@ function encodeDynamicKeyName(

switch (keyType) {
case 'Mapping':
return encodeDynamicMapping(name, dynamicKeyPartsArray);
return encodeDynamicMapping(name, dynamicKeyPartsArray as string[]);
case 'MappingWithGrouping':
return encodeDynamicMappingWithGrouping(name, dynamicKeyPartsArray);
return encodeDynamicMappingWithGrouping(
name,
dynamicKeyPartsArray as string[],
);
default:
throw new Error(
`Could not encode dynamic key: ${name} of type: ${keyType}`,
Expand Down Expand Up @@ -295,6 +298,13 @@ export function encodeKeyName(name: string, dynamicKeyParts?: DynamicKeyParts) {
]);
}
case 'Array': // Warning: this can not correctly encode subsequent keys of array, only the initial Array key will work
// encode for array index
if (dynamicKeyParts && typeof dynamicKeyParts === 'number') {
return encodeArrayKey(keccak256(name), dynamicKeyParts);
}

// encode for array length
return keccak256(name);
case 'Singleton':
return keccak256(name);
default:
Expand Down
8 changes: 6 additions & 2 deletions src/lib/schemaParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,19 @@ describe('schemaParser getSchema', () => {

assert.deepStrictEqual(schema, {
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000001': {
name: 'LSP12IssuedAssets[1]',
name: 'LSP12IssuedAssets[]',
key: '0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000001',
dynamicName: 'LSP12IssuedAssets[1]',
dynamicKeyPart: '0x00000000000000000000000000000001',
keyType: 'Singleton',
valueContent: 'Address',
valueType: 'address',
},
'0xdf30dba06db6a30e65354d9a64c6098600000000000000000000000000000000': {
name: 'AddressPermissions[0]',
name: 'AddressPermissions[]',
key: '0xdf30dba06db6a30e65354d9a64c6098600000000000000000000000000000000',
dynamicName: 'AddressPermissions[0]',
dynamicKeyPart: '0x00000000000000000000000000000000',
keyType: 'Singleton',
valueContent: 'Address',
valueType: 'address',
Expand Down
6 changes: 4 additions & 2 deletions src/lib/schemaParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const findSingletonSchemaForKey = (
const findArraySchemaForKey = (
key: string,
schemas: ERC725JSONSchema[],
): ERC725JSONSchema | null => {
): ERC725JSONSchema | DynamicNameSchema | null => {
// Should detect:

// 1. Initial key
Expand Down Expand Up @@ -132,7 +132,9 @@ const findArraySchemaForKey = (
return {
...arraySchema,
key,
name: arraySchema.name.replace('[]', `[${elementIndex}]`),
dynamicName: arraySchema.name.replace('[]', `[${elementIndex}]`),
dynamicKeyPart: `0x${key.substring(34)}`,
name: arraySchema.name,
keyType: 'Singleton',
};
};
Expand Down
68 changes: 34 additions & 34 deletions src/lib/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ describe('utils', () => {
// test encoding an array of address
{
schema: {
name: 'LSP3IssuedAssets[]',
key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
name: 'LSP12IssuedAssets[]',
key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
keyType: 'Array',
valueContent: 'Address',
valueType: 'address',
Expand All @@ -61,15 +61,15 @@ describe('utils', () => {
],
encodedValue: [
{
key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
value: '0x00000000000000000000000000000002',
},
{
key: '0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000000',
key: '0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000000',
value: '0xc444009d38d3046bb0cf81fa2cd295ce46a67c78',
},
{
key: '0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000001',
key: '0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000001',
value: '0x4febc3491230571f6e1829e46602e3b110215a2e',
},
],
Expand Down Expand Up @@ -239,8 +239,8 @@ describe('utils', () => {

it('should encode the array length only if passing a number', async () => {
const schema: ERC725JSONSchema = {
name: 'LSP3IssuedAssets[]',
key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
name: 'LSP12IssuedAssets[]',
key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
keyType: 'Array',
valueContent: 'Address',
valueType: 'address',
Expand Down Expand Up @@ -438,8 +438,8 @@ describe('utils', () => {
describe('encodeArrayKey', () => {
it('should encode the array length only if passing a number', async () => {
const schema: ERC725JSONSchema = {
name: 'LSP3IssuedAssets[]',
key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
name: 'LSP12IssuedAssets[]',
key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
keyType: 'Array',
valueContent: 'Address',
valueType: 'address',
Expand All @@ -455,8 +455,8 @@ describe('utils', () => {
describe('encodeData', () => {
const schemas: ERC725JSONSchema[] = [
{
name: 'LSP3IssuedAssets[]',
key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
name: 'LSP12IssuedAssets[]',
key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
keyType: 'Array',
valueContent: 'Address',
valueType: 'address',
Expand Down Expand Up @@ -550,7 +550,7 @@ describe('utils', () => {
const encodedDataWithMultipleKeys = encodeData(
[
{
keyName: 'LSP3IssuedAssets[]',
keyName: 'LSP12IssuedAssets[]',
value: ['0xa3e6F38477D45727F6e6f853Cdb479b0D60c0aC9'],
},
],
Expand All @@ -559,8 +559,8 @@ describe('utils', () => {

assert.deepStrictEqual(encodedDataWithMultipleKeys, {
keys: [
'0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000000',
'0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000000',
],
values: [
'0x00000000000000000000000000000001',
Expand All @@ -586,7 +586,7 @@ describe('utils', () => {
const encodedDataWithMultipleKeys = encodeData(
[
{
keyName: 'LSP3IssuedAssets[]',
keyName: 'LSP12IssuedAssets[]',
value: addressArray,
},
],
Expand All @@ -595,18 +595,18 @@ describe('utils', () => {

assert.deepStrictEqual(encodedDataWithMultipleKeys, {
keys: [
'0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000000',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000001',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000002',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000003',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000004',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000005',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000006',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000007',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000008',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000009',
'0x3a47ab5bd3a594c3a8995f8fa58d08760000000000000000000000000000000a',
'0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000000',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000001',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000002',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000003',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000004',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000005',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000006',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000007',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000008',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000009',
'0x7c8c3416d6cda87cd42c71ea1843df280000000000000000000000000000000a',
],
values: ['0x0000000000000000000000000000000b', ...addressArray],
});
Expand All @@ -618,7 +618,7 @@ describe('utils', () => {
const encodedArrayLengthKey = encodeData(
[
{
keyName: 'LSP3IssuedAssets[]',
keyName: 'LSP12IssuedAssets[]',
value: length,
},
],
Expand All @@ -627,7 +627,7 @@ describe('utils', () => {

assert.deepStrictEqual(encodedArrayLengthKey, {
keys: [
'0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
'0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
],
values: ['0x00000000000000000000000000000005'],
});
Expand All @@ -647,7 +647,7 @@ describe('utils', () => {
},
},
{
keyName: 'LSP3IssuedAssets[]',
keyName: 'LSP12IssuedAssets[]',
value: [
'0xD94353D9B005B3c0A9Da169b768a31C57844e490',
'0xDaea594E385Fc724449E3118B2Db7E86dFBa1826',
Expand All @@ -664,9 +664,9 @@ describe('utils', () => {
assert.deepStrictEqual(encodedMultipleKeys, {
keys: [
'0x5ef83ad9559033e6e941db7d7c495acdce616347d28e90c7ce47cbfcfcad3bc5',
'0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000000',
'0x3a47ab5bd3a594c3a8995f8fa58d087600000000000000000000000000000001',
'0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000000',
'0x7c8c3416d6cda87cd42c71ea1843df2800000000000000000000000000000001',
'0x0cfc51aec37c55a4d0b1a65c6255c4bf2fbdf6277f3cc0730c45b828b6db8b47',
],
values: [
Expand Down Expand Up @@ -921,7 +921,7 @@ describe('utils', () => {
},
{
keyType: 'Array',
keyName: 'LSP3IssuedAssets[]',
keyName: 'LSP12IssuedAssets[]',
},
{
keyType: 'Mapping',
Expand Down
2 changes: 1 addition & 1 deletion src/types/dynamicKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { EncodeDataType } from './encodeData/JSONURL';

export type DynamicKeyParts = string | string[];
export type DynamicKeyParts = string | string[] | number;

export interface DynamicKeyPartInput {
dynamicKeyParts: DynamicKeyParts;
Expand Down
4 changes: 2 additions & 2 deletions test/mockSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ export const mockSchema: (ERC725JSONSchema & {

// Case 9
{
name: 'LSP3IssuedAssets[]',
key: '0x3a47ab5bd3a594c3a8995f8fa58d0876c96819ca4516bd76100c92462f2f9dc0',
name: 'LSP12IssuedAssets[]',
key: '0x7c8c3416d6cda87cd42c71ea1843df28ac4850354f988d55ee2eaa47b6dc05cd',
keyType: 'Array',
valueContent: 'Address',
valueType: 'address',
Expand Down

0 comments on commit 622675d

Please sign in to comment.