From e5643c819ca8208d5e1b9a61bf5ba7e3502f785d Mon Sep 17 00:00:00 2001 From: "b00ste.lyx" <62855857+b00ste@users.noreply.github.com> Date: Tue, 30 Jul 2024 15:00:55 +0300 Subject: [PATCH] Create page for LSP4 Metadata encoding (#116) --- .github/workflows/ci.yaml | 3 + .github/workflows/deploy.yaml | 3 + .gitignore | 5 +- components/AddressButtons/AddressButtons.tsx | 2 +- components/AddressInfos/AddressInfos.tsx | 8 +- components/ContractOwner/ContractOwner.tsx | 6 +- .../ControllersList/ControllersList.tsx | 6 +- components/DataKeysTable/DataKeysTable.tsx | 8 +- components/Decode/Decode.tsx | 4 +- components/Encode/Encode.tsx | 2 +- .../Encode/components/EncodeExecute.tsx | 2 +- .../Encode/components/EncodeSetData.tsx | 2 +- .../components/EncodeTransferOwnership.tsx | 2 +- .../KeyManagerNonceChecker.tsx | 4 +- .../KeyManagerPermissions.tsx | 2 +- components/NavBar/NavBar.tsx | 172 ++-- .../NetworksSwitch/NetworksSwitch.tsx | 6 +- .../SampleAddressInput/SampleAddressInput.tsx | 4 +- .../ValueTypeDecoder/ValueTypeDecoder.tsx | 10 +- contexts/NetworksContext.tsx | 4 +- hooks/useWeb3.ts | 2 +- next.config.js | 20 + package-lock.json | 528 +++++++++++- package.json | 8 + pages/_app.tsx | 16 +- pages/abi-encoder.tsx | 6 +- pages/data-fetcher.tsx | 10 +- pages/index.tsx | 4 +- pages/inspector.tsx | 18 +- pages/key-manager.tsx | 4 +- pages/lsp-checker.tsx | 6 +- pages/lsp2-encoder.tsx | 2 +- pages/lsp4-metadata-encoder.tsx | 758 ++++++++++++++++++ styles/globals.scss | 2 +- tsconfig.json | 5 +- utils/web3.ts | 4 +- 36 files changed, 1513 insertions(+), 135 deletions(-) create mode 100644 pages/lsp4-metadata-encoder.tsx diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5698114..de9618a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,6 +5,9 @@ on: branches: - main +env: + SHARED_KEY: ${{ secrets.SHARED_KEY }} + jobs: build-and-lint: runs-on: ubuntu-latest diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 82e8bde..47cf433 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -4,6 +4,9 @@ on: push: branches: [main] +env: + SHARED_KEY: ${{ secrets.SHARED_KEY }} + jobs: build-and-deploy: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 88b6f0d..08ea45f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,10 +25,7 @@ yarn-debug.log* yarn-error.log* # local env files -.env.local -.env.development.local -.env.test.local -.env.production.local +.env* # vercel .vercel diff --git a/components/AddressButtons/AddressButtons.tsx b/components/AddressButtons/AddressButtons.tsx index e5e7e48..4edd2fa 100644 --- a/components/AddressButtons/AddressButtons.tsx +++ b/components/AddressButtons/AddressButtons.tsx @@ -3,7 +3,7 @@ * @author Felix Hildebrandt */ import React, { useContext } from 'react'; -import { NetworkContext } from '../../contexts/NetworksContext'; +import { NetworkContext } from '@/contexts/NetworksContext'; interface Props { address: string; diff --git a/components/AddressInfos/AddressInfos.tsx b/components/AddressInfos/AddressInfos.tsx index 36679e3..ba392ab 100644 --- a/components/AddressInfos/AddressInfos.tsx +++ b/components/AddressInfos/AddressInfos.tsx @@ -5,15 +5,15 @@ import React, { useState, useContext, useEffect } from 'react'; import Skeleton from 'react-loading-skeleton'; import { ERC725YDataKeys } from '@lukso/lsp-smart-contracts'; -import { NetworkContext } from '../../contexts/NetworksContext'; -import useWeb3 from '../../hooks/useWeb3'; +import { NetworkContext } from '@/contexts/NetworksContext'; +import useWeb3 from '@/hooks/useWeb3'; import { EXPLORER_BASE_URL, LSP1_DELEGATE_VERSIONS, LSP1_GRAVE_FORWARDER, UP_RECOVERY_ADDRESSES, -} from '../../globals'; -import { checkInterface, getData, checkIsGnosisSafe } from '../../utils/web3'; +} from '@/globals'; +import { checkInterface, getData, checkIsGnosisSafe } from '@/utils/web3'; import LSP7Artifact from '@lukso/lsp-smart-contracts/artifacts/LSP7DigitalAsset.json'; import { AbiItem } from 'web3-utils'; diff --git a/components/ContractOwner/ContractOwner.tsx b/components/ContractOwner/ContractOwner.tsx index 4ec8bdc..18f1de3 100644 --- a/components/ContractOwner/ContractOwner.tsx +++ b/components/ContractOwner/ContractOwner.tsx @@ -1,11 +1,11 @@ import { useState, useEffect } from 'react'; import ERC725Account from '@lukso/lsp-smart-contracts/artifacts/LSP0ERC725Account.json'; -import useWeb3 from '../../hooks/useWeb3'; +import useWeb3 from '@/hooks/useWeb3'; -import { eip165ABI } from '../../constants'; +import { eip165ABI } from '@/constants'; import { AbiItem, isAddress } from 'web3-utils'; import { INTERFACE_IDS } from '@lukso/lsp-smart-contracts'; -import AddressButtons from '../AddressButtons'; +import AddressButtons from '@/components/AddressButtons'; type Props = { contractAddress: string; diff --git a/components/ControllersList/ControllersList.tsx b/components/ControllersList/ControllersList.tsx index 4e93003..2d711c9 100644 --- a/components/ControllersList/ControllersList.tsx +++ b/components/ControllersList/ControllersList.tsx @@ -1,9 +1,9 @@ import React, { useEffect, useState } from 'react'; import ERC725, { encodeArrayKey, encodeKeyName } from '@erc725/erc725.js'; -import { getDataBatch } from '../../utils/web3'; -import useWeb3 from '../../hooks/useWeb3'; -import AddressInfos from '../AddressInfos'; +import { getDataBatch } from '@/utils/web3'; +import useWeb3 from '@/hooks/useWeb3'; +import AddressInfos from '@/components/AddressInfos'; import { ERC725YDataKeys } from '@lukso/lsp-smart-contracts'; interface Props { diff --git a/components/DataKeysTable/DataKeysTable.tsx b/components/DataKeysTable/DataKeysTable.tsx index 12616b0..fcc21e4 100644 --- a/components/DataKeysTable/DataKeysTable.tsx +++ b/components/DataKeysTable/DataKeysTable.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useState } from 'react'; import { ERC725JSONSchema } from '@erc725/erc725.js'; -import AddressButtons from '../AddressButtons'; -import ValueTypeDecoder from '../ValueTypeDecoder'; +import AddressButtons from '@/components/AddressButtons'; +import ValueTypeDecoder from '@/components/ValueTypeDecoder'; import ProfileSchema from './ProfileSchema.json'; import AssetSchema from './AssetSchema.json'; @@ -10,9 +10,9 @@ import LSP8Schema from './LSP8Schema.json'; import { SCHEMA_DOCS_LINKS, SchemaName } from './schemas'; -import { getDataBatch } from '../../utils/web3'; +import { getDataBatch } from '@/utils/web3'; -import useWeb3 from '../../hooks/useWeb3'; +import useWeb3 from '@/hooks/useWeb3'; interface Props { address: string; diff --git a/components/Decode/Decode.tsx b/components/Decode/Decode.tsx index efdaa45..17fb329 100644 --- a/components/Decode/Decode.tsx +++ b/components/Decode/Decode.tsx @@ -3,8 +3,8 @@ import Web3 from 'web3'; import { TRANSACTION_SELECTORS, TRANSACTION_TYPES, -} from '../../interfaces/transaction'; -import ErrorMessage from '../ErrorMessage/ErrorMessage'; +} from '@/interfaces/transaction'; +import ErrorMessage from '@/components/ErrorMessage'; import styles from './Decode.module.scss'; interface Props { diff --git a/components/Encode/Encode.tsx b/components/Encode/Encode.tsx index daaa6f9..21613a6 100644 --- a/components/Encode/Encode.tsx +++ b/components/Encode/Encode.tsx @@ -6,7 +6,7 @@ import EncodeSetData from './components/EncodeSetData'; import EncodeTransferOwnership from './components/EncodeTransferOwnership'; import styles from './Encode.module.scss'; -import { TRANSACTION_TYPES } from '../../interfaces/transaction'; +import { TRANSACTION_TYPES } from '@/interfaces/transaction'; interface Props { web3: Web3; diff --git a/components/Encode/components/EncodeExecute.tsx b/components/Encode/components/EncodeExecute.tsx index 0e0fe18..02c3184 100644 --- a/components/Encode/components/EncodeExecute.tsx +++ b/components/Encode/components/EncodeExecute.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import Web3 from 'web3'; import EncodedPayload from './EncodedPayload'; import ERC725Account from '@lukso/lsp-smart-contracts/artifacts/LSP0ERC725Account.json'; -import ErrorMessage from '../../ErrorMessage'; +import ErrorMessage from '@/components/ErrorMessage'; import styles from './EncodeExecute.module.scss'; interface Props { diff --git a/components/Encode/components/EncodeSetData.tsx b/components/Encode/components/EncodeSetData.tsx index 251c294..bfed35b 100644 --- a/components/Encode/components/EncodeSetData.tsx +++ b/components/Encode/components/EncodeSetData.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import Web3 from 'web3'; import EncodedPayload from './EncodedPayload'; import ERC725Account from '@lukso/lsp-smart-contracts/artifacts/LSP0ERC725Account.json'; -import ErrorMessage from '../../ErrorMessage'; +import ErrorMessage from '@/components/ErrorMessage'; import { AbiItem } from 'web3-utils'; import styles from './EncodeSetData.module.scss'; diff --git a/components/Encode/components/EncodeTransferOwnership.tsx b/components/Encode/components/EncodeTransferOwnership.tsx index 154bc4b..fa8754c 100644 --- a/components/Encode/components/EncodeTransferOwnership.tsx +++ b/components/Encode/components/EncodeTransferOwnership.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import Web3 from 'web3'; import EncodedPayload from './EncodedPayload'; import ERC725Account from '@lukso/lsp-smart-contracts/artifacts/LSP0ERC725Account.json'; -import ErrorMessage from '../../ErrorMessage'; +import ErrorMessage from '@/components/ErrorMessage'; import { Contract } from 'web3-eth-contract'; import styles from './EncodeTransferOwnership.module.scss'; interface Props { diff --git a/components/KeyManagerNonceChecker/KeyManagerNonceChecker.tsx b/components/KeyManagerNonceChecker/KeyManagerNonceChecker.tsx index 2176f53..6a47645 100644 --- a/components/KeyManagerNonceChecker/KeyManagerNonceChecker.tsx +++ b/components/KeyManagerNonceChecker/KeyManagerNonceChecker.tsx @@ -3,8 +3,8 @@ import { useContext, useState } from 'react'; import LSP6KeyManager from '@lukso/lsp-smart-contracts/artifacts/LSP6KeyManager.json'; -import useWeb3 from '../../hooks/useWeb3'; -import { NetworkContext } from '../../contexts/NetworksContext'; +import useWeb3 from '@/hooks/useWeb3'; +import { NetworkContext } from '@/contexts/NetworksContext'; const KeyManagerNonceChecker: React.FC = () => { const web3 = useWeb3(); diff --git a/components/KeyManagerPermissions/KeyManagerPermissions.tsx b/components/KeyManagerPermissions/KeyManagerPermissions.tsx index 8483913..a109de7 100644 --- a/components/KeyManagerPermissions/KeyManagerPermissions.tsx +++ b/components/KeyManagerPermissions/KeyManagerPermissions.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import ERC725 from '@erc725/erc725.js'; -import PermissionsBtns from '../PermissionsBtns'; +import PermissionsBtns from '@/components/PermissionsBtns'; const KeyManagerPermissions: React.FC = () => { const initialEncodedPermissions = diff --git a/components/NavBar/NavBar.tsx b/components/NavBar/NavBar.tsx index ddbd1c9..5731080 100644 --- a/components/NavBar/NavBar.tsx +++ b/components/NavBar/NavBar.tsx @@ -4,9 +4,116 @@ */ import React, { useState } from 'react'; import Link from 'next/link'; -import { useRouter } from 'next/router'; +import { NextRouter, useRouter } from 'next/router'; import NetworkSwitch from './components/NetworksSwitch'; import styles from './NavBar.module.scss'; +import clsx from 'clsx'; + +const LinksMenu = ({ + router, + createLink, +}: { + router: NextRouter; + createLink: (path: string) => string; +}) => { + const [isActive, setIsActive] = useState(false); + + return ( +
+
+ setIsActive(!isActive)} + > + Menu + +
+ +
+ ); +}; const NavBar: React.FC = () => { const [isActive, setIsActive] = useState(false); @@ -16,7 +123,7 @@ const NavBar: React.FC = () => { setIsActive(!isActive); }; - const createLink = (path) => { + const createLink = (path: string) => { if (typeof window === 'undefined') { return path; } @@ -42,7 +149,7 @@ const NavBar: React.FC = () => { - - - πŸ”Ž Inspector - - - - - βœ… LSP Checker - - - - - πŸ’½ Data Fetcher - - - - - πŸ” Key Manager - - - - - πŸ“œ ABI Encoder - - - - - πŸ“– LSP2 Encoder - -
-
- -
+ +
(); diff --git a/next.config.js b/next.config.js index 3dd7ef1..be8dfea 100644 --- a/next.config.js +++ b/next.config.js @@ -1,4 +1,24 @@ /** @type {import('next').NextConfig} */ + +const webpack = require('webpack'); + module.exports = { reactStrictMode: true, + webpack: (config) => { + config.resolve.fallback = { + fs: false, + net: false, + worker_threads: false, + }; + config.plugins.push( + new webpack.NormalModuleReplacementPlugin(/^node:/, (resource) => { + resource.request = resource.request.replace(/^node:/, ''); + }), + ); + + return config; + }, + env: { + SHARED_KEY: process.env.SHARED_KEY, + }, }; diff --git a/package-lock.json b/package-lock.json index 9d72d94..90e0a1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,21 @@ "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", "@erc725/erc725.js": "^0.27.0", + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.2", + "@lukso/data-provider-base": "^0.1.0", "@lukso/lsp-factory.js": "^3.2.1", "@lukso/lsp-smart-contracts": "^0.15.0", "@lukso/lsp-utils": "^0.2.0", + "clsx": "^2.1.1", "i": "^0.3.7", + "image-size": "^1.1.1", "next": "^12.1.6", "npm": "^9.6.0", "react": "17.0.2", "react-dom": "17.0.2", + "react-file-icon": "^1.5.0", "react-loading-skeleton": "^3.4.0", "sass": "^1.58.3", "web3": "^1.6.1", @@ -25,6 +32,7 @@ "devDependencies": { "@types/node": "17.0.5", "@types/react": "17.0.38", + "@types/react-file-icon": "^1.0.4", "@typescript-eslint/eslint-plugin": "^5.9.1", "bulma": "^0.9.3", "eslint": "8.5.0", @@ -1883,6 +1891,51 @@ "@ethersproject/strings": "^5.7.0" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz", + "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz", + "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz", + "integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.5.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -1963,6 +2016,35 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lukso/data-provider-base": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@lukso/data-provider-base/-/data-provider-base-0.1.0.tgz", + "integrity": "sha512-AgfyYj7r+3IdC/4nqrjf4cJwkdcRWX0vky5GtkKGKOkCex+Ajq0P1dfSz/AxcRkLKTchzVrnW1F2+s2lTMxISQ==", + "dependencies": { + "@ethersproject/keccak256": "^5.7.0", + "@types/jsonwebtoken": "^9.0.6", + "formdata-node": "^6.0.3", + "jsonwebtoken": "^9.0.2", + "node-fetch": "^3.3.2" + } + }, + "node_modules/@lukso/data-provider-base/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/@lukso/lsp-factory.js": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@lukso/lsp-factory.js/-/lsp-factory.js-3.3.1.tgz", @@ -3657,6 +3739,14 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -3710,6 +3800,15 @@ "csstype": "^3.0.2" } }, + "node_modules/@types/react-file-icon": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/react-file-icon/-/react-file-icon-1.0.4.tgz", + "integrity": "sha512-c1mIklUDaxm9odxf8RTiy/EAxsblZliJ86EKIOAyuafP9eK3iudyn4ATv53DX6ZvgGymc7IttVNm97LTGnTiYA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -4768,6 +4867,11 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-to-arraybuffer": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", @@ -5090,6 +5194,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -5426,6 +5538,14 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -5672,6 +5792,14 @@ "safer-buffer": "^2.1.0" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -7293,6 +7421,28 @@ "reusify": "^1.0.4" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -7424,6 +7574,25 @@ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==" }, + "node_modules/formdata-node": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", + "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==", + "engines": { + "node": ">= 18" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -7992,6 +8161,20 @@ "node": ">= 4" } }, + "node_modules/image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, "node_modules/immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", @@ -8879,6 +9062,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -8908,6 +9112,25 @@ "node": ">=4.0" } }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/keccak": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", @@ -9100,6 +9323,36 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -9111,6 +9364,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -10722,6 +10980,24 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "name": "@achingbrain/node-fetch", "version": "2.6.7", @@ -14199,7 +14475,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -14297,6 +14572,14 @@ "node": ">=0.10.0" } }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -14393,6 +14676,19 @@ "react": "17.0.2" } }, + "node_modules/react-file-icon": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-file-icon/-/react-file-icon-1.5.0.tgz", + "integrity": "sha512-6K2/nAI69CS838HOS+4S95MLXwf1neWywek1FgqcTFPTYjnM8XT7aBLz4gkjoqQKY9qPhu3A2tu+lvxhmZYY9w==", + "dependencies": { + "colord": "^2.9.3", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "^18.0.0 || ^17.0.0 || ^16.2.0", + "react-dom": "^18.0.0 || ^17.0.0 || ^16.2.0" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -16037,6 +16333,14 @@ "extsprintf": "^1.2.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "engines": { + "node": ">= 8" + } + }, "node_modules/web3": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.4.tgz", @@ -17913,6 +18217,35 @@ "@ethersproject/strings": "^5.7.0" } }, + "@fortawesome/fontawesome-common-types": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz", + "integrity": "sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz", + "integrity": "sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.5.2" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz", + "integrity": "sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.5.2" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "requires": { + "prop-types": "^15.8.1" + } + }, "@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -17981,6 +18314,30 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "@lukso/data-provider-base": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@lukso/data-provider-base/-/data-provider-base-0.1.0.tgz", + "integrity": "sha512-AgfyYj7r+3IdC/4nqrjf4cJwkdcRWX0vky5GtkKGKOkCex+Ajq0P1dfSz/AxcRkLKTchzVrnW1F2+s2lTMxISQ==", + "requires": { + "@ethersproject/keccak256": "^5.7.0", + "@types/jsonwebtoken": "^9.0.6", + "formdata-node": "^6.0.3", + "jsonwebtoken": "^9.0.2", + "node-fetch": "^3.3.2" + }, + "dependencies": { + "node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + } + } + }, "@lukso/lsp-factory.js": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@lukso/lsp-factory.js/-/lsp-factory.js-3.3.1.tgz", @@ -19270,6 +19627,14 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/jsonwebtoken": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.6.tgz", + "integrity": "sha512-/5hndP5dCjloafCXns6SZyESp3Ldq7YjH3zwzwczYnjxIT0Fqzk5ROSYVGfFyczIue7IUEj8hkvLbPoLQ18vQw==", + "requires": { + "@types/node": "*" + } + }, "@types/keyv": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", @@ -19323,6 +19688,15 @@ "csstype": "^3.0.2" } }, + "@types/react-file-icon": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/react-file-icon/-/react-file-icon-1.0.4.tgz", + "integrity": "sha512-c1mIklUDaxm9odxf8RTiy/EAxsblZliJ86EKIOAyuafP9eK3iudyn4ATv53DX6ZvgGymc7IttVNm97LTGnTiYA==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -20093,6 +20467,11 @@ "ieee754": "^1.2.1" } }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "buffer-to-arraybuffer": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", @@ -20324,6 +20703,11 @@ "mimic-response": "^1.0.0" } }, + "clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -20588,6 +20972,11 @@ "assert-plus": "^1.0.0" } }, + "data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -20761,6 +21150,14 @@ "safer-buffer": "^2.1.0" } }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -22168,6 +22565,15 @@ "reusify": "^1.0.4" } }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -22269,6 +22675,19 @@ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==" }, + "formdata-node": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-6.0.3.tgz", + "integrity": "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg==" + }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "requires": { + "fetch-blob": "^3.1.2" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -22671,6 +23090,14 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==" }, + "image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "requires": { + "queue": "6.0.2" + } + }, "immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", @@ -23361,6 +23788,23 @@ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==" }, + "jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + } + }, "jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -23384,6 +23828,25 @@ "object.values": "^1.1.6" } }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "keccak": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", @@ -23560,6 +24023,36 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -23571,6 +24064,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -24594,6 +25092,11 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==" + }, "node-fetch": { "version": "npm:@achingbrain/node-fetch@2.6.7", "resolved": "https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz", @@ -26848,7 +27351,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -26926,6 +27428,14 @@ "strict-uri-encode": "^1.0.0" } }, + "queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "requires": { + "inherits": "~2.0.3" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -26989,6 +27499,15 @@ "scheduler": "^0.20.2" } }, + "react-file-icon": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-file-icon/-/react-file-icon-1.5.0.tgz", + "integrity": "sha512-6K2/nAI69CS838HOS+4S95MLXwf1neWywek1FgqcTFPTYjnM8XT7aBLz4gkjoqQKY9qPhu3A2tu+lvxhmZYY9w==", + "requires": { + "colord": "^2.9.3", + "prop-types": "^15.7.2" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -28186,6 +28705,11 @@ "extsprintf": "^1.2.0" } }, + "web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" + }, "web3": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/web3/-/web3-1.10.4.tgz", diff --git a/package.json b/package.json index 515ee6f..4780919 100644 --- a/package.json +++ b/package.json @@ -18,14 +18,21 @@ "@emotion/react": "^11.7.1", "@emotion/styled": "^11.6.0", "@erc725/erc725.js": "^0.27.0", + "@fortawesome/fontawesome-svg-core": "^6.5.2", + "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@fortawesome/react-fontawesome": "^0.2.2", + "@lukso/data-provider-base": "^0.1.0", "@lukso/lsp-factory.js": "^3.2.1", "@lukso/lsp-smart-contracts": "^0.15.0", "@lukso/lsp-utils": "^0.2.0", + "clsx": "^2.1.1", "i": "^0.3.7", + "image-size": "^1.1.1", "next": "^12.1.6", "npm": "^9.6.0", "react": "17.0.2", "react-dom": "17.0.2", + "react-file-icon": "^1.5.0", "react-loading-skeleton": "^3.4.0", "sass": "^1.58.3", "web3": "^1.6.1", @@ -34,6 +41,7 @@ "devDependencies": { "@types/node": "17.0.5", "@types/react": "17.0.38", + "@types/react-file-icon": "^1.0.4", "@typescript-eslint/eslint-plugin": "^5.9.1", "bulma": "^0.9.3", "eslint": "8.5.0", diff --git a/pages/_app.tsx b/pages/_app.tsx index c226cf8..1100c6b 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,10 +1,20 @@ -import '../styles/globals.scss'; +import '@/styles/globals.scss'; import 'react-loading-skeleton/dist/skeleton.css'; import type { AppProps } from 'next/app'; -import NavBar from '../components/NavBar'; -import NetworksProvider from '../contexts/NetworksContext'; +import NavBar from '@/components/NavBar'; +import NetworksProvider from '@/contexts/NetworksContext'; + +// icons +import { library } from '@fortawesome/fontawesome-svg-core'; +import { + faPlusCircle, + faMinusCircle, + faUpload, + faAngleDown, +} from '@fortawesome/free-solid-svg-icons'; +library.add(faUpload, faPlusCircle, faMinusCircle, faAngleDown); function MyApp({ Component, pageProps }: AppProps) { return ( diff --git a/pages/abi-encoder.tsx b/pages/abi-encoder.tsx index 82a9490..9347f7d 100644 --- a/pages/abi-encoder.tsx +++ b/pages/abi-encoder.tsx @@ -2,9 +2,9 @@ import { NextPage } from 'next'; import Head from 'next/head'; import { useState } from 'react'; -import Decode from '../components/Decode'; -import Encode from '../components/Encode'; -import useWeb3 from '../hooks/useWeb3'; +import Decode from '@/components/Decode'; +import Encode from '@/components/Encode'; +import useWeb3 from '@/hooks/useWeb3'; enum TX_PARSER_MODES { ENCODE = 'ENCODE', diff --git a/pages/data-fetcher.tsx b/pages/data-fetcher.tsx index b2f310f..b7e9e9e 100644 --- a/pages/data-fetcher.tsx +++ b/pages/data-fetcher.tsx @@ -20,12 +20,12 @@ import LSP10DataKeys from '@erc725/erc725.js/schemas/LSP10ReceivedVaults.json'; import LSP12DataKeys from '@erc725/erc725.js/schemas/LSP12IssuedAssets.json'; import LSP17DataKeys from '@erc725/erc725.js/schemas/LSP17ContractExtension.json'; -import { checkInterface, getData } from '../utils/web3'; -import useWeb3 from '../hooks/useWeb3'; +import { checkInterface, getData } from '@/utils/web3'; +import useWeb3 from '@/hooks/useWeb3'; -import SampleAddressInput from '../components/SampleAddressInput/SampleAddressInput'; -import { SAMPLE_ADDRESS } from '../constants'; -import { NetworkContext } from '../contexts/NetworksContext'; +import SampleAddressInput from '@/components/SampleAddressInput/SampleAddressInput'; +import { SAMPLE_ADDRESS } from '@/constants'; +import { NetworkContext } from '@/contexts/NetworksContext'; import { useRouter } from 'next/router'; import { isValidTuple } from '@erc725/erc725.js/build/main/src/lib/decodeData'; diff --git a/pages/index.tsx b/pages/index.tsx index 584de0d..7254f02 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,7 +1,7 @@ import type { NextPage } from 'next'; import Head from 'next/head'; -import packageJson from '../package.json'; -import CardContainer from '../components/CardContainer'; +import packageJson from '@/package.json'; +import CardContainer from '@/components/CardContainer'; const ERC725_JS_VERSION = packageJson.dependencies['@erc725/erc725.js']; const LSP_SMART_CONTRACTS_VERSION = diff --git a/pages/inspector.tsx b/pages/inspector.tsx index d68c960..e9cf19d 100644 --- a/pages/inspector.tsx +++ b/pages/inspector.tsx @@ -7,17 +7,17 @@ import Head from 'next/head'; import React, { useContext, useEffect, useState } from 'react'; import { isAddress } from 'web3-utils'; -import '../styles/Inspect.module.css'; -import { checkInterface, getVersion } from '../utils/web3'; +import '@/styles/Inspect.module.css'; +import { checkInterface, getVersion } from '@/utils/web3'; -import DataKeysTable from '../components/DataKeysTable'; -import AddressButtons from '../components/AddressButtons'; -import SampleAddressInput from '../components/SampleAddressInput/SampleAddressInput'; -import { NetworkContext } from '../contexts/NetworksContext'; +import DataKeysTable from '@/components/DataKeysTable'; +import AddressButtons from '@/components/AddressButtons'; +import SampleAddressInput from '@/components/SampleAddressInput/SampleAddressInput'; +import { NetworkContext } from '@/contexts/NetworksContext'; -import ContractOwner from '../components/ContractOwner'; -import useWeb3 from '../hooks/useWeb3'; -import { SAMPLE_ADDRESS } from '../constants'; +import ContractOwner from '@/components/ContractOwner'; +import useWeb3 from '@/hooks/useWeb3'; +import { SAMPLE_ADDRESS } from '@/constants'; const Home: NextPage = () => { const router = useRouter(); diff --git a/pages/key-manager.tsx b/pages/key-manager.tsx index 966e252..64b5764 100644 --- a/pages/key-manager.tsx +++ b/pages/key-manager.tsx @@ -1,8 +1,8 @@ import type { NextPage } from 'next'; import Head from 'next/head'; -import KeyManagerNonceChecker from '../components/KeyManagerNonceChecker'; -import KeyManagerPermissions from '../components/KeyManagerPermissions'; +import KeyManagerNonceChecker from '@/components/KeyManagerNonceChecker'; +import KeyManagerPermissions from '@/components/KeyManagerPermissions'; const KeyManager: NextPage = () => { return ( diff --git a/pages/lsp-checker.tsx b/pages/lsp-checker.tsx index bc0d6fa..895c948 100644 --- a/pages/lsp-checker.tsx +++ b/pages/lsp-checker.tsx @@ -11,9 +11,9 @@ import { import LSP3Schema from '@erc725/erc725.js/schemas/LSP3ProfileMetadata.json'; import LSP6Schema from '@erc725/erc725.js/schemas/LSP6KeyManager.json'; -import SampleAddressInput from '../components/SampleAddressInput'; -import useWeb3 from '../hooks/useWeb3'; -import { checkInterface, getDataBatch } from '../utils/web3'; +import SampleAddressInput from '@/components/SampleAddressInput'; +import useWeb3 from '@/hooks/useWeb3'; +import { checkInterface, getDataBatch } from '@/utils/web3'; import { isAddress, keccak256, stripHexPrefix } from 'web3-utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires diff --git a/pages/lsp2-encoder.tsx b/pages/lsp2-encoder.tsx index a42f92a..7fbc3a5 100644 --- a/pages/lsp2-encoder.tsx +++ b/pages/lsp2-encoder.tsx @@ -1,5 +1,5 @@ import { NextPage } from 'next'; -import Lsp2Coder from '../components/Lsp2Coder'; +import Lsp2Coder from '@/components/Lsp2Coder'; const Lsp2CoderPage: NextPage = () => { return ; diff --git a/pages/lsp4-metadata-encoder.tsx b/pages/lsp4-metadata-encoder.tsx new file mode 100644 index 0000000..c1ad1be --- /dev/null +++ b/pages/lsp4-metadata-encoder.tsx @@ -0,0 +1,758 @@ +import Head from 'next/head'; +import { NextPage } from 'next'; +import { ChangeEvent, useState } from 'react'; +import clsx from 'clsx'; +import sizeOf from 'image-size'; +import { keccak256 } from 'web3-utils'; +import ERC725 from '@erc725/erc725.js'; +import LSP4Schema from '@erc725/erc725.js/schemas/LSP4DigitalAsset.json'; +import { + LSP4DigitalAssetMetadataJSON, + AssetMetadata, + ImageMetadata, + LinkMetadata, + AttributeMetadata, +} from '@lukso/lsp-smart-contracts'; + +// components +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { FileIcon, IconType } from 'react-file-icon'; +import { AuthenticatedFormDataUploader } from '@lukso/data-provider-base'; + +const erc725js = new ERC725(LSP4Schema); + +const gateway = 'https://api.universalprofile.cloud/api/v0/add'; +const sharedKey = Buffer.from( + process.env.SHARED_KEY as string, + 'base64', +).toString(); + +interface FileDetails { + name: string; + type: string; + hash: string; + buffer: Buffer; +} + +type ImageDetails = FileDetails & { + image: string; + width: number; + height: number; +}; + +const FileSelect = ({ + file, + inputText, + choose, +}: { + file: FileDetails | undefined; + inputText: string; + choose: (event: ChangeEvent) => Promise; +}) => { + return ( +
+ +
+ ); +}; + +const UploadedFile = ({ + file: { image, name, type }, + remove, + addToList, +}: { + file: FileDetails & { image?: string }; + remove: () => void; + addToList?: () => void; +}) => { + return ( +
+ {image ? ( + + ) : ( +
+ +
+ )} + +

{name}

+ {addToList ? ( +
+ + +
+ ) : ( + + )} +
+ ); +}; + +const AttributeTypeSelect = ({ + selectedType, + onChange, +}: { + selectedType: 'string' | 'number' | 'boolean'; + onChange: (type: string) => void; +}) => { + const [isActive, setIsActive] = useState(false); + const [text, setText] = useState(selectedType); + + return ( +
+
+ +
+ +
+ ); +}; + +const Lsp4MetadataEncoderPage: NextPage = () => { + const dataProvider = new AuthenticatedFormDataUploader(gateway, sharedKey); + + const [name, setName] = useState(''); + const [description, setDescription] = useState(''); + + const [links, setLinks] = useState([{ title: '', url: '' }]); + + const [attributes, setAttributes] = useState([ + { key: '', value: '', type: '' }, + ]); + + const [icons, setIcons] = useState([]); + const [selectedIcon, setSelectedIcon] = useState(); + + const [images, setImages] = useState([]); + const [selectedImage, setSelectedImage] = useState(); + + const [assets, setAssets] = useState([]); + const [selectedAsset, setSelectedAsset] = useState(); + + const [uploadStatus, setUploadStatus] = useState<0 | 1 | 2>(0); + const [verifiableUri, setVerifiableUri] = useState(''); + + const eventToFile = async (event: ChangeEvent) => { + if (event.target.files?.length) { + const file = event.target.files[0]; + const { name, type } = file; + const arrayBufferFile = await file.arrayBuffer(); + const buffer = Buffer.from(arrayBufferFile); + const hash = keccak256(`0x${buffer.toString('hex')}`); + + return { name, type, hash, buffer }; + } + }; + + const iconSelect = async (event: ChangeEvent) => { + const result = await eventToFile(event); + if (result) { + const { name, type, hash, buffer } = result; + + if (!type.startsWith('image/')) { + return; + } + + const image = `data:${type};base64,${buffer.toString('base64')}`; + const { height, width } = sizeOf(buffer); + + if (!height || !width) { + return; + } + + setSelectedIcon({ name, type, hash, buffer, image, width, height }); + } + }; + + const imageSelect = async (event: ChangeEvent) => { + const result = await eventToFile(event); + if (result) { + const { name, type, hash, buffer } = result; + + if (!type.startsWith('image/')) { + return; + } + + const image = `data:${type};base64,${buffer.toString('base64')}`; + const { height, width } = sizeOf(buffer); + + if (!height || !width) { + return; + } + + setSelectedImage({ name, type, hash, buffer, image, width, height }); + } + }; + + const assetSelect = async (event: ChangeEvent) => { + const result = await eventToFile(event); + if (result) { + const { name, type, hash, buffer } = result; + + setSelectedAsset({ name, type, hash, buffer }); + } + }; + + const upload = async () => { + setUploadStatus(1); + + const encodedIcons: ImageMetadata[] = []; + for (const { buffer, width, height } of icons) { + const { url, hash } = await dataProvider.upload(new Blob([buffer])); + + encodedIcons.push({ + width, + height, + url, + verification: { + method: 'keccak256(bytes)', + data: hash, + }, + }); + } + + const encodedImages: ImageMetadata[] = []; + for (const { buffer, width, height } of images) { + const { url, hash } = await dataProvider.upload(new Blob([buffer])); + + encodedImages.push({ + width, + height, + url, + verification: { + method: 'keccak256(bytes)', + data: hash, + }, + }); + } + + const encodedAssets: AssetMetadata[] = []; + for (const asset of assets) { + const { url, hash } = await dataProvider.upload(new Blob([asset.buffer])); + + encodedAssets.push({ + url, + verification: { + method: 'keccak256(bytes)', + data: hash, + }, + }); + } + + const metadata: LSP4DigitalAssetMetadataJSON = { + LSP4Metadata: { + name, + description, + links: links.filter(({ title, url }) => title && url), + attributes: attributes.filter( + ({ key, value, type }) => key && value && type, + ), + icon: encodedIcons, + images: [encodedImages], + assets: encodedAssets, + }, + }; + + const { url } = await dataProvider.upload( + new Blob([Buffer.from(JSON.stringify(metadata))]), + ); + + const { values } = erc725js.encodeData([ + { + keyName: 'LSP4Metadata', + value: { + json: metadata, + url, + }, + }, + ]); + console.log(values); + + setVerifiableUri(values[0]); + setUploadStatus(2); + }; + + const reset = () => { + setName(''); + setDescription(''); + setLinks([{ title: '', url: '' }]); + setAttributes([{ key: '', value: '', type: '' }]); + setIcons([]); + setSelectedIcon(undefined); + setImages([]); + setSelectedImage(undefined); + setAssets([]); + setSelectedAsset(undefined); + setUploadStatus(0); + setVerifiableUri(''); + }; + + return ( + <> + + LSP4 Metadata - ERC725 Tools + +
+ setName(event.target.value)} + /> +