From d861ab6c5ed4ce151d1c1fa9e1215f591b27d4eb Mon Sep 17 00:00:00 2001 From: samepant Date: Mon, 8 Jan 2024 12:00:17 -0500 Subject: [PATCH 01/12] update viem, wagmi, use rainbowkit --- frontend/package.json | 5 +- yarn.lock | 848 +++++++++++++++++++++++------------------- 2 files changed, 473 insertions(+), 380 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 62ac519..55c3587 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,6 +4,7 @@ "private": true, "devDependencies": { "0xsequence": "^1.6.2", + "@rainbow-me/rainbowkit": "^1.3.3", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", "@walletconnect/core": "^2.10.2", @@ -25,8 +26,8 @@ "react-scripts": "5.0.1", "typescript": "^5.2.2", "typescript-plugin-css-modules": "^5.0.1", - "viem": "^1.16.5", - "wagmi": "^1.4.3" + "viem": "^1.21.4", + "wagmi": "^1.4.13" }, "scripts": { "start": "react-scripts start", diff --git a/yarn.lock b/yarn.lock index 7a73559..b5fa626 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1886,7 +1886,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.8.4": +"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.8.4": version: 7.23.2 resolution: "@babel/runtime@npm:7.23.2" dependencies: @@ -1989,27 +1989,19 @@ __metadata: linkType: hard "@coinbase/wallet-sdk@npm:^3.6.6": - version: 3.7.2 - resolution: "@coinbase/wallet-sdk@npm:3.7.2" + version: 3.9.1 + resolution: "@coinbase/wallet-sdk@npm:3.9.1" dependencies: - "@metamask/safe-event-emitter": 2.0.0 - "@solana/web3.js": ^1.70.1 - bind-decorator: ^1.0.11 - bn.js: ^5.1.1 + bn.js: ^5.2.1 buffer: ^6.0.3 - clsx: ^1.1.0 - eth-block-tracker: 6.1.0 - eth-json-rpc-filters: 5.1.0 - eth-rpc-errors: 4.0.2 - json-rpc-engine: 6.1.0 - keccak: ^3.0.1 - preact: ^10.5.9 - qs: ^6.10.3 - rxjs: ^6.6.3 + clsx: ^1.2.1 + eth-block-tracker: ^7.1.0 + eth-json-rpc-filters: ^6.0.0 + eventemitter3: ^5.0.1 + keccak: ^3.0.3 + preact: ^10.16.0 sha.js: ^2.4.11 - stream-browserify: ^3.0.0 - util: ^0.12.4 - checksum: d42a7b7e443942f657f636eede671979024308c6713af68f774309c04c0e1974cdbfe83514adebf4c0bcdb84adce6a026e5a92b5cff35e08eb1fb0772b1ec7e5 + checksum: 8e6ab9c1fdfe87c703e65e046c62b5d24821b103ae616646dd79b5639a6fef8861e5548a501598bd21d3b6884cd2ed86821b4517c1d3b90574f23f4ca4a459ba languageName: node linkType: hard @@ -2195,6 +2187,13 @@ __metadata: languageName: node linkType: hard +"@emotion/hash@npm:^0.9.0": + version: 0.9.1 + resolution: "@emotion/hash@npm:0.9.1" + checksum: 716e17e48bf9047bf9383982c071de49f2615310fb4e986738931776f5a823bc1f29c84501abe0d3df91a3803c80122d24e28b57351bca9e01356ebb33d89876 + languageName: node + linkType: hard + "@erc6551/reference@https://github.com/erc6551/reference.git#commit=a38d3fe531c6c644d4880f41229ef49252804b92": version: 0.2.1 resolution: "@erc6551/reference@https://github.com/erc6551/reference.git#commit=a38d3fe531c6c644d4880f41229ef49252804b92" @@ -2244,6 +2243,16 @@ __metadata: languageName: node linkType: hard +"@ethereumjs/common@npm:^3.2.0": + version: 3.2.0 + resolution: "@ethereumjs/common@npm:3.2.0" + dependencies: + "@ethereumjs/util": ^8.1.0 + crc-32: ^1.2.0 + checksum: cb9cc11f5c868cb577ba611cebf55046e509218bbb89b47ccce010776dafe8256d70f8f43fab238aec74cf71f62601cd5842bc03a83261200802de365732a14b + languageName: node + linkType: hard + "@ethereumjs/rlp@npm:^4.0.1": version: 4.0.1 resolution: "@ethereumjs/rlp@npm:4.0.1" @@ -2253,6 +2262,18 @@ __metadata: languageName: node linkType: hard +"@ethereumjs/tx@npm:^4.1.2, @ethereumjs/tx@npm:^4.2.0": + version: 4.2.0 + resolution: "@ethereumjs/tx@npm:4.2.0" + dependencies: + "@ethereumjs/common": ^3.2.0 + "@ethereumjs/rlp": ^4.0.1 + "@ethereumjs/util": ^8.1.0 + ethereum-cryptography: ^2.0.0 + checksum: 87a3f5f2452cfbf6712f8847525a80c213210ed453c211c793c5df801fe35ecef28bae17fadd222fcbdd94277478a47e52d2b916a90a6b30cda21f1e0cdaee42 + languageName: node + linkType: hard + "@ethereumjs/util@npm:^8.1.0": version: 8.1.0 resolution: "@ethereumjs/util@npm:8.1.0" @@ -3111,13 +3132,6 @@ __metadata: languageName: node linkType: hard -"@ledgerhq/connect-kit-loader@npm:^1.1.0": - version: 1.1.2 - resolution: "@ledgerhq/connect-kit-loader@npm:1.1.2" - checksum: 614fdd9ac2363da60af667adcfe4721f863d8ea06ee45a08192a162c28e806dc07491bee4833d14def74de673eac1f1450eaf67e783c8c28da4e0cd095b4474a - languageName: node - linkType: hard - "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.4 resolution: "@leichtgewicht/ip-codec@npm:2.0.4" @@ -3159,6 +3173,17 @@ __metadata: languageName: node linkType: hard +"@metamask/eth-json-rpc-provider@npm:^1.0.0": + version: 1.0.1 + resolution: "@metamask/eth-json-rpc-provider@npm:1.0.1" + dependencies: + "@metamask/json-rpc-engine": ^7.0.0 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^5.0.1 + checksum: ff97648b002d2889bd020c03abc26137cf068df3280e46144b5333c1b294f35f5099361343825f900ef20b9dcb6819495830b7a99eb1cbfbd671e5b11c0dfde1 + languageName: node + linkType: hard + "@metamask/eth-sig-util@npm:^4.0.0": version: 4.0.1 resolution: "@metamask/eth-sig-util@npm:4.0.1" @@ -3172,22 +3197,67 @@ __metadata: languageName: node linkType: hard -"@metamask/safe-event-emitter@npm:2.0.0, @metamask/safe-event-emitter@npm:^2.0.0": +"@metamask/json-rpc-engine@npm:^7.0.0": + version: 7.3.1 + resolution: "@metamask/json-rpc-engine@npm:7.3.1" + dependencies: + "@metamask/rpc-errors": ^6.1.0 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^8.2.0 + checksum: 4952eb4e70c0011d334fb4a9bf56aa2d68bef745c892dddd06f6ed7e6303fb95b3b60b4e32c88b6d77bfc5091acc8e71ad274f389419e4bdcc5741ef49cde87d + languageName: node + linkType: hard + +"@metamask/rpc-errors@npm:^6.1.0": + version: 6.1.0 + resolution: "@metamask/rpc-errors@npm:6.1.0" + dependencies: + "@metamask/utils": ^8.1.0 + fast-safe-stringify: ^2.0.6 + checksum: 9f4821d804e2fcaa8987b0958d02c6d829b7c7db49740c811cb593f381d0c4b00dabb7f1802907f1b2f6126f7c0d83ec34219183d29650f5d24df014ac72906a + languageName: node + linkType: hard + +"@metamask/safe-event-emitter@npm:^2.0.0": version: 2.0.0 resolution: "@metamask/safe-event-emitter@npm:2.0.0" checksum: 8b717ac5d53df0027c05509f03d0534700b5898dd1c3a53fb2dc4c0499ca5971b14aae67f522d09eb9f509e77f50afa95fdb3eda1afbff8b071c18a3d2905e93 languageName: node linkType: hard -"@metamask/utils@npm:^3.0.1": - version: 3.6.0 - resolution: "@metamask/utils@npm:3.6.0" +"@metamask/safe-event-emitter@npm:^3.0.0": + version: 3.0.0 + resolution: "@metamask/safe-event-emitter@npm:3.0.0" + checksum: 8dc58a76f9f75bf2405931465fc311c68043d851e6b8ebe9f82ae339073a08a83430dba9338f8e3adc4bfc8067607125074bcafa32baee3a5157f42343dc89e5 + languageName: node + linkType: hard + +"@metamask/utils@npm:^5.0.1": + version: 5.0.2 + resolution: "@metamask/utils@npm:5.0.2" dependencies: + "@ethereumjs/tx": ^4.1.2 "@types/debug": ^4.1.7 debug: ^4.3.4 semver: ^7.3.8 superstruct: ^1.0.3 - checksum: 1ebc6677bb017e4d09d4af143621fe27194d8ed815234cfd76469c3c734dc1db2ea7b577c01a2096c21c04d8c9c4d721d3035b5353fe2ded3b4737f326755e43 + checksum: eca82e42911b2840deb4f32f0f215c5ffd14d22d68afbbe92d3180e920e509e310777b15eab29def3448f3535b66596ceb4c23666ec846adacc8e1bb093ff882 + languageName: node + linkType: hard + +"@metamask/utils@npm:^8.1.0, @metamask/utils@npm:^8.2.0": + version: 8.2.1 + resolution: "@metamask/utils@npm:8.2.1" + dependencies: + "@ethereumjs/tx": ^4.2.0 + "@noble/hashes": ^1.3.1 + "@scure/base": ^1.1.3 + "@types/debug": ^4.1.7 + debug: ^4.3.4 + pony-cause: ^2.1.10 + semver: ^7.5.4 + superstruct: ^1.0.3 + checksum: 36a714a17e4949d2040bedb28d4373a22e7e86bb797aa2d59223f9799fd76e662443bcede113719c4e200f5e9d90a9d62feafad5028fff8b9a7a85fface097ca languageName: node linkType: hard @@ -3294,7 +3364,7 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:1.2.0, @noble/curves@npm:^1.2.0, @noble/curves@npm:~1.2.0": +"@noble/curves@npm:1.2.0, @noble/curves@npm:~1.2.0": version: 1.2.0 resolution: "@noble/curves@npm:1.2.0" dependencies: @@ -3983,6 +4053,27 @@ __metadata: languageName: node linkType: hard +"@rainbow-me/rainbowkit@npm:^1.3.3": + version: 1.3.3 + resolution: "@rainbow-me/rainbowkit@npm:1.3.3" + dependencies: + "@vanilla-extract/css": 1.14.0 + "@vanilla-extract/dynamic": 2.1.0 + "@vanilla-extract/sprinkles": 1.6.1 + clsx: 2.1.0 + i18n-js: ^4.3.2 + qrcode: 1.5.3 + react-remove-scroll: 2.5.7 + ua-parser-js: ^1.0.37 + peerDependencies: + react: ">=17" + react-dom: ">=17" + viem: ~0.3.19 || ^1.0.0 + wagmi: ~1.0.1 || ~1.1.0 || ~1.2.0 || ~1.3.0 || ~1.4.0 + checksum: 5d6caeacde962e476211fb37c2d2f47a911528260fdc91531ffc876ddf04cdaf72e5367fbc538e846b450af15e18c0ef7f53d6163a13c8b8d74f54eeb5c4eb4a + languageName: node + linkType: hard + "@remix-run/router@npm:1.11.0": version: 1.11.0 resolution: "@remix-run/router@npm:1.11.0" @@ -4055,27 +4146,17 @@ __metadata: languageName: node linkType: hard -"@safe-global/safe-apps-provider@npm:^0.17.1": - version: 0.17.1 - resolution: "@safe-global/safe-apps-provider@npm:0.17.1" +"@safe-global/safe-apps-provider@npm:^0.18.1": + version: 0.18.1 + resolution: "@safe-global/safe-apps-provider@npm:0.18.1" dependencies: - "@safe-global/safe-apps-sdk": 8.0.0 + "@safe-global/safe-apps-sdk": ^8.1.0 events: ^3.3.0 - checksum: 02f0415a4bb77b82e55f0055be045af715d9c0ea0fa7daa4e0604f40cc2189051d111b8ead67ddab0e99b1e423b444753c11d69bb213d51e459f706d2b430e34 + checksum: fb77aee24149303a8886f1c23ed35ccd75ed63ed67cdb1dfd5c7160e7744f37c8872feadcfbf6d5712d2de65896a1aaf339dc4afb1fa648f0dddd689ff89183c languageName: node linkType: hard -"@safe-global/safe-apps-sdk@npm:8.0.0": - version: 8.0.0 - resolution: "@safe-global/safe-apps-sdk@npm:8.0.0" - dependencies: - "@safe-global/safe-gateway-typescript-sdk": ^3.5.3 - viem: ^1.0.0 - checksum: 07295c44afa4d85fbc9419b4baac56b4fb493816d4438d6956842261e0689fdcea639ab86b39ee693c456fddace17b6c556c77a637892634a57de96f6b00b0c3 - languageName: node - linkType: hard - -"@safe-global/safe-apps-sdk@npm:^8.0.0": +"@safe-global/safe-apps-sdk@npm:^8.1.0": version: 8.1.0 resolution: "@safe-global/safe-apps-sdk@npm:8.1.0" dependencies: @@ -4141,6 +4222,13 @@ __metadata: languageName: node linkType: hard +"@scure/base@npm:^1.1.3": + version: 1.1.5 + resolution: "@scure/base@npm:1.1.5" + checksum: 9e9ee6088cb3aa0fb91f5a48497d26682c7829df3019b1251d088d166d7a8c0f941c68aaa8e7b96bbad20c71eb210397cb1099062cde3e29d4bad6b975c18519 + languageName: node + linkType: hard + "@scure/base@npm:~1.1.0, @scure/base@npm:~1.1.2": version: 1.1.3 resolution: "@scure/base@npm:1.1.3" @@ -4308,38 +4396,6 @@ __metadata: languageName: node linkType: hard -"@solana/buffer-layout@npm:^4.0.0": - version: 4.0.1 - resolution: "@solana/buffer-layout@npm:4.0.1" - dependencies: - buffer: ~6.0.3 - checksum: bf846888e813187243d4008a7a9f58b49d16cbd995b9d7f1b72898aa510ed77b1ce5e8468e7b2fd26dd81e557a4e74a666e21fccb95f123c1f740d41138bbacd - languageName: node - linkType: hard - -"@solana/web3.js@npm:^1.70.1": - version: 1.87.6 - resolution: "@solana/web3.js@npm:1.87.6" - dependencies: - "@babel/runtime": ^7.23.2 - "@noble/curves": ^1.2.0 - "@noble/hashes": ^1.3.1 - "@solana/buffer-layout": ^4.0.0 - agentkeepalive: ^4.3.0 - bigint-buffer: ^1.1.5 - bn.js: ^5.2.1 - borsh: ^0.7.0 - bs58: ^4.0.1 - buffer: 6.0.3 - fast-stable-stringify: ^1.0.0 - jayson: ^4.1.0 - node-fetch: ^2.6.12 - rpc-websockets: ^7.5.1 - superstruct: ^0.14.2 - checksum: 182eb2a953f6ebebdfbc7dfda031d1985fb1591a2aa38b388d5dfb9fd3df0fb53a3962373384dbd91df343e148ec3d42a579324effab9ca86f0560c4f6f08481 - languageName: node - linkType: hard - "@solidity-parser/parser@npm:^0.14.0": version: 0.14.5 resolution: "@solidity-parser/parser@npm:0.14.5" @@ -4909,7 +4965,7 @@ __metadata: languageName: node linkType: hard -"@types/connect@npm:*, @types/connect@npm:^3.4.33": +"@types/connect@npm:*": version: 3.4.38 resolution: "@types/connect@npm:3.4.38" dependencies: @@ -5149,7 +5205,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^12.12.54, @types/node@npm:^12.12.6": +"@types/node@npm:^12.12.6": version: 12.20.55 resolution: "@types/node@npm:12.20.55" checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 @@ -5363,15 +5419,6 @@ __metadata: languageName: node linkType: hard -"@types/ws@npm:^7.4.4": - version: 7.4.7 - resolution: "@types/ws@npm:7.4.7" - dependencies: - "@types/node": "*" - checksum: b4c9b8ad209620c9b21e78314ce4ff07515c0cadab9af101c1651e7bfb992d7fd933bd8b9c99d110738fd6db523ed15f82f29f50b45510288da72e964dedb1a3 - languageName: node - linkType: hard - "@types/ws@npm:^8.5.5": version: 8.5.9 resolution: "@types/ws@npm:8.5.9" @@ -5545,18 +5592,61 @@ __metadata: languageName: node linkType: hard -"@wagmi/connectors@npm:3.1.5": - version: 3.1.5 - resolution: "@wagmi/connectors@npm:3.1.5" +"@vanilla-extract/css@npm:1.14.0": + version: 1.14.0 + resolution: "@vanilla-extract/css@npm:1.14.0" + dependencies: + "@emotion/hash": ^0.9.0 + "@vanilla-extract/private": ^1.0.3 + chalk: ^4.1.1 + css-what: ^6.1.0 + cssesc: ^3.0.0 + csstype: ^3.0.7 + deep-object-diff: ^1.1.9 + deepmerge: ^4.2.2 + media-query-parser: ^2.0.2 + modern-ahocorasick: ^1.0.0 + outdent: ^0.8.0 + checksum: ca12de26f72b908c7ac2ee9319faff885fb451ab3da7cef86aae8660c7e042c447041be40ac8c6155d87e8a709efb0697214db3a6cce211e8ef3c110d4dcf8a1 + languageName: node + linkType: hard + +"@vanilla-extract/dynamic@npm:2.1.0": + version: 2.1.0 + resolution: "@vanilla-extract/dynamic@npm:2.1.0" + dependencies: + "@vanilla-extract/private": ^1.0.3 + checksum: a6f129d096286cf7e2c7c868f12866d2da2967cd7591e071eb6420f0fafccce86c58e1d408864109fc894332399e731fe8ae67e2c92d456feb4b21c602287f6d + languageName: node + linkType: hard + +"@vanilla-extract/private@npm:^1.0.3": + version: 1.0.3 + resolution: "@vanilla-extract/private@npm:1.0.3" + checksum: 866a71ba6804edeb0735684e7723ba78f5cf0bb40d4fb538fe6bf7d73928099e341312337b2a510ac0ce96ff8a4b39eb7f7a5fad0c842532353dd20e7278f29b + languageName: node + linkType: hard + +"@vanilla-extract/sprinkles@npm:1.6.1": + version: 1.6.1 + resolution: "@vanilla-extract/sprinkles@npm:1.6.1" + peerDependencies: + "@vanilla-extract/css": ^1.0.0 + checksum: 13c53a94b19f9226c2684b0da06b98022d2faaf504cb5a4a8e5a0abae499aaa7855c17aa6d88534800d9427696b3248f4fc1a5332bde336c445d837017569f3b + languageName: node + linkType: hard + +"@wagmi/connectors@npm:3.1.11": + version: 3.1.11 + resolution: "@wagmi/connectors@npm:3.1.11" dependencies: "@coinbase/wallet-sdk": ^3.6.6 - "@ledgerhq/connect-kit-loader": ^1.1.0 - "@safe-global/safe-apps-provider": ^0.17.1 - "@safe-global/safe-apps-sdk": ^8.0.0 - "@walletconnect/ethereum-provider": 2.10.2 + "@safe-global/safe-apps-provider": ^0.18.1 + "@safe-global/safe-apps-sdk": ^8.1.0 + "@walletconnect/ethereum-provider": 2.11.0 "@walletconnect/legacy-provider": ^2.0.0 "@walletconnect/modal": 2.6.2 - "@walletconnect/utils": 2.10.2 + "@walletconnect/utils": 2.11.0 abitype: 0.8.7 eventemitter3: ^4.0.7 peerDependencies: @@ -5565,15 +5655,15 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 459370925b7dc278493b974579a29c0fe836130940c9c9294acda3ed0ad1b28d0382fa0d2e9898114073bf572c9af3fa0b9cf1e1fcc3d37620e142cd5cf41fe0 + checksum: c198b04751df5e39c37e0a7077f7dcaad7a19b15a71538ee03d5cec066b1c82a3e4b7cc8882b671c49b57066ffd7887dbcad19ed411f98f20e6588455142e9d5 languageName: node linkType: hard -"@wagmi/core@npm:1.4.7": - version: 1.4.7 - resolution: "@wagmi/core@npm:1.4.7" +"@wagmi/core@npm:1.4.13": + version: 1.4.13 + resolution: "@wagmi/core@npm:1.4.13" dependencies: - "@wagmi/connectors": 3.1.5 + "@wagmi/connectors": 3.1.11 abitype: 0.8.7 eventemitter3: ^4.0.7 zustand: ^4.3.1 @@ -5583,7 +5673,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 4ca79fc4cdf3d091fbef8b8a408cabfef676b8842aa1b277ab97cd68aaa47ab57a66b7a38162bd183560a023363724a30671aa543e59101b22e926f08f4a5fee + checksum: e35c5f8ec3ca066cab6affcb551c784e44bcce07742913ebb1285cc58648f5b2cab98d7a014cd6b8cfa1afb2eaa7047523f17d90519982458d2c9b3b6f7e2c9f languageName: node linkType: hard @@ -6003,23 +6093,23 @@ __metadata: languageName: node linkType: hard -"@walletconnect/types@npm:2.10.2": - version: 2.10.2 - resolution: "@walletconnect/types@npm:2.10.2" +"@walletconnect/types@npm:2.10.5": + version: 2.10.5 + resolution: "@walletconnect/types@npm:2.10.5" dependencies: "@walletconnect/events": ^1.0.1 "@walletconnect/heartbeat": 1.2.1 "@walletconnect/jsonrpc-types": 1.0.3 - "@walletconnect/keyvaluestorage": ^1.0.2 + "@walletconnect/keyvaluestorage": ^1.1.1 "@walletconnect/logger": ^2.0.1 events: ^3.3.0 - checksum: dafcb840b2b93343db56ca6684edfe8a20d9b2f703f81b2d1fdbea558fe41de9fbddec12c24e9d51a50c75ee6298a1cfd347d7fa0202146033788670371cfd6a + checksum: 2e88af16d0665577f5869de749445a4cf146e78448e5af17877143af72f58971d63df645c07ec4cb55e83c27808feb6588bde991bc2e5906d47a5bdeb47bb0e0 languageName: node linkType: hard -"@walletconnect/types@npm:2.10.5": - version: 2.10.5 - resolution: "@walletconnect/types@npm:2.10.5" +"@walletconnect/types@npm:2.11.0": + version: 2.11.0 + resolution: "@walletconnect/types@npm:2.11.0" dependencies: "@walletconnect/events": ^1.0.1 "@walletconnect/heartbeat": 1.2.1 @@ -6027,7 +6117,7 @@ __metadata: "@walletconnect/keyvaluestorage": ^1.1.1 "@walletconnect/logger": ^2.0.1 events: ^3.3.0 - checksum: 2e88af16d0665577f5869de749445a4cf146e78448e5af17877143af72f58971d63df645c07ec4cb55e83c27808feb6588bde991bc2e5906d47a5bdeb47bb0e0 + checksum: 32d0d7972b90683467e47eabf92005c7c5d1ae76400eb221576ac0d32501b9f0a414d5921f0c881efe86f07485db807e3e9d370c6b9cc264771822916dc4cca5 languageName: node linkType: hard @@ -6063,9 +6153,9 @@ __metadata: languageName: node linkType: hard -"@walletconnect/utils@npm:2.10.2": - version: 2.10.2 - resolution: "@walletconnect/utils@npm:2.10.2" +"@walletconnect/utils@npm:2.10.5, @walletconnect/utils@npm:^2.10.1, @walletconnect/utils@npm:^2.10.2": + version: 2.10.5 + resolution: "@walletconnect/utils@npm:2.10.5" dependencies: "@stablelib/chacha20poly1305": 1.0.1 "@stablelib/hkdf": 1.0.1 @@ -6075,19 +6165,19 @@ __metadata: "@walletconnect/relay-api": ^1.0.9 "@walletconnect/safe-json": ^1.0.2 "@walletconnect/time": ^1.0.2 - "@walletconnect/types": 2.10.2 + "@walletconnect/types": 2.10.5 "@walletconnect/window-getters": ^1.0.1 "@walletconnect/window-metadata": ^1.0.1 detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: ^3.1.0 - checksum: 168e65d48ce6121f04f040662668fce63c8e42050c7c7d1da2948cf2e486657f8bf972f3386dc84251fcabf3626a26bb696e3363d55bc92826ec1602d7b493c7 + checksum: 555e917de3d94b63b4137dfbc544a7fa7178ae6800604f43278c37ba843c6eab7126fde28a3b6322bcdd2bb72c4a51fd54b7a0a9f58dd25a806a6e0fdd00b0b6 languageName: node linkType: hard -"@walletconnect/utils@npm:2.10.5, @walletconnect/utils@npm:^2.10.1, @walletconnect/utils@npm:^2.10.2": - version: 2.10.5 - resolution: "@walletconnect/utils@npm:2.10.5" +"@walletconnect/utils@npm:2.11.0": + version: 2.11.0 + resolution: "@walletconnect/utils@npm:2.11.0" dependencies: "@stablelib/chacha20poly1305": 1.0.1 "@stablelib/hkdf": 1.0.1 @@ -6097,13 +6187,13 @@ __metadata: "@walletconnect/relay-api": ^1.0.9 "@walletconnect/safe-json": ^1.0.2 "@walletconnect/time": ^1.0.2 - "@walletconnect/types": 2.10.5 + "@walletconnect/types": 2.11.0 "@walletconnect/window-getters": ^1.0.1 "@walletconnect/window-metadata": ^1.0.1 detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: ^3.1.0 - checksum: 555e917de3d94b63b4137dfbc544a7fa7178ae6800604f43278c37ba843c6eab7126fde28a3b6322bcdd2bb72c4a51fd54b7a0a9f58dd25a806a6e0fdd00b0b6 + checksum: 9d8259ea6a2850e620eb366b26fc3f17cf7bf75ae9c50fdfa3252b9dd152d1c10444009dfad1aa5a0a7d1ed844e5efd76581540e973315ec289fba7b51ebf7d7 languageName: node linkType: hard @@ -6406,18 +6496,6 @@ __metadata: languageName: node linkType: hard -"JSONStream@npm:^1.3.5": - version: 1.3.5 - resolution: "JSONStream@npm:1.3.5" - dependencies: - jsonparse: ^1.2.0 - through: ">=2.2.7 <3" - bin: - JSONStream: ./bin.js - checksum: 2605fa124260c61bad38bb65eba30d2f72216a78e94d0ab19b11b4e0327d572b8d530c0c9cc3b0764f727ad26d39e00bf7ebad57781ca6368394d73169c59e46 - languageName: node - linkType: hard - "abab@npm:^2.0.3, abab@npm:^2.0.5": version: 2.0.6 resolution: "abab@npm:2.0.6" @@ -6629,15 +6707,6 @@ __metadata: languageName: node linkType: hard -"agentkeepalive@npm:^4.3.0": - version: 4.5.0 - resolution: "agentkeepalive@npm:4.5.0" - dependencies: - humanize-ms: ^1.2.1 - checksum: 13278cd5b125e51eddd5079f04d6fe0914ac1b8b91c1f3db2c1822f99ac1a7457869068997784342fe455d59daaff22e14fb7b8c3da4e741896e7e31faf92481 - languageName: node - linkType: hard - "aggregate-error@npm:^3.0.0": version: 3.1.0 resolution: "aggregate-error@npm:3.1.0" @@ -7417,16 +7486,6 @@ __metadata: languageName: node linkType: hard -"bigint-buffer@npm:^1.1.5": - version: 1.1.5 - resolution: "bigint-buffer@npm:1.1.5" - dependencies: - bindings: ^1.3.0 - node-gyp: latest - checksum: d010c9f57758bcdaccb435d88b483ffcc95fe8bbc6e7fb3a44fb5221f29c894ffaf4a3c5a4a530e0e7d6608203c2cde9b79ee4f2386cd6d4462d1070bc8c9f4e - languageName: node - linkType: hard - "bigint-crypto-utils@npm:^3.0.23": version: 3.3.0 resolution: "bigint-crypto-utils@npm:3.3.0" @@ -7434,7 +7493,7 @@ __metadata: languageName: node linkType: hard -"bignumber.js@npm:^9.0.0": +"bignumber.js@npm:*, bignumber.js@npm:^9.0.0": version: 9.1.2 resolution: "bignumber.js@npm:9.1.2" checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf @@ -7448,22 +7507,6 @@ __metadata: languageName: node linkType: hard -"bind-decorator@npm:^1.0.11": - version: 1.0.11 - resolution: "bind-decorator@npm:1.0.11" - checksum: 41b6c69af51ee7e6e01ea6f2939df94c9c760383f89f5befda0890951657baedbf499a0b96a789fd85cb77252465134f4e6184aae6639ed60cf59549ef15353d - languageName: node - linkType: hard - -"bindings@npm:^1.3.0": - version: 1.5.0 - resolution: "bindings@npm:1.5.0" - dependencies: - file-uri-to-path: 1.0.0 - checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 - languageName: node - linkType: hard - "blakejs@npm:^1.1.0": version: 1.2.1 resolution: "blakejs@npm:1.2.1" @@ -7492,7 +7535,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.1.1, bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": +"bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" checksum: 3dd8c8d38055fedfa95c1d5fc3c99f8dd547b36287b37768db0abab3c239711f88ff58d18d155dd8ad902b0b0cee973747b7ae20ea12a09473272b0201c9edd3 @@ -7538,17 +7581,6 @@ __metadata: languageName: node linkType: hard -"borsh@npm:^0.7.0": - version: 0.7.0 - resolution: "borsh@npm:0.7.0" - dependencies: - bn.js: ^5.2.0 - bs58: ^4.0.0 - text-encoding-utf-8: ^1.0.2 - checksum: e98bfb5f7cfb820819c2870b884dac58dd4b4ce6a86c286c8fbf5c9ca582e73a8c6094df67e81a28c418ff07a309c6b118b2e27fdfea83fd92b8100c741da0b5 - languageName: node - linkType: hard - "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -7638,7 +7670,7 @@ __metadata: languageName: node linkType: hard -"bs58@npm:^4.0.0, bs58@npm:^4.0.1": +"bs58@npm:^4.0.0": version: 4.0.1 resolution: "bs58@npm:4.0.1" dependencies: @@ -7688,7 +7720,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:6.0.3, buffer@npm:^6.0.3, buffer@npm:~6.0.3": +"buffer@npm:6.0.3, buffer@npm:^6.0.3": version: 6.0.3 resolution: "buffer@npm:6.0.3" dependencies: @@ -7904,7 +7936,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.2": +"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -8101,7 +8133,14 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^1.1.0, clsx@npm:^1.2.1": +"clsx@npm:2.1.0": + version: 2.1.0 + resolution: "clsx@npm:2.1.0" + checksum: 43fefc29b6b49c9476fbce4f8b1cc75c27b67747738e598e6651dd40d63692135dc60b18fa1c5b78a2a9ba8ae6fd2055a068924b94e20b42039bd53b78b98e1d + languageName: node + linkType: hard + +"clsx@npm:^1.2.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12 @@ -8240,7 +8279,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^2.20.0, commander@npm:^2.20.3": +"commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e @@ -8726,7 +8765,7 @@ __metadata: languageName: node linkType: hard -"css-what@npm:^6.0.1": +"css-what@npm:^6.0.1, css-what@npm:^6.1.0": version: 6.1.0 resolution: "css-what@npm:6.1.0" checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe @@ -8849,6 +8888,13 @@ __metadata: languageName: node linkType: hard +"csstype@npm:^3.0.7": + version: 3.1.3 + resolution: "csstype@npm:3.1.3" + checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7 + languageName: node + linkType: hard + "d@npm:1, d@npm:^1.0.1": version: 1.0.1 resolution: "d@npm:1.0.1" @@ -8998,6 +9044,13 @@ __metadata: languageName: node linkType: hard +"deep-object-diff@npm:^1.1.9": + version: 1.1.9 + resolution: "deep-object-diff@npm:1.1.9" + checksum: ecd42455e4773f653595d28070295e7aaa8402db5f8ab21d0bec115a7cb4de5e207a5665514767da5f025c96597f1d3a0a4888aeb4dd49e03c996871a3aa05ef + languageName: node + linkType: hard + "deepmerge@npm:^4.2.2": version: 4.3.1 resolution: "deepmerge@npm:4.3.1" @@ -9057,13 +9110,6 @@ __metadata: languageName: node linkType: hard -"delay@npm:^5.0.0": - version: 5.0.0 - resolution: "delay@npm:5.0.0" - checksum: 62f151151ecfde0d9afbb8a6be37a6d103c4cb24f35a20ef3fe56f920b0d0d0bb02bc9c0a3084d0179ef669ca332b91155f2ee4d9854622cd2cdba5fc95285f9 - languageName: node - linkType: hard - "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -9136,6 +9182,13 @@ __metadata: languageName: node linkType: hard +"detect-node-es@npm:^1.1.0": + version: 1.1.0 + resolution: "detect-node-es@npm:1.1.0" + checksum: e46307d7264644975b71c104b9f028ed1d3d34b83a15b8a22373640ce5ea630e5640b1078b8ea15f202b54641da71e4aa7597093bd4b91f113db520a26a37449 + languageName: node + linkType: hard + "detect-node@npm:^2.0.4": version: 2.1.0 resolution: "detect-node@npm:2.1.0" @@ -9753,22 +9806,13 @@ __metadata: languageName: node linkType: hard -"es6-promise@npm:^4.0.3, es6-promise@npm:^4.2.8": +"es6-promise@npm:^4.2.8": version: 4.2.8 resolution: "es6-promise@npm:4.2.8" checksum: 95614a88873611cb9165a85d36afa7268af5c03a378b35ca7bda9508e1d4f1f6f19a788d4bc755b3fd37c8ebba40782018e02034564ff24c9d6fa37e959ad57d languageName: node linkType: hard -"es6-promisify@npm:^5.0.0": - version: 5.0.0 - resolution: "es6-promisify@npm:5.0.0" - dependencies: - es6-promise: ^4.0.3 - checksum: fbed9d791598831413be84a5374eca8c24800ec71a16c1c528c43a98e2dadfb99331483d83ae6094ddb9b87e6f799a15d1553cebf756047e0865c753bc346b92 - languageName: node - linkType: hard - "es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": version: 3.1.3 resolution: "es6-symbol@npm:3.1.3" @@ -10284,15 +10328,16 @@ __metadata: languageName: node linkType: hard -"eth-block-tracker@npm:6.1.0": - version: 6.1.0 - resolution: "eth-block-tracker@npm:6.1.0" +"eth-block-tracker@npm:^7.1.0": + version: 7.1.0 + resolution: "eth-block-tracker@npm:7.1.0" dependencies: - "@metamask/safe-event-emitter": ^2.0.0 - "@metamask/utils": ^3.0.1 + "@metamask/eth-json-rpc-provider": ^1.0.0 + "@metamask/safe-event-emitter": ^3.0.0 + "@metamask/utils": ^5.0.1 json-rpc-random-id: ^1.0.1 pify: ^3.0.0 - checksum: 33ee6375a26822649d1e9ac24a3c39d70338eb505715f72b9102fb82e40d7a48902b4a7dd4a33bb4f121b79707c5ab045777507a2881cfcdb385c8ccbb3ac2a0 + checksum: 1d019f261e0ef07387cd74538b160700caa35ba9859ab9d4e5137c48bf9c92822c3b4ade40f8a504f16cb813de4c317c5378d047625ddf04592e256be8842588 languageName: node linkType: hard @@ -10322,16 +10367,16 @@ __metadata: languageName: node linkType: hard -"eth-json-rpc-filters@npm:5.1.0": - version: 5.1.0 - resolution: "eth-json-rpc-filters@npm:5.1.0" +"eth-json-rpc-filters@npm:^6.0.0": + version: 6.0.1 + resolution: "eth-json-rpc-filters@npm:6.0.1" dependencies: - "@metamask/safe-event-emitter": ^2.0.0 + "@metamask/safe-event-emitter": ^3.0.0 async-mutex: ^0.2.6 eth-query: ^2.1.2 json-rpc-engine: ^6.1.0 pify: ^5.0.0 - checksum: 864092e96277953c399a139df66572b864bd41247c5c1d18e6529973804d4fd8962658d8b10571152554802fa8daaa1003588aee79ffce754e0bc57c39b771d5 + checksum: 216f7417417599a48273b08fb2894581175276fe21cb1c9ffa66e98a9c2a67bc0ac821ad2ca163fdb8e8de0960aea0d9c5e53aee9d5dcfec355abf020e9458c5 languageName: node linkType: hard @@ -10345,15 +10390,6 @@ __metadata: languageName: node linkType: hard -"eth-rpc-errors@npm:4.0.2": - version: 4.0.2 - resolution: "eth-rpc-errors@npm:4.0.2" - dependencies: - fast-safe-stringify: ^2.0.6 - checksum: 1dbdee8f416090f1d318e17bdee2251d174d73c8faa4286fa364bc51ae9105672045f2d078ec23ca6a2b4b92af7cfbe7fa1ba17ad49e591fc653a363bf8cbab2 - languageName: node - linkType: hard - "eth-rpc-errors@npm:^4.0.2": version: 4.0.3 resolution: "eth-rpc-errors@npm:4.0.3" @@ -10560,6 +10596,13 @@ __metadata: languageName: node linkType: hard +"eventemitter3@npm:^5.0.1": + version: 5.0.1 + resolution: "eventemitter3@npm:5.0.1" + checksum: 543d6c858ab699303c3c32e0f0f47fc64d360bf73c3daf0ac0b5079710e340d6fe9f15487f94e66c629f5f82cd1a8678d692f3dbb6f6fcd1190e1b97fcad36f8 + languageName: node + linkType: hard + "events@npm:^3.2.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" @@ -10669,13 +10712,6 @@ __metadata: languageName: node linkType: hard -"eyes@npm:^0.1.8": - version: 0.1.8 - resolution: "eyes@npm:0.1.8" - checksum: c31703a92bf36ba75ee8d379ee7985c24ee6149f3a6175f44cec7a05b178c38bce9836d3ca48c9acb0329a960ac2c4b2ead4e60cdd4fe6e8c92cad7cd6913687 - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -10731,13 +10767,6 @@ __metadata: languageName: node linkType: hard -"fast-stable-stringify@npm:^1.0.0": - version: 1.0.0 - resolution: "fast-stable-stringify@npm:1.0.0" - checksum: ef1203d246a7e8ac15e2bfbda0a89fa375947bccf9f7910be0ea759856dbe8ea5024a0d8cc2cceabe18a9cb67e95927b78bb6173a3ae37ec55a518cf36e5244b - languageName: node - linkType: hard - "fastq@npm:^1.6.0": version: 1.15.0 resolution: "fastq@npm:1.15.0" @@ -10796,13 +10825,6 @@ __metadata: languageName: node linkType: hard -"file-uri-to-path@npm:1.0.0": - version: 1.0.0 - resolution: "file-uri-to-path@npm:1.0.0" - checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 - languageName: node - linkType: hard - "filelist@npm:^1.0.4": version: 1.0.4 resolution: "filelist@npm:1.0.4" @@ -11077,6 +11099,7 @@ __metadata: resolution: "frontend@workspace:frontend" dependencies: 0xsequence: ^1.6.2 + "@rainbow-me/rainbowkit": ^1.3.3 "@types/react": ^18.2.21 "@types/react-dom": ^18.2.7 "@walletconnect/core": ^2.10.2 @@ -11098,8 +11121,8 @@ __metadata: react-scripts: 5.0.1 typescript: ^5.2.2 typescript-plugin-css-modules: ^5.0.1 - viem: ^1.16.5 - wagmi: ^1.4.3 + viem: ^1.21.4 + wagmi: ^1.4.13 languageName: unknown linkType: soft @@ -11285,6 +11308,13 @@ __metadata: languageName: node linkType: hard +"get-nonce@npm:^1.0.0": + version: 1.0.1 + resolution: "get-nonce@npm:1.0.1" + checksum: e2614e43b4694c78277bb61b0f04583d45786881289285c73770b07ded246a98be7e1f78b940c80cbe6f2b07f55f0b724e6db6fd6f1bcbd1e8bdac16521074ed + languageName: node + linkType: hard + "get-own-enumerable-property-symbols@npm:^3.0.0": version: 3.0.2 resolution: "get-own-enumerable-property-symbols@npm:3.0.2" @@ -12116,12 +12146,14 @@ __metadata: languageName: node linkType: hard -"humanize-ms@npm:^1.2.1": - version: 1.2.1 - resolution: "humanize-ms@npm:1.2.1" +"i18n-js@npm:^4.3.2": + version: 4.3.2 + resolution: "i18n-js@npm:4.3.2" dependencies: - ms: ^2.0.0 - checksum: 9c7a74a2827f9294c009266c82031030eae811ca87b0da3dceb8d6071b9bde22c9f3daef0469c3c533cc67a97d8a167cd9fc0389350e5f415f61a79b171ded16 + bignumber.js: "*" + lodash: "*" + make-plural: "*" + checksum: 08a051dba75d93447e2021c1feb92f34c9034b5a818957885ea19ac58954d764c848c4deaaf46ada3e15d51f61ad9f7e0bf4ddffa3c765871ff1b26638ca0a8f languageName: node linkType: hard @@ -12265,7 +12297,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3, inherits@npm:~2.0.4": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -12304,6 +12336,15 @@ __metadata: languageName: node linkType: hard +"invariant@npm:^2.2.4": + version: 2.2.4 + resolution: "invariant@npm:2.2.4" + dependencies: + loose-envify: ^1.0.0 + checksum: cc3182d793aad82a8d1f0af697b462939cb46066ec48bbf1707c150ad5fad6406137e91a262022c269702e01621f35ef60269f6c0d7fd178487959809acdfb14 + languageName: node + linkType: hard + "io-ts@npm:1.10.4": version: 1.10.4 resolution: "io-ts@npm:1.10.4" @@ -12780,15 +12821,6 @@ __metadata: languageName: node linkType: hard -"isomorphic-ws@npm:^4.0.1": - version: 4.0.1 - resolution: "isomorphic-ws@npm:4.0.1" - peerDependencies: - ws: "*" - checksum: d7190eadefdc28bdb93d67b5f0c603385aaf87724fa2974abb382ac1ec9756ed2cfb27065cbe76122879c2d452e2982bc4314317f3d6c737ddda6c047328771a - languageName: node - linkType: hard - "isows@npm:1.0.3": version: 1.0.3 resolution: "isows@npm:1.0.3" @@ -12890,28 +12922,6 @@ __metadata: languageName: node linkType: hard -"jayson@npm:^4.1.0": - version: 4.1.0 - resolution: "jayson@npm:4.1.0" - dependencies: - "@types/connect": ^3.4.33 - "@types/node": ^12.12.54 - "@types/ws": ^7.4.4 - JSONStream: ^1.3.5 - commander: ^2.20.3 - delay: ^5.0.0 - es6-promisify: ^5.0.0 - eyes: ^0.1.8 - isomorphic-ws: ^4.0.1 - json-stringify-safe: ^5.0.1 - uuid: ^8.3.2 - ws: ^7.4.5 - bin: - jayson: bin/jayson.js - checksum: 86464322fbdc6db65d2bb4fc278cb6c86fad5c2a506065490d39459f09ba0d30f2b4fb740b33828a1424791419b6c8bd295dc54d361a4ad959bf70cc62b1ca7e - languageName: node - linkType: hard - "jest-changed-files@npm:^27.5.1": version: 27.5.1 resolution: "jest-changed-files@npm:27.5.1" @@ -13626,7 +13636,7 @@ __metadata: languageName: node linkType: hard -"json-rpc-engine@npm:6.1.0, json-rpc-engine@npm:^6.1.0": +"json-rpc-engine@npm:^6.1.0": version: 6.1.0 resolution: "json-rpc-engine@npm:6.1.0" dependencies: @@ -13671,13 +13681,6 @@ __metadata: languageName: node linkType: hard -"json-stringify-safe@npm:^5.0.1": - version: 5.0.1 - resolution: "json-stringify-safe@npm:5.0.1" - checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee - languageName: node - linkType: hard - "json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" @@ -13742,13 +13745,6 @@ __metadata: languageName: node linkType: hard -"jsonparse@npm:^1.2.0": - version: 1.3.1 - resolution: "jsonparse@npm:1.3.1" - checksum: 6514a7be4674ebf407afca0eda3ba284b69b07f9958a8d3113ef1005f7ec610860c312be067e450c569aab8b89635e332cee3696789c750692bb60daba627f4d - languageName: node - linkType: hard - "jsonpath@npm:^1.1.1": version: 1.1.1 resolution: "jsonpath@npm:1.1.1" @@ -13786,7 +13782,7 @@ __metadata: languageName: node linkType: hard -"keccak@npm:^3.0.0, keccak@npm:^3.0.1, keccak@npm:^3.0.2": +"keccak@npm:^3.0.0, keccak@npm:^3.0.2, keccak@npm:^3.0.3": version: 3.0.4 resolution: "keccak@npm:3.0.4" dependencies: @@ -14197,7 +14193,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.7.0": +"lodash@npm:*, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.7.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -14214,7 +14210,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -14340,6 +14336,13 @@ __metadata: languageName: node linkType: hard +"make-plural@npm:*": + version: 7.3.0 + resolution: "make-plural@npm:7.3.0" + checksum: bb39b4b77533f0d5fb94eec128340b54dda8c1707d6b0a98c148e5d7bc23094e123f88275a61573fa31dc2f5d7352215cee0df523cd69b5d8fcb3969a2bcf8f8 + languageName: node + linkType: hard + "makeerror@npm:1.0.12": version: 1.0.12 resolution: "makeerror@npm:1.0.12" @@ -14461,6 +14464,15 @@ __metadata: languageName: unknown linkType: soft +"media-query-parser@npm:^2.0.2": + version: 2.0.2 + resolution: "media-query-parser@npm:2.0.2" + dependencies: + "@babel/runtime": ^7.12.5 + checksum: 8ef956d9e63fe6f4041988beda69843b3a6bb48228ea2923a066f6e7c8f7c5dba75fae357318c48a97ed5beae840b8425cb7e727fc1bb77acc65f2005f8945ab + languageName: node + linkType: hard + "media-typer@npm:0.3.0": version: 0.3.0 resolution: "media-typer@npm:0.3.0" @@ -14836,6 +14848,13 @@ __metadata: languageName: node linkType: hard +"modern-ahocorasick@npm:^1.0.0": + version: 1.0.1 + resolution: "modern-ahocorasick@npm:1.0.1" + checksum: ec83479f406511f37a966d66ce1c2b1701bb4a2cc2aabbbc257001178c9fbc48ce748c88eb10dfe72ba8b7f991a0bc7f1fa14683f444685edd1a9eeb32ecbc1e + languageName: node + linkType: hard + "module-error@npm:^1.0.1, module-error@npm:^1.0.2": version: 1.0.2 resolution: "module-error@npm:1.0.2" @@ -14878,7 +14897,7 @@ __metadata: languageName: node linkType: hard -"ms@npm:2.1.3, ms@npm:^2.0.0, ms@npm:^2.1.1": +"ms@npm:2.1.3, ms@npm:^2.1.1": version: 2.1.3 resolution: "ms@npm:2.1.3" checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d @@ -15456,6 +15475,13 @@ __metadata: languageName: node linkType: hard +"outdent@npm:^0.8.0": + version: 0.8.0 + resolution: "outdent@npm:0.8.0" + checksum: 72b7c1a287674317ea477999ec24e73a9eda21de35eb9429218f4a5bab899e964afaee7508265898118fee5cbee1d79397916b66dd8aeee285cd948ea5b1f562 + languageName: node + linkType: hard + "p-limit@npm:^1.1.0": version: 1.3.0 resolution: "p-limit@npm:1.3.0" @@ -15865,6 +15891,13 @@ __metadata: languageName: node linkType: hard +"pony-cause@npm:^2.1.10": + version: 2.1.10 + resolution: "pony-cause@npm:2.1.10" + checksum: 8b61378f213e61056312dc274a1c79980154e9d864f6ad86e0c8b91a50d3ce900d430995ee24147c9f3caa440dfe7d51c274b488d7f033b65b206522536d7217 + languageName: node + linkType: hard + "postcss-attribute-case-insensitive@npm:^5.0.2": version: 5.0.2 resolution: "postcss-attribute-case-insensitive@npm:5.0.2" @@ -16724,10 +16757,10 @@ __metadata: languageName: node linkType: hard -"preact@npm:^10.12.0, preact@npm:^10.5.9": - version: 10.19.2 - resolution: "preact@npm:10.19.2" - checksum: fec27fa3f14ac2d7a5061818d0cf2973ffaece83126047a47e5a075aa8e40ca56b5fcebc36106ee9cf59be0aeb51f3d996760e158d2a2660b42cbfb2e71f37bf +"preact@npm:^10.12.0, preact@npm:^10.16.0": + version: 10.19.3 + resolution: "preact@npm:10.19.3" + checksum: cb4fcc801f7ff302b9706eb4bb4a36cc7cd96f3231ac28baeb3ea5caf6724372222121cb487f66af44a1312bf61dbe74825ce2fda98295d2108e7443c20b0e56 languageName: node linkType: hard @@ -16970,7 +17003,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.10.3, qs@npm:^6.4.0, qs@npm:^6.9.4": +"qs@npm:^6.4.0, qs@npm:^6.9.4": version: 6.11.2 resolution: "qs@npm:6.11.2" dependencies: @@ -17192,6 +17225,41 @@ __metadata: languageName: node linkType: hard +"react-remove-scroll-bar@npm:^2.3.4": + version: 2.3.4 + resolution: "react-remove-scroll-bar@npm:2.3.4" + dependencies: + react-style-singleton: ^2.2.1 + tslib: ^2.0.0 + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: b5ce5f2f98d65c97a3e975823ae4043a4ba2a3b63b5ba284b887e7853f051b5cd6afb74abde6d57b421931c52f2e1fdbb625dc858b1cb5a32c27c14ab85649d4 + languageName: node + linkType: hard + +"react-remove-scroll@npm:2.5.7": + version: 2.5.7 + resolution: "react-remove-scroll@npm:2.5.7" + dependencies: + react-remove-scroll-bar: ^2.3.4 + react-style-singleton: ^2.2.1 + tslib: ^2.1.0 + use-callback-ref: ^1.3.0 + use-sidecar: ^1.1.2 + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: e0dbb6856beaed2cff4996d9ca62d775686ff72e3e9de34043034d932223b588993b2fc7a18644750dd3d73eb19bd3f2cedb8d91f0e424c1ef8403010da24b1d + languageName: node + linkType: hard + "react-router-dom@npm:^6.15.0": version: 6.18.0 resolution: "react-router-dom@npm:6.18.0" @@ -17283,6 +17351,23 @@ __metadata: languageName: node linkType: hard +"react-style-singleton@npm:^2.2.1": + version: 2.2.1 + resolution: "react-style-singleton@npm:2.2.1" + dependencies: + get-nonce: ^1.0.0 + invariant: ^2.2.4 + tslib: ^2.0.0 + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 7ee8ef3aab74c7ae1d70ff34a27643d11ba1a8d62d072c767827d9ff9a520905223e567002e0bf6c772929d8ea1c781a3ba0cc4a563e92b1e3dc2eaa817ecbe8 + languageName: node + linkType: hard + "react@npm:^18.2.0": version: 18.2.0 resolution: "react@npm:18.2.0" @@ -17331,7 +17416,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.0.6, readable-stream@npm:^3.1.1, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0": +"readable-stream@npm:^3.0.6, readable-stream@npm:^3.1.1, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -17820,25 +17905,6 @@ __metadata: languageName: node linkType: hard -"rpc-websockets@npm:^7.5.1": - version: 7.6.2 - resolution: "rpc-websockets@npm:7.6.2" - dependencies: - "@babel/runtime": ^7.17.2 - bufferutil: ^4.0.1 - eventemitter3: ^4.0.7 - utf-8-validate: ^5.0.2 - uuid: ^8.3.2 - ws: ^8.5.0 - dependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: fa82613df99fd0a19a02f87c002808bc39fc0c040a17decf9ea6710bd22e21db507ac98edc335739ca0636cdf84459eaed69576e2c0c08fc12c65233c981318f - languageName: node - linkType: hard - "run-parallel-limit@npm:^1.1.0": version: 1.1.0 resolution: "run-parallel-limit@npm:1.1.0" @@ -17864,15 +17930,6 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^6.6.3": - version: 6.6.7 - resolution: "rxjs@npm:6.6.7" - dependencies: - tslib: ^1.9.0 - checksum: bc334edef1bb8bbf56590b0b25734ba0deaf8825b703256a93714308ea36dff8a11d25533671adf8e104e5e8f256aa6fdfe39b2e248cdbd7a5f90c260acbbd1b - languageName: node - linkType: hard - "safe-array-concat@npm:^1.0.0, safe-array-concat@npm:^1.0.1": version: 1.0.1 resolution: "safe-array-concat@npm:1.0.1" @@ -18709,16 +18766,6 @@ __metadata: languageName: node linkType: hard -"stream-browserify@npm:^3.0.0": - version: 3.0.0 - resolution: "stream-browserify@npm:3.0.0" - dependencies: - inherits: ~2.0.4 - readable-stream: ^3.5.0 - checksum: 4c47ef64d6f03815a9ca3874e2319805e8e8a85f3550776c47ce523b6f4c6cd57f40e46ec6a9ab8ad260fde61863c2718f250d3bedb3fe9052444eb9abfd9921 - languageName: node - linkType: hard - "stream-shift@npm:^1.0.0": version: 1.0.1 resolution: "stream-shift@npm:1.0.1" @@ -19021,13 +19068,6 @@ __metadata: languageName: node linkType: hard -"superstruct@npm:^0.14.2": - version: 0.14.2 - resolution: "superstruct@npm:0.14.2" - checksum: c5c4840f432da82125b923ec45faca5113217e83ae416e314d80eae012b8bb603d2e745025d173450758d116348820bc7028157f8c9a72b6beae879f94b837c0 - languageName: node - linkType: hard - "superstruct@npm:^1.0.3": version: 1.0.3 resolution: "superstruct@npm:1.0.3" @@ -19396,13 +19436,6 @@ __metadata: languageName: node linkType: hard -"text-encoding-utf-8@npm:^1.0.2": - version: 1.0.2 - resolution: "text-encoding-utf-8@npm:1.0.2" - checksum: ec4c15d50e738c5dba7327ad432ebf0725ec75d4d69c0bd55609254c5a3bc5341272d7003691084a0a73d60d981c8eb0e87603676fdb6f3fed60f4c9192309f9 - languageName: node - linkType: hard - "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -19473,7 +19506,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:>=2.2.7 <3": +"through@npm:2": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -19675,7 +19708,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:1.14.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": +"tslib@npm:1.14.1, tslib@npm:^1.8.1, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd @@ -19689,7 +19722,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.3.1": +"tslib@npm:^2.0.0, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad @@ -19950,6 +19983,13 @@ __metadata: languageName: node linkType: hard +"ua-parser-js@npm:^1.0.37": + version: 1.0.37 + resolution: "ua-parser-js@npm:1.0.37" + checksum: 4d481c720d523366d7762dc8a46a1b58967d979aacf786f9ceceb1cd767de069f64a4bdffb63956294f1c0696eb465ddb950f28ba90571709e33521b4bd75e07 + languageName: node + linkType: hard + "ufo@npm:^1.3.0, ufo@npm:^1.3.1": version: 1.3.2 resolution: "ufo@npm:1.3.2" @@ -20247,6 +20287,37 @@ __metadata: languageName: node linkType: hard +"use-callback-ref@npm:^1.3.0": + version: 1.3.1 + resolution: "use-callback-ref@npm:1.3.1" + dependencies: + tslib: ^2.0.0 + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 6a6a3a8bfe88f466eab982b8a92e5da560a7127b3b38815e89bc4d195d4b33aa9a53dba50d93e8138e7502bcc7e39efe9f2735a07a673212630990c73483e8e9 + languageName: node + linkType: hard + +"use-sidecar@npm:^1.1.2": + version: 1.1.2 + resolution: "use-sidecar@npm:1.1.2" + dependencies: + detect-node-es: ^1.1.0 + tslib: ^2.0.0 + peerDependencies: + "@types/react": ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 925d1922f9853e516eaad526b6fed1be38008073067274f0ecc3f56b17bb8ab63480140dd7c271f94150027c996cea4efe83d3e3525e8f3eda22055f6a39220b + languageName: node + linkType: hard + "use-sync-external-store@npm:1.2.0, use-sync-external-store@npm:^1.2.0": version: 1.2.0 resolution: "use-sync-external-store@npm:1.2.0" @@ -20292,7 +20363,7 @@ __metadata: languageName: node linkType: hard -"util@npm:^0.12.4, util@npm:^0.12.5": +"util@npm:^0.12.5": version: 0.12.5 resolution: "util@npm:0.12.5" dependencies: @@ -20422,6 +20493,27 @@ __metadata: languageName: node linkType: hard +"viem@npm:^1.21.4": + version: 1.21.4 + resolution: "viem@npm:1.21.4" + dependencies: + "@adraffy/ens-normalize": 1.10.0 + "@noble/curves": 1.2.0 + "@noble/hashes": 1.3.2 + "@scure/bip32": 1.3.2 + "@scure/bip39": 1.2.1 + abitype: 0.9.8 + isows: 1.0.3 + ws: 8.13.0 + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: c351fdea2d53d2d781ac73c964348b3b9fc5dd46f9eb53903e867705fc9e30a893cb9f2c8d7a00acdcdeca27d14eeebf976eed9f948c28c47018dc9211369117 + languageName: node + linkType: hard + "w3c-hr-time@npm:^1.0.2": version: 1.0.2 resolution: "w3c-hr-time@npm:1.0.2" @@ -20440,14 +20532,14 @@ __metadata: languageName: node linkType: hard -"wagmi@npm:^1.4.3": - version: 1.4.7 - resolution: "wagmi@npm:1.4.7" +"wagmi@npm:^1.4.13": + version: 1.4.13 + resolution: "wagmi@npm:1.4.13" dependencies: "@tanstack/query-sync-storage-persister": ^4.27.1 "@tanstack/react-query": ^4.28.0 "@tanstack/react-query-persist-client": ^4.28.0 - "@wagmi/core": 1.4.7 + "@wagmi/core": 1.4.13 abitype: 0.8.7 use-sync-external-store: ^1.2.0 peerDependencies: @@ -20457,7 +20549,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: b3223fc46e5aef3935626236bea34678905a0aadb6632a07cd53d7d06851c2eef5d28c3fed7d23fbee19e6bd5c403a236c03e5059767e2fa444119a595503562 + checksum: f53ac4837506cc5d7d71f3a104e100aadfe5e5fe00f46e741eaf03c3dbfa8c4a2a47800221f5b0c454a0826d1539837a2e4e858eb606c3f17ed04dd7c252af14 languageName: node linkType: hard @@ -21309,7 +21401,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.4.0, ws@npm:^7.4.5, ws@npm:^7.4.6, ws@npm:^7.5.1": +"ws@npm:^7.4.0, ws@npm:^7.4.6, ws@npm:^7.5.1": version: 7.5.9 resolution: "ws@npm:7.5.9" peerDependencies: @@ -21324,7 +21416,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.13.0, ws@npm:^8.5.0": +"ws@npm:^8.13.0": version: 8.14.2 resolution: "ws@npm:8.14.2" peerDependencies: @@ -21503,8 +21595,8 @@ __metadata: linkType: hard "zustand@npm:^4.3.1": - version: 4.4.6 - resolution: "zustand@npm:4.4.6" + version: 4.4.7 + resolution: "zustand@npm:4.4.7" dependencies: use-sync-external-store: 1.2.0 peerDependencies: @@ -21518,6 +21610,6 @@ __metadata: optional: true react: optional: true - checksum: da7b00cc6dbe5cf5fc2e3fbca745317da4bbaf53bf4a6909bbd3e335242704df9689027f613461aff07eb5f672d5570bc1a2ef99d0ad7bc868920a3b331613d4 + checksum: 9aeb6cc86162296c1dac504b8906ff952252c129fb3f05cc8926a7f5c9d7fbe098571d5161b3efe3347c0ee1d80197f787b768c7522721864f7323c28766717e languageName: node linkType: hard From 4fc000a0ab4075adbb4b61a3646d3b0d2d50543e Mon Sep 17 00:00:00 2001 From: samepant Date: Mon, 8 Jan 2024 12:02:22 -0500 Subject: [PATCH 02/12] use rainbowkit for connecting account --- frontend/src/chains.ts | 28 ++---- .../ChainSelect/ChainSelect.module.css | 82 ++++++++++++++++ frontend/src/components/ChainSelect/index.tsx | 94 +++++++++++++++---- .../ConnectButton/ConnectButton.module.css | 18 ++++ .../src/components/ConnectButton/index.tsx | 60 ++++++++++++ .../src/components/Layout/Layout.module.css | 25 +---- frontend/src/components/Layout/index.tsx | 30 +----- frontend/src/hooks/useClickAway.ts | 29 ++++++ frontend/src/index.tsx | 60 ++++++------ 9 files changed, 312 insertions(+), 114 deletions(-) create mode 100644 frontend/src/components/ConnectButton/ConnectButton.module.css create mode 100644 frontend/src/components/ConnectButton/index.tsx create mode 100644 frontend/src/hooks/useClickAway.ts diff --git a/frontend/src/chains.ts b/frontend/src/chains.ts index f8a0647..9a80c9a 100644 --- a/frontend/src/chains.ts +++ b/frontend/src/chains.ts @@ -1,28 +1,20 @@ -import { - mainnet, - goerli, - avalanche, - arbitrum, - bsc, - polygon, - polygonMumbai, - gnosis, -} from "wagmi/chains" - -export const CHAINS = { +import { mainnet, polygon, gnosis } from "wagmi/chains" + +import { Chain } from "viem/chains" + +type ChainInfo = { + [key: number]: { prefix: string } & Chain +} + +export const CHAINS: ChainInfo = { [mainnet.id]: { ...mainnet, prefix: "eth" }, - [goerli.id]: { ...goerli, prefix: "gor" }, - // [avalanche.id]: { ...avalanche, prefix: "avax" }, - // [arbitrum.id]: { ...arbitrum, prefix: "arb1" }, - // [bsc.id]: { ...bsc, prefix: "bnb" }, [polygon.id]: { ...polygon, prefix: "matic" }, - [polygonMumbai.id]: { ...polygonMumbai, prefix: "maticmum" }, [gnosis.id]: { ...gnosis, prefix: "gno" }, } export type ChainId = keyof typeof CHAINS -export const DEFAULT_CHAIN = CHAINS[5] +export const DEFAULT_CHAIN = CHAINS[1] export enum SequenceIndexerServices { MAINNET = "https://mainnet-indexer.sequence.app", diff --git a/frontend/src/components/ChainSelect/ChainSelect.module.css b/frontend/src/components/ChainSelect/ChainSelect.module.css index 40148a3..34f1a4b 100644 --- a/frontend/src/components/ChainSelect/ChainSelect.module.css +++ b/frontend/src/components/ChainSelect/ChainSelect.module.css @@ -1,8 +1,90 @@ .button { height: 40px; padding: 5px 10px; + border: none; + background: none; + display: flex; + align-items: center; + gap: 0.5rem; + box-shadow: none; +} + +.button:hover { + background-color: var(--button-bg); + filter: none; +} + +.chevronDown { + stroke: var(--text-color); + width: 1em; + padding-top: 3px; +} +.chevronDown.up { + transform: rotate(180deg); } .icon { height: 100%; } + +.dropdownIcon { + height: 100%; + width: 15px; +} + +.container { + position: relative; +} + +.dropdown { + position: absolute; + top: 50px; + right: 0; + background: var(--box-bg); + border-radius: 10px; + padding: 6px; + min-width: 200px; + z-index: 100; + border: 2px solid var(--button-bg); + box-shadow: 2px 2px 10px 0px rgba(150, 203, 0, 0.44); +} + +.dropdown ul { + list-style: none; + padding: 0; + margin: 0; + display: flex; + flex-direction: column; + gap: 10px; +} + +.dropdownItem { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + gap: 8px; + cursor: pointer; + background: none; + border: none; + color: var(--text-color); + padding: 10px 8px; + border-radius: 10px; +} + +.dropdownItem:hover { + background-color: var(--button-bg); +} + +.chain { + display: flex; + align-items: center; + gap: 0.5rem; +} + +.checkmark { + background-color: var(--box-bg); + padding: 2px 4px; + border-radius: 100px; + stroke: var(--text-color); +} diff --git a/frontend/src/components/ChainSelect/index.tsx b/frontend/src/components/ChainSelect/index.tsx index 278b859..032289c 100644 --- a/frontend/src/components/ChainSelect/index.tsx +++ b/frontend/src/components/ChainSelect/index.tsx @@ -1,34 +1,94 @@ -import { useWeb3Modal } from "@web3modal/react" +import { useChainId, useSwitchNetwork } from "wagmi" +import { Suspense, lazy, useState } from "react" +import clsx from "clsx" import Button from "../Button" - +import useClickAway from "../../hooks/useClickAway" import classes from "./ChainSelect.module.css" -import { Chain, useNetwork } from "wagmi" -import { Suspense, lazy, useEffect, useState } from "react" -import { DEFAULT_CHAIN } from "../../chains" +import { CHAINS } from "../../chains" const ChainIcon = lazy(() => import("../ChainIcon")) const ChainSelect = () => { - const [selectedChain, setSelectedChain] = useState(DEFAULT_CHAIN) - const { open } = useWeb3Modal() - const { chain } = useNetwork() - - useEffect(() => { - if (chain) { - setSelectedChain(chain) - } - }, [chain]) + const [showDropdown, setShowDropdown] = useState(false) + const { switchNetwork } = useSwitchNetwork() + const currentChainId = useChainId() + const ref = useClickAway(() => { + setShowDropdown(false) + }) + console.log("chain ID", currentChainId) + console.log("switchNetwork", switchNetwork) return ( -
+
+ {showDropdown && ( +
+
    + {Object.keys(CHAINS).map((chainId) => { + const chain = CHAINS[parseInt(chainId)] + return ( +
  • + +
  • + ) + })} +
+
+ )}
) } diff --git a/frontend/src/components/ConnectButton/ConnectButton.module.css b/frontend/src/components/ConnectButton/ConnectButton.module.css new file mode 100644 index 0000000..3efe045 --- /dev/null +++ b/frontend/src/components/ConnectButton/ConnectButton.module.css @@ -0,0 +1,18 @@ +.blockie { + height: 1.5em; +} + +.button { + height: 40px; + padding: 0 10px; +} +.connectedButton { + padding: 5px 10px 5px 5px; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.connectedButton p { + font-family: monospace; +} diff --git a/frontend/src/components/ConnectButton/index.tsx b/frontend/src/components/ConnectButton/index.tsx new file mode 100644 index 0000000..e6a73bc --- /dev/null +++ b/frontend/src/components/ConnectButton/index.tsx @@ -0,0 +1,60 @@ +import { ConnectButton as RKConnectButton } from "@rainbow-me/rainbowkit" +import clsx from "clsx" +import Button from "../Button" +import { shortenAddress } from "../../utils/shortenAddress" +import Blockie from "../Blockie" +import classes from "./ConnectButton.module.css" + +export const ConnectButton = () => { + return ( + + {({ account, chain, openAccountModal, openConnectModal, mounted }) => { + const ready = mounted + const connected = ready && account && chain + + return ( +
+ {(() => { + if (!connected) { + return ( + + ) + } + + return ( + + ) + })()} +
+ ) + }} +
+ ) +} + +export default ConnectButton diff --git a/frontend/src/components/Layout/Layout.module.css b/frontend/src/components/Layout/Layout.module.css index aede377..81ddeb9 100644 --- a/frontend/src/components/Layout/Layout.module.css +++ b/frontend/src/components/Layout/Layout.module.css @@ -9,6 +9,7 @@ position: fixed; top: 0; left: 0; + z-index: 100; width: 100%; display: flex; align-items: center; @@ -22,19 +23,6 @@ gap: 0.5rem; } -.button { - height: 40px; - padding: 0 10px; -} - -.connectedButton { - padding: 5px 10px 5px 5px; -} - -.connectedButton p { - font-family: monospace; -} - .cockpit { position: fixed; z-index: 1; @@ -56,17 +44,6 @@ z-index: 10; } -.connectedAccount { - display: flex; - align-items: center; - gap: 0.5rem; - height: 100%; -} - -.blockie { - height: 100%; -} - .nav { display: flex; align-items: center; diff --git a/frontend/src/components/Layout/index.tsx b/frontend/src/components/Layout/index.tsx index 066149a..e73d5d9 100644 --- a/frontend/src/components/Layout/index.tsx +++ b/frontend/src/components/Layout/index.tsx @@ -1,15 +1,10 @@ -import { useWeb3Modal, useWeb3ModalTheme } from "@web3modal/react" -import { useAccount } from "wagmi" import { ReactNode } from "react" -import Button from "../Button" - import classes from "./Layout.module.css" import { shortenAddress } from "../../utils/shortenAddress" -import Blockie from "../Blockie" -import clsx from "clsx" import { Link } from "react-router-dom" import ChainSelect from "../ChainSelect" +import ConnectButton from "../ConnectButton" interface Props { mechAddress?: string @@ -17,14 +12,6 @@ interface Props { } const Layout: React.FC = ({ children, mechAddress }) => { - const { setTheme } = useWeb3ModalTheme() - const { open } = useWeb3Modal() - const { address } = useAccount() - - setTheme({ - themeMode: "light", - }) - return (
cockpit @@ -42,20 +29,7 @@ const Layout: React.FC = ({ children, mechAddress }) => {
- +
{children}
diff --git a/frontend/src/hooks/useClickAway.ts b/frontend/src/hooks/useClickAway.ts new file mode 100644 index 0000000..0e5c379 --- /dev/null +++ b/frontend/src/hooks/useClickAway.ts @@ -0,0 +1,29 @@ +import { useEffect, useRef, useLayoutEffect } from "react" + +export default function useClickAway(cb: (e: MouseEvent | TouchEvent) => void) { + const ref = useRef(null) + const refCb = useRef(cb) + + useLayoutEffect(() => { + refCb.current = cb + }) + + useEffect(() => { + const handler = (e: MouseEvent | TouchEvent) => { + const element = ref.current + if (element && e.target && !element.contains(e.target as Node)) { + refCb.current(e) + } + } + + document.addEventListener("mousedown", handler) + document.addEventListener("touchstart", handler) + + return () => { + document.removeEventListener("mousedown", handler) + document.removeEventListener("touchstart", handler) + } + }, []) + + return ref +} diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 260bedc..0c507d9 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,17 +1,20 @@ import React from "react" import ReactDOM from "react-dom/client" -import { EthereumClient, w3mConnectors, w3mProvider } from "@web3modal/ethereum" - -import { Web3Modal } from "@web3modal/react" import { RouterProvider } from "react-router-dom" -import "./index.css" - +import { + getDefaultWallets, + RainbowKitProvider, + lightTheme, +} from "@rainbow-me/rainbowkit" import { configureChains, createConfig, WagmiConfig } from "wagmi" +import { infuraProvider } from "wagmi/providers/infura" +import { publicProvider } from "wagmi/providers/public" +import { mainnet, gnosis, polygon } from "wagmi/chains" + +import "./index.css" +import "@rainbow-me/rainbowkit/styles.css" -import { infuraProvider } from "@wagmi/core/providers/infura" -import { publicProvider } from "@wagmi/core/providers/public" import router from "./router" -import { CHAINS } from "./chains" window.Buffer = window.Buffer || require("buffer").Buffer @@ -20,28 +23,25 @@ if (!REACT_APP_WALLET_CONNECT_PROJECT_ID) { throw new Error("REACT_APP_WALLET_CONNECT_PROJECT_ID is not set") } -const { chains, publicClient } = configureChains(Object.values(CHAINS), [ - w3mProvider({ - projectId: REACT_APP_WALLET_CONNECT_PROJECT_ID, - }), +const supportedChains = [mainnet, gnosis, polygon] +const { chains, publicClient } = configureChains(supportedChains, [ infuraProvider({ apiKey: process.env.REACT_APP_INFURA_KEY || "" }), publicProvider(), ]) -export { chains } +const projectId = REACT_APP_WALLET_CONNECT_PROJECT_ID +const { connectors } = getDefaultWallets({ + appName: "Mech", + projectId, + chains, +}) const wagmiConfig = createConfig({ - autoConnect: true, - connectors: w3mConnectors({ - projectId: REACT_APP_WALLET_CONNECT_PROJECT_ID, - chains, - }), + autoConnect: false, + connectors, publicClient, }) -// Web3Modal Ethereum Client -const ethereumClient = new EthereumClient(wagmiConfig, chains) - const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement) // https://github.com/WalletConnect/walletconnect-monorepo/issues/748 @@ -50,13 +50,19 @@ const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement) root.render( - + + + - - ) From aa495022051f5ffda29610c8e57aa3ad992ba249 Mon Sep 17 00:00:00 2001 From: samepant Date: Mon, 8 Jan 2024 12:05:39 -0500 Subject: [PATCH 03/12] remove web3modal --- frontend/package.json | 3 - yarn.lock | 135 +----------------------------------------- 2 files changed, 2 insertions(+), 136 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 55c3587..fb879eb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,9 +10,6 @@ "@walletconnect/core": "^2.10.2", "@walletconnect/utils": "^2.10.2", "@walletconnect/web3wallet": "^1.9.2", - "@web3modal/ethereum": "^2.7.1", - "@web3modal/react": "^2.7.1", - "@web3modal/standalone": "^2.4.3", "buffer": "^6.0.3", "clsx": "^1.2.1", "copy-to-clipboard": "^3.3.3", diff --git a/yarn.lock b/yarn.lock index b5fa626..36396d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6255,82 +6255,6 @@ __metadata: languageName: node linkType: hard -"@web3modal/core@npm:2.4.3": - version: 2.4.3 - resolution: "@web3modal/core@npm:2.4.3" - dependencies: - buffer: 6.0.3 - valtio: 1.10.5 - checksum: af18f7c44266ed767830091e542eac69726a6f6c535024ad1b050bf5f406169bbea4a7f5e5e10f3415b08b4937e5a10f48d7c7f9f3e98742b84493753dfbc5b9 - languageName: node - linkType: hard - -"@web3modal/core@npm:2.7.1": - version: 2.7.1 - resolution: "@web3modal/core@npm:2.7.1" - dependencies: - valtio: 1.11.0 - checksum: 5f41bf44047e48a717b04167b482dc12d48ac5c4af5acc183c1dbfb400d945eb6139e894ecfd9875541c587d3323e219026328d260d01d50c3116f9ff373ec85 - languageName: node - linkType: hard - -"@web3modal/ethereum@npm:^2.7.1": - version: 2.7.1 - resolution: "@web3modal/ethereum@npm:2.7.1" - peerDependencies: - "@wagmi/core": ">=1" - viem: ">=1" - checksum: 272aca6b3d4647183b3bcd2ab126101b7b42bc70d13ebb744d8386ddb00105bdc6f31ca0feb2e339179fc66b95865836d24f31c3d3f5c0e0c0a636c66329f6d8 - languageName: node - linkType: hard - -"@web3modal/react@npm:^2.7.1": - version: 2.7.1 - resolution: "@web3modal/react@npm:2.7.1" - dependencies: - "@web3modal/core": 2.7.1 - "@web3modal/ui": 2.7.1 - peerDependencies: - react: ">=17" - react-dom: ">=17" - checksum: 14793cf61ccea770b0b07a999d4f667f712fd24748eed0a664c5a43df493b87b6fc7f3001daa580cecd1c00ef85102257548209bffdf270ffba1fc8c21ce064f - languageName: node - linkType: hard - -"@web3modal/standalone@npm:^2.4.3": - version: 2.4.3 - resolution: "@web3modal/standalone@npm:2.4.3" - dependencies: - "@web3modal/core": 2.4.3 - "@web3modal/ui": 2.4.3 - checksum: 3a5c6b93522f9c888979141f785f760aa27511be7b1a2de30bf3be5a4ee934dd0273b9e161aca5c4e10d6fe47c43cb66ef391a370e5bce7530ef1014867e4bb8 - languageName: node - linkType: hard - -"@web3modal/ui@npm:2.4.3": - version: 2.4.3 - resolution: "@web3modal/ui@npm:2.4.3" - dependencies: - "@web3modal/core": 2.4.3 - lit: 2.7.5 - motion: 10.16.2 - qrcode: 1.5.3 - checksum: 2198229f88b4242b5346ce0b2d3806e74c8014e21416f50ef4d7dc17a9d91485fd2146610dba7f9ff507b7b590342b66eddc70915a4b49a646d7bcab0e9b7859 - languageName: node - linkType: hard - -"@web3modal/ui@npm:2.7.1": - version: 2.7.1 - resolution: "@web3modal/ui@npm:2.7.1" - dependencies: - "@web3modal/core": 2.7.1 - lit: 2.7.6 - motion: 10.16.2 - qrcode: 1.5.3 - checksum: 1bb8fa415f7b22a4e9da75d55bab80e7a36429ed2f686f4c4ee55379cd41205a17913dc30a82e374d74238111cd37ed5e737d00b6b62f6aff5fffefc2336a9fc - languageName: node - linkType: hard - "@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": version: 1.11.6 resolution: "@webassemblyjs/ast@npm:1.11.6" @@ -7720,7 +7644,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:6.0.3, buffer@npm:^6.0.3": +"buffer@npm:^6.0.3": version: 6.0.3 resolution: "buffer@npm:6.0.3" dependencies: @@ -11105,9 +11029,6 @@ __metadata: "@walletconnect/core": ^2.10.2 "@walletconnect/utils": ^2.10.2 "@walletconnect/web3wallet": ^1.9.2 - "@web3modal/ethereum": ^2.7.1 - "@web3modal/react": ^2.7.1 - "@web3modal/standalone": ^2.4.3 buffer: ^6.0.3 clsx: ^1.2.1 copy-to-clipboard: ^3.3.3 @@ -14011,7 +13932,7 @@ __metadata: languageName: node linkType: hard -"lit-html@npm:^2.7.0, lit-html@npm:^2.8.0": +"lit-html@npm:^2.8.0": version: 2.8.0 resolution: "lit-html@npm:2.8.0" dependencies: @@ -14020,28 +13941,6 @@ __metadata: languageName: node linkType: hard -"lit@npm:2.7.5": - version: 2.7.5 - resolution: "lit@npm:2.7.5" - dependencies: - "@lit/reactive-element": ^1.6.0 - lit-element: ^3.3.0 - lit-html: ^2.7.0 - checksum: 61a3f87c57136618f47a30b36cdfb592fcba42dcfbdb104d2b5ca291148c2d9a32fcb713bb91090bd08d6897a00e73f8425da6e3626aa080eaf410a32397ae69 - languageName: node - linkType: hard - -"lit@npm:2.7.6": - version: 2.7.6 - resolution: "lit@npm:2.7.6" - dependencies: - "@lit/reactive-element": ^1.6.0 - lit-element: ^3.3.0 - lit-html: ^2.7.0 - checksum: 984a7fb9c0fa387f20177a07de22ea1c9cdc01a7dc7cb1c400d1df5b43a8956908460482a3259ea173555c6f0f13457d2ddc5c84d4c365007afd86e7ca58b384 - languageName: node - linkType: hard - "lit@npm:2.8.0": version: 2.8.0 resolution: "lit@npm:2.8.0" @@ -20417,36 +20316,6 @@ __metadata: languageName: node linkType: hard -"valtio@npm:1.10.5": - version: 1.10.5 - resolution: "valtio@npm:1.10.5" - dependencies: - proxy-compare: 2.5.1 - use-sync-external-store: 1.2.0 - peerDependencies: - react: ">=16.8" - peerDependenciesMeta: - react: - optional: true - checksum: a01d7cca44b3ff60213aa40470c42083f7522d8e2c2f2d9f696b0aa3eec4c3dba7393831d5ff47db1ad025904860d2788ce4d9654963ff3555481deb25376851 - languageName: node - linkType: hard - -"valtio@npm:1.11.0": - version: 1.11.0 - resolution: "valtio@npm:1.11.0" - dependencies: - proxy-compare: 2.5.1 - use-sync-external-store: 1.2.0 - peerDependencies: - react: ">=16.8" - peerDependenciesMeta: - react: - optional: true - checksum: 77e42f5841054ba3e41b456fbb96b679eaeb6d9dbb46b7ce9aee6acf1352de73969858dea837a706c969ca908155d6cb97966e33be10b69b097744dd99b5174a - languageName: node - linkType: hard - "valtio@npm:1.11.2": version: 1.11.2 resolution: "valtio@npm:1.11.2" From 23def978a77201bff4f9d766b626ac4acdc424e6 Mon Sep 17 00:00:00 2001 From: samepant Date: Mon, 8 Jan 2024 12:19:13 -0500 Subject: [PATCH 04/12] remove extraneous package resolution --- package.json | 3 - yarn.lock | 206 +++++++++++++-------------------------------------- 2 files changed, 50 insertions(+), 159 deletions(-) diff --git a/package.json b/package.json index 19290dd..2c863f7 100644 --- a/package.json +++ b/package.json @@ -87,8 +87,5 @@ "@gnosis.pm/safe-contracts": "^1.3.0", "@openzeppelin/contracts": "^4.9.3" }, - "resolutions": { - "@walletconnect/ethereum-provider": "2.7.0" - }, "packageManager": "yarn@3.7.0" } diff --git a/yarn.lock b/yarn.lock index 36396d8..540a05f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3101,37 +3101,6 @@ __metadata: languageName: node linkType: hard -"@json-rpc-tools/provider@npm:^1.5.5": - version: 1.7.6 - resolution: "@json-rpc-tools/provider@npm:1.7.6" - dependencies: - "@json-rpc-tools/utils": ^1.7.6 - axios: ^0.21.0 - safe-json-utils: ^1.1.1 - ws: ^7.4.0 - checksum: c60d73511db7f743c3844d499df6a7e243d5f5493127c00fbf9aec74c95d2e80a3033eb22369c428c2deec263a47cd1b334cd76c84859e30355a6dace893a589 - languageName: node - linkType: hard - -"@json-rpc-tools/types@npm:^1.7.6": - version: 1.7.6 - resolution: "@json-rpc-tools/types@npm:1.7.6" - dependencies: - keyvaluestorage-interface: ^1.0.0 - checksum: f23ec7d79a78aa4e896d1dff506108bd3da38015028afd997034e6498c1f3c7bedee70618b0d1a73adf13b4d2a6a91146c2e9505487280b3c376e74f5790e77c - languageName: node - linkType: hard - -"@json-rpc-tools/utils@npm:^1.7.6": - version: 1.7.6 - resolution: "@json-rpc-tools/utils@npm:1.7.6" - dependencies: - "@json-rpc-tools/types": ^1.7.6 - "@pedrouid/environment": ^1.0.1 - checksum: 32cac2e8cbf8a15d95415de8ded483c6206e6df392e129ad51acd90a4842511e931156c59cb26036fb9fae8054e8f20b719a35282304f39cd18683a5293cb67d - languageName: node - linkType: hard - "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.4 resolution: "@leichtgewicht/ip-codec@npm:2.0.4" @@ -4000,13 +3969,6 @@ __metadata: languageName: node linkType: hard -"@pedrouid/environment@npm:^1.0.1": - version: 1.0.1 - resolution: "@pedrouid/environment@npm:1.0.1" - checksum: fd88340ad760f26340a2816c3677f0ca913976e315880891c3de3f028fe64abc9704fb904234dce77a1ff15c22d0b6cbf1d4199a76de6695c2aed8353ce20590 - languageName: node - linkType: hard - "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -5722,26 +5684,28 @@ __metadata: languageName: node linkType: hard -"@walletconnect/core@npm:2.7.0": - version: 2.7.0 - resolution: "@walletconnect/core@npm:2.7.0" +"@walletconnect/core@npm:2.11.0": + version: 2.11.0 + resolution: "@walletconnect/core@npm:2.11.0" dependencies: "@walletconnect/heartbeat": 1.2.1 - "@walletconnect/jsonrpc-provider": ^1.0.12 - "@walletconnect/jsonrpc-utils": ^1.0.7 - "@walletconnect/jsonrpc-ws-connection": ^1.0.11 - "@walletconnect/keyvaluestorage": ^1.0.2 + "@walletconnect/jsonrpc-provider": 1.0.13 + "@walletconnect/jsonrpc-types": 1.0.3 + "@walletconnect/jsonrpc-utils": 1.0.8 + "@walletconnect/jsonrpc-ws-connection": 1.0.14 + "@walletconnect/keyvaluestorage": ^1.1.1 "@walletconnect/logger": ^2.0.1 "@walletconnect/relay-api": ^1.0.9 "@walletconnect/relay-auth": ^1.0.4 "@walletconnect/safe-json": ^1.0.2 "@walletconnect/time": ^1.0.2 - "@walletconnect/types": 2.7.0 - "@walletconnect/utils": 2.7.0 + "@walletconnect/types": 2.11.0 + "@walletconnect/utils": 2.11.0 events: ^3.3.0 + isomorphic-unfetch: 3.1.0 lodash.isequal: 4.5.0 uint8arrays: ^3.1.0 - checksum: 86017de59ef2fd48638897878aad109cb43b2bf40ec4c172972389e6569eb3228fe662ae022e345f38432b890d0b39059cc5fda3f3607f8e9024b587b26a5d70 + checksum: 419eff78df347eb5d5c51c2dbf60e3246b5dda00afdd77279795a89627285839cb769e1115e751026756d37e26e6bd708452170ded08be074d64256afd8a8663 languageName: node linkType: hard @@ -5779,25 +5743,21 @@ __metadata: languageName: node linkType: hard -"@walletconnect/ethereum-provider@npm:2.7.0": - version: 2.7.0 - resolution: "@walletconnect/ethereum-provider@npm:2.7.0" +"@walletconnect/ethereum-provider@npm:2.11.0": + version: 2.11.0 + resolution: "@walletconnect/ethereum-provider@npm:2.11.0" dependencies: - "@walletconnect/jsonrpc-http-connection": ^1.0.4 - "@walletconnect/jsonrpc-provider": ^1.0.11 - "@walletconnect/jsonrpc-types": ^1.0.2 - "@walletconnect/jsonrpc-utils": ^1.0.7 - "@walletconnect/sign-client": 2.7.0 - "@walletconnect/types": 2.7.0 - "@walletconnect/universal-provider": 2.7.0 - "@walletconnect/utils": 2.7.0 + "@walletconnect/jsonrpc-http-connection": ^1.0.7 + "@walletconnect/jsonrpc-provider": ^1.0.13 + "@walletconnect/jsonrpc-types": ^1.0.3 + "@walletconnect/jsonrpc-utils": ^1.0.8 + "@walletconnect/modal": ^2.6.2 + "@walletconnect/sign-client": 2.11.0 + "@walletconnect/types": 2.11.0 + "@walletconnect/universal-provider": 2.11.0 + "@walletconnect/utils": 2.11.0 events: ^3.3.0 - peerDependencies: - "@web3modal/standalone": ">=2" - peerDependenciesMeta: - "@web3modal/standalone": - optional: true - checksum: 4bfeec5d7dac54a1988b2882bacc4532902e5825c99b38abf6af24943261fafa0ac17263fb530e8e8490c058b7b75c0340812ff90db389ee3ec3de7900efae3f + checksum: 8b45eb7e6679d340e6d976c6c10b10b4ce0435b959d35b627677d946b9f152f20fc242e581a16e9b6f7ed98c5352748213856e342f55f3dbd4cd9130965d542c languageName: node linkType: hard @@ -5822,7 +5782,7 @@ __metadata: languageName: node linkType: hard -"@walletconnect/jsonrpc-http-connection@npm:^1.0.4": +"@walletconnect/jsonrpc-http-connection@npm:^1.0.4, @walletconnect/jsonrpc-http-connection@npm:^1.0.7": version: 1.0.7 resolution: "@walletconnect/jsonrpc-http-connection@npm:1.0.7" dependencies: @@ -5834,7 +5794,7 @@ __metadata: languageName: node linkType: hard -"@walletconnect/jsonrpc-provider@npm:1.0.13, @walletconnect/jsonrpc-provider@npm:^1.0.11, @walletconnect/jsonrpc-provider@npm:^1.0.12, @walletconnect/jsonrpc-provider@npm:^1.0.6": +"@walletconnect/jsonrpc-provider@npm:1.0.13, @walletconnect/jsonrpc-provider@npm:^1.0.13, @walletconnect/jsonrpc-provider@npm:^1.0.6": version: 1.0.13 resolution: "@walletconnect/jsonrpc-provider@npm:1.0.13" dependencies: @@ -5866,7 +5826,7 @@ __metadata: languageName: node linkType: hard -"@walletconnect/jsonrpc-ws-connection@npm:1.0.14, @walletconnect/jsonrpc-ws-connection@npm:^1.0.11": +"@walletconnect/jsonrpc-ws-connection@npm:1.0.14": version: 1.0.14 resolution: "@walletconnect/jsonrpc-ws-connection@npm:1.0.14" dependencies: @@ -5878,7 +5838,7 @@ __metadata: languageName: node linkType: hard -"@walletconnect/keyvaluestorage@npm:^1.0.2, @walletconnect/keyvaluestorage@npm:^1.1.1": +"@walletconnect/keyvaluestorage@npm:^1.1.1": version: 1.1.1 resolution: "@walletconnect/keyvaluestorage@npm:1.1.1" dependencies: @@ -5995,7 +5955,7 @@ __metadata: languageName: node linkType: hard -"@walletconnect/modal@npm:2.6.2": +"@walletconnect/modal@npm:2.6.2, @walletconnect/modal@npm:^2.6.2": version: 2.6.2 resolution: "@walletconnect/modal@npm:2.6.2" dependencies: @@ -6067,20 +6027,20 @@ __metadata: languageName: node linkType: hard -"@walletconnect/sign-client@npm:2.7.0": - version: 2.7.0 - resolution: "@walletconnect/sign-client@npm:2.7.0" +"@walletconnect/sign-client@npm:2.11.0": + version: 2.11.0 + resolution: "@walletconnect/sign-client@npm:2.11.0" dependencies: - "@walletconnect/core": 2.7.0 + "@walletconnect/core": 2.11.0 "@walletconnect/events": ^1.0.1 "@walletconnect/heartbeat": 1.2.1 - "@walletconnect/jsonrpc-utils": ^1.0.7 + "@walletconnect/jsonrpc-utils": 1.0.8 "@walletconnect/logger": ^2.0.1 "@walletconnect/time": ^1.0.2 - "@walletconnect/types": 2.7.0 - "@walletconnect/utils": 2.7.0 + "@walletconnect/types": 2.11.0 + "@walletconnect/utils": 2.11.0 events: ^3.3.0 - checksum: 85f6ca56d481616202cedec6e9c8af39e21d7d1ad9c021d54a4831d6b9cf71d684a00049474f8368a09c75c4b9425006d73fbfd6d8ac99f3ec23038b01522564 + checksum: 89230cf4ca95f9feb06104cc8097340e345b2b21257d45acf16729342ddcf5248bbf05097343b21e4dbebfa4fbacb6fe067099ee6127169a6b464563985d4716 languageName: node linkType: hard @@ -6121,35 +6081,20 @@ __metadata: languageName: node linkType: hard -"@walletconnect/types@npm:2.7.0": - version: 2.7.0 - resolution: "@walletconnect/types@npm:2.7.0" - dependencies: - "@walletconnect/events": ^1.0.1 - "@walletconnect/heartbeat": 1.2.1 - "@walletconnect/jsonrpc-types": ^1.0.2 - "@walletconnect/keyvaluestorage": ^1.0.2 - "@walletconnect/logger": ^2.0.1 - events: ^3.3.0 - checksum: 3380e52fdcb481c8f4ce048b5d7eb7b8af0ac33d34afcca292022b1e443cbadba2235a0d9a489705515cfcb5f42ab3ee341f41c986e3ad23d28fb8472a31c51a - languageName: node - linkType: hard - -"@walletconnect/universal-provider@npm:2.7.0": - version: 2.7.0 - resolution: "@walletconnect/universal-provider@npm:2.7.0" +"@walletconnect/universal-provider@npm:2.11.0": + version: 2.11.0 + resolution: "@walletconnect/universal-provider@npm:2.11.0" dependencies: - "@walletconnect/jsonrpc-http-connection": ^1.0.4 - "@walletconnect/jsonrpc-provider": ^1.0.11 + "@walletconnect/jsonrpc-http-connection": ^1.0.7 + "@walletconnect/jsonrpc-provider": 1.0.13 "@walletconnect/jsonrpc-types": ^1.0.2 "@walletconnect/jsonrpc-utils": ^1.0.7 "@walletconnect/logger": ^2.0.1 - "@walletconnect/sign-client": 2.7.0 - "@walletconnect/types": 2.7.0 - "@walletconnect/utils": 2.7.0 - eip1193-provider: 1.0.1 + "@walletconnect/sign-client": 2.11.0 + "@walletconnect/types": 2.11.0 + "@walletconnect/utils": 2.11.0 events: ^3.3.0 - checksum: b6e4a51eb021c123eee5a8dcf2cb148e7797a849ce3298ed5599f6c0fcf9f7e9ba89b5f11442d6caf1d42b987f36b076f2fc740494d68ed5b07f0c6cddfbdf20 + checksum: 7f4f187cd9148dc2e262e4afecadf0d0e136ae4183a60779562fef142411b927a3305c90793ef98dc3ecc61e4e2d4cfc8ac5491b1b42054021cfc4383f7ab81e languageName: node linkType: hard @@ -6197,29 +6142,6 @@ __metadata: languageName: node linkType: hard -"@walletconnect/utils@npm:2.7.0": - version: 2.7.0 - resolution: "@walletconnect/utils@npm:2.7.0" - dependencies: - "@stablelib/chacha20poly1305": 1.0.1 - "@stablelib/hkdf": 1.0.1 - "@stablelib/random": ^1.0.2 - "@stablelib/sha256": 1.0.1 - "@stablelib/x25519": ^1.0.3 - "@walletconnect/jsonrpc-utils": ^1.0.7 - "@walletconnect/relay-api": ^1.0.9 - "@walletconnect/safe-json": ^1.0.2 - "@walletconnect/time": ^1.0.2 - "@walletconnect/types": 2.7.0 - "@walletconnect/window-getters": ^1.0.1 - "@walletconnect/window-metadata": ^1.0.1 - detect-browser: 5.3.0 - query-string: 7.1.1 - uint8arrays: ^3.1.0 - checksum: 10920058ab4a0455b0aab85fef162fef0d02eccf9e963731b922f1a72d80645ea8dca5b0ed3a1d2299b3c619d173f93078496762cc4324990a578047e1acc571 - languageName: node - linkType: hard - "@walletconnect/web3wallet@npm:^1.9.2": version: 1.9.4 resolution: "@walletconnect/web3wallet@npm:1.9.4" @@ -7145,7 +7067,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:^0.21.0, axios@npm:^0.21.1": +"axios@npm:^0.21.1": version: 0.21.4 resolution: "axios@npm:0.21.4" dependencies: @@ -9398,15 +9320,6 @@ __metadata: languageName: node linkType: hard -"eip1193-provider@npm:1.0.1": - version: 1.0.1 - resolution: "eip1193-provider@npm:1.0.1" - dependencies: - "@json-rpc-tools/provider": ^1.5.5 - checksum: a56d6a874786b788c1f09f96d329b118ca6b3d381055865bb1ec1bde17da8d433a4141200baa2922108d67ac0d83813841940d2813814e56ea923fc9fafb369a - languageName: node - linkType: hard - "ejs@npm:^3.1.6": version: 3.1.9 resolution: "ejs@npm:3.1.9" @@ -12732,7 +12645,7 @@ __metadata: languageName: node linkType: hard -"isomorphic-unfetch@npm:^3.1.0": +"isomorphic-unfetch@npm:3.1.0, isomorphic-unfetch@npm:^3.1.0": version: 3.1.0 resolution: "isomorphic-unfetch@npm:3.1.0" dependencies: @@ -16911,18 +16824,6 @@ __metadata: languageName: node linkType: hard -"query-string@npm:7.1.1": - version: 7.1.1 - resolution: "query-string@npm:7.1.1" - dependencies: - decode-uri-component: ^0.2.0 - filter-obj: ^1.1.0 - split-on-first: ^1.0.0 - strict-uri-encode: ^2.0.0 - checksum: b227d1f588ae93f9f0ad078c6b811295fa151dc5a160a03bb2bac5fa0e6919cb1daa570aad1d288e77c8e89fde5362ba505b1014e6e793da9b1e885b59a690a6 - languageName: node - linkType: hard - "query-string@npm:7.1.3": version: 7.1.3 resolution: "query-string@npm:7.1.3" @@ -17855,13 +17756,6 @@ __metadata: languageName: node linkType: hard -"safe-json-utils@npm:^1.1.1": - version: 1.1.1 - resolution: "safe-json-utils@npm:1.1.1" - checksum: f82a5833b7f6f25583c46520b3e158da3864d4f6f85b7cd68ec956ae7023395872e834d75f7f6216c109c546d10b6ee15c066d849f75ac2a7b86b8a041b4f01f - languageName: node - linkType: hard - "safe-regex-test@npm:^1.0.0": version: 1.0.0 resolution: "safe-regex-test@npm:1.0.0" @@ -21270,7 +21164,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.4.0, ws@npm:^7.4.6, ws@npm:^7.5.1": +"ws@npm:^7.4.6, ws@npm:^7.5.1": version: 7.5.9 resolution: "ws@npm:7.5.9" peerDependencies: From fd6a817ab136fe708385a0fccc5afb7fd1472093 Mon Sep 17 00:00:00 2001 From: samepant Date: Thu, 18 Jan 2024 17:23:17 -0500 Subject: [PATCH 05/12] remove sequence, refactor hooks --- frontend/package.json | 6 +- frontend/src/chains.ts | 29 -- frontend/src/components/NFTGrid/index.tsx | 31 +- frontend/src/components/NFTGridItem/index.tsx | 38 ++- frontend/src/components/NFTItem/index.tsx | 42 +-- frontend/src/hooks/useDeployMech.tsx | 32 +- frontend/src/hooks/useTokenBalances.ts | 139 ++++---- frontend/src/hooks/useTokenMetadata.ts | 36 ++ frontend/src/index.tsx | 46 +-- frontend/src/types/Token.d.ts | 36 ++ frontend/src/utils/calculateMechAddress.ts | 12 +- frontend/src/utils/deployMech.ts | 15 +- frontend/src/utils/getNFTContext.ts | 12 + sdk/package.json | 2 +- yarn.lock | 310 ++---------------- 15 files changed, 281 insertions(+), 505 deletions(-) create mode 100644 frontend/src/hooks/useTokenMetadata.ts create mode 100644 frontend/src/types/Token.d.ts create mode 100644 frontend/src/utils/getNFTContext.ts diff --git a/frontend/package.json b/frontend/package.json index fb879eb..fbc5bb2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,7 +3,6 @@ "version": "1.0.0", "private": true, "devDependencies": { - "0xsequence": "^1.6.2", "@rainbow-me/rainbowkit": "^1.3.3", "@types/react": "^18.2.21", "@types/react-dom": "^18.2.7", @@ -47,5 +46,8 @@ "last 1 safari version" ] }, - "packageManager": "yarn@3.6.1" + "packageManager": "yarn@3.6.1", + "dependencies": { + "@tanstack/react-query": "^5.17.15" + } } diff --git a/frontend/src/chains.ts b/frontend/src/chains.ts index 9a80c9a..6bf077d 100644 --- a/frontend/src/chains.ts +++ b/frontend/src/chains.ts @@ -15,32 +15,3 @@ export const CHAINS: ChainInfo = { export type ChainId = keyof typeof CHAINS export const DEFAULT_CHAIN = CHAINS[1] - -export enum SequenceIndexerServices { - MAINNET = "https://mainnet-indexer.sequence.app", - - POLYGON = "https://polygon-indexer.sequence.app", - POLYGON_MUMBAI = "https://mumbai-indexer.sequence.app", - - POLYGON_ZKEVM = "https://polygon-zkevm-indexer.sequence.app", - - ARBITRUM = "https://arbitrum-indexer.sequence.app", - ARBITRUM_NOVA = "https://arbitrum-nova-indexer.sequence.app", - - OPTIMISM = "https://optimism-indexer.sequence.app", - AVALANCHE = "https://avalanche-indexer.sequence.app", - GNOSIS = "https://gnosis-indexer.sequence.app", - - BSC = "https://bsc-indexer.sequence.app", - BSC_TESTNET = "https://bsc-testnet-indexer.sequence.app", - - GOERLI = "https://goerli-indexer.sequence.app", -} - -export const SEQUENCER_ENDPOINTS: Record = { - 1: SequenceIndexerServices.MAINNET, - 5: SequenceIndexerServices.GOERLI, - 100: SequenceIndexerServices.GNOSIS, - 137: SequenceIndexerServices.POLYGON, - 80001: SequenceIndexerServices.POLYGON_MUMBAI, -} diff --git a/frontend/src/components/NFTGrid/index.tsx b/frontend/src/components/NFTGrid/index.tsx index 5296270..32c1ef7 100644 --- a/frontend/src/components/NFTGrid/index.tsx +++ b/frontend/src/components/NFTGrid/index.tsx @@ -1,4 +1,3 @@ -import { ContractType, TokenBalance } from "@0xsequence/indexer" import NFTGridItem from "../NFTGridItem" import Spinner from "../Spinner" @@ -8,6 +7,8 @@ import { useChainId } from "wagmi" import { useDeployedMechs } from "../../hooks/useDeployMech" import { calculateMechAddress } from "../../utils/calculateMechAddress" import useTokenBalances from "../../hooks/useTokenBalances" +import { getNFTContext, getNFTContexts } from "../../utils/getNFTContext" +import { MoralisNFT } from "../../types/Token" interface Props { address: string @@ -15,30 +16,26 @@ interface Props { const NFTGrid: React.FC = ({ address }) => { const chainId = useChainId() - - const { balances, isLoading } = useTokenBalances({ + console.log("chainId", chainId) + const { data, isLoading, error } = useTokenBalances({ accountAddress: address, chainId, }) + const nftBalances = data?.nfts || [] - const nftBalances = balances.filter( - (balance) => - balance.contractType === ContractType.ERC721 || - balance.contractType === ContractType.ERC1155 - ) - - const deployedMechs = useDeployedMechs(nftBalances) + const deployedMechs = useDeployedMechs(getNFTContexts(nftBalances), chainId) - const isDeployed = (nft: TokenBalance) => + const isDeployed = (nft: MoralisNFT) => deployedMechs.some( (mech) => mech.chainId === chainId && - mech.address.toLowerCase() === calculateMechAddress(nft).toLowerCase() + mech.address.toLowerCase() === + calculateMechAddress(getNFTContext(nft), chainId).toLowerCase() ) const deployed = nftBalances.filter(isDeployed) const undeployed = nftBalances.filter((nft) => !isDeployed(nft)) - + console.log("undeployed", undeployed.length) return (
@@ -54,8 +51,8 @@ const NFTGrid: React.FC = ({ address }) => { )}
    {deployed.map((nft, index) => ( -
  • - +
  • +
  • ))}
@@ -68,8 +65,8 @@ const NFTGrid: React.FC = ({ address }) => { {undeployed.length > 0 && (
    {undeployed.map((nft, index) => ( -
  • - +
  • +
  • ))}
diff --git a/frontend/src/components/NFTGridItem/index.tsx b/frontend/src/components/NFTGridItem/index.tsx index 4e4229f..8a33c35 100644 --- a/frontend/src/components/NFTGridItem/index.tsx +++ b/frontend/src/components/NFTGridItem/index.tsx @@ -1,4 +1,3 @@ -import { TokenBalance } from "@0xsequence/indexer" import { useState } from "react" import copy from "copy-to-clipboard" import clsx from "clsx" @@ -10,46 +9,51 @@ import { shortenAddress } from "../../utils/shortenAddress" import Spinner from "../Spinner" import ChainIcon from "../ChainIcon" import { calculateMechAddress } from "../../utils/calculateMechAddress" -import { CHAINS, ChainId } from "../../chains" +import { CHAINS } from "../../chains" import { useDeployMech } from "../../hooks/useDeployMech" +import { MoralisNFT } from "../../types/Token" +import { getNFTContext } from "../../utils/getNFTContext" interface Props { - tokenBalance: TokenBalance + nft: MoralisNFT + chainId: number } -const NFTGridItem: React.FC = ({ tokenBalance }) => { +const NFTGridItem: React.FC = ({ nft, chainId }) => { const [imageError, setImageError] = useState(false) - const chain = CHAINS[tokenBalance.chainId as ChainId] + const chain = CHAINS[chainId] - const mechAddress = calculateMechAddress(tokenBalance) - const { deploy, deployPending, deployed } = useDeployMech(tokenBalance) + const mechAddress = calculateMechAddress(getNFTContext(nft), chainId) + const { deploy, deployPending, deployed } = useDeployMech( + getNFTContext(nft), + chainId + ) - const name = - tokenBalance.tokenMetadata?.name || tokenBalance.contractInfo?.name + const name = nft.name || nft.metadata?.name return (

{name || "..."}

- {tokenBalance.tokenID.length < 5 && ( -

{tokenBalance.tokenID || "..."}

+ {nft.token_id.length < 5 && ( +

{nft.token_id || "..."}

)}
- {(imageError || !tokenBalance.tokenMetadata?.image) && ( + {(imageError || !nft.metadata?.image) && (
)} - {!imageError && tokenBalance.tokenMetadata?.image && ( + {!imageError && nft.metadata?.image && (
{name} setImageError(true)} @@ -70,9 +74,7 @@ const NFTGridItem: React.FC = ({ tokenBalance }) => {
{deployed ? ( - + diff --git a/frontend/src/components/NFTItem/index.tsx b/frontend/src/components/NFTItem/index.tsx index d45e18b..30fce9c 100644 --- a/frontend/src/components/NFTItem/index.tsx +++ b/frontend/src/components/NFTItem/index.tsx @@ -1,4 +1,3 @@ -import { TokenBalance } from "@0xsequence/indexer" import classes from "./NFTItem.module.css" import { useState } from "react" import { shortenAddress } from "../../utils/shortenAddress" @@ -11,46 +10,50 @@ import { useDeployMech } from "../../hooks/useDeployMech" import { calculateMechAddress } from "../../utils/calculateMechAddress" import { formatUnits } from "viem" +import { MoralisNFT } from "../../types/Token" +import { getNFTContext } from "../../utils/getNFTContext" interface Props { - tokenBalance: TokenBalance + nft: MoralisNFT + chainId: number } -const NFTItem: React.FC = ({ tokenBalance }) => { - const mechAddress = calculateMechAddress(tokenBalance) - const operatorAddress = tokenBalance.accountAddress +const NFTItem: React.FC = ({ nft, chainId }) => { + const mechAddress = calculateMechAddress(getNFTContext(nft), chainId) + const operatorAddress = nft.owner_of const [imageError, setImageError] = useState(false) const { - balances: mechBalances, + data, isLoading: mechBalancesLoading, error: mechBalancesError, } = useTokenBalances({ accountAddress: mechAddress, - chainId: tokenBalance.chainId, + chainId, }) - const { deployed } = useDeployMech(tokenBalance) - const name = - tokenBalance.tokenMetadata?.name || tokenBalance.contractInfo?.name || "..." + const mechBalances = data ? [data.native, ...data.erc20s] : [] + + const { deployed } = useDeployMech(getNFTContext(nft), chainId) + const name = nft.name || nft.metadata?.name || "..." return (

{name}

-

- {tokenBalance.tokenID} +

+ {nft.token_id}

- {(imageError || !tokenBalance.tokenMetadata?.image) && ( + {(imageError || !nft.metadata?.image) && (
)} - {!imageError && tokenBalance.tokenMetadata?.image && ( + {!imageError && nft.metadata?.image && (
{name} setImageError(true)} @@ -121,15 +124,12 @@ const NFTItem: React.FC = ({ tokenBalance }) => {
    {mechBalances.map((balance, index) => (
  • -
    {balance.contractInfo?.name}
    +
    {balance.name}

    - {formatUnits( - BigInt(balance.balance), - balance.contractInfo?.decimals || 0 - )} + {formatUnits(BigInt(balance.balance), balance.decimals || 0)}

    -

    {balance.contractInfo?.symbol}

    +

    {balance.symbol}

  • ))} diff --git a/frontend/src/hooks/useDeployMech.tsx b/frontend/src/hooks/useDeployMech.tsx index 8ea94bd..5e92db4 100644 --- a/frontend/src/hooks/useDeployMech.tsx +++ b/frontend/src/hooks/useDeployMech.tsx @@ -1,15 +1,14 @@ -import { TokenBalance } from "@0xsequence/indexer" import { useEffect, useState } from "react" import { - PublicClient, - useChainId, usePublicClient, + useWalletClient, useQuery, useQueryClient, - useWalletClient, } from "wagmi" +import { PublicClient } from "viem" import { calculateMechAddress } from "../utils/calculateMechAddress" import { makeMechDeployTransaction } from "../utils/deployMech" +import { NFTContext } from "../types/Token" interface QueryKeyArgs { address: `0x${string}` @@ -29,35 +28,32 @@ function queryFn(client: PublicClient) { } } -export const useDeployMech = (token: TokenBalance | null) => { - const mechAddress = token && calculateMechAddress(token) +export const useDeployMech = (token: NFTContext | null, chainId: number) => { + const mechAddress = token && calculateMechAddress(token, chainId) - const publicClient = usePublicClient({ chainId: token?.chainId }) + const publicClient = usePublicClient({ chainId: chainId }) const { data: deployed } = useQuery( - [ - "mechDeployed", - { address: mechAddress, chainId: token?.chainId }, - ] as const, + ["mechDeployed", { address: mechAddress, chainId: chainId }] as const, { queryFn: queryFn(publicClient) as any, enabled: !!mechAddress, } ) - const { data: walletClient } = useWalletClient({ chainId: token?.chainId }) + const { data: walletClient } = useWalletClient({ chainId }) const queryClient = useQueryClient() const [deployPending, setDeployPending] = useState(false) const deploy = async () => { if (!walletClient || !token) return - const tx = makeMechDeployTransaction(token) + const tx = makeMechDeployTransaction(token, chainId) setDeployPending(true) try { const hash = await walletClient.sendTransaction(tx) const receipt = await publicClient.waitForTransactionReceipt({ hash }) queryClient.setQueryData( - ["mechDeployed", { address: mechAddress, chainId: token.chainId }], + ["mechDeployed", { address: mechAddress, chainId }], true ) return receipt @@ -71,7 +67,7 @@ export const useDeployMech = (token: TokenBalance | null) => { return { deployed, deploy, deployPending } } -export const useDeployedMechs = (nfts: TokenBalance[]) => { +export const useDeployedMechs = (nfts: NFTContext[], chainId: number) => { const queryClient = useQueryClient() useEffect(() => { @@ -80,15 +76,15 @@ export const useDeployedMechs = (nfts: TokenBalance[]) => { .ensureQueryData([ "mechDeployed", { - address: calculateMechAddress(nft), - chainId: nft.chainId, + address: calculateMechAddress(nft, chainId), + chainId: chainId, }, ]) .catch((e) => { /* when switching networks, this might throw an error (`Missing queryFn for queryKey`) */ }) }) - }, [queryClient, nfts]) + }, [queryClient, nfts, chainId]) const deployedMechs = queryClient.getQueriesData([ "mechDeployed", diff --git a/frontend/src/hooks/useTokenBalances.ts b/frontend/src/hooks/useTokenBalances.ts index 06d9261..ce8ebe8 100644 --- a/frontend/src/hooks/useTokenBalances.ts +++ b/frontend/src/hooks/useTokenBalances.ts @@ -1,96 +1,79 @@ -import { - SequenceIndexer, - TokenBalance, - ContractType, -} from "@0xsequence/indexer" -import { useEffect, useState } from "react" -import { ChainId, SEQUENCER_ENDPOINTS } from "../chains" +import { useQuery } from "@tanstack/react-query" +import { CHAINS } from "../chains" +import { MoralisFungible, MoralisNFT } from "../types/Token" interface Props { accountAddress?: string chainId: number - tokenContract?: string - tokenId?: string } -const API_KEY = process.env.REACT_APP_SEQUENCE_API_KEY || "" +if (!process.env.REACT_APP_PROXY_URL) { + throw new Error("REACT_APP_PROXY_URL not set") +} -const useTokenBalances = ({ - accountAddress, - chainId, - tokenContract, - tokenId, -}: Props) => { - const [balances, setBalances] = useState([]) - const [isLoading, setIsLoading] = useState(false) - const [error, setError] = useState(null) +const useTokenBalances = ({ accountAddress, chainId }: Props) => { + return useQuery({ + queryKey: ["tokenBalances", chainId, accountAddress], + queryFn: async () => { + if (!chainId || !accountAddress) throw new Error("No chainId or account") - useEffect(() => { - const indexer = new SequenceIndexer( - SEQUENCER_ENDPOINTS[chainId as ChainId], - API_KEY - ) - const fetchData = async () => { try { - setIsLoading(true) - const tokenBalances = await indexer.getTokenBalances({ - includeMetadata: true, - accountAddress, - contractAddress: tokenContract, - tokenID: tokenId, - }) - - let balances = tokenBalances.balances.filter( - (balance) => - balance.contractType === ContractType.ERC20 || - balance.contractType === ContractType.ERC721 || - balance.contractType === ContractType.ERC1155 + // get nfts + const nftRes = await fetch( + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/${accountAddress}/nft` ) + if (!nftRes.ok) { + throw new Error("NFT request failed") + } + const nftJson = await nftRes.json() + const nftData = nftJson.result as MoralisNFT[] - // Inconveniently, the Sequence API sets all tokenIDs to 0 if fetched without contractAddress - if (!tokenContract) { - // fetch the balances for each tokenContract individually, these responses will have the correct tokenID values - const tokenContracts = new Set( - balances - .filter( - (balance) => - balance.contractType === ContractType.ERC721 || - balance.contractType === ContractType.ERC1155 - ) - .map((balance) => balance.contractAddress) - ) - - const nftBalances = await Promise.all( - [...tokenContracts].map(async (contractAddress) => { - const result = await indexer.getTokenBalances({ - includeMetadata: true, - accountAddress, - contractAddress, - }) - - return result.balances - }) - ) - - const erc20Balances = balances.filter( - (balance) => balance.contractType === ContractType.ERC20 - ) + // get erc20s + const erc20Res = await fetch( + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/${accountAddress}/erc20` + ) + if (!erc20Res.ok) { + throw new Error("ERC20 request failed") + } + const erc20Json = await erc20Res.json() + const erc20Data = erc20Json.result as MoralisFungible[] - balances = [...erc20Balances, ...nftBalances.flat()] + // get native balance + const nativeRes = await fetch( + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/${accountAddress}/balance` + ) + if (!nativeRes.ok) { + throw new Error("Native request failed") } + const nativeJson = await nativeRes.json() + const nativeData = { + balance: nativeJson.balance as string, + decimals: CHAINS[chainId].nativeCurrency.decimals, + name: CHAINS[chainId].nativeCurrency.name, + symbol: CHAINS[chainId].nativeCurrency.symbol, + } as MoralisFungible - setBalances(balances) - setIsLoading(false) - } catch (e) { - setError(e) - setIsLoading(false) + return { + nfts: nftData, + erc20s: erc20Data, + native: nativeData, + } + } catch (error) { + console.error(error) + return { + nfts: [], + erc20s: [], + native: { + balance: "0", + decimals: CHAINS[chainId].nativeCurrency.decimals, + name: CHAINS[chainId].nativeCurrency.name, + symbol: CHAINS[chainId].nativeCurrency.symbol, + }, + } } - } - - fetchData() - }, [accountAddress, tokenContract, tokenId, chainId]) - - return { balances, isLoading, error } + }, + enabled: !!chainId && !!accountAddress, + }) } export default useTokenBalances diff --git a/frontend/src/hooks/useTokenMetadata.ts b/frontend/src/hooks/useTokenMetadata.ts new file mode 100644 index 0000000..9ef7ccc --- /dev/null +++ b/frontend/src/hooks/useTokenMetadata.ts @@ -0,0 +1,36 @@ +import { useQuery } from "@tanstack/react-query" +import { CHAINS } from "../chains" +import { MoralisNFT } from "../types/Token" + +interface Props { + tokenAddress: string + tokenId: string + chainId: number +} + +if (!process.env.REACT_APP_PROXY_URL) { + throw new Error("REACT_APP_PROXY_URL not set") +} + +const useNFTMetadata = ({ tokenAddress, tokenId, chainId }: Props) => { + return useQuery({ + queryKey: ["tokenBalances", chainId, tokenAddress, tokenId], + queryFn: async () => { + if (!chainId || !tokenAddress || !tokenId) + throw new Error("No chainId or token") + + // get nfts + const nftRes = await fetch( + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/nft/${tokenAddress}/${tokenId}}` + ) + if (!nftRes.ok) { + throw new Error("NFT request failed") + } + const nftJson = (await nftRes.json()) as MoralisNFT + return nftJson + }, + enabled: !!chainId && !!tokenAddress && !!tokenId, + }) +} + +export default useNFTMetadata diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 0c507d9..1dcbb5f 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -6,10 +6,10 @@ import { RainbowKitProvider, lightTheme, } from "@rainbow-me/rainbowkit" -import { configureChains, createConfig, WagmiConfig } from "wagmi" -import { infuraProvider } from "wagmi/providers/infura" -import { publicProvider } from "wagmi/providers/public" +import { configureChains, createConfig, WagmiConfig, Chain } from "wagmi" +import { jsonRpcProvider } from "wagmi/providers/jsonRpc" import { mainnet, gnosis, polygon } from "wagmi/chains" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" import "./index.css" import "@rainbow-me/rainbowkit/styles.css" @@ -25,8 +25,11 @@ if (!REACT_APP_WALLET_CONNECT_PROJECT_ID) { const supportedChains = [mainnet, gnosis, polygon] const { chains, publicClient } = configureChains(supportedChains, [ - infuraProvider({ apiKey: process.env.REACT_APP_INFURA_KEY || "" }), - publicProvider(), + jsonRpcProvider({ + rpc: (chain) => ({ + http: `${process.env.REACT_APP_PROXY_URL}/${chain.id}/rpc`, + }), + }), ]) const projectId = REACT_APP_WALLET_CONNECT_PROJECT_ID @@ -37,7 +40,7 @@ const { connectors } = getDefaultWallets({ }) const wagmiConfig = createConfig({ - autoConnect: false, + autoConnect: true, connectors, publicClient, }) @@ -46,23 +49,26 @@ const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement) // https://github.com/WalletConnect/walletconnect-monorepo/issues/748 // window.Buffer = window.Buffer || require("buffer").Buffer +const queryClient = new QueryClient() root.render( - - - - - + + + + + + + ) diff --git a/frontend/src/types/Token.d.ts b/frontend/src/types/Token.d.ts new file mode 100644 index 0000000..5dfef3c --- /dev/null +++ b/frontend/src/types/Token.d.ts @@ -0,0 +1,36 @@ +export interface NFTContext { + tokenAddress: string + tokenId: string + contractType: NFTType +} + +export type NFTType = "ERC721" | "ERC1155" + +export interface MoralisNFT { + amount: string + token_id: string + token_address: string + contract_type: NFTType + owner_of: string + metadata?: any + block_number: string + block_number_minted: string + name: string + symbol: string + token_hash: string + token_uri: string + minter_address: string + verified_collection: boolean + possible_spam: boolean +} + +export interface MoralisFungible { + token_address: string + symbol: string + name: string + logo?: string + thumbnail?: string + decimals: number + balance: string + possible_spam?: boolean +} diff --git a/frontend/src/utils/calculateMechAddress.ts b/frontend/src/utils/calculateMechAddress.ts index aabe722..1f491a5 100644 --- a/frontend/src/utils/calculateMechAddress.ts +++ b/frontend/src/utils/calculateMechAddress.ts @@ -1,16 +1,16 @@ -import { TokenBalance, ContractType } from "@0xsequence/indexer" import { calculateERC1155TokenboundMechAddress, calculateERC721TokenboundMechAddress, } from "mech-sdk" +import { NFTContext } from "../types/Token" -export const calculateMechAddress = (token: TokenBalance) => { +export const calculateMechAddress = (token: NFTContext, chainId: number) => { const context = { - chainId: token.chainId, - token: token.contractAddress as `0x${string}`, - tokenId: BigInt(token.tokenID), + chainId, + token: token.tokenAddress as `0x${string}`, + tokenId: BigInt(token.tokenId), } - return token.contractType === ContractType.ERC1155 + return token.contractType === "ERC1155" ? calculateERC1155TokenboundMechAddress(context) : calculateERC721TokenboundMechAddress(context) } diff --git a/frontend/src/utils/deployMech.ts b/frontend/src/utils/deployMech.ts index 9c33c7f..e459442 100644 --- a/frontend/src/utils/deployMech.ts +++ b/frontend/src/utils/deployMech.ts @@ -1,16 +1,19 @@ -import { TokenBalance, ContractType } from "@0xsequence/indexer" import { makeERC1155TokenboundMechDeployTransaction, makeERC721TokenboundMechDeployTransaction, } from "mech-sdk" +import { NFTContext } from "../types/Token" -export const makeMechDeployTransaction = (token: TokenBalance) => { +export const makeMechDeployTransaction = ( + token: NFTContext, + chainId: number +) => { const context = { - chainId: token.chainId, - token: token.contractAddress as `0x${string}`, - tokenId: BigInt(token.tokenID), + chainId, + token: token.tokenAddress as `0x${string}`, + tokenId: BigInt(token.tokenId), } - return token.contractType === ContractType.ERC1155 + return token.contractType === "ERC1155" ? makeERC1155TokenboundMechDeployTransaction(context) : makeERC721TokenboundMechDeployTransaction(context) } diff --git a/frontend/src/utils/getNFTContext.ts b/frontend/src/utils/getNFTContext.ts new file mode 100644 index 0000000..c9698f8 --- /dev/null +++ b/frontend/src/utils/getNFTContext.ts @@ -0,0 +1,12 @@ +import { MoralisNFT, NFTContext } from "../types/Token" + +export const getNFTContext = (nft: MoralisNFT): NFTContext => { + return { + tokenAddress: nft.token_address, + tokenId: nft.token_id, + contractType: nft.contract_type, + } +} +export const getNFTContexts = (nfts: MoralisNFT[]): NFTContext[] => { + return nfts.map(getNFTContext) +} diff --git a/sdk/package.json b/sdk/package.json index 8f622fc..7a36838 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -45,4 +45,4 @@ "viem": "^1.16.5" }, "packageManager": "yarn@3.7.0" -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 540a05f..33f394d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,271 +5,6 @@ __metadata: version: 6 cacheKey: 8 -"0xsequence@npm:^1.6.2": - version: 1.6.2 - resolution: "0xsequence@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/account": 1.6.2 - "@0xsequence/api": 1.6.2 - "@0xsequence/auth": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/guard": 1.6.2 - "@0xsequence/indexer": 1.6.2 - "@0xsequence/metadata": 1.6.2 - "@0xsequence/migration": 1.6.2 - "@0xsequence/multicall": 1.6.2 - "@0xsequence/network": 1.6.2 - "@0xsequence/provider": 1.6.2 - "@0xsequence/relayer": 1.6.2 - "@0xsequence/sessions": 1.6.2 - "@0xsequence/signhub": 1.6.2 - "@0xsequence/utils": 1.6.2 - "@0xsequence/wallet": 1.6.2 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: a055251bcd950a3a5f94afddc75d480d4a058bad3495f0718289f1cdc4f43f12405d38358bcbb502531e97c150a2f085945ae2acd0e75d65731fac82a1921b63 - languageName: node - linkType: hard - -"@0xsequence/abi@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/abi@npm:1.6.2" - checksum: 83182a87053b1a76f5097e763338268c81ff6156bb507765b2fa1d723db6814e97cd154cff18c1d6b29a6b3b78291027f663705e5249a36d4751bdb1305ea742 - languageName: node - linkType: hard - -"@0xsequence/account@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/account@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/migration": 1.6.2 - "@0xsequence/network": 1.6.2 - "@0xsequence/relayer": 1.6.2 - "@0xsequence/sessions": 1.6.2 - "@0xsequence/utils": 1.6.2 - "@0xsequence/wallet": 1.6.2 - ethers: ^5.5.2 - checksum: 763ad2b56c36e875a6841b3839cbdd52086c22002cf5bfd8d362258720fbef96ce384d7750884fa6ee006ad94ccd701b48e3956ada0f9b99a0e50d8f58040a65 - languageName: node - linkType: hard - -"@0xsequence/api@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/api@npm:1.6.2" - checksum: 76b3fc7534588ddde3d542703a353fa797623027d7f4c1c6b650c4da7012347702d26d37d4956511538f56bfa23532dbbdcf0bcfbca3376d9179c95b763f0074 - languageName: node - linkType: hard - -"@0xsequence/auth@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/auth@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/account": 1.6.2 - "@0xsequence/api": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/ethauth": ^0.8.1 - "@0xsequence/indexer": 1.6.2 - "@0xsequence/metadata": 1.6.2 - "@0xsequence/migration": 1.6.2 - "@0xsequence/network": 1.6.2 - "@0xsequence/sessions": 1.6.2 - "@0xsequence/signhub": 1.6.2 - "@0xsequence/utils": 1.6.2 - "@0xsequence/wallet": 1.6.2 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: c1965eb1780a7a6c0fdc4b6f879816ea0428924b2728e44a4cf42da05a9da44d56e3c29a3533e8015a657ea8624f82d2d8b4658fef1474f12ff89b3ab63660b1 - languageName: node - linkType: hard - -"@0xsequence/core@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/core@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - peerDependencies: - ethers: ">=5.5" - checksum: e80bf76deb27818d96e9294b23597911c5397aca34d2e9e165142daf2c1384f1c2f62486c246289604f7cf0128e34a030e84c786297b16c72692f86ab5ebd363 - languageName: node - linkType: hard - -"@0xsequence/ethauth@npm:^0.8.1": - version: 0.8.1 - resolution: "@0xsequence/ethauth@npm:0.8.1" - dependencies: - js-base64: ^3.7.2 - peerDependencies: - ethers: ">=5.5" - checksum: 4122371cc69e63a34730bd3b05d93ab4b49b4cab6f6c11c3453e4c9cee4cc8d5b6f85e9482099a143fa3c9ca6dc3bd7635817026236f676a78b52a6bf4dedde9 - languageName: node - linkType: hard - -"@0xsequence/guard@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/guard@npm:1.6.2" - dependencies: - "@0xsequence/account": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/signhub": 1.6.2 - "@0xsequence/utils": 1.6.2 - ethers: ^5.7.2 - checksum: d6141c55d883b7879f48ae94abe4446c281531a11e6a099a455ded0d1448dbe389ec255b9ada649105a93965fa67c7aad595c129f46dc8de36e939812e073f60 - languageName: node - linkType: hard - -"@0xsequence/indexer@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/indexer@npm:1.6.2" - checksum: e97f359b5ad2962f60b157dd0821a1cc9a65ad7ad4c1316ea1f1c69fef6ff1f8a9c928dfb983549686719296b6d31f3f97b1944fc3f61f7d43f5374bac0f8918 - languageName: node - linkType: hard - -"@0xsequence/metadata@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/metadata@npm:1.6.2" - checksum: 39eab731990a7dc9bdfbd2a7d787be14c565477f37974629a65aff81b598a3bed1ba9b8ddd5a78e63f3224d93f5ea104acfa3144ac3332bd5a22361b7cbef945 - languageName: node - linkType: hard - -"@0xsequence/migration@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/migration@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/wallet": 1.6.2 - ethers: ^5.5.2 - checksum: 821fd4e7adde5b7e467fc44441d40bc64f8dcaa2712b093f74318fef0913f75aafb035c9ad56ecea174c1d6f9720bd1a277416a12aa9872da3d9d0dd1b84a3c4 - languageName: node - linkType: hard - -"@0xsequence/multicall@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/multicall@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/network": 1.6.2 - "@0xsequence/utils": 1.6.2 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: c0b7643de853ff9fcc7a12f2be2fdbd8749bb1767fd2b85574d944f9e890e1d7e0a2c724dbc19e1ad2255b09f264d077a64fbae82a771fe3af0f334a389e9384 - languageName: node - linkType: hard - -"@0xsequence/network@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/network@npm:1.6.2" - dependencies: - "@0xsequence/core": 1.6.2 - "@0xsequence/indexer": 1.6.2 - "@0xsequence/relayer": 1.6.2 - "@0xsequence/utils": 1.6.2 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: 8618c22e9285a095a919c75f78188e58ed5dbc35c3d578f15e189c7c87385dbda9853eec72945100c078d35a8415a4aa5e69a5bfb43a55cb9b5deca4cd69bc30 - languageName: node - linkType: hard - -"@0xsequence/provider@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/provider@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/account": 1.6.2 - "@0xsequence/auth": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/migration": 1.6.2 - "@0xsequence/network": 1.6.2 - "@0xsequence/relayer": 1.6.2 - "@0xsequence/utils": 1.6.2 - "@0xsequence/wallet": 1.6.2 - eventemitter2: ^6.4.5 - webextension-polyfill: ^0.10.0 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: 44ac5dc919dc80929364276ff51d61570f031776fbff8108e74bb30046253677b81a05d59220fd4048283af77062336d04305c3ae779a38aed200c7bd87c8db5 - languageName: node - linkType: hard - -"@0xsequence/relayer@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/relayer@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/utils": 1.6.2 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: 5a23aadc7625aa0896dde722b7827c67b94194eac4a44475419a59e7dee6ae87f0d3aea885a2c80eb87838cbdd4bf3fb1462b48263cb34f45fe2f4f4eec036e1 - languageName: node - linkType: hard - -"@0xsequence/replacer@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/replacer@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/core": 1.6.2 - peerDependencies: - ethers: ">=5.5" - checksum: 856610b82594ab09663d7a5cdadfd50e390bbcd875bbeda33f961f444dff41fde3d187cab03f1a41cfd1646a902209d59226458ad1eb03e62faf3b49b6529bdb - languageName: node - linkType: hard - -"@0xsequence/sessions@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/sessions@npm:1.6.2" - dependencies: - "@0xsequence/core": 1.6.2 - "@0xsequence/migration": 1.6.2 - "@0xsequence/replacer": 1.6.2 - ethers: ^5.5.2 - idb: ^7.1.1 - checksum: 1e9e2632d1f81bcb84409fc0a7d709bc7cb99b1b52bc1c7e027bf354eb63c9cd1b735632a96db223512fbb8fbd75872a07b7bc55aae8c64f1d30cf26af626ddd - languageName: node - linkType: hard - -"@0xsequence/signhub@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/signhub@npm:1.6.2" - dependencies: - "@0xsequence/core": 1.6.2 - ethers: ^5.5.2 - checksum: 52dffff344ce4d50948ea0488a7e7984a57816e8cb903c5275342ef1534cd2d77723a0a61ba06898c17a1f08974904591732a97c94306b269282cec8a19aad6f - languageName: node - linkType: hard - -"@0xsequence/utils@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/utils@npm:1.6.2" - dependencies: - js-base64: ^3.7.2 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: 46af3006dc534c2516c8be8ed5640288822b77536622c21222341d4129266473b92ce216ec22eb55045382d6aebc9234fee86de067ccff1620d0a0ef7bb29cb3 - languageName: node - linkType: hard - -"@0xsequence/wallet@npm:1.6.2": - version: 1.6.2 - resolution: "@0xsequence/wallet@npm:1.6.2" - dependencies: - "@0xsequence/abi": 1.6.2 - "@0xsequence/core": 1.6.2 - "@0xsequence/network": 1.6.2 - "@0xsequence/relayer": 1.6.2 - "@0xsequence/signhub": 1.6.2 - "@0xsequence/utils": 1.6.2 - peerDependencies: - ethers: ">=5.5 < 6" - checksum: b9d612cd97066fd5a1d9a5e535b50d315b53c4128b3d9b54c9e448a8f2ed0e5097770e9614215fb11505983975aa5c5c44ddf7a54294f1a39612441dcec304fe - languageName: node - linkType: hard - "@aashutoshrathi/word-wrap@npm:^1.2.3": version: 1.2.6 resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" @@ -4696,6 +4431,13 @@ __metadata: languageName: node linkType: hard +"@tanstack/query-core@npm:5.17.15": + version: 5.17.15 + resolution: "@tanstack/query-core@npm:5.17.15" + checksum: 58ee2b4233906d09cc7f7e519f07518ca69e01aebdca8aedc45d63e8f6111eaf259a088e689b5eb300760f452da63e206ac4f50e9020630272e8c61a38d5e67d + languageName: node + linkType: hard + "@tanstack/query-persist-client-core@npm:4.36.1": version: 4.36.1 resolution: "@tanstack/query-persist-client-core@npm:4.36.1" @@ -4744,6 +4486,17 @@ __metadata: languageName: node linkType: hard +"@tanstack/react-query@npm:^5.17.15": + version: 5.17.15 + resolution: "@tanstack/react-query@npm:5.17.15" + dependencies: + "@tanstack/query-core": 5.17.15 + peerDependencies: + react: ^18.0.0 + checksum: b48587f1765e31b42ec39bd70dd55eef99878691ca90abb94ada455d1e308b604083b6074d766659ac26f7eb4ea936b05816cf3e2591445253cb6864c92e30f3 + languageName: node + linkType: hard + "@tootallnate/once@npm:1": version: 1.1.2 resolution: "@tootallnate/once@npm:1.1.2" @@ -10339,7 +10092,7 @@ __metadata: languageName: node linkType: hard -"ethers@npm:^5.5.2, ethers@npm:^5.6.5, ethers@npm:^5.7.0, ethers@npm:^5.7.1, ethers@npm:^5.7.2": +"ethers@npm:^5.6.5, ethers@npm:^5.7.0, ethers@npm:^5.7.1, ethers@npm:^5.7.2": version: 5.7.2 resolution: "ethers@npm:5.7.2" dependencies: @@ -10412,13 +10165,6 @@ __metadata: languageName: node linkType: hard -"eventemitter2@npm:^6.4.5": - version: 6.4.9 - resolution: "eventemitter2@npm:6.4.9" - checksum: be59577c1e1c35509c7ba0e2624335c35bbcfd9485b8a977384c6cc6759341ea1a98d3cb9dbaa5cea4fff9b687e504504e3f9c2cc1674cf3bd8a43a7c74ea3eb - languageName: node - linkType: hard - "eventemitter3@npm:4.0.4": version: 4.0.4 resolution: "eventemitter3@npm:4.0.4" @@ -10935,8 +10681,8 @@ __metadata: version: 0.0.0-use.local resolution: "frontend@workspace:frontend" dependencies: - 0xsequence: ^1.6.2 "@rainbow-me/rainbowkit": ^1.3.3 + "@tanstack/react-query": ^5.17.15 "@types/react": ^18.2.21 "@types/react-dom": ^18.2.7 "@walletconnect/core": ^2.10.2 @@ -12025,7 +11771,7 @@ __metadata: languageName: node linkType: hard -"idb@npm:^7.0.1, idb@npm:^7.1.1": +"idb@npm:^7.0.1": version: 7.1.1 resolution: "idb@npm:7.1.1" checksum: 1973c28d53c784b177bdef9f527ec89ec239ec7cf5fcbd987dae75a16c03f5b7dfcc8c6d3285716fd0309dd57739805390bd9f98ce23b1b7d8849a3b52de8d56 @@ -13347,13 +13093,6 @@ __metadata: languageName: node linkType: hard -"js-base64@npm:^3.7.2": - version: 3.7.5 - resolution: "js-base64@npm:3.7.5" - checksum: 67a78c8b1c47b73f1c6fba1957e9fe6fd9dc78ac93ac46cc2e43472dcb9cf150d126fb0e593192e88e0497354fa634d17d255add7cc6ee3c7b4d29870faa8e18 - languageName: node - linkType: hard - "js-sdsl@npm:^4.1.4": version: 4.4.2 resolution: "js-sdsl@npm:4.4.2" @@ -20473,13 +20212,6 @@ __metadata: languageName: node linkType: hard -"webextension-polyfill@npm:^0.10.0": - version: 0.10.0 - resolution: "webextension-polyfill@npm:0.10.0" - checksum: 4a59036bda571360c2c0b2fb03fe1dc244f233946bcf9a6766f677956c40fd14d270aaa69cdba95e4ac521014afbe4008bfa5959d0ac39f91c990eb206587f91 - languageName: node - linkType: hard - "webidl-conversions@npm:^3.0.0": version: 3.0.1 resolution: "webidl-conversions@npm:3.0.1" From 9379ee05753a4fab53bd30dc231c6f593b280933 Mon Sep 17 00:00:00 2001 From: samepant Date: Thu, 18 Jan 2024 17:24:23 -0500 Subject: [PATCH 06/12] add basic search component --- .../src/components/Search/Search.module.css | 87 +++++++++++++ .../SearchResults/SearchResults.module.css | 53 ++++++++ .../components/Search/SearchResults/index.tsx | 77 ++++++++++++ frontend/src/components/Search/index.tsx | 114 ++++++++++++++++++ frontend/src/utils/parseMechBytecode.ts | 84 +++++++++++++ 5 files changed, 415 insertions(+) create mode 100644 frontend/src/components/Search/Search.module.css create mode 100644 frontend/src/components/Search/SearchResults/SearchResults.module.css create mode 100644 frontend/src/components/Search/SearchResults/index.tsx create mode 100644 frontend/src/components/Search/index.tsx create mode 100644 frontend/src/utils/parseMechBytecode.ts diff --git a/frontend/src/components/Search/Search.module.css b/frontend/src/components/Search/Search.module.css new file mode 100644 index 0000000..7a20c19 --- /dev/null +++ b/frontend/src/components/Search/Search.module.css @@ -0,0 +1,87 @@ +.searchBar { + flex-grow: 1; + max-width: 500px; + background-color: var(--box-bg); + border-radius: 20px; + position: relative; +} + +.magnifyingGlass { + height: 1.8em; + stroke: var(--text-color); + position: absolute; + left: 12px; + top: 12px; +} + +.input { + width: 100%; + height: 100%; + background: none; + border: none; + color: var(--text-color); + font-size: 1em; + padding: 5px 10px; + padding-left: 50px; + border-radius: 20px; + border: 2px solid transparent; + font-family: monospace; +} + +.input:focus { + outline: none; + border: 2px solid var(--button-border); +} +.input::placeholder { + color: var(--text-color); + opacity: 0.8; +} + +.invalidSearch { + position: absolute; + bottom: -14px; + right: 20px; + width: 100%; + display: flex; + gap: 5px; + align-items: center; + width: fit-content; + color: var(--text-color); + border: 1px solid var(--text-color); + font-size: 12px; + padding: 3px 8px; + padding-left: 4px; + border-radius: 20px; + background-color: rgb(255, 195, 213); +} + +.invalidSearch p { + font-weight: bold; + font-style: italic; +} + +.warning { + font-weight: bold; + /* font-style: italic; */ + aspect-ratio: 1; + width: 1.5em; + background-color: var(--text-color); + color: white; + border-radius: 50px; + display: flex; + justify-content: center; + align-items: center; +} + +.results { + display: flex; + width: 100%; + position: absolute; + top: calc(100% + 20px); + background: rgb(248 212 226); + border-radius: 20px; + padding: 20px 10px 10px; + z-index: 100; + border: 2px solid var(--button-bg); + box-shadow: 2px 2px 10px 0px rgba(150, 203, 0, 0.44); +} diff --git a/frontend/src/components/Search/SearchResults/SearchResults.module.css b/frontend/src/components/Search/SearchResults/SearchResults.module.css new file mode 100644 index 0000000..e9e7120 --- /dev/null +++ b/frontend/src/components/Search/SearchResults/SearchResults.module.css @@ -0,0 +1,53 @@ +.results { + display: flex; + flex-direction: column; + gap: 15px; + flex-grow: 1; +} + +.category { + display: flex; + flex-direction: column; + gap: 5px; + flex-grow: 1; +} + +.categoryResults { + display: flex; + flex-direction: column; + gap: 15px; + flex-grow: 1; +} + +.category h2 { + text-transform: uppercase; + font-size: 12px; + font-weight: bold; + padding-left: 10px; + color: var(--button-text); +} + +.result { + display: flex; + gap: 10px; + align-items: center; + cursor: pointer; + padding: 10px; +} + +.result:hover { + background-color: var(--button-bg); + border-radius: 10px; +} + +.result .address { + font-family: monospace; + font-size: 12px; + padding: 2px 4px; + text-align: right; + display: inline-block; +} + +.blockie { + width: 1.5em; +} diff --git a/frontend/src/components/Search/SearchResults/index.tsx b/frontend/src/components/Search/SearchResults/index.tsx new file mode 100644 index 0000000..0744c78 --- /dev/null +++ b/frontend/src/components/Search/SearchResults/index.tsx @@ -0,0 +1,77 @@ +import Blockie from "../../Blockie" + +import classes from "./SearchResults.module.css" + +export type SearchResult = { + address: string + type: "mech" | "account" | "nft" | "unknown" + name?: string + img?: string +} + +const SearchResults = ({ results }: { results: SearchResult[] }) => { + return ( +
      + {results + .filter((result) => result.type === "mech") + .map((result, index) => ( +
    • +

      Deployed Mech

      +
        +
      • + {result.type === "nft" && } +
      • +
      +
    • + ))} + {results + .filter((result) => result.type === "nft") + .map((result, index) => ( +
    • +

      NFT Collection

      +
        +
      • + {result.type === "nft" && } +
      • +
      +
    • + ))} + {results + .filter((result) => result.type === "account") + .map((result, index) => ( +
    • +

      Account

      +
        +
      • + {result.type === "account" && } +
      • +
      +
    • + ))} +
    + ) +} + +const NFTResult = ({ result }: { result: SearchResult }) => { + return ( + <> +
    + +
    +

    {result.address}

    + + ) +} + +const AccountResult = ({ result }: { result: SearchResult }) => { + return ( + <> +
    + +
    +

    {result.address}

    + + ) +} + +export default SearchResults diff --git a/frontend/src/components/Search/index.tsx b/frontend/src/components/Search/index.tsx new file mode 100644 index 0000000..c024910 --- /dev/null +++ b/frontend/src/components/Search/index.tsx @@ -0,0 +1,114 @@ +import { useState } from "react" +import { isAddress } from "viem" + +import classes from "./Search.module.css" +import SearchResults, { SearchResult } from "./SearchResults" +import { useChainId, usePublicClient } from "wagmi" +import parseMechBytecode from "../../utils/parseMechBytecode" + +const Search = () => { + const chainId = useChainId() + const client = usePublicClient() + const [search, setSearch] = useState("") + const [validSearch, setValidSearch] = useState(true) + const [results, setResults] = useState([]) + + const handleSearch = async (e: React.ChangeEvent) => { + setResults([]) + const newSearch = e.target.value || "" + setSearch(newSearch) + + if (!newSearch) { + return setValidSearch(true) + } + setValidSearch(isAddress(newSearch)) + + if (isAddress(newSearch)) { + // check if address is deployed contract + // check if bytecode is mech + // if not mech, check if address is nft collection + const bytecode = await client.getBytecode({ address: newSearch }) + if (bytecode && bytecode.length > 2) { + const mechInfo = parseMechBytecode(bytecode) + if (mechInfo) { + setResults([ + { + address: newSearch, + type: "mech", + }, + ]) + return + } + + const nftRes = await fetch( + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/nft/${newSearch}/metadata` + ) + if (!nftRes.ok || nftRes.status === 404) { + // unknown contract, show as account + setResults([ + { + address: newSearch, + type: "account", + }, + ]) + return + } + + const nftCollection = await nftRes.json() + setResults([ + { + address: newSearch, + type: "nft", + name: nftCollection.name, + }, + ]) + } else { + // only an EOA + setResults([ + { + address: newSearch, + type: "account", + }, + ]) + } + } + } + + return ( +
    + + + + e.target.select()} + /> + {!validSearch && ( +
    +
    !!
    +

    Please use a valid address

    +
    + )} + {results.length > 0 && ( +
    + +
    + )} +
    + ) +} + +export default Search diff --git a/frontend/src/utils/parseMechBytecode.ts b/frontend/src/utils/parseMechBytecode.ts new file mode 100644 index 0000000..5240ccd --- /dev/null +++ b/frontend/src/utils/parseMechBytecode.ts @@ -0,0 +1,84 @@ +import { getAddress, hexToNumber } from "viem" +import { + calculateERC1155ThresholdMechMastercopyAddress, + calculateERC721TokenboundMechMastercopyAddress, +} from "mech-sdk" + +const parseMechBytecode = (rawBytecode: `0x${string}`) => { + try { + const mech721Mastercopy = calculateERC721TokenboundMechMastercopyAddress() + const mech1155Mastercopy = calculateERC1155ThresholdMechMastercopyAddress() + const bytecode = rawBytecode.slice(2) + + if (!bytecode || !rawBytecode || !(rawBytecode.length > 2)) return null + + const [ + erc1167Header, + rawImplementationAddress, + erc1167Footer, + rawSalt, + rawChainId, + rawTokenContract, + rawTokenId, + ] = segmentBytecode(bytecode, 10, 20, 15, 32, 32, 32, 32) + + const chainId = hexToNumber(`0x${rawChainId}`, { size: 32 }) + const implementationAddress: `0x${string}` = getAddress( + `0x${rawImplementationAddress}` + ) + if ( + mech1155Mastercopy !== implementationAddress || + mech721Mastercopy !== implementationAddress + ) { + return null + } + + const salt = hexToNumber(`0x${rawSalt}`, { size: 32 }) + const tokenContract: `0x${string}` = getAddress( + `0x${rawTokenContract.slice( + rawTokenContract.length - 40, + rawTokenContract.length + )}` + ) + const tokenId = hexToNumber(`0x${rawTokenId}`, { size: 32 }).toString() + + return { + erc1167Header, + implementationAddress, + erc1167Footer, + salt, + tokenId, + tokenContract, + chainId, + } + } catch (error) { + throw error + } +} + +export default parseMechBytecode + +/** + * Splits a string into segments of specified lengths. + * + * @param input - The input string to split into segments. + * @param lengths - The lengths of the segments to extract, in bytes. + * @returns An array containing the extracted segments in the order they were specified. + * + * @example + * const bytecode = "0x1234567890abcdef1234567890abcdef1234567890abcdef"; + * const segments = segmentBytecode(bytecode, 2, 4, 8); + * console.log(segments); // ["0x", "1234", "567890ab"] + */ +export function segmentBytecode(input: string, ...lengths: number[]): string[] { + let position = 0 + const segments: string[] = [] + const cleanInput = input.startsWith("0x") ? input.substring(2) : input // Remove "0x" prefix if present + + for (const length of lengths) { + segments.push(cleanInput.substr(position, length * 2)) + position += length * 2 + } + + return segments +} From bab15a27a2e10d0cc9beb829c8383d42dcc82b31 Mon Sep 17 00:00:00 2001 From: samepant Date: Thu, 18 Jan 2024 17:29:22 -0500 Subject: [PATCH 07/12] rough ui re-org --- .../src/components/Blockie/Blockie.module.css | 1 + .../ChainSelect/ChainSelect.module.css | 2 +- frontend/src/components/ChainSelect/index.tsx | 3 +- .../LandingCard/LandingCard.module.css | 12 ++++--- frontend/src/components/LandingCard/index.tsx | 30 +++++++--------- .../src/components/Layout/Layout.module.css | 10 +++--- frontend/src/components/Layout/index.tsx | 8 ++--- frontend/src/router.tsx | 5 +++ .../src/routes/Account/Account.module.css | 4 +++ frontend/src/routes/Account/index.tsx | 35 +++++++++++++++++++ frontend/src/routes/Landing.tsx | 7 ++-- frontend/src/routes/Mech/index.tsx | 27 +++++++++----- 12 files changed, 95 insertions(+), 49 deletions(-) create mode 100644 frontend/src/routes/Account/Account.module.css create mode 100644 frontend/src/routes/Account/index.tsx diff --git a/frontend/src/components/Blockie/Blockie.module.css b/frontend/src/components/Blockie/Blockie.module.css index 4a6258c..cfc8216 100644 --- a/frontend/src/components/Blockie/Blockie.module.css +++ b/frontend/src/components/Blockie/Blockie.module.css @@ -1,6 +1,7 @@ .container { overflow: hidden; border-radius: 50%; + aspect-ratio: 1; } .container img { diff --git a/frontend/src/components/ChainSelect/ChainSelect.module.css b/frontend/src/components/ChainSelect/ChainSelect.module.css index 34f1a4b..9ed364a 100644 --- a/frontend/src/components/ChainSelect/ChainSelect.module.css +++ b/frontend/src/components/ChainSelect/ChainSelect.module.css @@ -40,7 +40,7 @@ position: absolute; top: 50px; right: 0; - background: var(--box-bg); + background: rgb(248 212 226); border-radius: 10px; padding: 6px; min-width: 200px; diff --git a/frontend/src/components/ChainSelect/index.tsx b/frontend/src/components/ChainSelect/index.tsx index 032289c..34b56e3 100644 --- a/frontend/src/components/ChainSelect/index.tsx +++ b/frontend/src/components/ChainSelect/index.tsx @@ -15,8 +15,7 @@ const ChainSelect = () => { const ref = useClickAway(() => { setShowDropdown(false) }) - console.log("chain ID", currentChainId) - console.log("switchNetwork", switchNetwork) + return (
-
) } diff --git a/frontend/src/components/Layout/Layout.module.css b/frontend/src/components/Layout/Layout.module.css index 81ddeb9..b4b97fc 100644 --- a/frontend/src/components/Layout/Layout.module.css +++ b/frontend/src/components/Layout/Layout.module.css @@ -46,15 +46,15 @@ .nav { display: flex; - align-items: center; - gap: 0.5rem; - background-color: var(--box-bg); - border-radius: 20px; - padding: 5px 10px; + gap: 1rem; + flex-grow: 1; } .nav h1 { font-size: 36px; + background-color: var(--box-bg); + border-radius: 20px; + padding: 5px 10px; } .nav a { diff --git a/frontend/src/components/Layout/index.tsx b/frontend/src/components/Layout/index.tsx index e73d5d9..21f16b0 100644 --- a/frontend/src/components/Layout/index.tsx +++ b/frontend/src/components/Layout/index.tsx @@ -5,6 +5,7 @@ import { shortenAddress } from "../../utils/shortenAddress" import { Link } from "react-router-dom" import ChainSelect from "../ChainSelect" import ConnectButton from "../ConnectButton" +import Search from "../Search" interface Props { mechAddress?: string @@ -20,12 +21,7 @@ const Layout: React.FC = ({ children, mechAddress }) => {

Mech

- {mechAddress && ( - <> -

/

-

{shortenAddress(mechAddress)}

- - )} +
diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index 23bea97..cbf7908 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -1,6 +1,7 @@ import React from "react" import { createBrowserRouter } from "react-router-dom" import Mech from "./routes/Mech" +import Account from "./routes/Account" import Landing from "./routes/Landing" export default createBrowserRouter([ @@ -12,4 +13,8 @@ export default createBrowserRouter([ path: "mechs/:token/:tokenId", element: , }, + { + path: "account/:address/", + element: , + }, ]) diff --git a/frontend/src/routes/Account/Account.module.css b/frontend/src/routes/Account/Account.module.css new file mode 100644 index 0000000..273503b --- /dev/null +++ b/frontend/src/routes/Account/Account.module.css @@ -0,0 +1,4 @@ +.connectButton { + font-size: 24px; + width: 100%; +} diff --git a/frontend/src/routes/Account/index.tsx b/frontend/src/routes/Account/index.tsx new file mode 100644 index 0000000..6b09787 --- /dev/null +++ b/frontend/src/routes/Account/index.tsx @@ -0,0 +1,35 @@ +import React from "react" +import { useParams } from "react-router-dom" + +import Layout from "../../components/Layout" +import NFTGrid from "../../components/NFTGrid" +import classes from "./Account.module.css" +import { getAddress } from "viem" + +const Landing: React.FC = () => { + const { address } = useParams() + let validAddress = "" + try { + validAddress = getAddress(address || "") + } catch (error) { + console.log(error) + } + + if (validAddress) { + return ( + +

Available mechs for {getAddress(address || "")}

+ +
+ ) + } + + return ( + +

+ {address} is not a valid address +

+
+ ) +} +export default Landing diff --git a/frontend/src/routes/Landing.tsx b/frontend/src/routes/Landing.tsx index 0474058..026c1e7 100644 --- a/frontend/src/routes/Landing.tsx +++ b/frontend/src/routes/Landing.tsx @@ -1,13 +1,12 @@ import React from "react" import Layout from "../components/Layout" import LandingCard from "../components/LandingCard" -import { useAccount } from "wagmi" -import NFTGrid from "../components/NFTGrid" const Landing: React.FC = () => { - const { address } = useAccount() return ( - {address ? : } + + + ) } export default Landing diff --git a/frontend/src/routes/Mech/index.tsx b/frontend/src/routes/Mech/index.tsx index bff300c..9228118 100644 --- a/frontend/src/routes/Mech/index.tsx +++ b/frontend/src/routes/Mech/index.tsx @@ -1,5 +1,4 @@ import React from "react" -import { TokenBalance } from "@0xsequence/indexer" import { useParams } from "react-router-dom" import Layout from "../../components/Layout" import NFTItem from "../../components/NFTItem" @@ -14,6 +13,8 @@ import MechDeploy from "../../components/Deploy" import { calculateMechAddress } from "../../utils/calculateMechAddress" import { CHAINS } from "../../chains" import useTokenBalances from "../../hooks/useTokenBalances" +import useNFTMetadata from "../../hooks/useTokenMetadata" +import { getNFTContext } from "../../utils/getNFTContext" const Mech: React.FC = () => { const { token, tokenId } = useParams() @@ -36,16 +37,24 @@ const Mech: React.FC = () => { throw new Error("token must be a valid address") } - const { balances, error, isLoading } = useTokenBalances({ - tokenContract: contractAddress, + const { + data: nft, + isLoading, + error, + } = useNFTMetadata({ chainId: chain.id, - tokenId: tokenId, + tokenAddress: contractAddress, + tokenId, }) - const balance: TokenBalance | null = balances[0] - const { deployed, deploy, deployPending } = useDeployMech(balance) + const { deployed, deploy, deployPending } = useDeployMech( + nft ? getNFTContext(nft) : null, + chain.id + ) - const mechAddress = balance && calculateMechAddress(balance) + const mechAddress = nft + ? calculateMechAddress(getNFTContext(nft), chain.id) + : null const handleRequest = useHandleRequest(mechAddress) @@ -53,9 +62,9 @@ const Mech: React.FC = () => {
{isLoading && } - {!error && !isLoading && balance && mechAddress && ( + {!error && !isLoading && nft && mechAddress && ( <> - + Date: Thu, 18 Jan 2024 18:07:47 -0500 Subject: [PATCH 08/12] fix links, link search results --- frontend/src/components/NFTGridItem/index.tsx | 2 +- frontend/src/components/NFTItem/index.tsx | 2 +- .../components/Search/SearchResults/index.tsx | 26 ++++++++++++++----- frontend/src/hooks/useTokenBalances.ts | 2 +- frontend/src/hooks/useTokenMetadata.ts | 2 +- frontend/src/router.tsx | 2 +- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/NFTGridItem/index.tsx b/frontend/src/components/NFTGridItem/index.tsx index 8a33c35..4fab867 100644 --- a/frontend/src/components/NFTGridItem/index.tsx +++ b/frontend/src/components/NFTGridItem/index.tsx @@ -37,7 +37,7 @@ const NFTGridItem: React.FC = ({ nft, chainId }) => {

{name || "..."} diff --git a/frontend/src/components/NFTItem/index.tsx b/frontend/src/components/NFTItem/index.tsx index 30fce9c..34b37ae 100644 --- a/frontend/src/components/NFTItem/index.tsx +++ b/frontend/src/components/NFTItem/index.tsx @@ -33,8 +33,8 @@ const NFTItem: React.FC = ({ nft, chainId }) => { chainId, }) + console.log(data) const mechBalances = data ? [data.native, ...data.erc20s] : [] - const { deployed } = useDeployMech(getNFTContext(nft), chainId) const name = nft.name || nft.metadata?.name || "..." return ( diff --git a/frontend/src/components/Search/SearchResults/index.tsx b/frontend/src/components/Search/SearchResults/index.tsx index 0744c78..fede392 100644 --- a/frontend/src/components/Search/SearchResults/index.tsx +++ b/frontend/src/components/Search/SearchResults/index.tsx @@ -18,8 +18,10 @@ const SearchResults = ({ results }: { results: SearchResult[] }) => {

  • Deployed Mech

  • @@ -30,8 +32,13 @@ const SearchResults = ({ results }: { results: SearchResult[] }) => {
  • NFT Collection

  • @@ -42,8 +49,15 @@ const SearchResults = ({ results }: { results: SearchResult[] }) => {
  • Account

  • diff --git a/frontend/src/hooks/useTokenBalances.ts b/frontend/src/hooks/useTokenBalances.ts index ce8ebe8..0867f5b 100644 --- a/frontend/src/hooks/useTokenBalances.ts +++ b/frontend/src/hooks/useTokenBalances.ts @@ -36,7 +36,7 @@ const useTokenBalances = ({ accountAddress, chainId }: Props) => { throw new Error("ERC20 request failed") } const erc20Json = await erc20Res.json() - const erc20Data = erc20Json.result as MoralisFungible[] + const erc20Data = erc20Json as MoralisFungible[] // get native balance const nativeRes = await fetch( diff --git a/frontend/src/hooks/useTokenMetadata.ts b/frontend/src/hooks/useTokenMetadata.ts index 9ef7ccc..14b5679 100644 --- a/frontend/src/hooks/useTokenMetadata.ts +++ b/frontend/src/hooks/useTokenMetadata.ts @@ -21,7 +21,7 @@ const useNFTMetadata = ({ tokenAddress, tokenId, chainId }: Props) => { // get nfts const nftRes = await fetch( - `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/nft/${tokenAddress}/${tokenId}}` + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/nft/${tokenAddress}/${tokenId}` ) if (!nftRes.ok) { throw new Error("NFT request failed") diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index cbf7908..7fb6e65 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -10,7 +10,7 @@ export default createBrowserRouter([ element: , }, { - path: "mechs/:token/:tokenId", + path: "mech/:token/:tokenId", element: , }, { From 39f03b266f12b3810e24c41bfb8eca13d4a94fb5 Mon Sep 17 00:00:00 2001 From: samepant Date: Fri, 19 Jan 2024 12:13:47 -0500 Subject: [PATCH 09/12] better layout for nftGrid and account page --- .../src/components/Layout/Layout.module.css | 15 +- frontend/src/components/Layout/index.tsx | 22 +-- .../src/components/NFTGrid/NFTGrid.module.css | 37 +---- frontend/src/components/NFTGrid/index.tsx | 51 ++----- .../components/NFTGridItem/NFTItem.module.css | 130 +++++++++++------- frontend/src/components/NFTGridItem/index.tsx | 77 +++++------ frontend/src/hooks/useTokenMetadata.ts | 1 - .../src/routes/Account/Account.module.css | 35 ++++- frontend/src/routes/Account/index.tsx | 17 ++- frontend/src/routes/Mech/index.tsx | 1 - 10 files changed, 205 insertions(+), 181 deletions(-) diff --git a/frontend/src/components/Layout/Layout.module.css b/frontend/src/components/Layout/Layout.module.css index b4b97fc..b5dbb3f 100644 --- a/frontend/src/components/Layout/Layout.module.css +++ b/frontend/src/components/Layout/Layout.module.css @@ -3,9 +3,11 @@ flex-direction: column; gap: 50px; min-height: 100vh; + max-width: 2000px; + margin: 0 auto; } -.header { +.headerContainer { position: fixed; top: 0; left: 0; @@ -13,7 +15,15 @@ width: 100%; display: flex; align-items: center; - justify-content: space-between; + justify-content: center; +} + +.header { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + max-width: 2000px; padding: 20px; } @@ -42,6 +52,7 @@ margin: 100px 0; position: relative; z-index: 10; + padding: 0 20px; } .nav { diff --git a/frontend/src/components/Layout/index.tsx b/frontend/src/components/Layout/index.tsx index 21f16b0..1b672f2 100644 --- a/frontend/src/components/Layout/index.tsx +++ b/frontend/src/components/Layout/index.tsx @@ -16,16 +16,18 @@ const Layout: React.FC = ({ children, mechAddress }) => { return (
    cockpit -
    -
    - -

    Mech

    - - -
    -
    - - +
    +
    +
    + +

    Mech

    + + +
    +
    + + +
    {children}
    diff --git a/frontend/src/components/NFTGrid/NFTGrid.module.css b/frontend/src/components/NFTGrid/NFTGrid.module.css index f357e4d..df33d9c 100644 --- a/frontend/src/components/NFTGrid/NFTGrid.module.css +++ b/frontend/src/components/NFTGrid/NFTGrid.module.css @@ -1,18 +1,19 @@ .grid { - display: flex; - flex-wrap: wrap; - justify-content: center; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + width: 100%; gap: 20px; margin-bottom: 20px; + width: 100%; +} + +.grid li { } .container { display: flex; flex-direction: column; align-items: center; - gap: 20px; - width: 72%; - max-width: 2000px; margin: 0 auto; } @@ -30,27 +31,3 @@ border-radius: 10px; width: fit-content; } - -.indicator { - width: 15px; - height: 15px; - border-radius: 50%; - background-color: var(--button-border); - filter: blur(4px); -} - -.indicator.undeployed { - background-color: rgb(189 192 179); -} - -.noDeployed { - display: flex; - align-items: center; - justify-content: center; - gap: 10px; - background-color: var(--box-bg); - padding: 10px 15px 10px 10px; - border-radius: 20px; - aspect-ratio: 2/1; - width: 250px; -} diff --git a/frontend/src/components/NFTGrid/index.tsx b/frontend/src/components/NFTGrid/index.tsx index 32c1ef7..77d493a 100644 --- a/frontend/src/components/NFTGrid/index.tsx +++ b/frontend/src/components/NFTGrid/index.tsx @@ -16,7 +16,6 @@ interface Props { const NFTGrid: React.FC = ({ address }) => { const chainId = useChainId() - console.log("chainId", chainId) const { data, isLoading, error } = useTokenBalances({ accountAddress: address, chainId, @@ -33,46 +32,18 @@ const NFTGrid: React.FC = ({ address }) => { calculateMechAddress(getNFTContext(nft), chainId).toLowerCase() ) - const deployed = nftBalances.filter(isDeployed) - const undeployed = nftBalances.filter((nft) => !isDeployed(nft)) - console.log("undeployed", undeployed.length) + const nfts = nftBalances.map((nft) => ({ ...nft, deployed: isDeployed(nft) })) + + if (isLoading) return + return ( -
    -
    -
    -
    -

    Deployed

    -
    -
    - {deployed.length === 0 && ( -
    -

    No mechs deployed

    -
    - )} -
      - {deployed.map((nft, index) => ( -
    • - -
    • - ))} -
    -
    -
    -
    -

    Undeployed

    -
    -
    - {undeployed.length > 0 && ( -
      - {undeployed.map((nft, index) => ( -
    • - -
    • - ))} -
    - )} - {isLoading && } -
    +
      + {nfts.map((nft, index) => ( +
    • + +
    • + ))} +
    ) } diff --git a/frontend/src/components/NFTGridItem/NFTItem.module.css b/frontend/src/components/NFTGridItem/NFTItem.module.css index 458e6d0..53f3730 100644 --- a/frontend/src/components/NFTGridItem/NFTItem.module.css +++ b/frontend/src/components/NFTGridItem/NFTItem.module.css @@ -1,30 +1,84 @@ -.itemContainer { +.linkContainer { border-radius: 20px; - background-color: var(--box-bg); - padding: 10px; display: flex; flex-direction: column; - gap: 10px; - + text-decoration: none; aspect-ratio: 1/1; - width: 250px; + position: relative; + text-decoration: none; + color: var(--text-color); + border: 2px solid transparent; + overflow: hidden; } -.header { +.linkContainer:hover { + border: 2px solid var(--button-border); +} + +.header, +.footer { display: flex; justify-content: space-between; + position: absolute; + left: 10px; + z-index: 10; + width: calc(100% - 20px); } .header p { display: inline-block; border-radius: 10px; - background-color: var(--box-bg); + background-color: rgb(246 241 212); padding: 2px 8px; text-overflow: ellipsis; overflow-x: hidden; white-space: nowrap; } +.header { + top: 10px; +} + +.footer { + display: none; + bottom: 10px; +} + +.deployStatus { + display: flex; + align-items: center; + gap: 5px; + border-radius: 10px; + background-color: rgb(246 241 212); + padding: 2px 8px; + font-style: italic; + font-size: 12px; +} + +.indicator { + width: 10px; + aspect-ratio: 1; + border-radius: 50%; + background-color: var(--button-border); + filter: blur(4px); +} + +.indicator.undeployed { + background-color: rgb(189 192 179); +} + +.chain { + display: flex; + align-items: center; + border-radius: 10px; + background-color: rgb(246 241 212); + padding: 2px 8px; +} +.chain svg { + width: 15px; + height: 15px; +} + .tokenId { max-width: 30%; font-family: monospace; @@ -40,30 +94,23 @@ } .main { - height: 63%; - display: flex; - justify-content: space-between; + aspect-ratio: 1; } .imageContainer { - width: 50%; + aspect-ratio: 1; display: flex; justify-content: center; } .main .image { - object-fit: contain; - object-position: top; - height: min-content; + object-fit: cover; max-height: 100%; border-radius: 10px; } .noImage { - width: 50%; height: 100%; - background-color: var(--box-bg); - border-radius: 10px; } .noImage::after { @@ -77,28 +124,6 @@ align-items: center; } -.infoItem { - font-size: 12px; - font-family: monospace; - display: flex; - justify-content: space-between; - align-items: center; - gap: 5px; - border-radius: 10px; - background-color: var(--box-bg); - padding: 2px 8px; - height: 30px; -} - -.address { - cursor: pointer; - transition: filter 0.1s ease-in-out; -} - -.address:hover { - filter: brightness(1.2); -} - .spinner { width: 100%; display: flex; @@ -106,16 +131,27 @@ align-items: center; min-height: 40px; } -.useButton { - width: 100%; -} -.chainIcon { - height: 80%; +.linkContainer:hover .footer { + display: flex; } -.info { +.linkContainer:hover .visit { display: flex; +} + +.visit { + position: absolute; + inset: 0; + display: none; flex-direction: column; - gap: 10px; + justify-content: center; + align-items: center; + background-color: rgb(241 255 203 / 65%); +} + +.visit h3 { + font-size: 1.5em; + color: var(--button-border); + mix-blend-mode: exclusion; } diff --git a/frontend/src/components/NFTGridItem/index.tsx b/frontend/src/components/NFTGridItem/index.tsx index 4fab867..16d424d 100644 --- a/frontend/src/components/NFTGridItem/index.tsx +++ b/frontend/src/components/NFTGridItem/index.tsx @@ -15,7 +15,7 @@ import { MoralisNFT } from "../../types/Token" import { getNFTContext } from "../../utils/getNFTContext" interface Props { - nft: MoralisNFT + nft: { deployed: boolean } & MoralisNFT chainId: number } @@ -24,16 +24,13 @@ const NFTGridItem: React.FC = ({ nft, chainId }) => { const chain = CHAINS[chainId] - const mechAddress = calculateMechAddress(getNFTContext(nft), chainId) - const { deploy, deployPending, deployed } = useDeployMech( - getNFTContext(nft), - chainId - ) - - const name = nft.name || nft.metadata?.name - + const metadata = JSON.parse(nft.metadata || "{}") + const name = nft.name || metadata.name return ( -
    +

    = ({ nft, chainId }) => { {name || "..."}

    - {nft.token_id.length < 5 && ( + {nft.token_id.length < 7 && (

    {nft.token_id || "..."}

    )}
    +
    +
    +
    +

    {nft.deployed ? "Deployed" : "Not Deployed"}

    +
    +
    + +
    +
    - {(imageError || !nft.metadata?.image) && ( + {(imageError || !metadata.image) && (
    )} - {!imageError && nft.metadata?.image && ( + {!imageError && metadata.image && (
    {name} setImageError(true)} />
    )} -
    -
    copy(mechAddress)} - > - {shortenAddress(mechAddress)} -
    -
    -

    Chain:

    - -
    -
    - {deployed ? ( - - - - ) : ( - <> - {deployPending ? ( -
    - -
    - ) : ( - - )} - - )} -
    +
    +

    ⬈⬈⬈⬈⬈⬈⬈⬈⬈

    +

    View Mech

    +

    ⬈⬈⬈⬈⬈⬈⬈⬈⬈

    +
    + ) } diff --git a/frontend/src/hooks/useTokenMetadata.ts b/frontend/src/hooks/useTokenMetadata.ts index 14b5679..0a9b664 100644 --- a/frontend/src/hooks/useTokenMetadata.ts +++ b/frontend/src/hooks/useTokenMetadata.ts @@ -1,5 +1,4 @@ import { useQuery } from "@tanstack/react-query" -import { CHAINS } from "../chains" import { MoralisNFT } from "../types/Token" interface Props { diff --git a/frontend/src/routes/Account/Account.module.css b/frontend/src/routes/Account/Account.module.css index 273503b..1a07886 100644 --- a/frontend/src/routes/Account/Account.module.css +++ b/frontend/src/routes/Account/Account.module.css @@ -1,4 +1,35 @@ -.connectButton { - font-size: 24px; +.container { width: 100%; + background: var(--box-bg); + border-radius: 20px; + padding: 20px; +} + +.accountHeader { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 20px; + background-color: var(--box-bg); + border-radius: 10px; + padding: 10px 20px; + width: 100%; +} + +.account { + display: flex; + align-items: center; + gap: 10px; +} +.title { + font-size: 1.5rem; +} +.accountHeader h1 { + font-size: 1rem; +} + +.blockie { + width: 25px; + aspect-ratio: 1/1; } diff --git a/frontend/src/routes/Account/index.tsx b/frontend/src/routes/Account/index.tsx index 6b09787..1192096 100644 --- a/frontend/src/routes/Account/index.tsx +++ b/frontend/src/routes/Account/index.tsx @@ -5,6 +5,7 @@ import Layout from "../../components/Layout" import NFTGrid from "../../components/NFTGrid" import classes from "./Account.module.css" import { getAddress } from "viem" +import Blockie from "../../components/Blockie" const Landing: React.FC = () => { const { address } = useParams() @@ -18,8 +19,20 @@ const Landing: React.FC = () => { if (validAddress) { return ( -

    Available mechs for {getAddress(address || "")}

    - +
    +
    +
    Inventory
    +
    +
    + +
    +

    + {validAddress} +

    +
    +
    + +
    ) } diff --git a/frontend/src/routes/Mech/index.tsx b/frontend/src/routes/Mech/index.tsx index 9228118..390d344 100644 --- a/frontend/src/routes/Mech/index.tsx +++ b/frontend/src/routes/Mech/index.tsx @@ -12,7 +12,6 @@ import { useDeployMech } from "../../hooks/useDeployMech" import MechDeploy from "../../components/Deploy" import { calculateMechAddress } from "../../utils/calculateMechAddress" import { CHAINS } from "../../chains" -import useTokenBalances from "../../hooks/useTokenBalances" import useNFTMetadata from "../../hooks/useTokenMetadata" import { getNFTContext } from "../../utils/getNFTContext" From 1467c93c7f30939f98331e0ea30e6392d9b806a2 Mon Sep 17 00:00:00 2001 From: samepant Date: Fri, 19 Jan 2024 12:45:41 -0500 Subject: [PATCH 10/12] add collection page and necessary hooks --- frontend/src/components/NFTGrid/index.tsx | 38 ++++++++++++- frontend/src/components/NFTGridItem/index.tsx | 20 ++----- frontend/src/hooks/useCollection.ts | 33 +++++++++++ frontend/src/hooks/useCollectionMetadata.ts | 34 +++++++++++ frontend/src/router.tsx | 6 +- frontend/src/routes/Account/index.tsx | 4 +- .../routes/Collection/Collection.module.css | 35 ++++++++++++ frontend/src/routes/Collection/index.tsx | 57 +++++++++++++++++++ frontend/src/types/Token.d.ts | 17 ++++++ 9 files changed, 223 insertions(+), 21 deletions(-) create mode 100644 frontend/src/hooks/useCollection.ts create mode 100644 frontend/src/hooks/useCollectionMetadata.ts create mode 100644 frontend/src/routes/Collection/Collection.module.css create mode 100644 frontend/src/routes/Collection/index.tsx diff --git a/frontend/src/components/NFTGrid/index.tsx b/frontend/src/components/NFTGrid/index.tsx index 77d493a..53a077c 100644 --- a/frontend/src/components/NFTGrid/index.tsx +++ b/frontend/src/components/NFTGrid/index.tsx @@ -9,12 +9,13 @@ import { calculateMechAddress } from "../../utils/calculateMechAddress" import useTokenBalances from "../../hooks/useTokenBalances" import { getNFTContext, getNFTContexts } from "../../utils/getNFTContext" import { MoralisNFT } from "../../types/Token" +import useCollection from "../../hooks/useCollection" interface Props { address: string } -const NFTGrid: React.FC = ({ address }) => { +export const AccountNftGrid: React.FC = ({ address }) => { const chainId = useChainId() const { data, isLoading, error } = useTokenBalances({ accountAddress: address, @@ -40,11 +41,42 @@ const NFTGrid: React.FC = ({ address }) => {
      {nfts.map((nft, index) => (
    • - +
    • ))}
    ) } -export default NFTGrid +export const CollectionNftGrid: React.FC = ({ address }) => { + const chainId = useChainId() + const { data, isLoading, error } = useCollection({ + tokenAddress: address, + chainId, + }) + const nftBalances = data || [] + + const deployedMechs = useDeployedMechs(getNFTContexts(nftBalances), chainId) + + const isDeployed = (nft: MoralisNFT) => + deployedMechs.some( + (mech) => + mech.chainId === chainId && + mech.address.toLowerCase() === + calculateMechAddress(getNFTContext(nft), chainId).toLowerCase() + ) + + const nfts = nftBalances.map((nft) => ({ ...nft, deployed: isDeployed(nft) })) + + if (isLoading) return + + return ( +
      + {nfts.map((nft, index) => ( +
    • + +
    • + ))} +
    + ) +} diff --git a/frontend/src/components/NFTGridItem/index.tsx b/frontend/src/components/NFTGridItem/index.tsx index 16d424d..f5d6fde 100644 --- a/frontend/src/components/NFTGridItem/index.tsx +++ b/frontend/src/components/NFTGridItem/index.tsx @@ -1,25 +1,19 @@ import { useState } from "react" -import copy from "copy-to-clipboard" import clsx from "clsx" import { Link } from "react-router-dom" import classes from "./NFTItem.module.css" -import Button from "../Button" -import { shortenAddress } from "../../utils/shortenAddress" -import Spinner from "../Spinner" import ChainIcon from "../ChainIcon" -import { calculateMechAddress } from "../../utils/calculateMechAddress" import { CHAINS } from "../../chains" -import { useDeployMech } from "../../hooks/useDeployMech" import { MoralisNFT } from "../../types/Token" -import { getNFTContext } from "../../utils/getNFTContext" interface Props { nft: { deployed: boolean } & MoralisNFT chainId: number + showCollectionName?: boolean } -const NFTGridItem: React.FC = ({ nft, chainId }) => { +const NFTGridItem: React.FC = ({ nft, chainId, showCollectionName }) => { const [imageError, setImageError] = useState(false) const chain = CHAINS[chainId] @@ -32,13 +26,9 @@ const NFTGridItem: React.FC = ({ nft, chainId }) => { className={classes.linkContainer} >
    -

    - - {name || "..."} - -

    + {showCollectionName && ( +

    {name || "..."}

    + )} {nft.token_id.length < 7 && (

    {nft.token_id || "..."}

    )} diff --git a/frontend/src/hooks/useCollection.ts b/frontend/src/hooks/useCollection.ts new file mode 100644 index 0000000..d1dd6cf --- /dev/null +++ b/frontend/src/hooks/useCollection.ts @@ -0,0 +1,33 @@ +import { useQuery } from "@tanstack/react-query" +import { MoralisApiListResponse, MoralisNFT } from "../types/Token" + +interface Props { + tokenAddress: string + chainId: number +} + +if (!process.env.REACT_APP_PROXY_URL) { + throw new Error("REACT_APP_PROXY_URL not set") +} + +const useCollection = ({ tokenAddress, chainId }: Props) => { + return useQuery({ + queryKey: ["collection", chainId, tokenAddress], + queryFn: async () => { + if (!chainId || !tokenAddress) throw new Error("No chainId or token") + + // get collection metadata + const nftRes = await fetch( + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/nft/${tokenAddress}` + ) + if (!nftRes.ok) { + throw new Error("NFT request failed") + } + const collection = (await nftRes.json()) as MoralisApiListResponse + return collection.result as MoralisNFT[] + }, + enabled: !!chainId && !!tokenAddress, + }) +} + +export default useCollection diff --git a/frontend/src/hooks/useCollectionMetadata.ts b/frontend/src/hooks/useCollectionMetadata.ts new file mode 100644 index 0000000..8722964 --- /dev/null +++ b/frontend/src/hooks/useCollectionMetadata.ts @@ -0,0 +1,34 @@ +import { useQuery } from "@tanstack/react-query" +import { MoralisCollectionMetadata } from "../types/Token" + +interface Props { + tokenAddress: string + chainId: number +} + +if (!process.env.REACT_APP_PROXY_URL) { + throw new Error("REACT_APP_PROXY_URL not set") +} + +const useCollectionMetadata = ({ tokenAddress, chainId }: Props) => { + return useQuery({ + queryKey: ["collectionMetadata", chainId, tokenAddress], + queryFn: async () => { + if (!chainId || !tokenAddress) throw new Error("No chainId or token") + + // get collection metadata + const nftRes = await fetch( + `${process.env.REACT_APP_PROXY_URL}/${chainId}/moralis/nft/${tokenAddress}/metadata` + ) + if (!nftRes.ok) { + throw new Error("NFT request failed") + } + const collectionMetadata = + (await nftRes.json()) as MoralisCollectionMetadata + return collectionMetadata + }, + enabled: !!chainId && !!tokenAddress, + }) +} + +export default useCollectionMetadata diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index 7fb6e65..298ac28 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -1,8 +1,8 @@ -import React from "react" import { createBrowserRouter } from "react-router-dom" import Mech from "./routes/Mech" import Account from "./routes/Account" import Landing from "./routes/Landing" +import Collection from "./routes/Collection" export default createBrowserRouter([ { @@ -17,4 +17,8 @@ export default createBrowserRouter([ path: "account/:address/", element: , }, + { + path: "collection/:address/", + element: , + }, ]) diff --git a/frontend/src/routes/Account/index.tsx b/frontend/src/routes/Account/index.tsx index 1192096..b3289aa 100644 --- a/frontend/src/routes/Account/index.tsx +++ b/frontend/src/routes/Account/index.tsx @@ -2,7 +2,7 @@ import React from "react" import { useParams } from "react-router-dom" import Layout from "../../components/Layout" -import NFTGrid from "../../components/NFTGrid" +import { AccountNftGrid } from "../../components/NFTGrid" import classes from "./Account.module.css" import { getAddress } from "viem" import Blockie from "../../components/Blockie" @@ -31,7 +31,7 @@ const Landing: React.FC = () => {
    - +
    ) diff --git a/frontend/src/routes/Collection/Collection.module.css b/frontend/src/routes/Collection/Collection.module.css new file mode 100644 index 0000000..1a07886 --- /dev/null +++ b/frontend/src/routes/Collection/Collection.module.css @@ -0,0 +1,35 @@ +.container { + width: 100%; + background: var(--box-bg); + border-radius: 20px; + padding: 20px; +} + +.accountHeader { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 20px; + background-color: var(--box-bg); + border-radius: 10px; + padding: 10px 20px; + width: 100%; +} + +.account { + display: flex; + align-items: center; + gap: 10px; +} +.title { + font-size: 1.5rem; +} +.accountHeader h1 { + font-size: 1rem; +} + +.blockie { + width: 25px; + aspect-ratio: 1/1; +} diff --git a/frontend/src/routes/Collection/index.tsx b/frontend/src/routes/Collection/index.tsx new file mode 100644 index 0000000..9b5f02c --- /dev/null +++ b/frontend/src/routes/Collection/index.tsx @@ -0,0 +1,57 @@ +import React from "react" +import { useParams } from "react-router-dom" + +import Layout from "../../components/Layout" +import { CollectionNftGrid } from "../../components/NFTGrid" +import classes from "./Collection.module.css" +import { getAddress } from "viem" +import Blockie from "../../components/Blockie" +import useCollectionMetadata from "../../hooks/useCollectionMetadata" +import { useChainId } from "wagmi" + +const Collection: React.FC = () => { + const { address } = useParams() + const chainId = useChainId() + let validAddress = "" + try { + validAddress = getAddress(address || "") + } catch (error) { + console.log(error) + } + const { data, isLoading, error } = useCollectionMetadata({ + tokenAddress: validAddress, + chainId, + }) + + if (validAddress) { + return ( + +
    +
    +
    + {data && !isLoading ? data.name : "Collection"} +
    +
    +
    + +
    +

    + {validAddress} +

    +
    +
    + +
    +
    + ) + } + + return ( + +

    + {address} is not a valid address +

    +
    + ) +} +export default Collection diff --git a/frontend/src/types/Token.d.ts b/frontend/src/types/Token.d.ts index 5dfef3c..a06be21 100644 --- a/frontend/src/types/Token.d.ts +++ b/frontend/src/types/Token.d.ts @@ -34,3 +34,20 @@ export interface MoralisFungible { balance: string possible_spam?: boolean } + +export interface MoralisCollectionMetadata { + token_address: string + name: string + symbol: string + contract_type: NFTType + possible_spam: boolean + verified_collection: boolean + synced_at: string +} + +export interface MoralisApiListResponse { + cursor: string + page: number + page_size: number + result: MoralisNFT[] | MoralisFungible[] +} From 10105305e3d3d3ed8775f244038c6b1c8808dea3 Mon Sep 17 00:00:00 2001 From: samepant Date: Fri, 19 Jan 2024 13:33:56 -0500 Subject: [PATCH 11/12] update nftItem component --- .../src/components/NFTGrid/NFTGrid.module.css | 10 +++++++ frontend/src/components/NFTGrid/index.tsx | 8 +++++ .../src/components/NFTItem/NFTItem.module.css | 9 ++++-- frontend/src/components/NFTItem/index.tsx | 29 +++++++++---------- frontend/src/hooks/useCollection.ts | 3 +- frontend/src/hooks/useDeployMech.tsx | 1 + frontend/src/routes/Mech/Mech.module.css | 4 +-- frontend/src/utils/shortenAddress.ts | 12 ++++---- 8 files changed, 47 insertions(+), 29 deletions(-) diff --git a/frontend/src/components/NFTGrid/NFTGrid.module.css b/frontend/src/components/NFTGrid/NFTGrid.module.css index df33d9c..f12c8a4 100644 --- a/frontend/src/components/NFTGrid/NFTGrid.module.css +++ b/frontend/src/components/NFTGrid/NFTGrid.module.css @@ -31,3 +31,13 @@ border-radius: 10px; width: fit-content; } + +.noNfts { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + background: var(--box-bg); + padding: 20px; + font-size: 12px; +} diff --git a/frontend/src/components/NFTGrid/index.tsx b/frontend/src/components/NFTGrid/index.tsx index 53a077c..08c3868 100644 --- a/frontend/src/components/NFTGrid/index.tsx +++ b/frontend/src/components/NFTGrid/index.tsx @@ -37,6 +37,14 @@ export const AccountNftGrid: React.FC = ({ address }) => { if (isLoading) return + if (nfts.length === 0) { + return ( +
    +

    No NFTs found

    +
    + ) + } + return (
      {nfts.map((nft, index) => ( diff --git a/frontend/src/components/NFTItem/NFTItem.module.css b/frontend/src/components/NFTItem/NFTItem.module.css index bb969b3..7287245 100644 --- a/frontend/src/components/NFTItem/NFTItem.module.css +++ b/frontend/src/components/NFTItem/NFTItem.module.css @@ -84,10 +84,11 @@ } .itemContainer label { - border: 2px solid var(--button-border); + background: var(--box-bg); border-radius: 7px; padding: 5px 10px; width: fit-content; + font-size: 12px; } .info .infoItem { @@ -100,6 +101,7 @@ padding: 5px 7px; box-shadow: 1px 1px 4px 0px rgba(157, 212, 0, 0.2); font-family: monospace; + font-size: 12px; } .info li { @@ -113,8 +115,8 @@ } .indicator { - width: 15px; - height: 15px; + width: 10px; + height: 10px; border-radius: 50%; filter: blur(4px); background-color: rgb(189 192 179); @@ -172,6 +174,7 @@ .asset { display: flex; justify-content: space-between; + font-size: 12px; } .asset .value { diff --git a/frontend/src/components/NFTItem/index.tsx b/frontend/src/components/NFTItem/index.tsx index 34b37ae..45b8c41 100644 --- a/frontend/src/components/NFTItem/index.tsx +++ b/frontend/src/components/NFTItem/index.tsx @@ -12,6 +12,7 @@ import { calculateMechAddress } from "../../utils/calculateMechAddress" import { formatUnits } from "viem" import { MoralisNFT } from "../../types/Token" import { getNFTContext } from "../../utils/getNFTContext" +import { AccountNftGrid } from "../NFTGrid" interface Props { nft: MoralisNFT @@ -33,10 +34,10 @@ const NFTItem: React.FC = ({ nft, chainId }) => { chainId, }) - console.log(data) const mechBalances = data ? [data.native, ...data.erc20s] : [] const { deployed } = useDeployMech(getNFTContext(nft), chainId) - const name = nft.name || nft.metadata?.name || "..." + const metadata = JSON.parse(nft.metadata || "{}") + const name = nft.name || metadata?.name || "..." return (
      @@ -47,13 +48,13 @@ const NFTItem: React.FC = ({ nft, chainId }) => {

      - {(imageError || !nft.metadata?.image) && ( + {(imageError || !metadata?.image) && (
      )} - {!imageError && nft.metadata?.image && ( + {!imageError && metadata?.image && (
      {name} setImageError(true)} @@ -81,7 +82,7 @@ const NFTItem: React.FC = ({ nft, chainId }) => { onClick={() => copy(mechAddress)} title={mechAddress} > - {shortenAddress(mechAddress)} + {shortenAddress(mechAddress, 6)}
    • @@ -96,21 +97,15 @@ const NFTItem: React.FC = ({ nft, chainId }) => { title={operatorAddress} >
      - {operatorAddress ? shortenAddress(operatorAddress) : "\u2014"} + {operatorAddress + ? shortenAddress(operatorAddress, 6) + : "\u2014"}
    • - {/*
    • - -
      - {assetsError || !assetsData - ? "n/a" - : `$ ${assetsData.totalBalanceUSD}`} -
      -
    • */}
    - +
    = ({ nft, chainId }) => { ))}
    + +
    ) } diff --git a/frontend/src/hooks/useCollection.ts b/frontend/src/hooks/useCollection.ts index d1dd6cf..840e26c 100644 --- a/frontend/src/hooks/useCollection.ts +++ b/frontend/src/hooks/useCollection.ts @@ -4,13 +4,14 @@ import { MoralisApiListResponse, MoralisNFT } from "../types/Token" interface Props { tokenAddress: string chainId: number + page?: number } if (!process.env.REACT_APP_PROXY_URL) { throw new Error("REACT_APP_PROXY_URL not set") } -const useCollection = ({ tokenAddress, chainId }: Props) => { +const useCollection = ({ tokenAddress, chainId, page = 0 }: Props) => { return useQuery({ queryKey: ["collection", chainId, tokenAddress], queryFn: async () => { diff --git a/frontend/src/hooks/useDeployMech.tsx b/frontend/src/hooks/useDeployMech.tsx index 5e92db4..b9f2ef8 100644 --- a/frontend/src/hooks/useDeployMech.tsx +++ b/frontend/src/hooks/useDeployMech.tsx @@ -81,6 +81,7 @@ export const useDeployedMechs = (nfts: NFTContext[], chainId: number) => { }, ]) .catch((e) => { + console.error(e) /* when switching networks, this might throw an error (`Missing queryFn for queryKey`) */ }) }) diff --git a/frontend/src/routes/Mech/Mech.module.css b/frontend/src/routes/Mech/Mech.module.css index feda08f..b9f8d74 100644 --- a/frontend/src/routes/Mech/Mech.module.css +++ b/frontend/src/routes/Mech/Mech.module.css @@ -3,9 +3,7 @@ align-items: flex-start; justify-content: center; gap: 50px; - width: 72%; - max-width: 2000px; - margin: 0 auto; + width: 100%; } /* @media (max-width: 800px) { diff --git a/frontend/src/utils/shortenAddress.ts b/frontend/src/utils/shortenAddress.ts index 7b3a627..090bd65 100644 --- a/frontend/src/utils/shortenAddress.ts +++ b/frontend/src/utils/shortenAddress.ts @@ -1,11 +1,11 @@ import { validateAddress } from "./addressValidation" -const VISIBLE_END = 4 -const VISIBLE_START = 4 - -export const shortenAddress = (address: string): string => { +export const shortenAddress = ( + address: string, + visibleDigits: number = 4 +): string => { const checksumAddress = validateAddress(address) - const start = checksumAddress.substring(0, VISIBLE_START + 2) - const end = checksumAddress.substring(42 - VISIBLE_END, 42) + const start = checksumAddress.substring(0, visibleDigits + 2) + const end = checksumAddress.substring(42 - visibleDigits, 42) return `${start}...${end}` } From 9032ad15c4adb4f101000d27c360405bc3cbd543 Mon Sep 17 00:00:00 2001 From: samepant Date: Fri, 19 Jan 2024 15:44:27 -0500 Subject: [PATCH 12/12] add view account button for viewing connected --- .../ConnectButton/ConnectButton.module.css | 5 ++++ .../src/components/ConnectButton/index.tsx | 1 + .../src/components/Layout/Layout.module.css | 30 +++++++++++++++++++ frontend/src/components/Layout/index.tsx | 24 ++++++++++++--- .../src/components/NFTGrid/NFTGrid.module.css | 3 -- frontend/src/components/NFTGrid/index.tsx | 1 - .../src/components/NFTItem/NFTItem.module.css | 4 --- frontend/src/components/NFTItem/index.tsx | 2 +- frontend/src/routes/Mech/index.tsx | 2 +- 9 files changed, 58 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/ConnectButton/ConnectButton.module.css b/frontend/src/components/ConnectButton/ConnectButton.module.css index 3efe045..f6ff10c 100644 --- a/frontend/src/components/ConnectButton/ConnectButton.module.css +++ b/frontend/src/components/ConnectButton/ConnectButton.module.css @@ -1,3 +1,8 @@ +.container { + position: relative; + z-index: 100; +} + .blockie { height: 1.5em; } diff --git a/frontend/src/components/ConnectButton/index.tsx b/frontend/src/components/ConnectButton/index.tsx index e6a73bc..df4f224 100644 --- a/frontend/src/components/ConnectButton/index.tsx +++ b/frontend/src/components/ConnectButton/index.tsx @@ -22,6 +22,7 @@ export const ConnectButton = () => { userSelect: "none", }, })} + className={classes.container} > {(() => { if (!connected) { diff --git a/frontend/src/components/Layout/Layout.module.css b/frontend/src/components/Layout/Layout.module.css index b5dbb3f..ab5be5b 100644 --- a/frontend/src/components/Layout/Layout.module.css +++ b/frontend/src/components/Layout/Layout.module.css @@ -76,3 +76,33 @@ .nav a:hover { filter: brightness(1.2); } + +.accountButtons { + position: relative; +} + +.accountButtons:hover .viewAccountContainer { + display: block; +} + +.viewAccountContainer { + display: none; + position: absolute; + bottom: -120%; + right: 0; + z-index: 90; + padding-top: 30%; +} + +button.viewAccount { + background: rgb(248 212 226); + border-radius: 10px; + padding: 6px 12px; + border: 2px solid var(--button-bg); + box-shadow: 2px 2px 10px 0px rgba(150, 203, 0, 0.44); +} + +button.viewAccount:hover { + background-color: var(--button-bg); + filter: brightness(1); +} diff --git a/frontend/src/components/Layout/index.tsx b/frontend/src/components/Layout/index.tsx index 1b672f2..8ae8d42 100644 --- a/frontend/src/components/Layout/index.tsx +++ b/frontend/src/components/Layout/index.tsx @@ -1,18 +1,19 @@ import { ReactNode } from "react" import classes from "./Layout.module.css" -import { shortenAddress } from "../../utils/shortenAddress" import { Link } from "react-router-dom" import ChainSelect from "../ChainSelect" import ConnectButton from "../ConnectButton" import Search from "../Search" +import { useAccount } from "wagmi" +import Button from "../Button" interface Props { - mechAddress?: string children: ReactNode } -const Layout: React.FC = ({ children, mechAddress }) => { +const Layout: React.FC = ({ children }) => { + const { address } = useAccount() return (
    cockpit @@ -26,7 +27,22 @@ const Layout: React.FC = ({ children, mechAddress }) => {
    - +
    + + {address && ( +
    + + + +
    + )} +
    diff --git a/frontend/src/components/NFTGrid/NFTGrid.module.css b/frontend/src/components/NFTGrid/NFTGrid.module.css index f12c8a4..ac292fe 100644 --- a/frontend/src/components/NFTGrid/NFTGrid.module.css +++ b/frontend/src/components/NFTGrid/NFTGrid.module.css @@ -7,9 +7,6 @@ width: 100%; } -.grid li { -} - .container { display: flex; flex-direction: column; diff --git a/frontend/src/components/NFTGrid/index.tsx b/frontend/src/components/NFTGrid/index.tsx index 08c3868..626b9c6 100644 --- a/frontend/src/components/NFTGrid/index.tsx +++ b/frontend/src/components/NFTGrid/index.tsx @@ -2,7 +2,6 @@ import NFTGridItem from "../NFTGridItem" import Spinner from "../Spinner" import classes from "./NFTGrid.module.css" -import clsx from "clsx" import { useChainId } from "wagmi" import { useDeployedMechs } from "../../hooks/useDeployMech" import { calculateMechAddress } from "../../utils/calculateMechAddress" diff --git a/frontend/src/components/NFTItem/NFTItem.module.css b/frontend/src/components/NFTItem/NFTItem.module.css index 7287245..2ceef78 100644 --- a/frontend/src/components/NFTItem/NFTItem.module.css +++ b/frontend/src/components/NFTItem/NFTItem.module.css @@ -72,10 +72,6 @@ justify-content: center; align-items: center; } - -.name { -} - .info { width: 45%; display: flex; diff --git a/frontend/src/components/NFTItem/index.tsx b/frontend/src/components/NFTItem/index.tsx index 45b8c41..28aa0d0 100644 --- a/frontend/src/components/NFTItem/index.tsx +++ b/frontend/src/components/NFTItem/index.tsx @@ -119,7 +119,7 @@ const NFTItem: React.FC = ({ nft, chainId }) => {
      {mechBalances.map((balance, index) => (
    • -
      {balance.name}
      +
      {balance.name}

      {formatUnits(BigInt(balance.balance), balance.decimals || 0)} diff --git a/frontend/src/routes/Mech/index.tsx b/frontend/src/routes/Mech/index.tsx index 390d344..ca40b3a 100644 --- a/frontend/src/routes/Mech/index.tsx +++ b/frontend/src/routes/Mech/index.tsx @@ -58,7 +58,7 @@ const Mech: React.FC = () => { const handleRequest = useHandleRequest(mechAddress) return ( - +

      {isLoading && } {!error && !isLoading && nft && mechAddress && (