From 6a51249ac877a306cdc6ba56508e7403efbb9e7f Mon Sep 17 00:00:00 2001 From: Jean Cvllr <31145285+CJ42@users.noreply.github.com> Date: Thu, 25 Jan 2024 18:17:42 +0000 Subject: [PATCH] build!: move LSP25 in its own package (#851) --- .github/workflows/solc_version.yml | 6 +- .../LSP6KeyManager/LSP6KeyManagerCore.sol | 6 +- contracts/Mocks/ERC165Interfaces.sol | 4 +- .../Reentrancy/BatchReentrancyRelayer.sol | 2 +- .../Reentrancy/SingleReentrancyRelayer.sol | 2 +- .../smart-contracts/contracts}/ERC725.md | 0 .../contracts}/LSP25MultiChannelNonce.md | 4 +- .../contracts/LSP2Utils.md | 0 dodoc/config.ts | 15 +- package-lock.json | 114 +++++++++++++++- package.json | 5 +- packages/LSP25ExecuteRelayCall/.eslintrc.js | 4 + packages/LSP25ExecuteRelayCall/.solhint.json | 25 ++++ packages/LSP25ExecuteRelayCall/README.md | 3 + .../contracts}/ILSP25ExecuteRelayCall.sol | 0 .../contracts}/LSP25Constants.sol | 0 .../contracts}/LSP25Errors.sol | 0 .../contracts}/LSP25MultiChannelNonce.sol | 0 .../Mocks/LSP25MultiChannelNonceTester.sol | 4 +- .../LSP25ExecuteRelayCall/hardhat.config.ts | 128 ++++++++++++++++++ packages/LSP25ExecuteRelayCall/package.json | 46 +++++++ .../tests}/LSP25MultiChannelNonce.test.ts | 6 +- packages/LSP25ExecuteRelayCall/tsconfig.json | 4 + remappings.txt | 1 + scripts/interfaceIds.ts | 28 +++- template/hardhat.config.ts | 2 + 26 files changed, 370 insertions(+), 39 deletions(-) rename docs/contracts/{ERC725 => @erc725/smart-contracts/contracts}/ERC725.md (100%) rename docs/contracts/{LSP25ExecuteRelayCall => lsp25/contracts}/LSP25MultiChannelNonce.md (97%) rename docs/contracts/{ => packages}/LSP2ERC725YJSONSchema/contracts/LSP2Utils.md (100%) create mode 100644 packages/LSP25ExecuteRelayCall/.eslintrc.js create mode 100644 packages/LSP25ExecuteRelayCall/.solhint.json create mode 100644 packages/LSP25ExecuteRelayCall/README.md rename {contracts/LSP25ExecuteRelayCall => packages/LSP25ExecuteRelayCall/contracts}/ILSP25ExecuteRelayCall.sol (100%) rename {contracts/LSP25ExecuteRelayCall => packages/LSP25ExecuteRelayCall/contracts}/LSP25Constants.sol (100%) rename {contracts/LSP25ExecuteRelayCall => packages/LSP25ExecuteRelayCall/contracts}/LSP25Errors.sol (100%) rename {contracts/LSP25ExecuteRelayCall => packages/LSP25ExecuteRelayCall/contracts}/LSP25MultiChannelNonce.sol (100%) rename {contracts => packages/LSP25ExecuteRelayCall/contracts}/Mocks/LSP25MultiChannelNonceTester.sol (92%) create mode 100644 packages/LSP25ExecuteRelayCall/hardhat.config.ts create mode 100644 packages/LSP25ExecuteRelayCall/package.json rename {tests/LSP25ExecuteRelayCall => packages/LSP25ExecuteRelayCall/tests}/LSP25MultiChannelNonce.test.ts (96%) create mode 100644 packages/LSP25ExecuteRelayCall/tsconfig.json diff --git a/.github/workflows/solc_version.yml b/.github/workflows/solc_version.yml index a0e7f6cd9..73bba6ab9 100644 --- a/.github/workflows/solc_version.yml +++ b/.github/workflows/solc_version.yml @@ -80,9 +80,11 @@ jobs: --allow-paths $(pwd)/node_modules/,$(pwd)/packages/ \ @=node_modules/@ \ solidity-bytes-utils/=node_modules/solidity-bytes-utils/ \ - ../=$(pwd)/contracts/ + ../=$(pwd)/contracts/ \ + lsp25/=packages/LSP25ExecuteRelayCall/ else solc contracts/**/*.sol \ @=node_modules/@ \ - solidity-bytes-utils/=node_modules/solidity-bytes-utils/ + solidity-bytes-utils/=node_modules/solidity-bytes-utils/ \ + lsp25/=packages/LSP25ExecuteRelayCall/ fi; diff --git a/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol b/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol index b7ac0d30e..4a6722cc1 100644 --- a/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol +++ b/contracts/LSP6KeyManager/LSP6KeyManagerCore.sol @@ -15,7 +15,7 @@ import { } from "../LSP20CallVerification/ILSP20CallVerifier.sol"; import { ILSP25ExecuteRelayCall as ILSP25 -} from "../LSP25ExecuteRelayCall/ILSP25ExecuteRelayCall.sol"; +} from "lsp25/contracts/ILSP25ExecuteRelayCall.sol"; // modules import {ILSP14Ownable2Step} from "../LSP14Ownable2Step/ILSP14Ownable2Step.sol"; @@ -29,7 +29,7 @@ import { import {LSP6OwnershipModule} from "./LSP6Modules/LSP6OwnershipModule.sol"; import { LSP25MultiChannelNonce -} from "../LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol"; +} from "lsp25/contracts/LSP25MultiChannelNonce.sol"; // libraries import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; @@ -69,7 +69,7 @@ import { _LSP20_VERIFY_CALL_SUCCESS_VALUE_WITH_POST_VERIFICATION, _LSP20_VERIFY_CALL_RESULT_SUCCESS_VALUE } from "../LSP20CallVerification/LSP20Constants.sol"; -import {_INTERFACEID_LSP25} from "../LSP25ExecuteRelayCall/LSP25Constants.sol"; +import {_INTERFACEID_LSP25} from "lsp25/contracts/LSP25Constants.sol"; /** * @title Core implementation of the LSP6 Key Manager standard. diff --git a/contracts/Mocks/ERC165Interfaces.sol b/contracts/Mocks/ERC165Interfaces.sol index 9d84fb9d9..827842f33 100644 --- a/contracts/Mocks/ERC165Interfaces.sol +++ b/contracts/Mocks/ERC165Interfaces.sol @@ -57,7 +57,7 @@ import { } from "../LSP20CallVerification/ILSP20CallVerifier.sol"; import { ILSP25ExecuteRelayCall as ILSP25 -} from "../LSP25ExecuteRelayCall/ILSP25ExecuteRelayCall.sol"; +} from "lsp25/contracts/ILSP25ExecuteRelayCall.sol"; // constants import {_INTERFACEID_LSP0} from "../LSP0ERC725Account/LSP0Constants.sol"; @@ -83,7 +83,7 @@ import { _INTERFACEID_LSP20_CALL_VERIFICATION, _INTERFACEID_LSP20_CALL_VERIFIER } from "../LSP20CallVerification/LSP20Constants.sol"; -import {_INTERFACEID_LSP25} from "../LSP25ExecuteRelayCall/LSP25Constants.sol"; +import {_INTERFACEID_LSP25} from "lsp25/contracts/LSP25Constants.sol"; // libraries import { diff --git a/contracts/Mocks/Reentrancy/BatchReentrancyRelayer.sol b/contracts/Mocks/Reentrancy/BatchReentrancyRelayer.sol index 4c6385f9e..b04060d76 100644 --- a/contracts/Mocks/Reentrancy/BatchReentrancyRelayer.sol +++ b/contracts/Mocks/Reentrancy/BatchReentrancyRelayer.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.4; // interfaces import { ILSP25ExecuteRelayCall -} from "../../LSP25ExecuteRelayCall/ILSP25ExecuteRelayCall.sol"; +} from "lsp25/contracts/ILSP25ExecuteRelayCall.sol"; contract BatchReentrancyRelayer { bytes[] private _signatures; diff --git a/contracts/Mocks/Reentrancy/SingleReentrancyRelayer.sol b/contracts/Mocks/Reentrancy/SingleReentrancyRelayer.sol index 0e24078de..351076001 100644 --- a/contracts/Mocks/Reentrancy/SingleReentrancyRelayer.sol +++ b/contracts/Mocks/Reentrancy/SingleReentrancyRelayer.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.4; // interfaces import { ILSP25ExecuteRelayCall -} from "../../LSP25ExecuteRelayCall/ILSP25ExecuteRelayCall.sol"; +} from "lsp25/contracts/ILSP25ExecuteRelayCall.sol"; contract SingleReentrancyRelayer { bytes private _signature; diff --git a/docs/contracts/ERC725/ERC725.md b/docs/contracts/@erc725/smart-contracts/contracts/ERC725.md similarity index 100% rename from docs/contracts/ERC725/ERC725.md rename to docs/contracts/@erc725/smart-contracts/contracts/ERC725.md diff --git a/docs/contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.md b/docs/contracts/lsp25/contracts/LSP25MultiChannelNonce.md similarity index 97% rename from docs/contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.md rename to docs/contracts/lsp25/contracts/LSP25MultiChannelNonce.md index e789fed02..08dcb54c9 100644 --- a/docs/contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.md +++ b/docs/contracts/lsp25/contracts/LSP25MultiChannelNonce.md @@ -5,12 +5,12 @@ :::info Standard Specifications -[`LSP-25-ExecuteRelayCall`](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-25-ExecuteRelayCall.md) +[`LSP-25-MultiChannelNonce.sol`](https://github.com/lukso-network/lips/tree/main/LSPs/LSP-25-MultiChannelNonce.sol.md) ::: :::info Solidity implementation -[`LSP25MultiChannelNonce.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol) +[`LSP25MultiChannelNonce.sol`](https://github.com/lukso-network/lsp-smart-contracts/blob/develop/lsp25/contracts/LSP25MultiChannelNonce.sol) ::: diff --git a/docs/contracts/LSP2ERC725YJSONSchema/contracts/LSP2Utils.md b/docs/contracts/packages/LSP2ERC725YJSONSchema/contracts/LSP2Utils.md similarity index 100% rename from docs/contracts/LSP2ERC725YJSONSchema/contracts/LSP2Utils.md rename to docs/contracts/packages/LSP2ERC725YJSONSchema/contracts/LSP2Utils.md diff --git a/dodoc/config.ts b/dodoc/config.ts index 019a2ecf7..63c41cf47 100644 --- a/dodoc/config.ts +++ b/dodoc/config.ts @@ -20,7 +20,7 @@ export const dodocConfig = { 'contracts/LSP20CallVerification/LSP20CallVerification.sol', 'contracts/LSP23LinkedContractsFactory/LSP23LinkedContractsFactory.sol', 'contracts/LSP23LinkedContractsFactory/IPostDeploymentModule.sol', - 'contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol', + 'lsp25/contracts/LSP25MultiChannelNonce.sol', // tokens 'contracts/LSP4DigitalAssetMetadata/LSP4DigitalAssetMetadata.sol', @@ -48,6 +48,8 @@ export const dodocConfig = { // external -------------------- '@erc725/smart-contracts/contracts/ERC725.sol', + // 'solidity-bytes-utils/contracts/BytesLib.sol', + '@openzeppelin/contracts/token/ERC20/ERC20.sol', ], libraries: [ 'contracts/LSP1UniversalReceiver/LSP1Utils.sol', @@ -335,13 +337,14 @@ const generateContractSpecsDetails = (contractName: string) => { if (value.endsWith(`${contractName}.sol`)) return value; })[0]; - const specs = contractPath.split('/')[1]; + const specsIndex = contractPath.startsWith('lsp') ? 2 : 1; + const specs = contractPath.split('/')[specsIndex]; - const specsName = `LSP-${specs.match(/\d+/)[0]}-${specs.split(/LSP\d+/)[1]}`; + const lspNumber = specs.match(/\d+/)[0]; + const lspName = specs.split(/LSP\d+/)[1]; - const specsLink = `${linkBase}lips/tree/main/LSPs/LSP-${specs.match(/\d+/)[0]}-${ - specs.split(/LSP\d+/)[1] - }.md`; + const specsName = `LSP-${lspNumber}-${lspName}`; + const specsLink = `${linkBase}lips/tree/main/LSPs/LSP-${lspNumber}-${lspName}.md`; return { specsName, specsLink }; }; diff --git a/package-lock.json b/package-lock.json index 18dccb16a..1eb21e892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,10 +17,11 @@ "@erc725/smart-contracts": "^7.0.0", "@openzeppelin/contracts": "^4.9.2", "@openzeppelin/contracts-upgradeable": "^4.9.2", + "lsp25": "*", "solidity-bytes-utils": "0.8.0" }, "devDependencies": { - "@b00ste/hardhat-dodoc": "^0.3.15", + "@b00ste/hardhat-dodoc": "^0.3.16", "@defi-wonderland/smock": "^2.3.4", "@erc725/erc725.js": "0.17.2", "@lukso/eip191-signer.js": "^0.2.2", @@ -101,11 +102,12 @@ } }, "node_modules/@b00ste/hardhat-dodoc": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@b00ste/hardhat-dodoc/-/hardhat-dodoc-0.3.15.tgz", - "integrity": "sha512-3aGhCRr09oe0meHxoE1xxk0aXbTe0XHcTbyeNEuaNBgCvN+ESAtsi/VUCL3IG9kWEgOgeXeEfHlPTGRjNx2dmg==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@b00ste/hardhat-dodoc/-/hardhat-dodoc-0.3.16.tgz", + "integrity": "sha512-ofCRmEkKG/DADlMzeMNQm1U5wthZpYdhOU4jQ2h3Enh3kygRBLqP7A7zAzOfFqLOvrGf+IsfZZosbcVtjhK1og==", "dev": true, "dependencies": { + "@lukso/lsp-smart-contracts": "^0.14.0", "squirrelly": "^8.0.8" }, "peerDependencies": { @@ -1920,6 +1922,19 @@ "web3-utils": "^1.7.5" } }, + "node_modules/@lukso/lsp-smart-contracts": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@lukso/lsp-smart-contracts/-/lsp-smart-contracts-0.14.0.tgz", + "integrity": "sha512-HjMpO/DfcAnL2YAoGSq4TazwsKof3CClyi33cwkOIdH7b81DMP5Z4LLjOjAGURrJlMj8wH4cLp5+4nvZ4NVSIA==", + "dev": true, + "dependencies": { + "@account-abstraction/contracts": "^0.6.0", + "@erc725/smart-contracts": "^7.0.0", + "@openzeppelin/contracts": "^4.9.2", + "@openzeppelin/contracts-upgradeable": "^4.9.2", + "solidity-bytes-utils": "0.8.0" + } + }, "node_modules/@metamask/eth-sig-util": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", @@ -13286,6 +13301,10 @@ "resolved": "packages/LSP2ERC725YJSONSchema", "link": true }, + "node_modules/lsp25": { + "resolved": "packages/LSP25ExecuteRelayCall", + "link": true + }, "node_modules/ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", @@ -23509,6 +23528,44 @@ "ethers": "^5.7.0" } }, + "packages/LSP25ExecuteRelayCall": { + "name": "lsp25", + "version": "0.12.1", + "license": "Apache-2.0", + "dependencies": { + "@openzeppelin/contracts": "^4.9.3" + }, + "devDependencies": { + "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@typechain/ethers-v5": "^10.2.0", + "dotenv": "^16.0.3", + "eslint-config-custom": "*", + "ethers": "^5.7.2", + "hardhat": "^2.13.0", + "hardhat-contract-sizer": "^2.8.0", + "hardhat-deploy": "^0.11.25", + "hardhat-gas-reporter": "^1.0.9", + "hardhat-packager": "^1.4.2", + "solhint": "^3.6.2", + "ts-node": "^10.2.0", + "tsconfig": "*", + "typechain": "^8.0.0", + "typescript": "^4.9.5" + } + }, + "packages/LSP25ExecuteRelayCall/node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "packages/LSP2ERC725YJSONSchema": { "name": "lsp2", "version": "0.12.1", @@ -23557,11 +23614,12 @@ } }, "@b00ste/hardhat-dodoc": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@b00ste/hardhat-dodoc/-/hardhat-dodoc-0.3.15.tgz", - "integrity": "sha512-3aGhCRr09oe0meHxoE1xxk0aXbTe0XHcTbyeNEuaNBgCvN+ESAtsi/VUCL3IG9kWEgOgeXeEfHlPTGRjNx2dmg==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@b00ste/hardhat-dodoc/-/hardhat-dodoc-0.3.16.tgz", + "integrity": "sha512-ofCRmEkKG/DADlMzeMNQm1U5wthZpYdhOU4jQ2h3Enh3kygRBLqP7A7zAzOfFqLOvrGf+IsfZZosbcVtjhK1og==", "dev": true, "requires": { + "@lukso/lsp-smart-contracts": "^0.14.0", "squirrelly": "^8.0.8" } }, @@ -24709,6 +24767,19 @@ "web3-utils": "^1.7.5" } }, + "@lukso/lsp-smart-contracts": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@lukso/lsp-smart-contracts/-/lsp-smart-contracts-0.14.0.tgz", + "integrity": "sha512-HjMpO/DfcAnL2YAoGSq4TazwsKof3CClyi33cwkOIdH7b81DMP5Z4LLjOjAGURrJlMj8wH4cLp5+4nvZ4NVSIA==", + "dev": true, + "requires": { + "@account-abstraction/contracts": "^0.6.0", + "@erc725/smart-contracts": "^7.0.0", + "@openzeppelin/contracts": "^4.9.2", + "@openzeppelin/contracts-upgradeable": "^4.9.2", + "solidity-bytes-utils": "0.8.0" + } + }, "@metamask/eth-sig-util": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", @@ -33595,6 +33666,35 @@ "typescript": "^5.3.3" } }, + "lsp25": { + "version": "file:packages/LSP25ExecuteRelayCall", + "requires": { + "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@openzeppelin/contracts": "^4.9.3", + "@typechain/ethers-v5": "^10.2.0", + "dotenv": "^16.0.3", + "eslint-config-custom": "*", + "ethers": "^5.7.2", + "hardhat": "^2.13.0", + "hardhat-contract-sizer": "^2.8.0", + "hardhat-deploy": "^0.11.25", + "hardhat-gas-reporter": "^1.0.9", + "hardhat-packager": "^1.4.2", + "solhint": "^3.6.2", + "ts-node": "^10.2.0", + "tsconfig": "*", + "typechain": "^8.0.0", + "typescript": "^4.9.5" + }, + "dependencies": { + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + } + } + }, "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", diff --git a/package.json b/package.json index 33e7d816b..7faf13f18 100644 --- a/package.json +++ b/package.json @@ -111,10 +111,11 @@ "@erc725/smart-contracts": "^7.0.0", "@openzeppelin/contracts": "^4.9.2", "@openzeppelin/contracts-upgradeable": "^4.9.2", - "solidity-bytes-utils": "0.8.0" + "solidity-bytes-utils": "0.8.0", + "lsp25": "*" }, "devDependencies": { - "@b00ste/hardhat-dodoc": "^0.3.15", + "@b00ste/hardhat-dodoc": "^0.3.16", "@defi-wonderland/smock": "^2.3.4", "@erc725/erc725.js": "0.17.2", "@lukso/eip191-signer.js": "^0.2.2", diff --git a/packages/LSP25ExecuteRelayCall/.eslintrc.js b/packages/LSP25ExecuteRelayCall/.eslintrc.js new file mode 100644 index 000000000..03ee7431b --- /dev/null +++ b/packages/LSP25ExecuteRelayCall/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: ['custom'], +}; diff --git a/packages/LSP25ExecuteRelayCall/.solhint.json b/packages/LSP25ExecuteRelayCall/.solhint.json new file mode 100644 index 000000000..26e01c48a --- /dev/null +++ b/packages/LSP25ExecuteRelayCall/.solhint.json @@ -0,0 +1,25 @@ +{ + "extends": "solhint:recommended", + "rules": { + "avoid-sha3": "error", + "avoid-suicide": "error", + "avoid-throw": "error", + "avoid-tx-origin": "error", + "check-send-result": "error", + "compiler-version": ["error", "^0.8.0"], + "func-visibility": ["error", { "ignoreConstructors": true }], + "not-rely-on-block-hash": "error", + "not-rely-on-time": "error", + "reentrancy": "error", + "constructor-syntax": "error", + "private-vars-leading-underscore": ["error", { "strict": false }], + "imports-on-top": "error", + "visibility-modifier-order": "error", + "no-unused-import": "error", + "no-global-import": "error", + "reason-string": ["warn", { "maxLength": 120 }], + "avoid-low-level-calls": "off", + "no-empty-blocks": ["error", { "ignoreConstructors": true }], + "custom-errors": "off" + } +} diff --git a/packages/LSP25ExecuteRelayCall/README.md b/packages/LSP25ExecuteRelayCall/README.md new file mode 100644 index 000000000..de272643c --- /dev/null +++ b/packages/LSP25ExecuteRelayCall/README.md @@ -0,0 +1,3 @@ +# LSP25 Execute Relay Call + +Package for the LSP25 Execute Relay Call standard. diff --git a/contracts/LSP25ExecuteRelayCall/ILSP25ExecuteRelayCall.sol b/packages/LSP25ExecuteRelayCall/contracts/ILSP25ExecuteRelayCall.sol similarity index 100% rename from contracts/LSP25ExecuteRelayCall/ILSP25ExecuteRelayCall.sol rename to packages/LSP25ExecuteRelayCall/contracts/ILSP25ExecuteRelayCall.sol diff --git a/contracts/LSP25ExecuteRelayCall/LSP25Constants.sol b/packages/LSP25ExecuteRelayCall/contracts/LSP25Constants.sol similarity index 100% rename from contracts/LSP25ExecuteRelayCall/LSP25Constants.sol rename to packages/LSP25ExecuteRelayCall/contracts/LSP25Constants.sol diff --git a/contracts/LSP25ExecuteRelayCall/LSP25Errors.sol b/packages/LSP25ExecuteRelayCall/contracts/LSP25Errors.sol similarity index 100% rename from contracts/LSP25ExecuteRelayCall/LSP25Errors.sol rename to packages/LSP25ExecuteRelayCall/contracts/LSP25Errors.sol diff --git a/contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol b/packages/LSP25ExecuteRelayCall/contracts/LSP25MultiChannelNonce.sol similarity index 100% rename from contracts/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol rename to packages/LSP25ExecuteRelayCall/contracts/LSP25MultiChannelNonce.sol diff --git a/contracts/Mocks/LSP25MultiChannelNonceTester.sol b/packages/LSP25ExecuteRelayCall/contracts/Mocks/LSP25MultiChannelNonceTester.sol similarity index 92% rename from contracts/Mocks/LSP25MultiChannelNonceTester.sol rename to packages/LSP25ExecuteRelayCall/contracts/Mocks/LSP25MultiChannelNonceTester.sol index c825ea946..a87def96b 100644 --- a/contracts/Mocks/LSP25MultiChannelNonceTester.sol +++ b/packages/LSP25ExecuteRelayCall/contracts/Mocks/LSP25MultiChannelNonceTester.sol @@ -1,9 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.4; -import { - LSP25MultiChannelNonce -} from "../LSP25ExecuteRelayCall/LSP25MultiChannelNonce.sol"; +import {LSP25MultiChannelNonce} from "../LSP25MultiChannelNonce.sol"; /** * @dev This contract is used only for testing the internal functions. diff --git a/packages/LSP25ExecuteRelayCall/hardhat.config.ts b/packages/LSP25ExecuteRelayCall/hardhat.config.ts new file mode 100644 index 000000000..d818a205d --- /dev/null +++ b/packages/LSP25ExecuteRelayCall/hardhat.config.ts @@ -0,0 +1,128 @@ +import { HardhatUserConfig } from 'hardhat/config'; +import { NetworkUserConfig } from 'hardhat/types'; +import { config as dotenvConfig } from 'dotenv'; +import { resolve } from 'path'; + +/** + * this package includes: + * - @nomiclabs/hardhat-ethers + * - @nomicfoundation/hardhat-chai-matchers + * - @nomicfoundation/hardhat-network-helpers + * - @nomiclabs/hardhat-etherscan + * - hardhat-gas-reporter (is this true? Why do we have it as a separate dependency?) + * - @typechain/hardhat + * - solidity-coverage + */ +import '@nomicfoundation/hardhat-toolbox'; + +// additional hardhat plugins +import 'hardhat-packager'; +import 'hardhat-contract-sizer'; +import 'hardhat-deploy'; + +// custom built hardhat plugins and scripts +// can be imported here (e.g: docs generation, gas benchmark, etc...) + +dotenvConfig({ path: resolve(__dirname, './.env') }); + +function getTestnetChainConfig(): NetworkUserConfig { + const config: NetworkUserConfig = { + live: true, + url: 'https://rpc.testnet.lukso.network', + chainId: 4201, + }; + + if (process.env.CONTRACT_VERIFICATION_TESTNET_PK !== undefined) { + config['accounts'] = [process.env.CONTRACT_VERIFICATION_TESTNET_PK]; + } + + return config; +} + +const config: HardhatUserConfig = { + defaultNetwork: 'hardhat', + networks: { + hardhat: { + live: false, + saveDeployments: false, + allowBlocksWithSameTimestamp: true, + }, + luksoTestnet: getTestnetChainConfig(), + }, + namedAccounts: { + owner: 0, + }, + // uncomment if the contracts from this LSP package must be deployed at deterministic + // // addresses across multiple chains + // deterministicDeployment: { + // luksoTestnet: { + // // Nick Factory. See https://github.com/Arachnid/deterministic-deployment-proxy + // factory: '0x4e59b44847b379578588920ca78fbf26c0b4956c', + // deployer: '0x3fab184622dc19b6109349b94811493bf2a45362', + // funding: '0x0000000000000000000000000000000000000000000000000000000000000000', + // signedTx: + // '0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222', + // }, + // }, + etherscan: { + apiKey: 'no-api-key-needed', + customChains: [ + { + network: 'luksoTestnet', + chainId: 4201, + urls: { + apiURL: 'https://api.explorer.execution.testnet.lukso.network/api', + browserURL: 'https://explorer.execution.testnet.lukso.network/', + }, + }, + ], + }, + gasReporter: { + enabled: true, + currency: 'USD', + gasPrice: 21, + excludeContracts: ['Helpers/'], + src: './contracts', + showMethodSig: true, + }, + solidity: { + version: '0.8.17', + settings: { + optimizer: { + enabled: true, + /** + * Optimize for how many times you intend to run the code. + * Lower values will optimize more for initial deployment cost, higher + * values will optimize more for high-frequency usage. + * @see https://docs.soliditylang.org/en/v0.8.6/internals/optimizer.html#opcode-based-optimizer-module + */ + runs: 1000, + }, + outputSelection: { + '*': { + '*': ['storageLayout'], + }, + }, + }, + }, + packager: { + // What contracts to keep the artifacts and the bindings for. + contracts: [], + // Whether to include the TypeChain factories or not. + // If this is enabled, you need to run the TypeChain files through the TypeScript compiler before shipping to the registry. + includeFactories: true, + }, + paths: { + artifacts: 'artifacts', + tests: 'tests', + }, + typechain: { + outDir: 'types', + target: 'ethers-v5', + }, + mocha: { + timeout: 10000000, + }, +}; + +export default config; diff --git a/packages/LSP25ExecuteRelayCall/package.json b/packages/LSP25ExecuteRelayCall/package.json new file mode 100644 index 000000000..a67183d3a --- /dev/null +++ b/packages/LSP25ExecuteRelayCall/package.json @@ -0,0 +1,46 @@ +{ + "name": "lsp25", + "version": "0.12.1", + "description": "Package for the LSP25 Execute Relay Call standard", + "license": "Apache-2.0", + "author": "", + "keywords": [ + "LUKSO", + "LSP", + "Blockchain", + "Standards", + "Smart Contracts", + "Ethereum", + "EVM", + "Solidity" + ], + "scripts": { + "build": "hardhat compile --show-stack-traces", + "clean": "hardhat clean", + "format": "prettier --write .", + "lint": "eslint . --ext .ts,.js", + "lint:solidity": "solhint 'contracts/**/*.sol' && prettier --check 'contracts/**/*.sol'", + "test": "hardhat test --no-compile tests/*.test.ts", + "test:coverage": "hardhat coverage" + }, + "dependencies": { + "@openzeppelin/contracts": "^4.9.3" + }, + "devDependencies": { + "@nomicfoundation/hardhat-toolbox": "^2.0.2", + "@typechain/ethers-v5": "^10.2.0", + "dotenv": "^16.0.3", + "eslint-config-custom": "*", + "ethers": "^5.7.2", + "hardhat": "^2.13.0", + "hardhat-contract-sizer": "^2.8.0", + "hardhat-deploy": "^0.11.25", + "hardhat-gas-reporter": "^1.0.9", + "hardhat-packager": "^1.4.2", + "solhint": "^3.6.2", + "ts-node": "^10.2.0", + "tsconfig": "*", + "typechain": "^8.0.0", + "typescript": "^4.9.5" + } +} diff --git a/tests/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.test.ts b/packages/LSP25ExecuteRelayCall/tests/LSP25MultiChannelNonce.test.ts similarity index 96% rename from tests/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.test.ts rename to packages/LSP25ExecuteRelayCall/tests/LSP25MultiChannelNonce.test.ts index 1d3b9c6cd..2bf3c80b4 100644 --- a/tests/LSP25ExecuteRelayCall/LSP25MultiChannelNonce.test.ts +++ b/packages/LSP25ExecuteRelayCall/tests/LSP25MultiChannelNonce.test.ts @@ -1,10 +1,10 @@ import { ethers } from 'hardhat'; import { expect } from 'chai'; -import { LSP25_VERSION } from '../../constants'; -import { LOCAL_PRIVATE_KEYS } from '../utils/helpers'; +import { LSP25_VERSION } from '../../../constants'; +import { LOCAL_PRIVATE_KEYS } from '../../../tests/utils/helpers'; import { EIP191Signer } from '@lukso/eip191-signer.js'; -import { LSP25MultiChannelNonceTester, LSP25MultiChannelNonceTester__factory } from '../../types'; +import { LSP25MultiChannelNonceTester, LSP25MultiChannelNonceTester__factory } from '../types'; describe('LSP25MultiChannelNonce', () => { let contract: LSP25MultiChannelNonceTester; diff --git a/packages/LSP25ExecuteRelayCall/tsconfig.json b/packages/LSP25ExecuteRelayCall/tsconfig.json new file mode 100644 index 000000000..b7a34e03f --- /dev/null +++ b/packages/LSP25ExecuteRelayCall/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "tsconfig/contracts.json", + "include": ["**/*.ts"] +} diff --git a/remappings.txt b/remappings.txt index ca89288f2..ff83d2174 100644 --- a/remappings.txt +++ b/remappings.txt @@ -7,3 +7,4 @@ hardhat-deploy/=node_modules/hardhat-deploy/ hardhat/=node_modules/hardhat/ solidity-bytes-utils/=node_modules/solidity-bytes-utils/ ds-test/=lib/forge-std/lib/ds-test/src/ +lsp25/=packages/LSP25ExecuteRelayCall/ diff --git a/scripts/interfaceIds.ts b/scripts/interfaceIds.ts index fb6c79a1a..f528ce104 100644 --- a/scripts/interfaceIds.ts +++ b/scripts/interfaceIds.ts @@ -59,8 +59,8 @@ async function main() { folder = contract; } - const source = `contracts/${folder}/${lspInterface}.sol:${lspInterface}`; - const build = await hre.artifacts.getBuildInfo(source); + let source = `contracts/${folder}/${lspInterface}.sol:${lspInterface}`; + let build = await hre.artifacts.getBuildInfo(source); const [path] = source.split(':'); @@ -68,15 +68,29 @@ async function main() { if (!devdoc) { // search in the first implementation contract - const source = `contracts/${folder}/${contract}.sol:${contract}`; - const build = await hre.artifacts.getBuildInfo(source); + source = `contracts/${folder}/${contract}.sol:${contract}`; + build = await hre.artifacts.getBuildInfo(source); - const [path] = source.split(':'); + let contractDevDoc; - const contractDevDoc = build?.output?.contracts?.[path]?.[contract]['devdoc']; + // otherwise search in the `lsp` package + if (build == undefined) { + const lspNumber = lspInterface.match(/\d+/); + + if (lspNumber != null) { + source = `lsp${lspNumber}/contracts/${lspInterface}.sol:${lspInterface}`; + build = await hre.artifacts.getBuildInfo(source); + const [path] = source.split(':'); + contractDevDoc = build?.output?.contracts?.[path]?.[lspInterface]['devdoc']; + } + } else { + const [path] = source.split(':'); + + contractDevDoc = build?.output?.contracts?.[path]?.[contract]['devdoc']; + } if (contractDevDoc == undefined) { - throw new Error(`No devdoc for ${contract}`); + throw new Error(`No devdoc for ${contract} at path ${path}`); } if (contractDevDoc.hasOwnProperty('title')) { diff --git a/template/hardhat.config.ts b/template/hardhat.config.ts index 8b6acf5d3..d818a205d 100644 --- a/template/hardhat.config.ts +++ b/template/hardhat.config.ts @@ -124,3 +124,5 @@ const config: HardhatUserConfig = { timeout: 10000000, }, }; + +export default config;