diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..dbe6e5a --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.3.0 \ No newline at end of file diff --git a/README.md b/README.md index 0850df7..f9e47be 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Proposal title +# Proposal to update Tornado IPFS hashes in ENS ### Changes / effect description @@ -10,7 +10,7 @@ - Rust ([Need only for Windows](https://doc.rust-lang.org/cargo/getting-started/installation.html)) - Foundryup ([Windows](https://github.com/altugbakan/foundryup-windows), [Linux](https://book.getfoundry.sh/getting-started/installation)) -- Node 14 or higher ([Windows](https://github.com/coreybutler/nvm-windows), [Linux](https://github.com/nvm-sh/nvm)) +- Node 20 or higher ([Windows](https://github.com/coreybutler/nvm-windows), [Linux](https://github.com/nvm-sh/nvm)) ### Installation @@ -18,7 +18,7 @@ git clone --recurse-submodules cd npm install -npm init +npm run init ``` ### Testing diff --git a/data/ensNodesDeclarations.txt b/data/ensNodesDeclarations.txt index c6a4a27..a9600e2 100644 --- a/data/ensNodesDeclarations.txt +++ b/data/ensNodesDeclarations.txt @@ -1,10 +1,9 @@ - bytes32 rootTornadoENSNode = 0xe6ae31d630cc7a8279c0f1c7cbe6e7064814c47d1785fa2703d9ae511ee2be0c; - bytes32 tornadoContractENSNode = 0xe7e1d618367ebadd8e172150a43cfc839fd19022c2be81a6e8d45e06aa1011cd; - bytes32 stakingRewardsENSNode = 0x3da4b79cd8c20d2fafb1c7cb37a62be8668f543393f6636d421fba0be735e68f; - bytes32 novaENSNode = 0xc3964c598b56aeaee4c253283fb1ebb12510b95db00960589cdc62807a2537a0; - bytes32 docsENSNode = 0xd7b8aac14a9b2507ab99b5fde3060197fddb9735afa9bf38b1f7e34923cb935e; - bytes32 relayersUIENSNode = 0x4e37047f2c961db41dfb7d38cf79ca745faf134a8392cfb834d3a93330b9108d; - bytes32 testNode = 0x121818cfd40893900bebefa5ccf60544db43ba8fa1d2d56433984132883bee88; + bytes32 rootTornadoENSNode = 0xe6ae31d630cc7a8279c0f1c7cbe6e7064814c47d1785fa2703d9ae511ee2be0c; + bytes32 tornadoContractENSNode = 0xe7e1d618367ebadd8e172150a43cfc839fd19022c2be81a6e8d45e06aa1011cd; + bytes32 stakingRewardsENSNode = 0x3da4b79cd8c20d2fafb1c7cb37a62be8668f543393f6636d421fba0be735e68f; + bytes32 novaENSNode = 0xc3964c598b56aeaee4c253283fb1ebb12510b95db00960589cdc62807a2537a0; + bytes32 docsENSNode = 0xd7b8aac14a9b2507ab99b5fde3060197fddb9735afa9bf38b1f7e34923cb935e; + bytes32 relayersUIENSNode = 0x4e37047f2c961db41dfb7d38cf79ca745faf134a8392cfb834d3a93330b9108d; - bytes32 tornadoContractENSLabelhash = 0x7f6dd79f0020bee2024a097aaa5d32ab7ca31126fa375538de047e7475fa8572; - bytes32 stakingRewardsENSLabelhash = 0x15826fcf9999635849b273bcd226f436dc42a8fabf43049b60971ab51d8d6b8f; + bytes32 tornadoContractENSLabelhash = 0x7f6dd79f0020bee2024a097aaa5d32ab7ca31126fa375538de047e7475fa8572; + bytes32 stakingRewardsENSLabelhash = 0x15826fcf9999635849b273bcd226f436dc42a8fabf43049b60971ab51d8d6b8f; diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..75f1746 --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 75f1746c949ae56377611e5f2128aa93d381431f diff --git a/package.json b/package.json index 02065b5..bef9b36 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,28 @@ { - "name": "forge-proposal-template", - "version": "1.0.0", - "repository": "https://git.tornado.ws/Theo/forge-proposal-template", - "author": "Theo", - "license": "MIT", - "private": false, - "scripts": { - "init": "cd lib && git clone --recurse-submodules https://github.com/foundry-rs/forge-std", - "test:windows": ".\\.env.bat && forge test", - "test:linux": ". .env && forge test", - "test:gas:windows": ".\\.env.bat && forge test --gas-report", - "test:gas:linux": ". .env && forge test --gas-report" - }, - "dependencies": { - "@ensdomains/ens-contracts": "^0.0.21", - "@openzeppelin/contracts": "^4.9.0", - "@openzeppelin/upgrades-core": "^1.26.2" - }, - "optionalDependencies": { - "@gnosis.pm/ido-contracts": "^0.5.0", - "@gnosis.pm/safe-contracts": "1.3.0" - } + "name": "proposal-27", + "version": "1.0.0", + "repository": "https://git.tornado.ws/Theo/proposal-27-update-ipfs", + "author": "Theo", + "license": "MIT", + "private": false, + "scripts": { + "calculateENS": "npx ts-node scripts/calculateENSNodes.ts", + "calculateIpfsV1Cids": "npx ts-node scripts/calculateIpfsV1Cids", + "calculateIPFS": "npx ts-node scripts/calculateIPFSContenthashes", + "init": "cd lib && git clone --recurse-submodules https://github.com/foundry-rs/forge-std", + "test:windows": ".\\.env.bat && forge test", + "test:linux": ". .env && forge test", + "test:gas:windows": ".\\.env.bat && forge test --gas-report", + "test:gas:linux": ". .env && forge test --gas-report" + }, + "dependencies": { + "@ensdomains/ens-contracts": "^0.0.21", + "@ensdomains/eth-ens-namehash": "^2.0.15", + "@openzeppelin/contracts": "^4.9.0", + "@openzeppelin/upgrades-core": "^1.26.2", + "content-hash": "^2.5.2", + "js-sha3": "^0.8.0", + "ts-node": "^10.9.1", + "typescript": "^5.1.6" + } } diff --git a/scripts/utils.ts b/scripts/utils.ts index 88491d4..9b1252b 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -1,6 +1,6 @@ type NodeVarObject = { [key: string]: string }; -const solidityCodePadding = " ".repeat(4); +const solidityCodePadding = " ".repeat(8); const pad = (decl: string, padding: string = solidityCodePadding) => padding + decl + "\n"; class DeclCalculator { diff --git a/src/ExampleProposal.sol b/src/ExampleProposal.sol deleted file mode 100644 index 68fd33d..0000000 --- a/src/ExampleProposal.sol +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.19; - -import { IGovernance } from "@interfaces/IGovernance.sol"; - -contract ExampleProposal { - function executeProposal() public { - /* ... */ - } -} diff --git a/src/UpdateENSDataProposal.sol b/src/UpdateENSDataProposal.sol new file mode 100644 index 0000000..937770c --- /dev/null +++ b/src/UpdateENSDataProposal.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.19; + +import { IGovernance } from "@interfaces/IGovernance.sol"; +import { IENSRegistry } from "@interfaces/IENSRegistry.sol"; +import { IENSResolver } from "@interfaces/IENSResolver.sol"; + +import { TornadoAddresses } from "@proprietary/TornadoAddresses.sol"; + +contract UpdateENSDataProposal is TornadoAddresses { + function executeProposal() public { + address ensResolverAddress = 0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41; + address ensRegistryAddress = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; + + IENSRegistry ensRegistry = IENSRegistry(ensRegistryAddress); + IENSResolver ensResolver = IENSResolver(ensResolverAddress); + + // From data/ensNodesDeclarations.txt, calculated via scripts/calculateENSNodes.ts + bytes32 rootTornadoENSNode = 0xe6ae31d630cc7a8279c0f1c7cbe6e7064814c47d1785fa2703d9ae511ee2be0c; + bytes32 tornadoContractENSNode = 0xe7e1d618367ebadd8e172150a43cfc839fd19022c2be81a6e8d45e06aa1011cd; + bytes32 stakingRewardsENSNode = 0x3da4b79cd8c20d2fafb1c7cb37a62be8668f543393f6636d421fba0be735e68f; + bytes32 novaENSNode = 0xc3964c598b56aeaee4c253283fb1ebb12510b95db00960589cdc62807a2537a0; + bytes32 docsENSNode = 0xd7b8aac14a9b2507ab99b5fde3060197fddb9735afa9bf38b1f7e34923cb935e; + bytes32 relayersUIENSNode = 0x4e37047f2c961db41dfb7d38cf79ca745faf134a8392cfb834d3a93330b9108d; + + bytes32 tornadoContractENSLabelhash = 0x7f6dd79f0020bee2024a097aaa5d32ab7ca31126fa375538de047e7475fa8572; + bytes32 stakingRewardsENSLabelhash = 0x15826fcf9999635849b273bcd226f436dc42a8fabf43049b60971ab51d8d6b8f; + + // At first change owner of subdomain contract.tornadocash.eth and then staking-rewards.contract.tornadocash.eth to Governance + ensRegistry.setSubnodeOwner(rootTornadoENSNode, tornadoContractENSLabelhash, governanceAddress); + ensRegistry.setSubnodeOwner(tornadoContractENSNode, stakingRewardsENSLabelhash, governanceAddress); + + // Update staking address, that has been changed in proposal 22: https://tornado.ws/governance/22 + ensResolver.setAddr(stakingRewardsENSNode, stakingAddress); + + // From data/ensDomainsIPFSContenthashes.txt, calculated via scripts/calculateIPFSContenthashes.ts + bytes memory classicUiIPFSContenthash = hex"e301017012208124caa06a8419371b1d2eab9180191727d1ce0c0832975362f77a679ce614b6"; + bytes memory novaUiIPFSContenthash = hex"e3010170122069648b09fb7ed9a89ca153a000bc8c1bf82a779195a640609e1510dc36c28bb7"; + bytes memory relayersUiIPFSContenthash = hex"e301017012203d61bed0641d7c53d5f036b6448f9d455ae6e0ceda44563009536a12e51d52cf"; + bytes memory docsIPFSContenthash = hex"e3010170122008ba5879914413355290e3c8574825f7a09e59a9802a5fad1edfb3ce6a4f825b"; + + ensResolver.setContenthash(rootTornadoENSNode, classicUiIPFSContenthash); + ensResolver.setContenthash(novaENSNode, novaUiIPFSContenthash); + ensResolver.setContenthash(docsENSNode, docsIPFSContenthash); + ensResolver.setContenthash(relayersUIENSNode, relayersUiIPFSContenthash); + } +} diff --git a/src/interfaces/IENSRegistry.sol b/src/interfaces/IENSRegistry.sol new file mode 100644 index 0000000..eeca72a --- /dev/null +++ b/src/interfaces/IENSRegistry.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.19; + +interface IENSRegistry { + function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external returns (bytes32); + + function setOwner(bytes32 node, address owner) external; +} diff --git a/src/interfaces/IENSResolver.sol b/src/interfaces/IENSResolver.sol new file mode 100644 index 0000000..b269eed --- /dev/null +++ b/src/interfaces/IENSResolver.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.19; + +interface IENSResolver { + function setContenthash(bytes32 node, bytes memory hash) external; + + function setAddr(bytes32 node, address a) external; + + function addr(bytes32 node) external view returns (address); + + function contenthash(bytes32 node) external returns (bytes memory); +} diff --git a/src/interfaces/IGnosisSafe.sol b/src/interfaces/IGnosisSafe.sol deleted file mode 100644 index 5a96277..0000000 --- a/src/interfaces/IGnosisSafe.sol +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.8.19; - -interface IGnosisSafe { - enum Operation { - Call, - DelegateCall - } - - function NAME() external view returns (string memory); - - function VERSION() external view returns (string memory); - - function nonce() external view returns (uint256); - - function domainSeparator() external view returns (bytes32); - - function signedMessages(bytes32) external view returns (uint256); - - function approvedHashes(address, bytes32) external view returns (uint256); - - function setup( - address[] calldata _owners, - uint256 _threshold, - address to, - bytes calldata data, - address fallbackHandler, - address paymentToken, - uint256 payment, - address payable paymentReceiver - ) external; - - function execTransaction( - address to, - uint256 value, - bytes calldata data, - Operation operation, - uint256 safeTxGas, - uint256 baseGas, - uint256 gasPrice, - address gasToken, - address payable refundReceiver, - bytes calldata signatures - ) external returns (bool success); - - function requiredTxGas(address to, uint256 value, bytes calldata data, Operation operation) - external - returns (uint256); - - function approveHash(bytes32 hashToApprove) external; - - function signMessage(bytes calldata _data) external; - - function isValidSignature(bytes calldata _data, bytes calldata _signature) external returns (bytes4); - - function getMessageHash(bytes memory message) external view returns (bytes32); - - function encodeTransactionData( - address to, - uint256 value, - bytes memory data, - Operation operation, - uint256 safeTxGas, - uint256 baseGas, - uint256 gasPrice, - address gasToken, - address refundReceiver, - uint256 _nonce - ) external view returns (bytes memory); - - function getTransactionHash( - address to, - uint256 value, - bytes memory data, - Operation operation, - uint256 safeTxGas, - uint256 baseGas, - uint256 gasPrice, - address gasToken, - address refundReceiver, - uint256 _nonce - ) external view returns (bytes32); -} diff --git a/src/interfaces/IGovernance.sol b/src/interfaces/IGovernance.sol index 8d86702..a88f324 100644 --- a/src/interfaces/IGovernance.sol +++ b/src/interfaces/IGovernance.sol @@ -50,6 +50,7 @@ interface IGovernance { function propose(address target, string memory description) external returns (uint256); function castVote(uint256 proposalId, bool support) external; function lock(address owner, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; + function unlock(uint256 amount) external; function lockWithApproval(uint256 amount) external; function execute(uint256 proposalId) external payable; function state(uint256 proposalId) external view returns (ProposalState); diff --git a/test/ExampleProposal.t.sol b/test/ExampleProposal.t.sol deleted file mode 100644 index 9efd7bc..0000000 --- a/test/ExampleProposal.t.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import { ProposalUtils } from "./utils/ProposalUtils.sol"; -import { ExampleProposal } from "@root/ExampleProposal.sol"; - -import { console2 } from "@forge-std/console2.sol"; - -contract TestExampleProposal is ProposalUtils { - modifier executeCurrentProposalBefore() { - createAndExecuteProposal(); - _; - } - - function createAndExecuteProposal() public { - address proposalAddress = address(new ExampleProposal()); /* your proposal initialization */ - - proposeAndExecute(proposalAddress); - } - - /* your tests */ - - function testProposal() public executeCurrentProposalBefore { } -} diff --git a/test/GoerliENSTestProposal.sol b/test/GoerliENSTestProposal.sol new file mode 100644 index 0000000..2e99741 --- /dev/null +++ b/test/GoerliENSTestProposal.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.19; + +import { IENSResolver } from "@interfaces/IENSResolver.sol"; +import { IENSRegistry } from "@interfaces/IENSRegistry.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; + +contract GoerliTestProposal is Ownable { + address ensResolverAddress = 0xd7a4F6473f32aC2Af804B3686AE8F1932bC35750; // goerli ENS resolver for testedy.eth + address ensRegistryAddress = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; + bytes32 testNode = 0x121818cfd40893900bebefa5ccf60544db43ba8fa1d2d56433984132883bee88; // test.testedy.eth + + function executeProposal() public onlyOwner { + IENSResolver ensResolver = IENSResolver(ensResolverAddress); + + bytes memory classicUiIPFSContenthash = hex"e301017012208124caa06a8419371b1d2eab9180191727d1ce0c0832975362f77a679ce614b6"; + + ensResolver.setContenthash(testNode, classicUiIPFSContenthash); + } + + function returnDomainOwnership() public onlyOwner { + IENSRegistry ensRegistry = IENSRegistry(ensRegistryAddress); + + ensRegistry.setOwner(testNode, owner()); + } +} diff --git a/test/UpdateENSDataProposal.t.sol b/test/UpdateENSDataProposal.t.sol new file mode 100644 index 0000000..6f386e6 --- /dev/null +++ b/test/UpdateENSDataProposal.t.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import { ProposalUtils } from "./utils/ProposalUtils.sol"; +import { UpdateENSDataProposal } from "@root/UpdateENSDataProposal.sol"; + +import { console2 } from "@forge-std/console2.sol"; +import { IENSResolver } from "@interfaces/IENSResolver.sol"; + +contract TestExampleProposal is ProposalUtils { + IENSResolver ensResolver = IENSResolver(0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41); + + modifier executeCurrentProposalBefore() { + createAndExecuteProposal(); + _; + } + + function createAndExecuteProposal() public { + address proposalAddress = address(new UpdateENSDataProposal()); + + proposeAndExecute(proposalAddress); + } + + function testStakingAddressChanged() public executeCurrentProposalBefore { + bytes32 stakingRewardsENSNode = 0x3da4b79cd8c20d2fafb1c7cb37a62be8668f543393f6636d421fba0be735e68f; + address stakingAddressAfterProposal = ensResolver.addr(stakingRewardsENSNode); + + console2.log("Address on staking ENS Tornado subdomain (staking-rewards.contract.tornadocash.eth): %s", stakingAddressAfterProposal); + require(stakingAddressAfterProposal == stakingAddress); + } +} diff --git a/test/utils/ProposalUtils.sol b/test/utils/ProposalUtils.sol index 83cec32..31b9197 100644 --- a/test/utils/ProposalUtils.sol +++ b/test/utils/ProposalUtils.sol @@ -67,12 +67,12 @@ contract ProposalUtils is Utils { uint256 proposalExecutableTime = getProposalExecutableTime(proposalId); uint256 tokensUnlockTime = proposalExecutableTime + PROPOSAL_VOTE_EXTEND_TIME + PROPOSAL_EXECUTION_MAX_DURATION + 1 seconds; - if(block.timestamp < tokensUnlockTime) vm.warp(tokensUnlockTime); + if (block.timestamp < tokensUnlockTime) vm.warp(tokensUnlockTime); vm.startPrank(TEST_ADDRESS_ONE); governance.unlock(retrievedAmount); - IERC20(_tokenAddress).transfer(_governanceAddress, retrievedAmount); + IERC20(tornTokenAddress).transfer(governanceAddress, retrievedAmount); vm.stopPrank(); } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..9165c4c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "ES2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "CommonJS" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + "resolveJsonModule": true /* Enable importing .json files. */, + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist" /* Specify an output folder for all emitted files. */, + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +}