From d52aad94aab28f82111f28fa17fb5c2bd9f2c71c Mon Sep 17 00:00:00 2001 From: adjoly Date: Thu, 24 Jul 2025 12:17:59 +0200 Subject: [PATCH 01/11] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20work=20in=20progress,=20not=20done=20yet.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Justfile | 2 + flake.lock | 6 +- flake.nix | 14 +- package.json | 3 +- pnpm-lock.yaml | 648 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 663 insertions(+), 10 deletions(-) diff --git a/Justfile b/Justfile index b71e040..6a884a6 100644 --- a/Justfile +++ b/Justfile @@ -1,3 +1,5 @@ +set dotenv-load + @default: just -l diff --git a/flake.lock b/flake.lock index 44afde9..782aaad 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1751271578, - "narHash": "sha256-P/SQmKDu06x8yv7i0s8bvnnuJYkxVGBWLWHaU+tt4YY=", + "lastModified": 1753250450, + "narHash": "sha256-i+CQV2rPmP8wHxj0aq4siYyohHwVlsh40kV89f3nw1s=", "owner": "nixos", "repo": "nixpkgs", - "rev": "3016b4b15d13f3089db8a41ef937b13a9e33a8df", + "rev": "fc02ee70efb805d3b2865908a13ddd4474557ecf", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index c50d37f..62eb6a2 100644 --- a/flake.nix +++ b/flake.nix @@ -33,18 +33,20 @@ nixd nixfmt-rfc-style + solc + vscode-solidity-server typescript-language-server nodejs_22 pnpm just ]; shellHook = '' - if [ ! -d node_modules/ ]; then - echo Installing node env - pnpm install - fi - export PATH+=:$(pwd)/node_modules/.bin - echo entering ft_trans env + if [ ! -d node_modules/ ]; then + echo Installing node env + pnpm install + fi + export PATH+=:$(pwd)/node_modules/.bin + echo entering ft_trans env ''; }; } diff --git a/package.json b/package.json index 671f7c1..149bcc0 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "fastify": "^5.4.0", "fastify-cli": "^7.4.0", "google-auth-library": "^10.1.0", - "prom-client": "^15.1.3" + "prom-client": "^15.1.3", + "solhint": "^6.0.0" }, "type": "module", "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 788206f..8c12749 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ importers: prom-client: specifier: ^15.1.3 version: 15.1.3 + solhint: + specifier: ^6.0.0 + version: 6.0.0(typescript@5.8.3) devDependencies: '@tailwindcss/vite': specifier: ^4.1.11 @@ -64,6 +67,14 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + '@esbuild/aix-ppc64@0.25.6': resolution: {integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==} engines: {node: '>=18'} @@ -250,6 +261,10 @@ packages: '@fastify/proxy-addr@5.0.0': resolution: {integrity: sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==} + '@humanwhocodes/momoa@2.0.4': + resolution: {integrity: sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==} + engines: {node: '>=10.10.0'} + '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -275,6 +290,18 @@ packages: resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@2.3.1': + resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} + engines: {node: '>=12'} + '@rollup/rollup-android-arm-eabi@4.44.2': resolution: {integrity: sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==} cpu: [arm] @@ -375,6 +402,17 @@ packages: cpu: [x64] os: [win32] + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + + '@solidity-parser/parser@0.20.2': + resolution: {integrity: sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==} + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + '@tailwindcss/node@4.1.11': resolution: {integrity: sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==} @@ -468,6 +506,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + abstract-logging@2.0.1: resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} @@ -475,6 +516,11 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} + ajv-errors@1.0.1: + resolution: {integrity: sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==} + peerDependencies: + ajv: '>=5.0.0' + ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: @@ -483,16 +529,37 @@ packages: ajv: optional: true + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + antlr4@4.13.2: + resolution: {integrity: sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg==} + engines: {node: '>=16'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + asn1.js@5.4.1: resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} + ast-parents@0.0.1: + resolution: {integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -506,6 +573,9 @@ packages: axios@1.10.0: resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base32.js@0.1.0: resolution: {integrity: sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==} engines: {node: '>=0.12.0'} @@ -517,6 +587,12 @@ packages: resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==} engines: {node: '>= 18'} + better-ajv-errors@2.0.2: + resolution: {integrity: sha512-1cLrJXEq46n0hjV8dDYwg9LKYjDb3KbeW7nZTv4kvfoDD9c2DXHIE31nxM+Y/cIfXMggLUfmxbm6h/JoM/yotA==} + engines: {node: '>= 18.20.6'} + peerDependencies: + ajv: 4.11.8 - 8 + better-sqlite3@12.2.0: resolution: {integrity: sha512-eGbYq2CT+tos1fBwLQ/tkBt9J5M3JEHjku4hbvQUePCckkvVf14xWj+1m7dGoK81M/fOjFT7yM9UMeKT/+vFLQ==} engines: {node: 20.x || 22.x || 23.x || 24.x} @@ -536,16 +612,31 @@ packages: bn.js@4.12.2: resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -578,13 +669,29 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + commist@3.2.0: resolution: {integrity: sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==} + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + cookie@1.0.2: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -609,6 +716,10 @@ packages: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -636,6 +747,9 @@ packages: ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -646,6 +760,9 @@ packages: env-schema@6.0.1: resolution: {integrity: sha512-WRD40Q25pP4NUbI3g3CNU5PPzcaiX7YYcPwiCZlfR4qGsKmTlckRixgHww0/fOXiXSNKA87pwshzq0ULTK/48A==} + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -683,6 +800,12 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-json-stringify@6.0.1: resolution: {integrity: sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==} @@ -758,6 +881,10 @@ packages: debug: optional: true + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + form-data@4.0.4: resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} @@ -769,6 +896,13 @@ packages: fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -797,9 +931,18 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + google-auth-library@10.1.0: resolution: {integrity: sha512-GspVjZj1RbyRWpQ9FbAXMKjFGzZwDKnUHi66JJ+tcjcu5/xYAP1pdlWotCuIkMwjfVsxxDvsGZXGLzRt72D0sQ==} engines: {node: '>=18'} @@ -812,6 +955,13 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -838,6 +988,13 @@ packages: help-me@5.0.0: resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -845,6 +1002,18 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -855,11 +1024,18 @@ packages: resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} engines: {node: '>= 10'} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} hasBin: true + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + isbinaryfile@4.0.10: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} engines: {node: '>= 8.0.0'} @@ -872,21 +1048,55 @@ packages: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + json-bigint@1.0.0: resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-ref-resolver@2.0.1: resolution: {integrity: sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + jwa@2.0.1: resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} jws@4.0.0: resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + light-my-request@6.6.0: resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} @@ -954,10 +1164,23 @@ packages: resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} engines: {node: '>= 12.0.0'} + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -980,9 +1203,17 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -1037,6 +1268,10 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + normalize-url@8.0.2: + resolution: {integrity: sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==} + engines: {node: '>=14.16'} + obliterator@2.0.5: resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} @@ -1047,6 +1282,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -1059,10 +1298,26 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1088,6 +1343,10 @@ packages: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -1097,6 +1356,11 @@ packages: engines: {node: '>=10'} hasBin: true + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + process-warning@4.0.1: resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} @@ -1107,15 +1371,26 @@ packages: resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==} engines: {node: ^16 || ^18 || >=20} + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -1132,14 +1407,33 @@ packages: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + registry-auth-token@5.1.0: + resolution: {integrity: sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + resolve-from@5.0.0: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + ret@0.5.0: resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} engines: {node: '>=10'} @@ -1189,6 +1483,14 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + solhint@6.0.0: + resolution: {integrity: sha512-PQGfwFqfeYdebi2tEG1fhVfMjqSzbW3Noz+LYf8UusKe5nkikCghdgEjYQPcGfFZj4snlVyJQt//AaxkubOtVQ==} + hasBin: true + sonic-boom@4.2.0: resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} @@ -1206,9 +1508,17 @@ packages: steed@1.1.3: resolution: {integrity: sha512-EUkci0FAUiE4IvGTSKcDJIQ/eRUP2JJb56+fvZ4sdnguLTqIdKjSxUe138poW8mkvKWXW2sFPrgTsxqoISnmoA==} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -1221,6 +1531,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + tailwindcss@4.1.11: resolution: {integrity: sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==} @@ -1242,6 +1556,9 @@ packages: tdigest@0.1.2: resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} @@ -1264,6 +1581,13 @@ packages: engines: {node: '>=14.17'} hasBin: true + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -1336,6 +1660,14 @@ snapshots: '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.27.1': {} + '@esbuild/aix-ppc64@0.25.6': optional: true @@ -1457,6 +1789,8 @@ snapshots: '@fastify/forwarded': 3.0.0 ipaddr.js: 2.2.0 + '@humanwhocodes/momoa@2.0.4': {} + '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.1.2 @@ -1479,6 +1813,18 @@ snapshots: '@opentelemetry/api@1.9.0': {} + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@2.3.1': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + '@rollup/rollup-android-arm-eabi@4.44.2': optional: true @@ -1539,6 +1885,14 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.44.2': optional: true + '@sindresorhus/is@5.6.0': {} + + '@solidity-parser/parser@0.20.2': {} + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + '@tailwindcss/node@4.1.11': dependencies: '@ampproject/remapping': 2.3.0 @@ -1612,14 +1966,27 @@ snapshots: '@types/estree@1.0.8': {} + '@types/http-cache-semantics@4.0.4': {} + abstract-logging@2.0.1: {} agent-base@7.1.4: {} + ajv-errors@1.0.1(ajv@6.12.6): + dependencies: + ajv: 6.12.6 + ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 @@ -1627,10 +1994,16 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + ansi-regex@5.0.1: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + antlr4@4.13.2: {} + + argparse@2.0.1: {} + asn1.js@5.4.1: dependencies: bn.js: 4.12.2 @@ -1638,6 +2011,10 @@ snapshots: minimalistic-assert: 1.0.1 safer-buffer: 2.1.2 + ast-parents@0.0.1: {} + + astral-regex@2.0.0: {} + asynckit@0.4.0: {} atomic-sleep@1.0.0: {} @@ -1655,6 +2032,8 @@ snapshots: transitivePeerDependencies: - debug + balanced-match@1.0.2: {} + base32.js@0.1.0: {} base64-js@1.5.1: {} @@ -1664,6 +2043,15 @@ snapshots: node-addon-api: 8.4.0 node-gyp-build: 4.8.4 + better-ajv-errors@2.0.2(ajv@6.12.6): + dependencies: + '@babel/code-frame': 7.27.1 + '@humanwhocodes/momoa': 2.0.4 + ajv: 6.12.6 + chalk: 4.1.2 + jsonpointer: 5.0.1 + leven: 3.1.0 + better-sqlite3@12.2.0: dependencies: bindings: 1.5.0 @@ -1685,6 +2073,10 @@ snapshots: bn.js@4.12.2: {} + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + buffer-equal-constant-time@1.0.1: {} buffer@5.7.1: @@ -1692,11 +2084,25 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.2.0 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.0.2 + responselike: 3.0.0 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 + callsites@3.1.0: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -1724,10 +2130,26 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@10.0.1: {} + commist@3.2.0: {} + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + cookie@1.0.2: {} + cosmiconfig@8.3.6(typescript@5.8.3): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.8.3 + data-uri-to-buffer@4.0.1: {} dateformat@4.6.3: {} @@ -1742,6 +2164,8 @@ snapshots: deep-extend@0.6.0: {} + defer-to-connect@2.0.1: {} + delayed-stream@1.0.0: {} dequal@2.0.3: {} @@ -1762,6 +2186,8 @@ snapshots: dependencies: safe-buffer: 5.2.1 + emoji-regex@8.0.0: {} + end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -1777,6 +2203,10 @@ snapshots: dotenv: 16.6.1 dotenv-expand: 10.0.0 + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -1831,6 +2261,10 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-diff@1.3.0: {} + + fast-json-stable-stringify@2.1.0: {} + fast-json-stringify@6.0.1: dependencies: '@fastify/merge-json-schemas': 0.2.1 @@ -1937,6 +2371,8 @@ snapshots: follow-redirects@1.15.9: {} + form-data-encoder@2.1.4: {} + form-data@4.0.4: dependencies: asynckit: 0.4.0 @@ -1951,6 +2387,14 @@ snapshots: fs-constants@1.0.0: {} + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true @@ -1997,8 +2441,18 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-stream@6.0.1: {} + github-from-package@0.0.0: {} + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + google-auth-library@10.1.0: dependencies: base64-js: 1.5.1 @@ -2015,6 +2469,22 @@ snapshots: gopd@1.2.0: {} + got@12.6.1: + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + + graceful-fs@4.2.10: {} + graceful-fs@4.2.11: {} gtoken@8.0.0: @@ -2038,6 +2508,13 @@ snapshots: help-me@5.0.0: {} + http-cache-semantics@4.2.0: {} + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -2047,30 +2524,66 @@ snapshots: ieee754@1.2.1: {} + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + inherits@2.0.4: {} ini@1.3.8: {} ipaddr.js@2.2.0: {} + is-arrayish@0.2.1: {} + is-docker@2.2.1: {} + is-fullwidth-code-point@3.0.0: {} + isbinaryfile@4.0.10: {} jiti@2.4.2: {} joycon@3.1.1: {} + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + json-bigint@1.0.0: dependencies: bignumber.js: 9.3.1 + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + json-schema-ref-resolver@2.0.1: dependencies: dequal: 2.0.3 + json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonpointer@5.0.1: {} + jwa@2.0.1: dependencies: buffer-equal-constant-time: 1.0.1 @@ -2082,6 +2595,16 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 + + leven@3.1.0: {} + light-my-request@6.6.0: dependencies: cookie: 1.0.2 @@ -2133,11 +2656,19 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.1 lightningcss-win32-x64-msvc: 1.30.1 + lines-and-columns@1.2.4: {} + locate-path@3.0.0: dependencies: p-locate: 3.0.0 path-exists: 3.0.0 + lodash.truncate@4.4.2: {} + + lodash@4.17.21: {} + + lowercase-keys@3.0.0: {} + magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.4 @@ -2156,8 +2687,14 @@ snapshots: mimic-response@3.1.0: {} + mimic-response@4.0.0: {} + minimalistic-assert@1.0.1: {} + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.2 + minimist@1.2.8: {} minipass@7.1.2: {} @@ -2196,6 +2733,8 @@ snapshots: node-gyp-build@4.8.4: {} + normalize-url@8.0.2: {} + obliterator@2.0.5: {} on-exit-leak-free@2.1.2: {} @@ -2204,6 +2743,8 @@ snapshots: dependencies: wrappy: 1.0.2 + p-cancelable@3.0.0: {} + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -2214,8 +2755,28 @@ snapshots: p-try@2.2.0: {} + package-json@8.1.1: + dependencies: + got: 12.6.1 + registry-auth-token: 5.1.0 + registry-url: 6.0.1 + semver: 7.7.2 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + path-exists@3.0.0: {} + path-type@4.0.0: {} + picocolors@1.1.1: {} picomatch@4.0.2: {} @@ -2260,6 +2821,8 @@ snapshots: dependencies: find-up: 3.0.0 + pluralize@8.0.0: {} + postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -2281,6 +2844,9 @@ snapshots: tar-fs: 2.1.3 tunnel-agent: 0.6.0 + prettier@2.8.8: + optional: true + process-warning@4.0.1: {} process-warning@5.0.0: {} @@ -2290,6 +2856,8 @@ snapshots: '@opentelemetry/api': 1.9.0 tdigest: 0.1.2 + proto-list@1.2.4: {} + proxy-from-env@1.1.0: {} pump@3.0.3: @@ -2297,8 +2865,12 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode@2.3.1: {} + quick-format-unescaped@4.0.4: {} + quick-lru@5.1.1: {} + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -2316,10 +2888,26 @@ snapshots: real-require@0.2.0: {} + registry-auth-token@5.1.0: + dependencies: + '@pnpm/npm-conf': 2.3.1 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + require-from-string@2.0.2: {} + resolve-alpn@1.2.1: {} + + resolve-from@4.0.0: {} + resolve-from@5.0.0: {} + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + ret@0.5.0: {} reusify@1.1.0: {} @@ -2378,6 +2966,40 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + solhint@6.0.0(typescript@5.8.3): + dependencies: + '@solidity-parser/parser': 0.20.2 + ajv: 6.12.6 + ajv-errors: 1.0.1(ajv@6.12.6) + antlr4: 4.13.2 + ast-parents: 0.0.1 + better-ajv-errors: 2.0.2(ajv@6.12.6) + chalk: 4.1.2 + commander: 10.0.1 + cosmiconfig: 8.3.6(typescript@5.8.3) + fast-diff: 1.3.0 + fs-extra: 11.3.0 + glob: 8.1.0 + ignore: 5.3.2 + js-yaml: 4.1.0 + latest-version: 7.0.0 + lodash: 4.17.21 + pluralize: 8.0.0 + semver: 7.7.2 + strip-ansi: 6.0.1 + table: 6.9.0 + text-table: 0.2.0 + optionalDependencies: + prettier: 2.8.8 + transitivePeerDependencies: + - typescript + sonic-boom@4.2.0: dependencies: atomic-sleep: 1.0.0 @@ -2398,10 +3020,20 @@ snapshots: fastseries: 1.7.2 reusify: 1.1.0 + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + strip-json-comments@2.0.1: {} strip-json-comments@3.1.1: {} @@ -2410,6 +3042,14 @@ snapshots: dependencies: has-flag: 4.0.0 + table@6.9.0: + dependencies: + ajv: 8.17.1 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + tailwindcss@4.1.11: {} tapable@2.2.2: {} @@ -2442,6 +3082,8 @@ snapshots: dependencies: bintrees: 1.0.2 + text-table@0.2.0: {} + thread-stream@3.1.0: dependencies: real-require: 0.2.0 @@ -2461,6 +3103,12 @@ snapshots: typescript@5.8.3: {} + universalify@2.0.1: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + util-deprecate@1.0.2: {} vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1): From f148526efa2043e2701c8b35ecff19ca869c0ce8 Mon Sep 17 00:00:00 2001 From: adjoly Date: Thu, 24 Jul 2025 12:42:33 +0200 Subject: [PATCH 02/11] =?UTF-8?q?=E3=80=8C=F0=9F=8E=89=E3=80=8D=20init:=20?= =?UTF-8?q?started=20blockchain=20dev?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 40 ++++++++++++++++++++++++++++++++++++++ .gitignore | 7 ++++++- .solhint.json | 3 +++ flake.nix | 5 +++++ foundry.toml | 6 ++++++ src/contract/main.sol | 7 +++++++ 6 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/test.yml create mode 100644 .solhint.json create mode 100644 foundry.toml create mode 100644 src/contract/main.sol diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..4481ec6 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,40 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + name: Foundry project + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Show Forge version + run: | + forge --version + + - name: Run Forge fmt + run: | + forge fmt --check + id: fmt + + - name: Run Forge build + run: | + forge build --sizes + id: build + + - name: Run Forge tests + run: | + forge test -vvv + id: test diff --git a/.gitignore b/.gitignore index 438ac14..b63ca91 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,9 @@ node_modules/ .env # built files -dist/* +dist + +# foundry files +lib +out +cache diff --git a/.solhint.json b/.solhint.json new file mode 100644 index 0000000..ce2220e --- /dev/null +++ b/.solhint.json @@ -0,0 +1,3 @@ +{ + "extends": "solhint:recommended" +} diff --git a/flake.nix b/flake.nix index 62eb6a2..698748e 100644 --- a/flake.nix +++ b/flake.nix @@ -39,12 +39,17 @@ nodejs_22 pnpm just + foundry ]; shellHook = '' if [ ! -d node_modules/ ]; then echo Installing node env pnpm install fi + if [ ! -d lib/ ]; then + echo Installing foundry env + forge i + fi export PATH+=:$(pwd)/node_modules/.bin echo entering ft_trans env ''; diff --git a/foundry.toml b/foundry.toml new file mode 100644 index 0000000..5a859ad --- /dev/null +++ b/foundry.toml @@ -0,0 +1,6 @@ +[profile.default] +src = "src/contract" +out = "out" +libs = ["node_modules", "lib"] + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/src/contract/main.sol b/src/contract/main.sol new file mode 100644 index 0000000..4464fd4 --- /dev/null +++ b/src/contract/main.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8; + +contract scoreStore { + +} From 9897235de88073029da6909307355fbb9f13aead Mon Sep 17 00:00:00 2001 From: adjoly Date: Thu, 24 Jul 2025 12:44:52 +0200 Subject: [PATCH 03/11] =?UTF-8?q?=E3=80=8C=E2=9C=8F=EF=B8=8F=E3=80=8D=20no?= =?UTF-8?q?rm:=20normed=20project.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contract/main.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/contract/main.sol b/src/contract/main.sol index 4464fd4..aa644f3 100644 --- a/src/contract/main.sol +++ b/src/contract/main.sol @@ -2,6 +2,4 @@ pragma solidity ^0.8; -contract scoreStore { - -} +contract scoreStore {} From 622548f6788eabc453416c81029d3160d8e8fd0e Mon Sep 17 00:00:00 2001 From: Adam <45126464+KeyZox71@users.noreply.github.com> Date: Thu, 24 Jul 2025 12:50:45 +0200 Subject: [PATCH 04/11] Delete .github directory --- .github/workflows/test.yml | 40 -------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 4481ec6..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: CI - -on: - push: - pull_request: - workflow_dispatch: - -env: - FOUNDRY_PROFILE: ci - -jobs: - check: - name: Foundry project - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - - - name: Show Forge version - run: | - forge --version - - - name: Run Forge fmt - run: | - forge fmt --check - id: fmt - - - name: Run Forge build - run: | - forge build --sizes - id: build - - - name: Run Forge tests - run: | - forge test -vvv - id: test From 9a7fbec3cb262f7f9200b04a91c3e4033c9f2c8b Mon Sep 17 00:00:00 2001 From: adjoly Date: Thu, 24 Jul 2025 15:31:54 +0200 Subject: [PATCH 05/11] =?UTF-8?q?=E3=80=8C=F0=9F=9A=A7=E3=80=8D=20test:=20?= =?UTF-8?q?testing=20things,=20might=20broke.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contract/main.sol | 8 +++++++- test/main.t.sol | 13 +++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/main.t.sol diff --git a/src/contract/main.sol b/src/contract/main.sol index aa644f3..4f400ad 100644 --- a/src/contract/main.sol +++ b/src/contract/main.sol @@ -2,4 +2,10 @@ pragma solidity ^0.8; -contract scoreStore {} +contract scoreStore { + uint16 test = 0; + + function up(uint16 plus) public { + test += plus; + } +} diff --git a/test/main.t.sol b/test/main.t.sol new file mode 100644 index 0000000..bb58846 --- /dev/null +++ b/test/main.t.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8; + +import "src/contract/main.sol"; +import "forge-std/Test.sol"; + +contract mainTest is Test, scoreStore { + function testUp() public { + up(2); + assertEq(test, 2); + } +} From d90cdf825e99e54d91a8a5a8b246ee636893cb81 Mon Sep 17 00:00:00 2001 From: adjoly Date: Mon, 28 Jul 2025 13:21:58 +0200 Subject: [PATCH 06/11] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20work=20in=20progress,=20not=20done=20yet.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 +++ lib/forge-std | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 lib/forge-std diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..888d42d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/forge-std"] + path = lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/lib/forge-std b/lib/forge-std new file mode 160000 index 0000000..60acb7a --- /dev/null +++ b/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 60acb7aaadcce2d68e52986a0a66fe79f07d138f From 443a5a4099da87f36836758fbb213684f4a92a06 Mon Sep 17 00:00:00 2001 From: adjoly Date: Mon, 28 Jul 2025 20:31:21 +0200 Subject: [PATCH 07/11] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20seemingly=20working=20smart=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contract/main.sol | 42 ++++++++++++++++++++++++++++++++++++++---- test/main.t.sol | 30 +++++++++++++++++++++++++----- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/contract/main.sol b/src/contract/main.sol index 4f400ad..a3a2940 100644 --- a/src/contract/main.sol +++ b/src/contract/main.sol @@ -1,11 +1,45 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8; +pragma solidity 0.8.28; + +struct score { + string p1; + string p2; + uint128 p1Score; + uint128 p2Score; +} contract scoreStore { - uint16 test = 0; + address public owner; + uint public lastId; + mapping (uint => score) public scores; - function up(uint16 plus) public { - test += plus; + constructor() { + owner = msg.sender; + lastId = 0; } + + modifier ownerOnly { + require(msg.sender == owner, "Need to be contract owner"); + _; + } + + function addScore(string memory p1, string memory p2, uint128 p1Score, uint128 p2Score) external ownerOnly returns (uint id) { + score memory s; + + s.p1 = p1; + s.p2 = p2; + s.p1Score = p1Score; + s.p2Score = p2Score; + + scores[lastId] = s; + id = lastId; + lastId++; + + return (id); + } + + function getScore(uint id) external view returns (score memory) { + return scores[id]; + } } diff --git a/test/main.t.sol b/test/main.t.sol index bb58846..0014208 100644 --- a/test/main.t.sol +++ b/test/main.t.sol @@ -1,13 +1,33 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8; +pragma solidity 0.8.28; import "src/contract/main.sol"; import "forge-std/Test.sol"; -contract mainTest is Test, scoreStore { - function testUp() public { - up(2); - assertEq(test, 2); +contract scoreStoreTest is Test { + scoreStore scoreS; + address nonOwner = address(1); + + function setUp() public { + scoreS = new scoreStore(); } + + function testAddScore() public { + uint id = scoreS.addScore("omg", "test", 5, 8); + + score memory s = scoreS.getScore(id); + assertEq(s.p1, "omg"); + assertEq(s.p2, "test"); + assertEq(s.p1Score, 5); + assertEq(s.p2Score, 8); + + id = scoreS.addScore("ahhhhh", "test", 5, 8); + + s = scoreS.getScore(id); + assertEq(s.p1, "ahhhhh"); + assertEq(s.p2, "test"); + assertEq(s.p1Score, 5); + assertEq(s.p2Score, 8); + } } From 0449ad7ad2472d851959fe698508f214cdb32bfc Mon Sep 17 00:00:00 2001 From: adjoly Date: Mon, 28 Jul 2025 21:49:48 +0200 Subject: [PATCH 08/11] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20started=20doing=20the=20api=20for=20the=20contract?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 63 +++++++++++++++++++++++ src/api/scoreStore/default.js | 13 +++++ src/api/scoreStore/getTx.js | 19 +++++++ src/contract/{main.sol => scoreStore.sol} | 0 src/utils/scoreDB.js | 52 +++++++++++++++++++ test/{main.t.sol => scoreStore.t.sol} | 6 +-- 7 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 src/api/scoreStore/default.js create mode 100644 src/api/scoreStore/getTx.js rename src/contract/{main.sol => scoreStore.sol} (100%) create mode 100644 src/utils/scoreDB.js rename test/{main.t.sol => scoreStore.t.sol} (83%) diff --git a/package.json b/package.json index 149bcc0..e03c068 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "dependencies": { + "@avalabs/avalanchejs": "^5.0.0", "@fastify/cookie": "^11.0.2", "@fastify/env": "^5.0.2", "@fastify/jwt": "^9.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c12749..a454ff7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@avalabs/avalanchejs': + specifier: ^5.0.0 + version: 5.0.0 '@fastify/cookie': specifier: ^11.0.2 version: 11.0.2 @@ -67,6 +70,10 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@avalabs/avalanchejs@5.0.0': + resolution: {integrity: sha512-0hJK/Hdf8v+q05c8+5K6arFmzq7o1W4I05/Dmr+Es1XRi8canvTu1Y0RruYd6ea2rrvX3UhKrPs3BzLhCTHDrw==} + engines: {node: '>=20'} + '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} @@ -231,6 +238,11 @@ packages: cpu: [x64] os: [win32] + '@ethereumjs/rlp@5.0.0': + resolution: {integrity: sha512-WuS1l7GJmB0n0HsXLozCoEFc9IwYgf3l0gCkKVYgR67puVF1O4OpEaN0hWmm1c+iHUHFCKt1hJrvy5toLg+6ag==} + engines: {node: '>=18'} + hasBin: true + '@fastify/ajv-compiler@4.0.2': resolution: {integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==} @@ -286,6 +298,16 @@ packages: resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} engines: {node: '>=8'} + '@noble/curves@1.3.0': + resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + + '@noble/hashes@1.3.3': + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} + + '@noble/secp256k1@2.0.0': + resolution: {integrity: sha512-rUGBd95e2a45rlmFTqQJYEFA4/gdIARFfuTuTqLglz0PZ6AKyzyXsEZZq7UZn8hZsvaBgpCzKKBJizT2cJERXw==} + '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} @@ -402,6 +424,9 @@ packages: cpu: [x64] os: [win32] + '@scure/base@1.1.5': + resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} + '@sindresorhus/is@5.6.0': resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} @@ -1191,6 +1216,12 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + micro-eth-signer@0.7.2: + resolution: {integrity: sha512-uFH23nqPNdg2KZ9ZdvLG4GO3bTAOWRhwGTsecY4Et2IdQOJ26x6inu8lJ9oyslnYL/0o1vnETCGhMimMvO0SqQ==} + + micro-packed@0.5.3: + resolution: {integrity: sha512-zWRoH+qUb/ZMp9gVZhexvRGCENDM5HEQF4sflqpdilUHWK2/zKR7/MT8GBctnTwbhNJwy1iuk5q6+TYP7/twYA==} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -1660,6 +1691,14 @@ snapshots: '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 + '@avalabs/avalanchejs@5.0.0': + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@noble/secp256k1': 2.0.0 + '@scure/base': 1.1.5 + micro-eth-signer: 0.7.2 + '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 @@ -1746,6 +1785,8 @@ snapshots: '@esbuild/win32-x64@0.25.6': optional: true + '@ethereumjs/rlp@5.0.0': {} + '@fastify/ajv-compiler@4.0.2': dependencies: ajv: 8.17.1 @@ -1811,6 +1852,14 @@ snapshots: '@lukeed/ms@2.0.2': {} + '@noble/curves@1.3.0': + dependencies: + '@noble/hashes': 1.3.3 + + '@noble/hashes@1.3.3': {} + + '@noble/secp256k1@2.0.0': {} + '@opentelemetry/api@1.9.0': {} '@pnpm/config.env-replace@1.1.0': {} @@ -1885,6 +1934,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.44.2': optional: true + '@scure/base@1.1.5': {} + '@sindresorhus/is@5.6.0': {} '@solidity-parser/parser@0.20.2': {} @@ -2679,6 +2730,18 @@ snapshots: math-intrinsics@1.1.0: {} + micro-eth-signer@0.7.2: + dependencies: + '@ethereumjs/rlp': 5.0.0 + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.5 + micro-packed: 0.5.3 + + micro-packed@0.5.3: + dependencies: + '@scure/base': 1.1.5 + mime-db@1.52.0: {} mime-types@2.1.35: diff --git a/src/api/scoreStore/default.js b/src/api/scoreStore/default.js new file mode 100644 index 0000000..627fbc1 --- /dev/null +++ b/src/api/scoreStore/default.js @@ -0,0 +1,13 @@ +import { evm } from '@avalabs/avalanchejs'; +import scoreDB from '../../utils/scoreDB.js'; +import { getTx } from './getTx.js'; + +/** + * @param {import('fastify').FastifyInstance} fastify + * @param {import('fastify').FastifyPluginOptions} options + */ +export default async function(fastify, options) { + fastify.get("/:id", async (request, reply) => { + return getTx(request, reply, fastify); + }); +} diff --git a/src/api/scoreStore/getTx.js b/src/api/scoreStore/getTx.js new file mode 100644 index 0000000..8cbdb84 --- /dev/null +++ b/src/api/scoreStore/getTx.js @@ -0,0 +1,19 @@ +import scoreDB from "../../utils/scoreDB.js"; + +/** + * @async + * @param {import("fastify".FastifyRequest)} request + * @param {import("fastify").FastifyReply} reply + * @param {import("fastify").FastifyInstance} fastify + * + * @returns {import('fastify').FastifyReply} + */ +export async function getTx(request, reply, fastify) { + try { + + } catch (err) { + fastify.log.error(err); + return reply.code(500).send({ error: "Internal server error" }); + } +} + diff --git a/src/contract/main.sol b/src/contract/scoreStore.sol similarity index 100% rename from src/contract/main.sol rename to src/contract/scoreStore.sol diff --git a/src/utils/scoreDB.js b/src/utils/scoreDB.js new file mode 100644 index 0000000..c1e0ffb --- /dev/null +++ b/src/utils/scoreDB.js @@ -0,0 +1,52 @@ +import { Int } from "@avalabs/avalanchejs"; +import Database from "better-sqlite3"; + +var env = process.env.NODE_ENV || 'development'; +let database; + +if (!env || env === 'development') { + database = new Database(":memory:", { verbose: console.log }); +} else { + var dbPath = process.env.DB_PATH || '/db/db.sqlite'; + database = new Database(dbPath); +} + +/** + * @description Can be used to prepare the database + */ +function prepareDB() { + database.exec(` + CREATE TABLE IF NOT EXISTS scoresTx ( + id INTEGER PRIMARY KEY, + txHash TEXT + ) STRICT + `); +} + +/** + * @description Can be used to add a score hash to the DB + * @param {Int} The id of the score + * @param {String} The hash of the score + */ +function addTx(id, txHash) { + const txAdd = database.prepare('INSERT INTO scoresTx (id, txHash) VALUES (?, ?)'); + txAdd.run(id, txHash); +} + +/** + * @description Can be used to get a tx hash from an id + * @param {Int} The id to get + * @returns {String} The tx hash + */ +function getTx(id) { + const txGet = database.prepare('SELECT txHash FROM credentials WHERE id = ?;') + return txGet.get(id); +} + +const scoreDB = { + prepareDB, + addTx, + getTx +}; + +export default scoreDB; diff --git a/test/main.t.sol b/test/scoreStore.t.sol similarity index 83% rename from test/main.t.sol rename to test/scoreStore.t.sol index 0014208..e9b6b91 100644 --- a/test/main.t.sol +++ b/test/scoreStore.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.28; -import "src/contract/main.sol"; +import "src/contract/scoreStore.sol"; import "forge-std/Test.sol"; contract scoreStoreTest is Test { @@ -22,12 +22,12 @@ contract scoreStoreTest is Test { assertEq(s.p1Score, 5); assertEq(s.p2Score, 8); - id = scoreS.addScore("ahhhhh", "test", 5, 8); + id = scoreS.addScore("ahhhhh", "test", 7, 8); s = scoreS.getScore(id); assertEq(s.p1, "ahhhhh"); assertEq(s.p2, "test"); - assertEq(s.p1Score, 5); + assertEq(s.p1Score, 7); assertEq(s.p2Score, 8); } } From 041bb2deb5100aec30e00bf0610d91f647d3f8a0 Mon Sep 17 00:00:00 2001 From: adjoly Date: Wed, 30 Jul 2025 16:04:18 +0200 Subject: [PATCH 09/11] =?UTF-8?q?=E3=80=8C=F0=9F=8F=97=EF=B8=8F=E3=80=8D?= =?UTF-8?q?=20wip:=20seems=20to=20be=20working?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Justfile | 9 ++++ package.json | 1 + pnpm-lock.yaml | 85 ++++++++++++++++++++++++++++-- src/api/scoreStore/addTx.js | 26 ++++++++++ src/api/scoreStore/default.js | 23 ++++++++- src/api/scoreStore/getTx.js | 11 +++- src/contract/scoreStore.json | 1 + src/start.js | 14 +++++ src/utils/scoreDB.js | 6 +-- src/utils/scoreStore_contract.js | 88 ++++++++++++++++++++++++++++++++ 10 files changed, 252 insertions(+), 12 deletions(-) create mode 100644 src/api/scoreStore/addTx.js create mode 100644 src/contract/scoreStore.json create mode 100644 src/utils/scoreStore_contract.js diff --git a/Justfile b/Justfile index 6a884a6..17db908 100644 --- a/Justfile +++ b/Justfile @@ -11,6 +11,9 @@ set dotenv-load @user $FASTIFY_LOG_LEVEL="info" $FASTIFY_PRETTY_LOGS="true": fastify start src/api/user/default.js +@scoreStore $FASTIFY_LOG_LEVEL="info" $FASTIFY_PRETTY_LOGS="true": + fastify start src/api/scoreStore/default.js + # To launch all apis @apis: node src/dev.js @@ -44,3 +47,9 @@ set dotenv-load # To clean only the container launched by the compose @clean-compose: stop-docker docker compose -f docker/docker-compose.yml rm + +@deploy-contract-scoreStore: + forge create scoreStore --rpc-url=${RPC_URL} --private-key=${PRIVATE_KEY} + +@verify-contract: + forge verify-contract --chain-id 43113 --rpc-url=${AVAX_RPC_URL} --watch ${AVAX_CONTRACT_ADDR} diff --git a/package.json b/package.json index e03c068..a46bd97 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "base32.js": "^0.1.0", "bcrypt": "^6.0.0", "better-sqlite3": "^12.2.0", + "ethers": "^6.15.0", "fastify": "^5.4.0", "fastify-cli": "^7.4.0", "google-auth-library": "^10.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a454ff7..bf6d865 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: better-sqlite3: specifier: ^12.2.0 version: 12.2.0 + ethers: + specifier: ^6.15.0 + version: 6.15.0 fastify: specifier: ^5.4.0 version: 5.4.0 @@ -50,7 +53,7 @@ importers: devDependencies: '@tailwindcss/vite': specifier: ^4.1.11 - version: 4.1.11(vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1)) + version: 4.1.11(vite@6.3.5(@types/node@22.7.5)(jiti@2.4.2)(lightningcss@1.30.1)) pino-pretty: specifier: ^13.0.0 version: 13.0.0 @@ -62,10 +65,13 @@ importers: version: 5.8.3 vite: specifier: ^6.3.5 - version: 6.3.5(jiti@2.4.2)(lightningcss@1.30.1) + version: 6.3.5(@types/node@22.7.5)(jiti@2.4.2)(lightningcss@1.30.1) packages: + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -298,9 +304,16 @@ packages: resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} engines: {node: '>=8'} + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + '@noble/curves@1.3.0': resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + '@noble/hashes@1.3.3': resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} engines: {node: '>= 16'} @@ -534,9 +547,15 @@ packages: '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + abstract-logging@2.0.1: resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -809,6 +828,10 @@ packages: engines: {node: '>=18'} hasBin: true + ethers@6.15.0: + resolution: {integrity: sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==} + engines: {node: '>=14.0.0'} + expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -1604,6 +1627,9 @@ packages: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -1612,6 +1638,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -1672,6 +1701,18 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -1686,6 +1727,8 @@ packages: snapshots: + '@adraffy/ens-normalize@1.10.1': {} + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.12 @@ -1852,10 +1895,16 @@ snapshots: '@lukeed/ms@2.0.2': {} + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + '@noble/curves@1.3.0': dependencies: '@noble/hashes': 1.3.3 + '@noble/hashes@1.3.2': {} + '@noble/hashes@1.3.3': {} '@noble/secp256k1@2.0.0': {} @@ -2008,19 +2057,25 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.11 '@tailwindcss/oxide-win32-x64-msvc': 4.1.11 - '@tailwindcss/vite@4.1.11(vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1))': + '@tailwindcss/vite@4.1.11(vite@6.3.5(@types/node@22.7.5)(jiti@2.4.2)(lightningcss@1.30.1))': dependencies: '@tailwindcss/node': 4.1.11 '@tailwindcss/oxide': 4.1.11 tailwindcss: 4.1.11 - vite: 6.3.5(jiti@2.4.2)(lightningcss@1.30.1) + vite: 6.3.5(@types/node@22.7.5)(jiti@2.4.2)(lightningcss@1.30.1) '@types/estree@1.0.8': {} '@types/http-cache-semantics@4.0.4': {} + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + abstract-logging@2.0.1: {} + aes-js@4.0.0-beta.5: {} + agent-base@7.1.4: {} ajv-errors@1.0.1(ajv@6.12.6): @@ -2302,6 +2357,19 @@ snapshots: '@esbuild/win32-ia32': 0.25.6 '@esbuild/win32-x64': 0.25.6 + ethers@6.15.0: + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + expand-template@2.0.3: {} extend@3.0.2: {} @@ -3160,12 +3228,16 @@ snapshots: toad-cache@3.7.0: {} + tslib@2.7.0: {} + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 typescript@5.8.3: {} + undici-types@6.19.8: {} + universalify@2.0.1: {} uri-js@4.4.1: @@ -3174,7 +3246,7 @@ snapshots: util-deprecate@1.0.2: {} - vite@6.3.5(jiti@2.4.2)(lightningcss@1.30.1): + vite@6.3.5(@types/node@22.7.5)(jiti@2.4.2)(lightningcss@1.30.1): dependencies: esbuild: 0.25.6 fdir: 6.4.6(picomatch@4.0.2) @@ -3183,6 +3255,7 @@ snapshots: rollup: 4.44.2 tinyglobby: 0.2.14 optionalDependencies: + '@types/node': 22.7.5 fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.30.1 @@ -3195,6 +3268,8 @@ snapshots: wrappy@1.0.2: {} + ws@8.17.1: {} + xtend@4.0.2: {} yallist@5.0.0: {} diff --git a/src/api/scoreStore/addTx.js b/src/api/scoreStore/addTx.js new file mode 100644 index 0000000..d1640bb --- /dev/null +++ b/src/api/scoreStore/addTx.js @@ -0,0 +1,26 @@ +import { ContractTransactionResponse } from "ethers"; +import scoreDB from "../../utils/scoreDB.js"; +import { callAddScore, callLastId } from "../../utils/scoreStore_contract.js"; + +/** + * @async + * @param {import("fastify").FastifyRequest} request + * @param {import("fastify").FastifyReply} reply + * @param {import("fastify").FastifyInstance} fastify + */ +export async function addTx(request, reply, fastify) { + try { + const id = await callLastId(); + /** @type ContractTransactionResponse */ + const tx = await callAddScore(request.body.p1, request.body.p2, request.body.p1Score, request.body.p2Score); + + scoreDB.addTx(id, tx.hash); + + return reply.code(200).send({ + tx: tx.hash + }); + } catch (err) { + fastify.log.error(err); + return reply.code(500).send({ error: "Internal server error" }); + } +} diff --git a/src/api/scoreStore/default.js b/src/api/scoreStore/default.js index 627fbc1..954fcc8 100644 --- a/src/api/scoreStore/default.js +++ b/src/api/scoreStore/default.js @@ -1,6 +1,8 @@ -import { evm } from '@avalabs/avalanchejs'; -import scoreDB from '../../utils/scoreDB.js'; import { getTx } from './getTx.js'; +import { addTx } from './addTx.js'; +import scoreDB from '../../utils/scoreDB.js'; + +scoreDB.prepareDB(); /** * @param {import('fastify').FastifyInstance} fastify @@ -10,4 +12,21 @@ export default async function(fastify, options) { fastify.get("/:id", async (request, reply) => { return getTx(request, reply, fastify); }); + + fastify.post("/", { + schema: { + body: { + type: 'object', + required: ['p1', 'p2', 'p1Score', 'p2Score'], + properties: { + p1: { type: 'string', minLength: 1 }, + p2: { type: 'string', minLength: 1 }, + p1Score: { type: 'integer', minimum: 0 }, + p2Score: { type: 'integer', minimum: 0 }, + } + } + } + }, async (request, reply) => { + return addTx(request, reply, fastify); + }); } diff --git a/src/api/scoreStore/getTx.js b/src/api/scoreStore/getTx.js index 8cbdb84..ffd8363 100644 --- a/src/api/scoreStore/getTx.js +++ b/src/api/scoreStore/getTx.js @@ -1,4 +1,5 @@ import scoreDB from "../../utils/scoreDB.js"; +import { callGetScore } from "../../utils/scoreStore_contract.js"; /** * @async @@ -10,10 +11,16 @@ import scoreDB from "../../utils/scoreDB.js"; */ export async function getTx(request, reply, fastify) { try { - + const tx = scoreDB.getTx(request.params.id); + + const score = callGetScore(request.params.id); + + return reply.code(200).send({ + score: score, + tx: tx + }); } catch (err) { fastify.log.error(err); return reply.code(500).send({ error: "Internal server error" }); } } - diff --git a/src/contract/scoreStore.json b/src/contract/scoreStore.json new file mode 100644 index 0000000..552e1bc --- /dev/null +++ b/src/contract/scoreStore.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint128","name":"p1Score","type":"uint128"},{"internalType":"uint128","name":"p2Score","type":"uint128"}],"name":"addScore","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"getScore","outputs":[{"components":[{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint128","name":"p1Score","type":"uint128"},{"internalType":"uint128","name":"p2Score","type":"uint128"}],"internalType":"struct score","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"scores","outputs":[{"internalType":"string","name":"p1","type":"string"},{"internalType":"string","name":"p2","type":"string"},{"internalType":"uint128","name":"p1Score","type":"uint128"},{"internalType":"uint128","name":"p2Score","type":"uint128"}],"stateMutability":"view","type":"function"}] diff --git a/src/start.js b/src/start.js index 6111c96..7573f69 100644 --- a/src/start.js +++ b/src/start.js @@ -1,6 +1,7 @@ import Fastify from 'fastify'; import authApi from './api/auth/default.js'; import userApi from './api/user/default.js'; +import scoreApi from './api/scoreStore/default.js'; const loggerOption = { transport: { @@ -47,6 +48,19 @@ async function start() { console.log('User API listening on http://localhost:3002'); } } + + if (target === 'scoreStore' || target === 'all') { + const scoreStore = Fastify({ logger: loggerOption }); + scoreStore.register(scoreApi); + if (target !== 'all') { + await scoreStore.listen({ port: 3000, host: '0.0.0.0' }); + console.log('scoreStore API listening on http://0.0.0.0:3000'); + } + else { + await scoreStore.listen({ port: 3002, host: '127.0.0.1'}); + console.log('scoreStore API listening on http://localhost:3002'); + } + } } start().catch(console.error); diff --git a/src/utils/scoreDB.js b/src/utils/scoreDB.js index c1e0ffb..f2f7a16 100644 --- a/src/utils/scoreDB.js +++ b/src/utils/scoreDB.js @@ -17,7 +17,7 @@ if (!env || env === 'development') { function prepareDB() { database.exec(` CREATE TABLE IF NOT EXISTS scoresTx ( - id INTEGER PRIMARY KEY, + id INT PRIMARY KEY, txHash TEXT ) STRICT `); @@ -25,7 +25,7 @@ function prepareDB() { /** * @description Can be used to add a score hash to the DB - * @param {Int} The id of the score + * @param {Number} The id of the score * @param {String} The hash of the score */ function addTx(id, txHash) { @@ -39,7 +39,7 @@ function addTx(id, txHash) { * @returns {String} The tx hash */ function getTx(id) { - const txGet = database.prepare('SELECT txHash FROM credentials WHERE id = ?;') + const txGet = database.prepare('SELECT txHash FROM scoresTx WHERE id = ?;') return txGet.get(id); } diff --git a/src/utils/scoreStore_contract.js b/src/utils/scoreStore_contract.js new file mode 100644 index 0000000..dd7c69e --- /dev/null +++ b/src/utils/scoreStore_contract.js @@ -0,0 +1,88 @@ +import { ethers } from "ethers"; +import { readFile } from "fs/promises"; + +export const rpc_url = process.env.AVAX_RPC_URL; +export const contract_addr = process.env.AVAX_CONTRACT_ADDR; +export const owner_priv_key = process.env.AVAX_PRIVATE_KEY; + +const provider = new ethers.JsonRpcProvider(rpc_url); + +const wallet = new ethers.Wallet(owner_priv_key, provider); + +async function loadContract() { + try { + const contractABI = JSON.parse(await readFile(new URL('../contract/scoreStore.json', import.meta.url))); + + const contract = new ethers.Contract(contract_addr, contractABI, wallet); + return contract; + } catch (error) { + console.error('Error loading contract ABI:', error); + throw error; + } +} + +/** + * @param {int} id + * @returns {Promise} A promise that resolves to the score details if successful. + * @throws {Error} Throws an error if the function call fails. + */ +async function callGetScore(id) { + try { + const contract = await loadContract(); + const result = await contract.getScore(id); + return result; + } catch (error) { + console.error('Error calling view function:', error); + throw error; + } +} + +/** + * Adds a new score to the smart contract. + * + * @async + * @param {string} p1 - The name of the first player. + * @param {string} p2 - The name of the second player. + * @param {number} p1Score - The score of the first player. + * @param {number} p2Score - The score of the second player. + * @returns {Promise} A promise that resolves to the transaction response if successful. + * @throws {Error} Throws an error if the function call fails. + */ +async function callAddScore(p1, p2, p1Score, p2Score) { + try { + const contract = await loadContract(); + const tx = await contract.addScore(p1, p2, p1Score, p2Score); + console.log('Transaction sent:', tx.hash); + await tx.wait(); // Wait for the transaction to be mined + console.log('Transaction confirmed'); + return tx; + } catch (error) { + console.error('Error calling addScore function:', error); + throw error; + } +} + +/** + * Fetches the last ID from the smart contract. + * + * @async + * @returns {Promise} A promise that resolves to the last ID. + * @throws {Error} Throws an error if the function call fails. + */ +async function callLastId() { + try { + const contract = await loadContract(); + const lastId = await contract.lastId(); + console.log('Last ID:', lastId.toString()); + return lastId; + } catch (error) { + console.error('Error calling lastId function:', error); + throw error; + } +} + +export { + callAddScore, + callGetScore, + callLastId +}; From ffc94f95adc8acffa4d21f054260f8acdd445ec1 Mon Sep 17 00:00:00 2001 From: adjoly Date: Wed, 30 Jul 2025 16:10:13 +0200 Subject: [PATCH 10/11] =?UTF-8?q?=E3=80=8C=F0=9F=94=A8=E3=80=8D=20fix:=20f?= =?UTF-8?q?ixed=20random=20skill=20issue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/scoreStore/addTx.js | 9 +++++---- src/api/scoreStore/getTx.js | 9 +++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/api/scoreStore/addTx.js b/src/api/scoreStore/addTx.js index d1640bb..ab9ae96 100644 --- a/src/api/scoreStore/addTx.js +++ b/src/api/scoreStore/addTx.js @@ -11,13 +11,14 @@ import { callAddScore, callLastId } from "../../utils/scoreStore_contract.js"; export async function addTx(request, reply, fastify) { try { const id = await callLastId(); - /** @type ContractTransactionResponse */ - const tx = await callAddScore(request.body.p1, request.body.p2, request.body.p1Score, request.body.p2Score); + const tx = callAddScore(request.body.p1, request.body.p2, request.body.p1Score, request.body.p2Score); - scoreDB.addTx(id, tx.hash); + tx.then(tx => { + scoreDB.addTx(id, tx.hash); + }); return reply.code(200).send({ - tx: tx.hash + id: id }); } catch (err) { fastify.log.error(err); diff --git a/src/api/scoreStore/getTx.js b/src/api/scoreStore/getTx.js index ffd8363..f932a0a 100644 --- a/src/api/scoreStore/getTx.js +++ b/src/api/scoreStore/getTx.js @@ -13,10 +13,15 @@ export async function getTx(request, reply, fastify) { try { const tx = scoreDB.getTx(request.params.id); - const score = callGetScore(request.params.id); + const score = await callGetScore(request.params.id); return reply.code(200).send({ - score: score, + score: { + p1: score.p1, + p2: score.p2, + p1Score: Number(score.p1Score), + p2Score: Number(score.p2Score) + }, tx: tx }); } catch (err) { From 2e618fdbaaa414a504d5f49ed925cd14a4e0be18 Mon Sep 17 00:00:00 2001 From: Adam <45126464+KeyZox71@users.noreply.github.com> Date: Wed, 30 Jul 2025 16:14:54 +0200 Subject: [PATCH 11/11] Delete pnpm-lock.yaml --- pnpm-lock.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 pnpm-lock.yaml diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index e69de29..0000000