diff --git a/docs/getting-started.md b/docs/getting-started.md index d2527739..28e52c46 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -134,6 +134,10 @@ const verifiableURI = encodeDataSourceWithHash( Try running the code snippets below within your browser using [StackBlitz](https://stackblitz.com/edit/erc725js-instantiation?devtoolsheight=66&file=index.js). ::: +The _erc725.js_ contains multiple functionalities such as reading and decoding data. A full list is available under the [**Methods**](./methods.md) page. + +For fetching data, it is possible to query one data key (as a `string` name) or multiple data keys at once by passing an array parameter, as shown below. + ```js await erc725.getOwner(); // > '0x28D25E70819140daF65b724158D00c373D1a18ee' diff --git a/docs/methods.md b/docs/methods.md index 953f3062..7db0ba5e 100644 --- a/docs/methods.md +++ b/docs/methods.md @@ -3,7 +3,7 @@ sidebar_position: 1 title: 'Methods' --- -import CodeSandbox from "../../../src/components/CodeSandbox"; +import CodeSandbox from "@site/src/components/CodeSandbox"; @@ -508,6 +508,64 @@ ERC725.encodeData( +
+ Encode a tuple of CompactBytesArray + +```ts title="Encode a tuple of CompactBytesArray" +import ERC725 from '@erc725/erc725.js'; + +const schemas = [ +{ + name: 'AddressPermissions:AllowedCalls:
', + key: '0x4b80742de2bf393a64c70000
', + keyType: 'MappingWithGrouping', + valueType: '(bytes4,address,bytes4,bytes4)[CompactBytesArray]', + valueContent: '(BitArray,Address,Bytes4,Bytes4)', + } +]; + +ERC725.encodeData( + [ + { + keyName: 'AddressPermissions:AllowedCalls:
', + dynamicKeyParts: "0xcafecafecafecafecafecafecafecafecafecafe" + value: [ + '0x00000003', // CALL and TRANSFERVALUE + '0xCA41e4ea94c8fA99889c8EA2c8948768cBaf4bc0', // addresses are decoded as checksummed + '0x3e89ad98', // LSP0 interface ID + '0xffffffff', // any function + ], + [ + '0x00000002', // CALL only + '0xF70Ce3b58f275A4c28d06C98615760dDe774DE57', + '0xffffffff', // any standard interface ID + '0x760d9bba', // function selector of `transfer(address,address,uint256,bool,bytes)` + ], + [ + '0x00000001', // TRANSFERVALUE only + '0xd3236aa1B8A4dDe5eA375fd1F2Fb5c354e686c9f', + '0xffffffff', // any standard interface ID + '0xffffffff', // any function + ], + }, + ], + schemas, +); +/** +{ + keys: [ + '0x4b80742de2bf393a64c70000cafecafecafecafecafecafecafecafecafecafe', // -> data key for `AddressPermissions:AllowedCalls:0xcafecafecafecafecafecafecafecafecafecafe` + ], + values: [ + '0x002000000003ca41e4ea94c8fa99889c8ea2c8948768cbaf4bc03e89ad98ffffffff002000000002f70ce3b58f275a4c28d06c98615760dde774de57ffffffff760d9bba002000000001d3236aa1b8a4dde5ea375fd1f2fb5c354e686c9fffffffffffffffff', // (bytes4,address,bytes4,bytes4)[CompactBytesArray] + ], +} +*/ + +``` + +
+ --- ### encodeKeyName @@ -965,6 +1023,61 @@ ERC725.decodeData( */ ``` +#### Tuple of CompactBytesArray Example + +```ts title="Decode a tuple of CompactBytesArray" +import ERC725 from '@erc725/erc725.js'; + +const schemas = [ + { + name: 'AddressPermissions:AllowedCalls:
', + key: '0x4b80742de2bf393a64c70000
', + keyType: 'MappingWithGrouping', + valueType: '(bytes4,address,bytes4,bytes4)[CompactBytesArray]', + valueContent: '(BitArray,Address,Bytes4,Bytes4)', + } +]; + +ERC725.decodeData( + [ + { + keyName: 'AddressPermissions:AllowedCalls:
', + dynamicKeyParts: "0xcafecafecafecafecafecafecafecafecafecafe" + value: '0x002000000003ca41e4ea94c8fa99889c8ea2c8948768cbaf4bc03e89ad98ffffffff002000000002f70ce3b58f275a4c28d06c98615760dde774de57ffffffff760d9bba002000000001d3236aa1b8a4dde5ea375fd1f2fb5c354e686c9fffffffffffffffff' + }, + ], + schemas, +); + +/** +{ + key: '0x4b80742de2bf393a64c70000cafecafecafecafecafecafecafecafecafecafe', + name: 'AddressPermissions:AllowedCalls:cafecafecafecafecafecafecafecafecafecafe', + value: [ + [ + '0x00000003', // CALL and TRANSFERVALUE + '0xCA41e4ea94c8fA99889c8EA2c8948768cBaf4bc0', // addresses are decoded as checksummed + '0x3e89ad98', // LSP0 interface ID + '0xffffffff', // any function + ], + [ + '0x00000002', // CALL only + '0xF70Ce3b58f275A4c28d06C98615760dDe774DE57', + '0xffffffff', // any standard interface ID + '0x760d9bba', // function selector of `transfer(address,address,uint256,bool,bytes)` + ], + [ + '0x00000001', // TRANSFERVALUE only + '0xd3236aa1B8A4dDe5eA375fd1F2Fb5c354e686c9f', + '0xffffffff', // any standard interface ID + '0xffffffff', // any function + ] + ] +} +*/ + +``` + ### decodeValueType ```js diff --git a/docs/schemas.md b/docs/schemas.md index 2f7f0b21..143f2f98 100644 --- a/docs/schemas.md +++ b/docs/schemas.md @@ -4,13 +4,17 @@ sidebar_position: 2 # Schemas -The `@erc725/erc725.js` library contains a range of standard [LSP ERC725 JSON schemas](https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md). +:::info 📄 Schema Specification -Schemas allow erc725.js to know how to decode and encode data written in an [ERC725Y](https://eips.ethereum.org/EIPS/eip-725) smart contract. +For more details on schemas, see the [**official specification** of the LSP2 ERC725 JSON schemas](https://github.com/lukso-network/LIPs/blob/main/LSPs/LSP-2-ERC725YJSONSchema.md) standard specification -_A quick reference for keys used in schema definitions can be seen below_ +::: + +The ⚒️ [erc725.js](https://npmjs.com/package/@erc725/erc725.js) library works with [ERC725Y JSON schemas](../../standards/generic-standards/lsp2-json-schema). These schemas are JSON structures that tell developers and programs how to decode and encode 🗂️ [ERC725Y data keys](../../standards/lsp-background/erc725#erc725y-generic-data-keyvalue-store) from any [ERC725Y](https://eips.ethereum.org/EIPS/eip-725) smart contract.. You need to load the required schemas of the data keys you want to fetch when initializing the `ERC725` class. -[Official Documentation](https://github.com/lukso-network/LIPs/blob/master/LSPs/LSP-2-ERC725YJSONSchema.md). +The most common and standard schemas are [available](../../tools/erc725js/schemas.md) directly within the _erc725.js_ library. But you can also create and load your own ERC725Y JSON schemas if you want to use custom data keys. + +_A quick reference for keys used in schema definitions can be seen below_ - `name`: An arbitrary name - `key`: The sha3 hash of the name diff --git a/examples/package-lock.json b/examples/package-lock.json index 129175bd..334ab741 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -3858,6 +3858,11 @@ "@scure/bip39": "1.2.2" } }, + "../node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "../node_modules/execa": { "version": "5.1.1", "dev": true, @@ -9308,10 +9313,11 @@ } }, "../node_modules/web3-errors": { - "version": "1.1.4", - "license": "LGPL-3.0", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.2.0.tgz", + "integrity": "sha512-58Kczou5zyjcm9LuSs5Hrm6VrG8t9p2J8X0yGArZrhKNPZL66gMGkOUpPx+EopE944Sk4yE+Q25hKv4H5BH+kA==", "dependencies": { - "web3-types": "^1.3.1" + "web3-types": "^1.6.0" }, "engines": { "node": ">=14", @@ -9509,21 +9515,24 @@ } }, "../node_modules/web3-types": { - "version": "1.4.0", - "license": "LGPL-3.0", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.7.0.tgz", + "integrity": "sha512-nhXxDJ7a5FesRw9UG5SZdP/C/3Q2EzHGnB39hkAV+YGXDMgwxBXFWebQLfEzZzuArfHnvC0sQqkIHNwSKcVjdA==", "engines": { "node": ">=14", "npm": ">=6.12.0" } }, "../node_modules/web3-utils": { - "version": "4.2.0", - "license": "LGPL-3.0", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.3.0.tgz", + "integrity": "sha512-fGG2IZr0XB1vEoWZiyJzoy28HpsIfZgz4mgPeQA9aj5rIx8z0o80qUPtIyrCYX/Bo2gYALlV5SWIJWxJNUQn9Q==", "dependencies": { "ethereum-cryptography": "^2.0.0", - "web3-errors": "^1.1.4", - "web3-types": "^1.4.0", - "web3-validator": "^2.0.4" + "eventemitter3": "^5.0.1", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "web3-validator": "^2.0.6" }, "engines": { "node": ">=14", @@ -9531,13 +9540,14 @@ } }, "../node_modules/web3-validator": { - "version": "2.0.4", - "license": "LGPL-3.0", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.6.tgz", + "integrity": "sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==", "dependencies": { "ethereum-cryptography": "^2.0.0", "util": "^0.12.5", - "web3-errors": "^1.1.4", - "web3-types": "^1.3.1", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", "zod": "^3.21.4" }, "engines": { @@ -9652,8 +9662,9 @@ } }, "../node_modules/ws": { - "version": "8.16.0", - "license": "MIT", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, @@ -10593,8 +10604,9 @@ } }, "node_modules/ws": { - "version": "8.16.0", - "license": "MIT", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "engines": { "node": ">=10.0.0" }, diff --git a/package-lock.json b/package-lock.json index 9571819a..d1f0a8bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8596,9 +8596,9 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==" }, "node_modules/path-type": { "version": "4.0.0", diff --git a/package.json b/package.json index 31307b66..eb63fc05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@erc725/erc725.js", - "version": "0.24.0", + "version": "0.27.1", "description": "Library to interact with ERC725 smart contracts", "main": "build/main/src/index.js", "typings": "build/main/src/index.d.ts", diff --git a/src/lib/utils.test.ts b/src/lib/utils.test.ts index 2fabaed1..380921ba 100644 --- a/src/lib/utils.test.ts +++ b/src/lib/utils.test.ts @@ -198,28 +198,31 @@ describe('utils', () => { name: 'AddressPermissions:AllowedCalls:
', key: '0x4b80742de2bf393a64c70000
', keyType: 'MappingWithGrouping', - valueType: '(bytes4,address,bytes4)[CompactBytesArray]', - valueContent: '(Bytes4,Address,Bytes4)', + valueType: '(bytes4,address,bytes4,bytes4)[CompactBytesArray]', + valueContent: '(BitArray,Address,Bytes4,Bytes4)', }, decodedValue: [ [ - '0xcafecafe', - '0xDAFEA492D9c6733ae3d56b7Ed1ADB60692c98Bc5', - '0xcafecafe', + '0x00000003', // CALL and TRANSFERVALUE + '0xCA41e4ea94c8fA99889c8EA2c8948768cBaf4bc0', // addresses are decoded as checksummed + '0x3e89ad98', // LSP0 interface ID + '0xffffffff', // any function ], [ - '0xbeefbeef', - '0xFE31320faF8Da1492Eadf8Deb79bd264D7cF2141', - '0xbeefbeef', + '0x00000002', // CALL only + '0xF70Ce3b58f275A4c28d06C98615760dDe774DE57', + '0xffffffff', // any standard interface ID + '0x760d9bba', // function selector of `transfer(address,address,uint256,bool,bytes)` ], [ - '0xf00df00d', - '0xc527702b14BF2f79F70B32e09F62B6A74cADFd80', - '0xf00df00d', + '0x00000001', // TRANSFERVALUE only + '0xd3236aa1B8A4dDe5eA375fd1F2Fb5c354e686c9f', + '0xffffffff', // any standard interface ID + '0xffffffff', // any function ], ], encodedValue: - '0x001ccafecafeDAFEA492D9c6733ae3d56b7Ed1ADB60692c98Bc5cafecafe001cbeefbeefFE31320faF8Da1492Eadf8Deb79bd264D7cF2141beefbeef001cf00df00dc527702b14BF2f79F70B32e09F62B6A74cADFd80f00df00d'.toLowerCase(), + '0x002000000003ca41e4ea94c8fa99889c8ea2c8948768cbaf4bc03e89ad98ffffffff002000000002f70ce3b58f275a4c28d06c98615760dde774de57ffffffff760d9bba002000000001d3236aa1b8a4dde5ea375fd1f2fb5c354e686c9fffffffffffffffff', }, ]; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 14fa11fc..d156d564 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -550,7 +550,7 @@ export function isDataAuthentic( options: Verification, capture?: string[], ): boolean { - if (!options || !options.method) { + if (!options?.method || options?.method === '0x00000000') { return true; } @@ -613,7 +613,9 @@ export function patchIPFSUrlsIfApplicable( receivedData: URLDataWithHash, ipfsGateway: string, ): URLDataWithHash { - if (receivedData?.url?.indexOf('ipfs://') !== -1) { + // Only map URL if it's indeed an ipfs:// URL and ignore if it's a data:// URL with JSON + // possibly containing an IPFS URL inside of the JSON data. + if (receivedData?.url?.startsWith('ipfs://')) { return { ...receivedData, url: receivedData.url.replace('ipfs://', ipfsGateway), diff --git a/src/types/decodeData.ts b/src/types/decodeData.ts index 057b65c5..66539731 100644 --- a/src/types/decodeData.ts +++ b/src/types/decodeData.ts @@ -4,7 +4,7 @@ import { EncodeDataType, URLDataWithHash } from './encodeData/JSONURL'; export interface DataInput { keyName: string; // can be the name or the hex/hash value; - dynamicKeyParts?: string | string[]; + dynamicKeyParts?: string | string[] | number; totalArrayLength?: number; startingIndex?: number; }