From 49934b3ddd51b58abdbe7ec61c81909e4941fd81 Mon Sep 17 00:00:00 2001 From: Rohit Ranjan Date: Tue, 21 Nov 2023 15:52:33 +0530 Subject: [PATCH] integrate katana & starknet-devnet-rs --- plugin/package.json | 2 +- plugin/pnpm-lock.yaml | 205 +++++++++++++++--- plugin/src/atoms/connection.ts | 6 +- plugin/src/atoms/environment.ts | 2 +- plugin/src/atoms/index.ts | 6 +- .../DevnetAccountSelector/index.tsx | 31 +-- .../components/EnvironmentSelector/index.tsx | 14 +- plugin/src/components/ManualAccount/index.tsx | 15 +- plugin/src/features/Compilation/index.tsx | 37 ++-- plugin/src/features/Environment/index.tsx | 2 +- plugin/src/features/Interaction/index.tsx | 166 ++++++++------ plugin/src/hooks/useAccount.ts | 6 +- plugin/src/hooks/useProvider.ts | 6 +- plugin/src/utils/misc.ts | 24 +- plugin/src/utils/network.ts | 26 ++- plugin/src/utils/types/accounts.ts | 1 + plugin/src/utils/types/contracts.ts | 6 +- plugin/src/utils/types/transaction.ts | 9 +- 18 files changed, 385 insertions(+), 179 deletions(-) diff --git a/plugin/package.json b/plugin/package.json index aadd033f..d38ba425 100644 --- a/plugin/package.json +++ b/plugin/package.json @@ -26,7 +26,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^4.10.1", - "starknet": "5.14.1", + "starknet": "5.19.5", "vite-plugin-svgr": "^4.0.0", "web-vitals": "^2.1.4", "yup": "^1.2.0" diff --git a/plugin/pnpm-lock.yaml b/plugin/pnpm-lock.yaml index e496a1da..1e631d21 100644 --- a/plugin/pnpm-lock.yaml +++ b/plugin/pnpm-lock.yaml @@ -54,7 +54,7 @@ dependencies: version: 2.4.2(react@18.2.0) get-starknet: specifier: ^3.0.1 - version: 3.0.1(starknet@5.14.1) + version: 3.0.1(starknet@5.19.5) jotai: specifier: ^2.2.2 version: 2.2.2(react@18.2.0) @@ -71,8 +71,8 @@ dependencies: specifier: ^4.10.1 version: 4.10.1(react@18.2.0) starknet: - specifier: 5.14.1 - version: 5.14.1 + specifier: 5.19.5 + version: 5.19.5 vite-plugin-svgr: specifier: ^4.0.0 version: 4.0.0(typescript@4.9.5)(vite@4.4.9) @@ -978,18 +978,14 @@ packages: eslint-scope: 5.1.1 dev: true - /@noble/curves@1.0.0: - resolution: {integrity: sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==} + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} dependencies: - '@noble/hashes': 1.3.0 + '@noble/hashes': 1.3.2 dev: false - /@noble/hashes@1.3.0: - resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} - dev: false - - /@noble/hashes@1.3.1: - resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} engines: {node: '>= 16'} dev: false @@ -1705,6 +1701,61 @@ packages: picomatch: 2.3.1 dev: false + /@rometools/cli-darwin-arm64@12.1.3: + resolution: {integrity: sha512-AmFTUDYjBuEGQp/Wwps+2cqUr+qhR7gyXAUnkL5psCuNCz3807TrUq/ecOoct5MIavGJTH6R4aaSL6+f+VlBEg==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rometools/cli-darwin-x64@12.1.3: + resolution: {integrity: sha512-k8MbWna8q4LRlb005N2X+JS1UQ+s3ZLBBvwk4fP8TBxlAJXUz17jLLu/Fi+7DTTEmMhM84TWj4FDKW+rNar28g==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@rometools/cli-linux-arm64@12.1.3: + resolution: {integrity: sha512-X/uLhJ2/FNA3nu5TiyeNPqiD3OZoFfNfRvw6a3ut0jEREPvEn72NI7WPijH/gxSz55znfQ7UQ6iM4DZumUknJg==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rometools/cli-linux-x64@12.1.3: + resolution: {integrity: sha512-csP17q1eWiUXx9z6Jr/JJPibkplyKIwiWPYNzvPCGE8pHlKhwZj3YHRuu7Dm/4EOqx0XFIuqqWZUYm9bkIC8xg==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@rometools/cli-win32-arm64@12.1.3: + resolution: {integrity: sha512-RymHWeod57EBOJY4P636CgUwYA6BQdkQjh56XKk4pLEHO6X1bFyMet2XL7KlHw5qOTalzuzf5jJqUs+vf3jdXQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@rometools/cli-win32-x64@12.1.3: + resolution: {integrity: sha512-yHSKYidqJMV9nADqg78GYA+cZ0hS1twANAjiFibQdXj9aGzD+s/IzIFEIi/U/OBLvWYg/SCw0QVozi2vTlKFDQ==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@scure/starknet@0.3.0: + resolution: {integrity: sha512-Ma66yZlwa5z00qI5alSxdWtIpky5LBhy22acVFdoC5kwwbd9uDyMWEYzWHdNyKmQg9t5Y2UOXzINMeb3yez+Gw==} + dependencies: + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + dev: false + /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.23.0): resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} engines: {node: '>=14'} @@ -2132,6 +2183,16 @@ packages: - supports-color dev: true + /abi-wan-kanabi@1.0.3: + resolution: {integrity: sha512-Xwva0AnhXx/IVlzo3/kwkI7Oa7ZX7codtcSn+Gmoa2PmjGPF/0jeVud9puasIPtB7V50+uBdUj4Mh3iATqtBvg==} + hasBin: true + dependencies: + fs-extra: 10.1.0 + rome: 12.1.3 + typescript: 4.9.5 + yargs: 17.7.2 + dev: false + /acorn-jsx@5.3.2(acorn@8.10.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -2437,6 +2498,15 @@ packages: fsevents: 2.3.3 dev: true + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: false + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -2640,6 +2710,10 @@ packages: minimalistic-crypto-utils: 1.0.1 dev: false + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false + /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true @@ -3251,6 +3325,15 @@ packages: tslib: 2.6.0 dev: false + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: false + /fs-extra@11.1.1: resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} engines: {node: '>=14.14'} @@ -3291,6 +3374,11 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: false + /get-intrinsic@1.2.1: resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} dependencies: @@ -3304,19 +3392,19 @@ packages: engines: {node: '>=6'} dev: false - /get-starknet-core@3.1.0(starknet@5.14.1): + /get-starknet-core@3.1.0(starknet@5.19.5): resolution: {integrity: sha512-SPeYnzqKRXuukNoEr5aobxBmvhUSt4uWs6kFhMXl+3fG2R43u2D2DreDkA1n6T5DF10x5zLogldiHqn/jGlxEA==} peerDependencies: starknet: ^5.14.1 dependencies: - starknet: 5.14.1 + starknet: 5.19.5 dev: false - /get-starknet@3.0.1(starknet@5.14.1): + /get-starknet@3.0.1(starknet@5.19.5): resolution: {integrity: sha512-EyUl+DVQH5PXW2OUdY06/yaqlMizzLKRLzp3S+VhYz+l6wGvW5pmhTXHLaYI4hWfebIDfFkFvAPxVPv/TkWLyA==} dependencies: bowser: 2.11.0 - get-starknet-core: 3.1.0(starknet@5.14.1) + get-starknet-core: 3.1.0(starknet@5.19.5) transitivePeerDependencies: - starknet dev: false @@ -3391,7 +3479,6 @@ packages: /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -3559,6 +3646,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -3745,7 +3837,6 @@ packages: universalify: 2.0.0 optionalDependencies: graceful-fs: 4.2.11 - dev: true /jsx-ast-utils@3.3.4: resolution: {integrity: sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==} @@ -3848,13 +3939,6 @@ packages: engines: {node: '>= 8'} dev: true - /micro-starknet@0.2.3: - resolution: {integrity: sha512-6XBcC+GerlwJSR4iA0VaeXtS2wrayWFcA4PEzrJPMuFmWCaUtuGIq5K/DB5F/XgnL54/zl2Bxo690Lj7mYVA8A==} - dependencies: - '@noble/curves': 1.0.0 - '@noble/hashes': 1.3.1 - dev: false - /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -4272,6 +4356,11 @@ packages: engines: {node: '>=8'} dev: true + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: false + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -4313,6 +4402,20 @@ packages: optionalDependencies: fsevents: 2.3.3 + /rome@12.1.3: + resolution: {integrity: sha512-e+ff72hxDpe/t5/Us7YRBVw3PBET7SeczTQNn6tvrWdrCaAw3qOukQQ+tDCkyFtS4yGsnhjrJbm43ctNbz27Yg==} + engines: {node: '>=14.*'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@rometools/cli-darwin-arm64': 12.1.3 + '@rometools/cli-darwin-x64': 12.1.3 + '@rometools/cli-linux-arm64': 12.1.3 + '@rometools/cli-linux-x64': 12.1.3 + '@rometools/cli-win32-arm64': 12.1.3 + '@rometools/cli-win32-x64': 12.1.3 + dev: false + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -4384,13 +4487,14 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - /starknet@5.14.1: - resolution: {integrity: sha512-EtJwQ6RmFsqSLGuMP+PRp4DwNsMYXy63HDnd1plLCdQKl3FMYajqNKf5RbDl03uGU0uE5ctGp+OW3firHuv6IA==} + /starknet@5.19.5: + resolution: {integrity: sha512-S7V4ifyYd+ApsIwYTd7YA5U2Px+NZkCsQPnmgY/wkc5LLFKhYMNpzHQ5nIA15p70AwtSXCcsEBnHNRBOuci13Q==} dependencies: - '@noble/curves': 1.0.0 + '@noble/curves': 1.2.0 + '@scure/starknet': 0.3.0 + abi-wan-kanabi: 1.0.3 isomorphic-fetch: 3.0.0 lossless-json: 2.0.11 - micro-starknet: 0.2.3 pako: 2.1.0 url-join: 4.0.1 transitivePeerDependencies: @@ -4404,6 +4508,15 @@ packages: internal-slot: 1.0.5 dev: false + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: false + /string.prototype.matchall@4.0.8: resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} dependencies: @@ -4447,7 +4560,6 @@ packages: engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 - dev: true /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} @@ -4615,7 +4727,6 @@ packages: /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} - dev: true /update-browserslist-db@1.0.11(browserslist@4.21.9): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} @@ -4867,6 +4978,15 @@ packages: isexe: 2.0.0 dev: true + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true @@ -4884,6 +5004,11 @@ packages: optional: true dev: false + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: false + /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -4891,6 +5016,24 @@ packages: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: false + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: false + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/plugin/src/atoms/connection.ts b/plugin/src/atoms/connection.ts index 1a036b4f..672c3872 100644 --- a/plugin/src/atoms/connection.ts +++ b/plugin/src/atoms/connection.ts @@ -1,15 +1,13 @@ import { atom } from 'jotai' import { - type Account, type AccountInterface, - type Provider, type ProviderInterface } from 'starknet' import { type StarknetWindowObject } from 'get-starknet' -const account = atom(null) -const provider = atom(null) +const account = atom(null) +const provider = atom(null) const starknetWindowObject = atom(null) export { account, provider, starknetWindowObject } diff --git a/plugin/src/atoms/environment.ts b/plugin/src/atoms/environment.ts index 833c8c2f..0208f575 100644 --- a/plugin/src/atoms/environment.ts +++ b/plugin/src/atoms/environment.ts @@ -4,7 +4,7 @@ import { type Devnet, devnets, type DevnetAccount } from '../utils/network' const devnetAtom = atom(devnets[1]) -export type Env = 'remoteDevnet' | 'wallet' | 'manual' | 'localDevnet' +export type Env = 'remoteDevnet' | 'wallet' | 'manual' | 'localDevnet' | 'localKatanaDevnet' const envAtom = atom('remoteDevnet') diff --git a/plugin/src/atoms/index.ts b/plugin/src/atoms/index.ts index f628611d..f1f49a13 100644 --- a/plugin/src/atoms/index.ts +++ b/plugin/src/atoms/index.ts @@ -1,8 +1,8 @@ import { atomWithStorage } from 'jotai/utils' import { type AbiElement, type Input } from '../utils/types/contracts' import { - type CallContractResponse, - type InvokeTransactionReceiptResponse + type InvokeFunctionResponse, + type CallContractResponse } from 'starknet' const STORAGE_KEYS = { @@ -15,7 +15,7 @@ export type EnhancedInput = Input & { export type EnhancedAbiElement = Omit & { callResponse?: CallContractResponse - invocationResponse?: InvokeTransactionReceiptResponse + invocationResponse?: InvokeFunctionResponse inputs: EnhancedInput[] } diff --git a/plugin/src/components/DevnetAccountSelector/index.tsx b/plugin/src/components/DevnetAccountSelector/index.tsx index 64e5d0c3..f0068aad 100644 --- a/plugin/src/components/DevnetAccountSelector/index.tsx +++ b/plugin/src/components/DevnetAccountSelector/index.tsx @@ -5,7 +5,7 @@ import { } from '../../utils/utils' import { getAccounts } from '../../utils/network' import React, { useEffect, useState } from 'react' -import { Account, Provider } from 'starknet' +import { Account, RpcProvider } from 'starknet' import { MdCopyAll, MdRefresh } from 'react-icons/md' import './devnetAccountSelector.css' import copy from 'copy-to-clipboard' @@ -29,7 +29,8 @@ const DevnetAccountSelector: React.FC = () => { const checkDevnetUrl = async (): Promise => { try { - const response = await fetch(`${devnet.url}/is_alive`, { + const isKatanaEnv = (env === 'localKatanaDevnet') + const response = await fetch(`${devnet.url}/${isKatanaEnv ? '' : 'is_alive'}`, { method: 'GET', redirect: 'follow', headers: { @@ -37,7 +38,15 @@ const DevnetAccountSelector: React.FC = () => { } }) const status = await response.text() - + if (isKatanaEnv) { + const jsonStatus: { health: boolean } = JSON.parse(status) + if (jsonStatus.health) { + setIsDevnetAlive(true) + } else { + setIsDevnetAlive(false) + } + return + } if (status !== 'Alive!!!' || response.status !== 200) { setIsDevnetAlive(false) } else { @@ -83,7 +92,7 @@ const DevnetAccountSelector: React.FC = () => { const refreshDevnetAccounts = async (): Promise => { setAccountRefreshing(true) try { - const accounts = await getAccounts(devnet.url) + const accounts = await getAccounts(devnet.url, (env === 'localKatanaDevnet')) if ( JSON.stringify(accounts) !== JSON.stringify(availableDevnetAccounts) ) { @@ -122,11 +131,7 @@ const DevnetAccountSelector: React.FC = () => { }, [availableDevnetAccounts, devnet]) useEffect(() => { - const newProvider = new Provider({ - sequencer: { - baseUrl: devnet.url - } - }) + const newProvider = new RpcProvider({ nodeUrl: devnet.url }) if (selectedDevnetAccount != null) { setAccount( new Account( @@ -145,11 +150,7 @@ const DevnetAccountSelector: React.FC = () => { } setAccountIdx(value) setSelectedDevnetAccount(availableDevnetAccounts[value]) - const newProvider = new Provider({ - sequencer: { - baseUrl: devnet.url - } - }) + const newProvider = new RpcProvider({ nodeUrl: devnet.url }) if (provider == null) setProvider(newProvider) setAccount( new Account( @@ -202,7 +203,7 @@ const DevnetAccountSelector: React.FC = () => { 6, 4 )} (${getRoundedNumber( - weiToEth(account.initial_balance), + weiToEth((env === 'localKatanaDevnet') ? account.balance : account.initial_balance), 2 )} ether)`} diff --git a/plugin/src/components/EnvironmentSelector/index.tsx b/plugin/src/components/EnvironmentSelector/index.tsx index f1b883a3..7580fbf3 100644 --- a/plugin/src/components/EnvironmentSelector/index.tsx +++ b/plugin/src/components/EnvironmentSelector/index.tsx @@ -19,8 +19,17 @@ const EnvironmentSelector: React.FC = () => { const value = parseInt(ipValue) if (!isNaN(value) && value > 0) { setDevnet(devnets[value - 1]) - if (value === 2) setEnv('remoteDevnet') - else setEnv('localDevnet') + switch (value) { + case 1: + setEnv('localDevnet') + break + case 2: + setEnv('remoteDevnet') + break + case 3: + setEnv('localKatanaDevnet') + break + } setProvider(null) return } @@ -39,6 +48,7 @@ const EnvironmentSelector: React.FC = () => { case 'manual': return 'Manual' case 'localDevnet': return 'Local Devnet' case 'remoteDevnet': return 'Remote Devnet' + case 'localKatanaDevnet': return 'Local Katana Devnet' case 'wallet': return 'Wallet' } } diff --git a/plugin/src/components/ManualAccount/index.tsx b/plugin/src/components/ManualAccount/index.tsx index 494721b2..24d8af20 100644 --- a/plugin/src/components/ManualAccount/index.tsx +++ b/plugin/src/components/ManualAccount/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react' -import { Account, CallData, Provider, ec, hash, stark } from 'starknet' +import { Account, CallData, RpcProvider, ec, hash, stark } from 'starknet' import { type Network, networks as networkConstants, @@ -62,8 +62,9 @@ const ManualAccount: React.FC<{ const chainId = networkEquivalents.get(networkName) if (chainId && netName) { setProvider( - new Provider({ - sequencer: { network: netName, chainId } + new RpcProvider({ + nodeUrl: netName, + chainId }) ) } @@ -174,11 +175,9 @@ const ManualAccount: React.FC<{ setNetworkName(event.target.value) if (event.target.value.length > 0 && chainId && networkName) { setProvider( - new Provider({ - sequencer: { - network: networkName, - chainId - } + new RpcProvider({ + nodeUrl: networkName, + chainId }) ) return diff --git a/plugin/src/features/Compilation/index.tsx b/plugin/src/features/Compilation/index.tsx index cba8ce63..09d9e65f 100644 --- a/plugin/src/features/Compilation/index.tsx +++ b/plugin/src/features/Compilation/index.tsx @@ -17,8 +17,17 @@ import { useAtom, useAtomValue, useSetAtom } from 'jotai' // Imported Atoms import cairoVersionAtom from '../../atoms/cairoVersion' -import { compiledContractsAtom, selectedCompiledContract } from '../../atoms/compiledContracts' -import { activeTomlPathAtom, compilationAtom, hashDirAtom, isCompilingAtom, statusAtom } from '../../atoms/compilation' +import { + compiledContractsAtom, + selectedCompiledContract +} from '../../atoms/compiledContracts' +import { + activeTomlPathAtom, + compilationAtom, + hashDirAtom, + isCompilingAtom, + statusAtom +} from '../../atoms/compilation' import useRemixClient from '../../hooks/useRemixClient' import { isEmpty } from '../../utils/misc' import CompilationCard from './CompilationCard' @@ -102,6 +111,7 @@ const Compilation: React.FC = ({ setAccordian }) => { if (!currentFilePath.endsWith('.cairo')) { throw new Error('Not a valid cairo file') } + const currentFileContent = await remixClient.call( 'fileManager', 'readFile', @@ -302,14 +312,8 @@ const Compilation: React.FC = ({ setAccordian }) => { }) try { - await writeFileContent( - sierraPath, - sierra.file_content - ) - await writeFileContent( - casmPath, - casm.file_content - ) + await writeFileContent(sierraPath, sierra.file_content) + await writeFileContent(casmPath, casm.file_content) } catch (e) { if (e instanceof Error) { await remixClient.call( @@ -393,9 +397,7 @@ const Compilation: React.FC = ({ setAccordian }) => { } ) if (!response.ok) { - await showNotification( - 'Could not reach cairo compilation server' - ) + await showNotification('Could not reach cairo compilation server') throw new Error('Cairo Compilation Request Failed') } } @@ -429,9 +431,7 @@ const Compilation: React.FC = ({ setAccordian }) => { 'compile-scarb-result' ) } catch (e) { - await showNotification( - 'Could not reach cairo compilation server' - ) + await showNotification('Could not reach cairo compilation server') throw new Error('Cairo Compilation Request Failed') } const scarbCompile: ScarbCompileResponse = JSON.parse(result) @@ -440,7 +440,8 @@ const Compilation: React.FC = ({ setAccordian }) => { { id: 'starknetRemixPluginAlert', title: 'Scarb compilation failed!', - message: 'Scarb compilation failed!, you can read logs in the terminal console' + message: + 'Scarb compilation failed!, you can read logs in the terminal console' }, 'alert' ) @@ -512,7 +513,7 @@ const Compilation: React.FC = ({ setAccordian }) => { } if (notifyCasmInclusion) { await showNotification( - 'Please include \'casm=true\' in Scarb.toml to deploy cairo contracts' + "Please include 'casm=true' in Scarb.toml to deploy cairo contracts" ) } diff --git a/plugin/src/features/Environment/index.tsx b/plugin/src/features/Environment/index.tsx index 5f0506a7..d82fa4dd 100644 --- a/plugin/src/features/Environment/index.tsx +++ b/plugin/src/features/Environment/index.tsx @@ -81,7 +81,7 @@ const Environment: React.FC = () => {
- {['localDevnet', 'remoteDevnet'].includes(env) ? ( + {['localDevnet', 'remoteDevnet', 'localKatanaDevnet'].includes(env) ? ( ) : ( > + setInteractionStatus: React.Dispatch< + React.SetStateAction<'loading' | 'error' | 'success' | ''> + > } const Interaction: React.FC = (props) => { @@ -85,8 +94,7 @@ const Interaction: React.FC = (props) => { if (selectedContract != null) { const currentContractObj = contractsState[selectedContract.address] switch (stateType) { - case 'view': - { + case 'view': { const readState = currentContractObj.readState const oldElemIdx = readState.findIndex( (rObj) => rObj.name === funcName @@ -114,8 +122,7 @@ const Interaction: React.FC = (props) => { } break } - case 'external': - { + case 'external': { const writeState = currentContractObj.writeState const oldElemWIdx = writeState.findIndex( (rObj) => rObj.name === funcName @@ -126,7 +133,7 @@ const Interaction: React.FC = (props) => { ...oldElemW, invocationResponse: response as InvokeFunctionResponse } - const newWriteStateFunc = writeState.map((rObj) => { + const newWriteState = writeState.map((rObj) => { if (rObj.name === funcName) { return newElemW } @@ -137,7 +144,7 @@ const Interaction: React.FC = (props) => { ...contractsState, [selectedContract?.address]: { ...currentContractObj, - writeState: newWriteStateFunc + writeState: newWriteState } }) } @@ -200,7 +207,8 @@ const Interaction: React.FC = (props) => { }) // Merge with old objs, since old objs can have responses. - const oldContractObj: undefined | UiAbiState = contractsState[selectedContract.address] + const oldContractObj: undefined | UiAbiState = + contractsState[selectedContract.address] if (oldContractObj !== undefined) { const oldReadObjs = oldContractObj.readState const oldWriteObj = oldContractObj.writeState @@ -251,11 +259,9 @@ const Interaction: React.FC = (props) => { contractAddress: string, entrypoint: string, calldata: BigNumberish[] = [] - ): (( - account: Account | AccountInterface - ) => Promise) => { + ): ((account: AccountInterface) => Promise) => { const invocation = async ( - account: Account | AccountInterface + account: AccountInterface ): Promise => { const response = await account.execute({ contractAddress, @@ -301,11 +307,9 @@ const Interaction: React.FC = (props) => { contractAddress: string, entrypoint: string, calldata: BigNumberish[] = [] - ): (( - account: Account | AccountInterface - ) => Promise) => { + ): ((account: AccountInterface) => Promise) => { const call = async ( - account: Account | AccountInterface + account: AccountInterface ): Promise => { const response = await account.callContract({ contractAddress, @@ -376,10 +380,9 @@ const Interaction: React.FC = (props) => { return } switch (type) { - case 'view': - { + case 'view': { const readFunctions = - contractsState[selectedContract?.address].readState + contractsState[selectedContract?.address].readState const newReadFns = readFunctions.map((rf) => { if (rf.name === funcName) { return { @@ -395,10 +398,9 @@ const Interaction: React.FC = (props) => { setReadState(newReadFns) break } - case 'external': - { + case 'external': { const writeFunctions = - contractsState[selectedContract?.address].writeState + contractsState[selectedContract?.address].writeState const newWriteFns = writeFunctions.map((rf) => { if (rf.name === funcName) { return { @@ -428,10 +430,9 @@ const Interaction: React.FC = (props) => { return } switch (type) { - case 'view': - { + case 'view': { const readFunctions = - contractsState[selectedContract?.address].readState + contractsState[selectedContract?.address].readState const newReadFns = readFunctions.map((rf) => { if (rf.name === funcName) { const oldInputIdx = rf.inputs.findIndex((i) => i.name === inputName) @@ -456,10 +457,9 @@ const Interaction: React.FC = (props) => { setReadState(newReadFns) break } - case 'external': - { + case 'external': { const writeFunctions = - contractsState[selectedContract?.address].writeState + contractsState[selectedContract?.address].writeState const newWriteFns = writeFunctions.map((rf) => { if (rf.name === funcName) { const oldInputIdx = rf.inputs.findIndex((i) => i.name === inputName) @@ -497,31 +497,33 @@ const Interaction: React.FC = (props) => { return } switch (type) { - case 'view': - { + case 'view': { const readFunctions = - contractsState[selectedContract?.address].readState + contractsState[selectedContract?.address].readState const calledReadFn = readFunctions.find((rf) => rf.name === funcName) if (calledReadFn != null) { const transformedCallData = makeCallDatafromInput( calledReadFn.inputs, finalIPs ) - handleCall(funcName, 'view', transformedCallData).catch(e => { console.error(e) }) + handleCall(funcName, 'view', transformedCallData).catch((e) => { + console.error(e) + }) } break } - case 'external': - { + case 'external': { const writeFunctions = - contractsState[selectedContract?.address].writeState + contractsState[selectedContract?.address].writeState const calledWriteFn = writeFunctions.find((rf) => rf.name === funcName) if (calledWriteFn != null) { const transformedCallData = makeCallDatafromInput( calledWriteFn.inputs, finalIPs ) - handleCall(funcName, 'external', transformedCallData).catch(e => { console.error(e) }) + handleCall(funcName, 'external', transformedCallData).catch((e) => { + console.error(e) + }) } break } @@ -570,7 +572,8 @@ const Interaction: React.FC = (props) => { remixClient.emit('statusChanged', { key: 'succeed', type: 'success', - title: 'Function call succeeded, results are written to the terminal log' + title: + 'Function call succeeded, results are written to the terminal log' }) } else { const invocation = getInvocation( @@ -629,35 +632,44 @@ const Interaction: React.FC = (props) => { }) } } - const isContractSelected = contracts.length > 0 && selectedContract != null && selectedContract !== undefined - const isAccountAndContractValid = isContractSelected && account != null && selectedContract.deployedInfo.some( - (info) => info.address === account.address && info.chainId === chainId - ) + const isContractSelected = + contracts.length > 0 && + selectedContract != null && + selectedContract !== undefined + const isAccountAndContractValid = + isContractSelected && + account != null && + selectedContract.deployedInfo.some( + (info) => info.address === account.address && info.chainId === chainId + ) return ( {contracts.length > 0 && selectedContract != null ? ( - + ) : ( -
-

No compiled contracts to interact with... Yet.

-
+
+

No compiled contracts to interact with... Yet.

+
)} - {isContractSelected && isAccountAndContractValid - ? <> + {isContractSelected && isAccountAndContractValid ? ( + <>
{contractsState[selectedContract.address]?.readState?.map( (func, index) => { - const init: Record = func.inputs.reduce((p, c) => { - return { - ...p, - // Check if already has a rawInput in storage - [c.name]: c.rawInput ?? '' - } - }, {}) + const init: Record = func.inputs.reduce( + (p, c) => { + return { + ...p, + // Check if already has a rawInput in storage + [c.name]: c.rawInput ?? '' + } + }, + {} + ) const validationSchema = func.inputs.reduce((p, c) => { return { @@ -670,7 +682,10 @@ const Interaction: React.FC = (props) => { }, {}) return ( -
+
{ @@ -727,9 +742,15 @@ const Interaction: React.FC = (props) => {
{func.inputs.length > 0 && func.inputs.map((input, index) => { - const hasErrors = (!isEmpty(errors[input.name]) && touched[input.name]) ?? false + const hasErrors = + (!isEmpty(errors[input.name]) && + touched[input.name]) ?? + false return ( -
+
{hasErrors && (
@@ -741,8 +762,9 @@ const Interaction: React.FC = (props) => { name={input.name} value={values[input.name]} data-datatype={input.type} - placeholder={`${input.name - } (${getParameterType(input.type) ?? ''})`} + placeholder={`${input.name} (${ + getParameterType(input.type) ?? '' + })`} onBlur={handleBlur} disabled={isSubmitting} className={ @@ -855,9 +877,15 @@ const Interaction: React.FC = (props) => {
{func.inputs.length > 0 && func.inputs.map((input, index) => { - const hasErrors = (errors[input.name] != null && touched[input.name] != null) ?? false + const hasErrors = + (errors[input.name] != null && + touched[input.name] != null) ?? + false return ( -
+
{hasErrors && (
@@ -869,8 +897,9 @@ const Interaction: React.FC = (props) => { name={input.name} value={values[input.name]} data-datatype={input.type} - placeholder={`${input.name - } (${getParameterType(input.type)})`} + placeholder={`${ + input.name + } (${getParameterType(input.type)})`} onBlur={handleBlur} disabled={isSubmitting} className={ @@ -904,8 +933,9 @@ const Interaction: React.FC = (props) => { } )} - :

Selected contract is not deployed yet...

- } + ) : ( +

Selected contract is not deployed yet...

+ )} ) } diff --git a/plugin/src/hooks/useAccount.ts b/plugin/src/hooks/useAccount.ts index 06f1c7e8..76adfd8c 100644 --- a/plugin/src/hooks/useAccount.ts +++ b/plugin/src/hooks/useAccount.ts @@ -1,12 +1,12 @@ import type React from 'react' -import { type Account, type AccountInterface } from 'starknet' +import { type AccountInterface } from 'starknet' import { account as atomAccount } from '../atoms/connection' import { useAtom } from 'jotai' const useAccount = (): { - account: Account | AccountInterface | null - setAccount: React.Dispatch> + account: AccountInterface | null + setAccount: React.Dispatch> } => { const [account, setAccount] = useAtom(atomAccount) return { account, setAccount } diff --git a/plugin/src/hooks/useProvider.ts b/plugin/src/hooks/useProvider.ts index ae799b78..c12a73ab 100644 --- a/plugin/src/hooks/useProvider.ts +++ b/plugin/src/hooks/useProvider.ts @@ -1,11 +1,11 @@ import type React from 'react' -import { type Provider, type ProviderInterface } from 'starknet' +import { type ProviderInterface } from 'starknet' import { provider as atomProvider } from '../atoms/connection' import { useAtom } from 'jotai' const useProvider = (): { - provider: Provider | ProviderInterface | null - setProvider: React.Dispatch> + provider: ProviderInterface | null + setProvider: React.Dispatch> } => { const [provider, setProvider] = useAtom(atomProvider) return { provider, setProvider } diff --git a/plugin/src/utils/misc.ts b/plugin/src/utils/misc.ts index 69bb38fa..91f0fd7a 100644 --- a/plugin/src/utils/misc.ts +++ b/plugin/src/utils/misc.ts @@ -1,31 +1,31 @@ // Set of functions I thought I might need to use in the future. // TODO: erase if not neeeded. -import { Provider } from 'starknet' +import { RpcProvider } from 'starknet' import { devnetUrl } from './constants' -const getProvider = (network: string): Provider => { +const getProvider = (network: string): RpcProvider => { switch (network) { case 'mainnet-alpha': - return new Provider({ - sequencer: { baseUrl: 'https://sequencer.starknet.io' } + return new RpcProvider({ + nodeUrl: 'https://sequencer.starknet.io' }) case 'goerli-alpha': - return new Provider({ - sequencer: { baseUrl: 'https://goerli.starknet.io' } + return new RpcProvider({ + nodeUrl: 'https://goerli.starknet.io' }) case 'goerli-alpha-2': - return new Provider({ - sequencer: { baseUrl: 'https://goerli.starknet.io' } + return new RpcProvider({ + nodeUrl: 'https://goerli.starknet.io' }) case devnetUrl: - return new Provider({ + return new RpcProvider({ // TODO: Let user chose port eventually. - sequencer: { baseUrl: devnetUrl } + nodeUrl: devnetUrl }) default: - return new Provider({ - sequencer: { baseUrl: 'https://goerli.starknet.io' } + return new RpcProvider({ + nodeUrl: 'https://goerli.starknet.io' }) } } diff --git a/plugin/src/utils/network.ts b/plugin/src/utils/network.ts index 54b5eaf4..87f42e85 100644 --- a/plugin/src/utils/network.ts +++ b/plugin/src/utils/network.ts @@ -4,8 +4,6 @@ const apiUrl: string = import.meta.env.VITE_API_URL ?? 'cairo-compile-remix-test const devnetUrl: string = import.meta.env.VITE_DEVNET_URL ?? 'http://localhost:5050' const remoteDevnetUrl: string = import.meta.env.VITE_REMOTE_DEVNET_URL ?? 'https://starknet-devnet-dev.nethermind.io' -console.log(apiUrl) - interface Devnet { name: string url: string @@ -19,12 +17,34 @@ const devnets: Devnet[] = [ { name: 'Remote Devnet', url: remoteDevnetUrl + }, + { + name: 'Local Katana Devnet', + url: devnetUrl } ] const getAccounts = async ( - customDevnetUrl: string = devnetUrl + customDevnetUrl: string = devnetUrl, + isKatana: boolean = false ): Promise => { + if (isKatana) { + const response = await fetch(`${customDevnetUrl}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + jsonrpc: '2.0', + method: 'katana_predeployedAccounts', + params: [], + id: 1 + }) + }) + const jsonResp = await response.json() + const accounts: DevnetAccount[] = jsonResp.result + return accounts + } const response = await fetch(`${customDevnetUrl}/predeployed_accounts`) const accounts: DevnetAccount[] = await response.json() return accounts diff --git a/plugin/src/utils/types/accounts.ts b/plugin/src/utils/types/accounts.ts index bce11c72..b536fa95 100644 --- a/plugin/src/utils/types/accounts.ts +++ b/plugin/src/utils/types/accounts.ts @@ -9,6 +9,7 @@ enum StarknetChainId { } interface DevnetAccount { + balance: number initial_balance: number address: string private_key: string diff --git a/plugin/src/utils/types/contracts.ts b/plugin/src/utils/types/contracts.ts index 217ae780..d5780cf1 100644 --- a/plugin/src/utils/types/contracts.ts +++ b/plugin/src/utils/types/contracts.ts @@ -1,9 +1,9 @@ import { type BigNumberish } from 'ethers' import { type constants, - type Account, type CairoAssembly, - type InvokeFunctionResponse + type InvokeFunctionResponse, + type AccountInterface } from 'starknet' interface Contract { @@ -39,7 +39,7 @@ interface AbiElement { state_mutability?: string calldata?: CallDataObj[] items?: AbiElement[] - callFunction?: (account: Account) => Promise + callFunction?: (account: AccountInterface) => Promise } type Abi = AbiElement[] diff --git a/plugin/src/utils/types/transaction.ts b/plugin/src/utils/types/transaction.ts index a9b139fa..4412c8fd 100644 --- a/plugin/src/utils/types/transaction.ts +++ b/plugin/src/utils/types/transaction.ts @@ -1,9 +1,12 @@ -import { type Provider, type Account, type AccountInterface, type ProviderInterface } from 'starknet' +import { + type AccountInterface, + type ProviderInterface +} from 'starknet' export interface Transaction { type: 'deploy' | 'declare' | 'invoke' | 'deployAccount' txId: string env: string - account: Account | AccountInterface | null - provider: Provider | ProviderInterface | null + account: AccountInterface | null + provider: ProviderInterface | null }