Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: add support for VerifiableURI and deprecate JSONURL / AssetURL #365

Merged
merged 11 commits into from
Dec 14, 2023
71 changes: 52 additions & 19 deletions src/lib/decodeData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('decodeData', () => {
key: '0x',
keyType: 'MappingWithGrouping',
valueType: 'bytes',
valueContent: 'JSONURL',
valueContent: 'JSONURL', // Deprecated - We keep it for backward compatibility between v0.21.3 and v0.22.0
},
{
name: 'MyKeyName2:<bytes32>:<bool>',
Expand All @@ -54,7 +54,7 @@ describe('decodeData', () => {
key: '0x',
keyType: 'Mapping',
CJ42 marked this conversation as resolved.
Show resolved Hide resolved
valueType: 'bytes',
valueContent: 'JSONURL',
valueContent: 'JSONURL', // Deprecated - We keep it for backward compatibility between v0.21.3 and v0.22.0
},
{
name: 'MyDynamicKey2:<address>',
Expand Down Expand Up @@ -83,6 +83,56 @@ describe('decodeData', () => {
expect(decodedData.map(({ name }) => name)).to.eql(['KeyOne', 'KeyTwo']);
});

it('is backward compatible with JSONURL and AssetURL and decodes these encoding correctly', () => {
const decodedData = decodeData(
[
{
keyName: 'JSONURLCase',
value:
'0x6f357c6a820464ddfac1bec070cc14a8daf04129871d458f2ca94368aae8391311af6361696670733a2f2f516d597231564a4c776572673670456f73636468564775676f3339706136727963455a4c6a7452504466573834554178',
},
{
keyName: 'AssetURLCase',
value:
'0x8019f9b1d47cf10786205bb08ce508e91c424d413d0f6c48e24dbfde2920d16a9561a723697066733a2f2f516d57346e554e7933767476723344785a48754c66534c6e687a4b4d6532576d67735573454750504668385a7470',
},
],
[
{
name: 'JSONURLCase',
key: '0x9136feeb09af67b63993b586ce46a43bd3456990d3fdb39d07beab9dee8d5910',
keyType: 'Singleton',
valueType: 'bytes',
valueContent: 'JSONURL', // Deprecated - We keep it for backward compatibility between v0.21.3 and v0.22.0
},
{
name: 'AssetURLCase',
key: '0xbda5878fa57d8da097bf7cfd78c28e75f2c2c7b028e4e056d16d7e4b83f98081',
keyType: 'Singleton',
valueType: 'bytes',
valueContent: 'AssetURL', // Deprecated - We keep it for backward compatibility between v0.21.3 and v0.22.0
},
],
);

expect(decodedData.map(({ value }) => value)).to.eql([
{
verification: {
method: 'keccak256(utf8)', // 0x6f357c6a
data: '0x820464ddfac1bec070cc14a8daf04129871d458f2ca94368aae8391311af6361',
},
url: 'ifps://QmYr1VJLwerg6pEoscdhVGugo39pa6rycEZLjtRPDfW84UAx',
},
{
verification: {
method: 'keccak256(bytes)', // 0x8019f9b1
data: '0xd47cf10786205bb08ce508e91c424d413d0f6c48e24dbfde2920d16a9561a723',
},
url: 'ipfs://QmW4nUNy3vtvr3DxZHuLfSLnhzKMe2WmgsUsEGPPFh8Ztp',
},
]);
});

it('parses non array input correctly', () => {
const decodedData = decodeData(
{
Expand Down Expand Up @@ -159,21 +209,6 @@ describe('decodeData', () => {
it('decodes dynamic keys', () => {
const decodedData = decodeData(
[
{
keyName: 'MyKeyName:<bytes32>:<bool>',
dynamicKeyParts: [
'0xaaaabbbbccccddddeeeeffff111122223333444455556666777788889999aaaa',
'true',
],
value:
'0x6f357c6a820464ddfac1bec070cc14a8daf04129871d458f2ca94368aae8391311af6361697066733a2f2f516d597231564a4c776572673670456f73636468564775676f3339706136727963455a4c6a7452504466573834554178',
},
{
keyName: 'MyDynamicKey:<address>',
dynamicKeyParts: '0xcafecafecafecafecafecafecafecafecafecafe',
value:
'0x6f357c6a820464ddfac1bec070cc14a8daf04129871d458f2ca94368aae8391311af6361697066733a2f2f516d597231564a4c776572673670456f73636468564775676f3339706136727963455a4c6a7452504466573834554178',
},
{
keyName: 'MyKeyName2:<bytes32>:<bool>',
dynamicKeyParts: [
Expand All @@ -198,8 +233,6 @@ describe('decodeData', () => {
);

expect(decodedData.map(({ name }) => name)).to.eql([
'MyKeyName:aaaabbbbccccddddeeeeffff111122223333444455556666777788889999aaaa:true',
'MyDynamicKey:cafecafecafecafecafecafecafecafecafecafe',
'MyKeyName2:aaaabbbbccccddddeeeeffff111122223333444455556666777788889999aaaa:true',
'MyDynamicKey2:cafecafecafecafecafecafecafecafecafecafe',
'KeyTwo',
Expand Down
18 changes: 18 additions & 0 deletions src/lib/encoder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,9 @@ describe('encoder', () => {
decodedValue: 'http://test.com',
encodedValue: '0x687474703a2f2f746573742e636f6d',
},
// AssetURL is deprecated since:
// https://github.com/lukso-network/LIPs/pull/263
// We keep it in our tests for backward compatibility testing for v0.22.0 release
{
valueContent: 'AssetURL',
decodedValue: {
Expand All @@ -905,6 +908,19 @@ describe('encoder', () => {
},
url: 'http://test.com/asset.glb',
},
// Starting from v0.22.0, we force AssetURL encode to VerifiableURI as AssetURL is deprecated
encodedValue:
'0x00006f357c6a0020027547537d35728a741470df1ccf65de10b454ca0def7c5c20b257b7b8d16168687474703a2f2f746573742e636f6d2f61737365742e676c62',
},
{
valueContent: 'VerifiableURI',
decodedValue: {
verification: {
method: SUPPORTED_VERIFICATION_METHOD_STRINGS.KECCAK256_UTF8,
data: '0x027547537d35728a741470df1ccf65de10b454ca0def7c5c20b257b7b8d16168',
},
url: 'http://test.com/asset.glb',
},
encodedValue:
'0x00006f357c6a0020027547537d35728a741470df1ccf65de10b454ca0def7c5c20b257b7b8d16168687474703a2f2f746573742e636f6d2f61737365742e676c62',
},
Expand Down Expand Up @@ -964,6 +980,8 @@ describe('encoder', () => {
const jsonVerificationData = keccak256(
JSON.stringify(dataToEncode.json),
).substring(2);

// Starting from v0.22.0, we force JSONURL encode to VerifiableURI as JSONURL is deprecated
assert.deepStrictEqual(
encodedValue,
`0x0000${stripHexPrefix(verificationMethod)}${stripHexPrefix(
Expand Down
23 changes: 9 additions & 14 deletions src/lib/encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,14 @@ const decodeDataSourceWithHash = (value: string): URLDataWithHash => {
820464ddfac1be...[18 + data len]
[18 + data len]...696670733a2f2...[...rest]
*/
const verificationMethodSig = `0x${value.slice(6, 14)}`;
// NOTE: verificationMethodSig can be 0x00000000 if no verification method is used
const verificationMethodSignature = `0x${value.slice(6, 14)}`;
// NOTE: verificationMethodSignature can be 0x00000000 if no verification method is used
// this means that an invalid verification method should still return all data
// and not be an error. It's up to the method calling this to figure out
// whether an unknown verification method is an error or not.
const verificationMethod = getVerificationMethod(verificationMethodSig);
const verificationMethod = getVerificationMethod(
verificationMethodSignature,
);
const encodedLength = `0x${value.slice(14, 18)}`; // Rest of data string after function hash
const dataLength = hexToNumber(encodedLength, false) as number;
const dataHash = `0x${value.slice(18, 18 + dataLength * 2)}`; // Get jsonHash 32 bytes
Expand All @@ -124,8 +126,8 @@ const decodeDataSourceWithHash = (value: string): URLDataWithHash => {
};
}

const verificationMethodSig = value.slice(0, 10);
const verificationMethod = getVerificationMethod(verificationMethodSig);
const verificationMethodSignature = value.slice(0, 10);
const verificationMethod = getVerificationMethod(verificationMethodSignature);
Hugoo marked this conversation as resolved.
Show resolved Hide resolved
const encodedData = value.slice(10); // Rest of data string after function hash
const dataHash = '0x' + encodedData.slice(0, 64); // Get jsonHash 32 bytes
const dataSource = hexToUtf8('0x' + encodedData.slice(64)); // Get remainder as URI
Expand Down Expand Up @@ -678,16 +680,9 @@ export const valueContentEncodingMap = (
decode: (value: string) => hexToUtf8(value),
};
}
case 'AssetURL': {
return {
type: 'custom',
encode: (value: AssetURLEncode) =>
encodeDataSourceWithHash(value.verification, value.url),
decode: (value: string) => decodeDataSourceWithHash(value),
};
}
// https://github.com/lukso-network/LIPs/blob/master/LSPs/LSP-2-ERC725YJSONSchema.md#jsonurl
Hugoo marked this conversation as resolved.
Show resolved Hide resolved
case 'JSONURL':
case 'AssetURL': // Deprecated since v0.22.0
case 'JSONURL': // Deprecated since v0.22.0
case 'VerifiableURI': {
return {
type: 'custom',
Expand Down
2 changes: 1 addition & 1 deletion src/lib/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('utils', () => {
name: 'TestObjArray[]',
key: '0x9985edaf12cbacf5ac7d6ed54f0445cc0ea56075aee9b9942e4ab3bf4239f950',
keyType: 'Array',
valueContent: 'JSONURL',
valueContent: 'JSONURL', // Deprecated - we keep it for backward compatibility
valueType: 'bytes',
},
decodedValue: [
Expand Down
Loading