Skip to content

Commit

Permalink
feat: export method isDataAuthentic as static, single method or mem…
Browse files Browse the repository at this point in the history
…ber of class
  • Loading branch information
CJ42 committed May 21, 2024
1 parent f426a31 commit 0c7ba98
Show file tree
Hide file tree
Showing 5 changed files with 331 additions and 4 deletions.
179 changes: 177 additions & 2 deletions docs/methods/external-data-source-utilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,181 @@ getVerificationMethod('0x6f357c6a');
*/
```

## hashData

## isDataAuthentic

```js
const myErc725 = new ERC725();
ERC725.isDataAuthentic(data, verificationOptions);
```

```js
ERC725.isDataAuthentic(data, verificationOptions);
```

```js
import { isDataAuthentic } from '@erc725/erc725.js';

isDataAuthentic(data, verificationOptions);
```

Hashes the `data` passed as parameter using the specified hashing functions (available under `method` in the `verificationOption` object) and compares the result with the provided hash.

:::info
This method will console an error if the hash provided as `data` and the expected hash obtained using the verification method do not match.
:::

#### Parameters

| Name | Type | Description |
| :-------------------- | :----------------------- | :---------------------------------- |
| `data` | `string` or `Uint8Array` | The data to be hashed and verified. |
| `verificationOptions` | `Verification` | An object as defined below |

<details>
<summary>Types details</summary>

```js
KECCAK256_UTF8 = ,
KECCAK256_BYTES = ,
HASH_KECCAK256_UTF8 = ,
HASH_KECCAK256_BYTES = ,

export interface Verification {
data: string;
method: 'keccak256(utf8)' | 'keccak256(bytes)' | '0x6f357c6a' | '0x8019f9b1' | string;
source?: string;
}
```

</details>

#### Returns

| Name | Type | Description |
| :--- | :-------- | :-------------------------------------------------------------------------------------------- |
| | `boolean` | `true` if the data is authentic according to the verification method used, `false` otherwise. |

### Example

<details>
<summary>JSON data to verify from <code>data.json</code></summary>

```json
[
{
"name": "LSP3Profile",
"key": "0x5ef83ad9559033e6e941db7d7c495acdce616347d28e90c7ce47cbfcfcad3bc5",
"value": {
"LSP3Profile": {
"name": "test",
"description": "",
"tags": ["profile"],
"links": [],
"profileImage": [
{
"width": 1024,
"height": 709,
"verification": {
"method": "keccak256(bytes)",
"data": "0x6a0a28680d65b69f5696859be7e0fcebbbcf0df47f1f767926de35402c7d525c"
},
"url": "ipfs://QmVUYyft3j2JVrG4RzDe1Qx7K5gNtJGFhrExHQFeiRXz1C"
},
{
"width": 640,
"height": 443,
"verification": {
"method": "keccak256(bytes)",
"data": "0x7cd399f2a2552aa5cd21b1584a98db3efa39c701c311c38a60c680343cfa6d82"
},
"url": "ipfs://QmeU8FUZC9F1qMYmcWyBhfGqaf7g3kLzGb4xBpoCfyVLZW"
},
{
"width": 320,
"height": 221,
"verification": {
"method": "keccak256(bytes)",
"data": "0x272d2e57ae1710ac7c5e3d1c9f9d24f48954ad43d0e821f8bd041a4734e309a5"
},
"url": "ipfs://QmdViKPWYhZv7u86z7HBTgAkTAwEkNSRi1VkYEU8K5yUsH"
},
{
"width": 180,
"height": 124,
"verification": {
"method": "keccak256(bytes)",
"data": "0x1a464ff7e0eff05da98ed309a25195d8666b6211a5dfa2214865c3fd50ead810"
},
"url": "ipfs://QmXZUCW6MqCNfYJEFsi54Vkj6PRrUoiPjzTuA2mWtas3RJ"
}
],
"backgroundImage": [
{
"width": 1800,
"height": 1012,
"verification": {
"method": "keccak256(bytes)",
"data": "0x3f6be73b35d348fb8f0b87a47d8c8b6b9db8858ee044cb13734cdfe5d28031d8"
},
"url": "ipfs://QmfLCPmL31f31RRB4R7yoTg3Hsk5PjrWyS3ZaaYyhRPT4n"
},
{
"width": 1024,
"height": 576,
"verification": {
"method": "keccak256(bytes)",
"data": "0xcb57ed802bcd7dc4964395a609b3a0f557c5f46a602b28b058b9587bb77bb54f"
},
"url": "ipfs://QmPoPEaoGNVYhiMTwBWp6XzLPRXyuLjZWnuMobdCbfqsU9"
},
{
"width": 640,
"height": 360,
"verification": {
"method": "keccak256(bytes)",
"data": "0x57e8039288c3e1a7f891c839e03805984ab36524b710656f072492c1c8ebd967"
},
"url": "ipfs://QmU3pDA4eDNPMeARsJXxKaZsMC5MgFLgzGQccnydbU9WLV"
},
{
"width": 320,
"height": 180,
"verification": {
"method": "keccak256(bytes)",
"data": "0x2bebf9baac33d719bbd3b481b1af468701409ad7578f84be04e8f7563d5a1509"
},
"url": "ipfs://QmcKtenPsRvrqZJQ1gLCdUFkex4i9DGp7RFvucb9nbkzsz"
},
{
"width": 180,
"height": 101,
"verification": {
"method": "keccak256(bytes)",
"data": "0xe32154c03c892d7c41c91220b8757ec5b7847eb2dd91413f7238b0c25f55b475"
},
"url": "ipfs://QmU7ueJ467E9HRahaqQmSPhvkTkMhCLXRxV45P4kmMk6vm"
}
]
}
}
}
]
```

</details>

```typescript title="isDataAuthentic example"
import jsonData from './data.json';

isDataAuthentic(jsonData, {
data: '0xdb864ed42104cee179785036cb4ff1183ebc57e5532ae766ad8533fa48acfbb3',
method: 'keccak256(utf8)',
});
// true

isDataAuthentic(jsonData, {
data: '0xdeadbeef00000000000000000000000000000000000000000000000000000000',
method: 'keccak256(utf8)',
});
// false
```
22 changes: 21 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
generateSchemasFromDynamicKeys,
duplicateMultiTypeERC725SchemaEntry,
getVerificationMethod,
isDataAuthentic,
} from './lib/utils';

import { getSchema } from './lib/schemaParser';
Expand Down Expand Up @@ -93,7 +94,12 @@ export {
};

export { ERC725Config, KeyValuePair, ProviderTypes } from './types';
export { encodeData, encodeArrayKey, getVerificationMethod } from './lib/utils';
export {
encodeData,
encodeArrayKey,
getVerificationMethod,
isDataAuthentic,
} from './lib/utils';
export { decodeData } from './lib/decodeData';
export { encodeKeyName, isDynamicKeyName } from './lib/encodeKeyName';
export { decodeMappingKey } from './lib/decodeMappingKey';
Expand Down Expand Up @@ -797,6 +803,20 @@ export class ERC725 {
| undefined {
return getVerificationMethod(nameOrSig);
}

static isDataAuthentic(
data: string | Uint8Array,
verificationOptions: Verification,
): boolean {
return isDataAuthentic(data, verificationOptions);
}

isDataAuthentic(
data: string | Uint8Array,
verificationOptions: Verification,
): boolean {
return isDataAuthentic(data, verificationOptions);
}
}

export default ERC725;
130 changes: 130 additions & 0 deletions src/lib/getDataFromExternalSources.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,134 @@ describe('getDataFromExternalSources', () => {
);
}).to.not.throw();
});

it("should return the right data when the schema's valueContent is VerifiableURI", async () => {
const schema: ERC725JSONSchema = {
name: 'LSP3Profile',
key: '0x5ef83ad9559033e6e941db7d7c495acdce616347d28e90c7ce47cbfcfcad3bc5',
keyType: 'Singleton',
valueType: 'bytes',
valueContent: 'VerifiableURI',
};

const dataFromChain: DecodeDataOutput[] = [
{
name: 'LSP3Profile',
key: '0x5ef83ad9559033e6e941db7d7c495acdce616347d28e90c7ce47cbfcfcad3bc5',
value: {
verification: {
data: '0xdb864ed42104cee179785036cb4ff1183ebc57e5532ae766ad8533fa48acfbb3',
method: 'keccak256(utf8)',
},
url: 'ipfs://QmdMGUxuQsm1U9Qs8oJSn5PfY4B1apGG75YBRxQPybtRVm',
},
},
];

const result = await getDataFromExternalSources(
[schema],
dataFromChain,
'https://api.universalprofile.cloud/ipfs/',
);

expect(result).to.deep.equal([
{
name: 'LSP3Profile',
key: '0x5ef83ad9559033e6e941db7d7c495acdce616347d28e90c7ce47cbfcfcad3bc5',
value: {
LSP3Profile: {
name: 'test',
description: '',
tags: ['profile'],
links: [],
profileImage: [
{
width: 1024,
height: 709,
verification: {
method: 'keccak256(bytes)',
data: '0x6a0a28680d65b69f5696859be7e0fcebbbcf0df47f1f767926de35402c7d525c',
},
url: 'ipfs://QmVUYyft3j2JVrG4RzDe1Qx7K5gNtJGFhrExHQFeiRXz1C',
},
{
width: 640,
height: 443,
verification: {
method: 'keccak256(bytes)',
data: '0x7cd399f2a2552aa5cd21b1584a98db3efa39c701c311c38a60c680343cfa6d82',
},
url: 'ipfs://QmeU8FUZC9F1qMYmcWyBhfGqaf7g3kLzGb4xBpoCfyVLZW',
},
{
width: 320,
height: 221,
verification: {
method: 'keccak256(bytes)',
data: '0x272d2e57ae1710ac7c5e3d1c9f9d24f48954ad43d0e821f8bd041a4734e309a5',
},
url: 'ipfs://QmdViKPWYhZv7u86z7HBTgAkTAwEkNSRi1VkYEU8K5yUsH',
},
{
width: 180,
height: 124,
verification: {
method: 'keccak256(bytes)',
data: '0x1a464ff7e0eff05da98ed309a25195d8666b6211a5dfa2214865c3fd50ead810',
},
url: 'ipfs://QmXZUCW6MqCNfYJEFsi54Vkj6PRrUoiPjzTuA2mWtas3RJ',
},
],
backgroundImage: [
{
width: 1800,
height: 1012,
verification: {
method: 'keccak256(bytes)',
data: '0x3f6be73b35d348fb8f0b87a47d8c8b6b9db8858ee044cb13734cdfe5d28031d8',
},
url: 'ipfs://QmfLCPmL31f31RRB4R7yoTg3Hsk5PjrWyS3ZaaYyhRPT4n',
},
{
width: 1024,
height: 576,
verification: {
method: 'keccak256(bytes)',
data: '0xcb57ed802bcd7dc4964395a609b3a0f557c5f46a602b28b058b9587bb77bb54f',
},
url: 'ipfs://QmPoPEaoGNVYhiMTwBWp6XzLPRXyuLjZWnuMobdCbfqsU9',
},
{
width: 640,
height: 360,
verification: {
method: 'keccak256(bytes)',
data: '0x57e8039288c3e1a7f891c839e03805984ab36524b710656f072492c1c8ebd967',
},
url: 'ipfs://QmU3pDA4eDNPMeARsJXxKaZsMC5MgFLgzGQccnydbU9WLV',
},
{
width: 320,
height: 180,
verification: {
method: 'keccak256(bytes)',
data: '0x2bebf9baac33d719bbd3b481b1af468701409ad7578f84be04e8f7563d5a1509',
},
url: 'ipfs://QmcKtenPsRvrqZJQ1gLCdUFkex4i9DGp7RFvucb9nbkzsz',
},
{
width: 180,
height: 101,
verification: {
method: 'keccak256(bytes)',
data: '0xe32154c03c892d7c41c91220b8757ec5b7847eb2dd91413f7238b0c25f55b475',
},
url: 'ipfs://QmU7ueJ467E9HRahaqQmSPhvkTkMhCLXRxV45P4kmMk6vm',
},
],
},
},
},
]);
});
});
2 changes: 2 additions & 0 deletions src/lib/getDataFromExternalSources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,14 @@ export const getDataFromExternalSources = (
if (/^(\[.*\]|\{.*\})\s*$/s.test(key)) {
const json = arrToBufArr(receivedData).toString();
const value = JSON.parse(json);

if (isDataAuthentic(value, urlDataWithHash.verification)) {
return { ...dataEntry, value };
}
if (isDataAuthentic(receivedData, urlDataWithHash.verification)) {
return { ...dataEntry, value };
}

throw new Error('result did not correctly validate');
}
} catch {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ export function encodeKeyValue(

/**
*
* @param key A data key either as a 32 bytes long value, or a data key name of keyType = 'Array'
* @param key The schema key of a schema with keyType = 'Array'
* @param index An integer representing the intended array index
* @return The raw bytes key for the array element
*/
Expand Down

0 comments on commit 0c7ba98

Please sign in to comment.